{"id":14962761,"url":"https://github.com/baseballyama/svelte-preprocess-delegate-events","last_synced_at":"2025-04-06T07:14:27.463Z","repository":{"id":162800635,"uuid":"635363958","full_name":"baseballyama/svelte-preprocess-delegate-events","owner":"baseballyama","description":"You can delegate events by on:* 🎉","archived":false,"fork":false,"pushed_at":"2024-10-27T22:30:09.000Z","size":352,"stargazers_count":53,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-30T00:32:54.247Z","etag":null,"topics":["preprocessor","svelte","sveltejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/baseballyama.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-02T14:34:08.000Z","updated_at":"2024-10-27T22:30:02.000Z","dependencies_parsed_at":"2023-12-26T07:24:32.446Z","dependency_job_id":"18792928-45ff-4801-b852-5f2ac1c8e5b0","html_url":"https://github.com/baseballyama/svelte-preprocess-delegate-events","commit_stats":{"total_commits":168,"total_committers":4,"mean_commits":42.0,"dds":0.3214285714285714,"last_synced_commit":"d4178e23d5686e6769726cbe09cb12f0a89b36d6"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baseballyama%2Fsvelte-preprocess-delegate-events","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baseballyama%2Fsvelte-preprocess-delegate-events/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baseballyama%2Fsvelte-preprocess-delegate-events/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baseballyama%2Fsvelte-preprocess-delegate-events/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baseballyama","download_url":"https://codeload.github.com/baseballyama/svelte-preprocess-delegate-events/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445681,"owners_count":20939961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["preprocessor","svelte","sveltejs"],"created_at":"2024-09-24T13:30:28.538Z","updated_at":"2025-04-06T07:14:27.437Z","avatar_url":"https://github.com/baseballyama.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"[![NPM license](https://img.shields.io/npm/l/svelte-preprocess-delegate-events.svg)](https://www.npmjs.com/package/svelte-preprocess-delegate-events)\n[![NPM version](https://img.shields.io/npm/v/svelte-preprocess-delegate-events.svg)](https://www.npmjs.com/package/svelte-preprocess-delegate-events)\n[![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n[![Build Status](https://github.com/baseballyama/svelte-preprocess-delegate-events/workflows/CI/badge.svg?branch=main)](https://github.com/baseballyama/svelte-preprocess-delegate-events/actions?query=workflow:ci)\n[![Coverage Status](https://coveralls.io/repos/github/baseballyama/svelte-preprocess-delegate-events/badge.svg?branch=main)](https://coveralls.io/github/baseballyama/svelte-preprocess-delegate-events?branch=main)\n\n# Delegate events with `on:*` 🎉\n\n- 💡 Easy to use\n- ⚡️ No performance impact\n- 🔑 No type errors with [svelte-check](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check)\n\n## Try it on [Stackblitz](https://stackblitz.com/edit/sveltejs-kit-template-default-rwmhls?file=src%2Froutes%2F%2Bpage.svelte\u0026terminal=dev) 🚀.\n\n# Overview\n\nSince 2019, one popular issue on the Svelte GitHub repository has been delegating all events.\u003cbr\u003e\nhttps://github.com/sveltejs/svelte/issues/2837\n\nThis repository aims to solve this issue.\n\n# Example\n\n**Component.svelte**\n\n```svelte\n\u003c!-- Delegate all events with `on:*` 🎉 --\u003e\n\u003cinput on:* /\u003e\n```\n\n**App.svelte**\n\n```svelte\n\u003cscript\u003e\n  import Component from './Component.svelte';\n\u003c/script\u003e\n\n\u003c!-- Handle events as desired --\u003e\n\u003cComponent\n  on:input=\"{(e) =\u003e console.log(e.target.value)}\"\n  on:blur=\"{() =\u003e console.log('blur')}\"\n/\u003e\n```\n\n# Prerequisites\n\nThis library needs Svelte 3 or Svelte 4.\n\n# Installation\n\n```shell\nnpm install -D svelte-preprocess-delegate-events\n```\n\n# Usage\n\nAfter installation, add this as a Svelte preprocessor.\n\n```js\n// svelte.config.js\nimport delegateEvents from \"svelte-preprocess-delegate-events/preprocess\";\n\nconst config = {\n  // Add this preprocessor at the end of the array.\n  preprocess: [delegateEvents()],\n};\n\nexport default config;\n```\n\n# Integration with svelte-check\n\nIf you want to use `svelte-check`, create `svelte-jsx.d.ts` at the project root and update `[tj]sconfig.json`.\n\n**svelte-jsx.d.ts**\n```ts\ndeclare namespace svelteHTML {\n  /**\n   * base: https://github.com/sveltejs/language-tools/blob/651db67858d18ace44d000d263ac57ed5590ea05/packages/svelte2tsx/svelte-jsx.d.ts#L42\n   */\n  type HTMLProps\u003cProperty extends string, Override\u003e =\n    Omit\u003c\n      Omit\u003cimport('svelte/elements').SvelteHTMLElements[Property], keyof EventsWithColon\u003cOmit\u003csvelte.JSX.IntrinsicElements[Property \u0026 string], svelte.JSX.AttributeNames\u003e\u003e\u003e \u0026 EventsWithColon\u003cOmit\u003csvelte.JSX.IntrinsicElements[Property \u0026 string], svelte.JSX.AttributeNames\u003e\u003e,\n      keyof Override\n    \u003e \u0026 Override \u0026 (Record\u003c'on:*', (event: Event \u0026 { currentTarget: EventTarget \u0026 EventTarget }) =\u003e any | never\u003e | object);\n}\n```\n\n**[tj]sconfig.json**\n```diff\n{\n+ \"include\": [\"./svelte-jsx.d.ts\"]\n}\n```\n\n# How the Preprocessor Works?\n\nThis chapter explains how the preprocessor functions. The preprocessor operates differently for Elements and Components.\n\n## Element\n\nConsider the following simple example:\n\n```svelte\n\u003c!-- Parant.svelte --\u003e\n\u003cscript\u003e\n  import Child from './Child.svelte';\n\u003c/script\u003e\n\u003cChild on:click={() =\u003e console.log('clicked!')} /\u003e\n\n\u003c!-- Child.svelte --\u003e\n\u003cbutton on:*\u003eClick Me\u003c/button\u003e\n```\n\nSvelte executes events registered in `component.$$.callbacks` when an event is triggered in a child component. In the example above, `component.$$.callbacks` is as follows:\n```js\ncomponent.$$.callbacks = {\n  click: () =\u003e console.log('clicked!')\n}\n```\n\nThis preprocessor adds a process to listen for events registered in `component.$$.callbacks` for elements with `on:*`. After preprocessing, Child.svelte looks like this:\n```svelte\n\u003c!-- Child.svelte --\u003e\n\u003cscript\u003e\n  import { boundElements, registerDelegatedEvents } from 'svelte-preprocess-delegate-events/runtime';\n  import { get_current_component } from 'svelte/internal';\n  let button = boundElements();\n  const component = get_current_component();\n  $: registerDelegatedEvents(button.bounds, component, (handler) =\u003e handler, {});\n\u003c/script\u003e\n\n\u003cbutton bind:this={button.bounds}\u003eClick Me\u003c/button\u003e\n```\nNOTE: The reason for binding `\u003cbutton\u003e` to `button.bounds` instead of binding it to the `button` variable is to support cases where multiple elements exist, such as `\u003cbutton\u003e` in a `{#each}` block.\n\nIn this way, only events that are being listened to by the parent component are listened to, thus providing a mechanism with no performance overhead.\n\n## Component\n\nComponent uses a different mechanism than Element. Consider the following simple example:\n```svelte\n\u003c!-- Parant.svelte --\u003e\n\u003cscript\u003e\n  import Child from './Child.svelte';\n\u003c/script\u003e\n\u003cChild on:click={() =\u003e console.log('clicked!')} /\u003e\n\n\u003c!-- Child.svelte --\u003e\n\u003cscript\u003e\n  import GrandChild from './GrandChild.svelte';\n\u003c/script\u003e\n\u003cGrandChild on:* /\u003e\n\n\u003c!-- GrandChild.svelte --\u003e\n\u003cbutton on:click on:blur\u003eClick Me\u003c/button\u003e\n```\n\nIf you are using `on:*` in `Child.svelte`, you need to forward all events from `GrandChild` to `Parent`. However, `Child` does not know what events are coming from `GrandChild`, so you need to do something. Specifically, when `GrandChild` triggers an event, it will refer to `component.$$.callbacks` to run its event handlers. By proxying `component.$$.callbacks`, you will know which events have been forwarded. Forwarded events can be communicated to the parent component so that the `Parent` component can handle the event.\n\nAfter preprocessing, it looks like this:\n```svelte\n\u003c!-- Child.svelte --\u003e\n\u003cscript\u003e\n  import { boundComponents, proxyCallbacks } from 'svelte-preprocess-delegate-events/runtime';\n  import { get_current_component } from 'svelte/internal';\n  import GrandChild from './GrandChild.svelte';\n\n  const GrandChild = boundComponents();\n  const component = get_current_component();\n  $: proxyCallbacks(component, GrandChild.bounds, false);\n  \u003c/script\u003e\n\n\u003cGrandChild bind:this={GrandChild.bounds} /\u003e\n```\n\n# Note\n\n`on:*` does not support specifying event handlers directly because a useful use case could not be found. If you have a useful use case, please create a new issue.\n\n```svelte\n\u003cscript\u003e\n  import Component from './Component.svelte';\n  const handleEvent = (e) =\u003e {\n    console.log(e);\n  }\n\u003c/script\u003e\n\n\u003c!-- Specifying event handler directly is not supported --\u003e\n\u003cinput on:*=\"{handleEvent}\" /\u003e\n\n\u003c!-- Specifying event handler directly is not supported --\u003e\n\u003cComponent on:*=\"{handleEvent}\" /\u003e\n```\n\n# For Svelte 5 Users\n\nFor Svelte 5, event forwarding is natively supported.🎉\n\nhttps://svelte-5-preview.vercel.app/docs/event-handlers#bubbling-events\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaseballyama%2Fsvelte-preprocess-delegate-events","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaseballyama%2Fsvelte-preprocess-delegate-events","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaseballyama%2Fsvelte-preprocess-delegate-events/lists"}