feat: add svelete/events package and export attach function

pull/11912/head
Dominic Gannaway 2 years ago
parent ca6e9b5745
commit b51fcdd83a

@ -0,0 +1,5 @@
---
"svelte": patch
---
feat: add svelete/events package and export attach function

@ -81,6 +81,10 @@
"./transition": {
"types": "./types/index.d.ts",
"default": "./src/transition/index.js"
},
"./events": {
"types": "./types/index.d.ts",
"default": "./src/events/index.js"
}
},
"repository": {

@ -33,6 +33,7 @@ await createBundle({
[`${pkg.name}/server`]: `${dir}/src/server/index.js`,
[`${pkg.name}/store`]: `${dir}/src/store/public.d.ts`,
[`${pkg.name}/transition`]: `${dir}/src/transition/public.d.ts`,
[`${pkg.name}/events`]: `${dir}/src/events/index.js`,
// TODO remove in Svelte 6
[`${pkg.name}/types/compiler/preprocess`]: `${dir}/src/compiler/preprocess/legacy-public.d.ts`,
[`${pkg.name}/types/compiler/interfaces`]: `${dir}/src/compiler/types/legacy-interfaces.d.ts`

@ -0,0 +1 @@
export { attach } from '../internal/client/dom/elements/events';

@ -66,6 +66,20 @@ export function create_event(event_name, dom, handler, options) {
return target_handler;
}
/**
* @param {Element} dom
* @param {string} event_name
* @param {EventListener} handler
* @param {AddEventListenerOptions} [options]
*/
export function attach(dom, event_name, handler, options = {}) {
var target_handler = create_event(event_name, dom, handler, options);
return () => {
dom.removeEventListener(event_name, target_handler, options);
};
}
/**
* @param {string} event_name
* @param {Element} dom

@ -0,0 +1,17 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
test({ assert, target, logs }) {
const [b1] = target.querySelectorAll('button');
b1?.click();
b1?.click();
b1?.click();
flushSync();
assert.htmlEqual(target.innerHTML, '<section><button>clicks: 3</button></section>');
assert.deepEqual(logs, []);
}
});

@ -0,0 +1,23 @@
<script>
import {attach} from 'svelte/events';
let count = $state(0);
function increment(e) {
e.stopPropagation();
count += 1;
}
let sectionEl
$effect(() => {
return attach(sectionEl, 'click', () => {
console.log('logged from addEventListener');
});
});
</script>
<section bind:this={sectionEl} onclick={() => console.log('logged from onclick')}>
<button onclick={increment}>
clicks: {count}
</button>
</section>

@ -2336,6 +2336,10 @@ declare module 'svelte/transition' {
}) => () => TransitionConfig];
}
declare module 'svelte/events' {
export function attach(dom: Element, event_name: string, handler: EventListener, options?: AddEventListenerOptions | undefined): () => void;
}
declare module 'svelte/types/compiler/preprocess' {
/** @deprecated import this from 'svelte/preprocess' instead */
export type MarkupPreprocessor = MarkupPreprocessor_1;

@ -115,6 +115,33 @@ Svelte provides reactive `Map`, `Set`, `Date` and `URL` classes. These can be im
<input bind:value={url.href} />
```
## `svelte/events`
Svelte provides a way of imperatively attaching DOM event listeners to elements using the `attach` export from `svelte/events`. This can be used in place of
imperatively doing `element.addEventListener`, with that benefit that `attach` will allow Svelte to co-ordinate the event through its own event delegation system.
```js
import { attach } from 'svelte/events';
attach(element, 'click', () => {
console.log('click the element!');
});
```
Additionally, `attach` returns a function that easily allows for removal of the attached event handler:
```js
import { attach } from 'svelte/events';
const remove = attach(element, 'click', () => {
console.log('click the element!');
});
// ...
remove();
```
> Note: `attach` also accepts 4th optional argument for defining the options for the event handler. This matches that of the options argument (`EventListenerOptions`) for `addEventListener`.
## `svelte/server`
### `render`

Loading…
Cancel
Save