* **breaking** Minimum supported Node version is now Node 14
* **breaking** Minimum supported TypeScript version is now 5 (it will likely work with lower versions, but we make no guarantess about that)
* **breaking** Stricter types for `createEventDispatcher` (see PR for migration instructions) ([#7224](https://github.com/sveltejs/svelte/pull/7224))
* **breaking** Stricter types for `Action` and `ActionReturn` (see PR for migration instructions) ([#7224](https://github.com/sveltejs/svelte/pull/7224))
* **breaking** Stricter types for `onMount` - now throws a type error when returning a function asynchronously to catch potential mistakes around callback functions (see PR for migration instructions) ([#8136](https://github.com/sveltejs/svelte/pull/8136))
* Bind `null` option and input values consistently ([#8312](https://github.com/sveltejs/svelte/issues/8312))
## Unreleased (3.0)
* Handle `width`/`height` attributes when spreading ([#6752](https://github.com/sveltejs/svelte/issues/6752))
* Add support for resize observer bindings (`<divbind:contentRect|contentBoxSize|borderBoxSize|devicePixelContentBoxSize>`) ([#8022](https://github.com/sveltejs/svelte/pull/8022))
## 3.58.0
* Add `bind:innerText` for `contenteditable` elements ([#3311](https://github.com/sveltejs/svelte/issues/3311))
* Add support for CSS `@container` queries ([#6969](https://github.com/sveltejs/svelte/issues/6969))
* Respect `preserveComments` in DOM output ([#7182](https://github.com/sveltejs/svelte/pull/7182))
* Allow use of `document` for `target` in typings ([#7554](https://github.com/sveltejs/svelte/pull/7554))
* Add `axis` parameter to `slide` transition ([#6182](https://github.com/sveltejs/svelte/issues/6182))
* Add `readonly` utility to convert `writable` store to readonly ([#6518](https://github.com/sveltejs/svelte/pull/6518))
* Add `readyState` binding for media elements ([#6666](https://github.com/sveltejs/svelte/issues/6666))
* Generate valid automatic component names when the filename contains only special characters ([#7143](https://github.com/sveltejs/svelte/issues/7143))
* Add `naturalWidth` and `naturalHeight` bindings ([#7771](https://github.com/sveltejs/svelte/issues/7771))
* Support `<!-- svelte-ignore ... -->` on components ([#8082](https://github.com/sveltejs/svelte/issues/8082))
* Add a11y warnings:
* Add a11y warnings:
* `aria-activedescendant-has-tabindex`: elements with `aria-activedescendant` need to have a `tabindex` ([#8172](https://github.com/sveltejs/svelte/pull/8172))
* `aria-activedescendant-has-tabindex`: checks that elements with `aria-activedescendant` have a `tabindex` ([#8172](https://github.com/sveltejs/svelte/pull/8172))
*
* `role-supports-aria-props`: checks that the (implicit) element role supports the given aria attributes ([#8195](https://github.com/sveltejs/svelte/pull/8195))
* Omit a11y warning on `<video>` tags with `aria-hidden="true"` ([#7874](https://github.com/sveltejs/svelte/issues/7874))
* Omit a11y "no child content" warning on elements with `aria-label` ([#8299](https://github.com/sveltejs/svelte/pull/8299))
* Make `noreferrer` warning less zealous ([#6289](https://github.com/sveltejs/svelte/issues/6289))
* `trusted-types` CSP compatibility for Web Components ([#8134](https://github.com/sveltejs/svelte/issues/8134))
* Add `data-sveltekit-replacestate` and `data-sveltekit-keepfocus` attribute typings ([#8281](https://github.com/sveltejs/svelte/issues/8281))
* Add `data-sveltekit-replacestate` and `data-sveltekit-keepfocus` attribute typings ([#8281](https://github.com/sveltejs/svelte/issues/8281))
* Don't throw when calling `unsubscribe` twice ([#8186](https://github.com/sveltejs/svelte/pull/8186))
* Compute node dimensions immediately before crossfading ([#4111](https://github.com/sveltejs/svelte/issues/4111))
* Ensure `afterUpdate` is not called after `onDestroy` ([#7476](https://github.com/sveltejs/svelte/issues/7476))
* Improve handling of `inert` attribute ([#7500](https://github.com/sveltejs/svelte/issues/7500))
* Reduce use of template literals in SSR output for better performance ([#7539](https://github.com/sveltejs/svelte/pull/7539))
* Ensure `<input>` value persists when swapping elements with spread attributes in an `{#each}` block ([#7578](https://github.com/sveltejs/svelte/issues/7578))
* Simplify generated code for reactive statements if dependencies are all static ([#7942](https://github.com/sveltejs/svelte/pull/7942))
* Fix race condition on `<svelte:element>` with transitions ([#7948](https://github.com/sveltejs/svelte/issues/7948))
* Allow assigning to a property of a `const` when destructuring ([#7964](https://github.com/sveltejs/svelte/issues/7964))
* Match browser behavior for decoding malformed HTML entities ([#8026](https://github.com/sveltejs/svelte/issues/8026))
* Ensure `trusted-types` CSP compatibility for Web Components ([#8134](https://github.com/sveltejs/svelte/issues/8134))
* Optimise `<svelte:element>` output code for static tag and static attribute ([#8161](https://github.com/sveltejs/svelte/pull/8161))
* Don't throw when calling unsubscribing from a store twice ([#8186](https://github.com/sveltejs/svelte/pull/8186))
* Clear inputs when `bind:group` value is set to `undefined` ([#8214](https://github.com/sveltejs/svelte/issues/8214))
* Fix handling of nested arrays with keyed `{#each}` containing a non-keyed `{#each}` ([#8282](https://github.com/sveltejs/svelte/issues/8282))
readonly'bind:contentBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
readonly'bind:borderBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
readonly'bind:devicePixelContentBoxSize'?:Array<{blockSize: number;inlineSize: number}>|undefined|null;// TODO make this ResizeObserverSize once we require TS>=4.4
"test":"npm run test:unit && npm run test:integration",
"test":"npm run test:unit && npm run test:integration && echo \"manually check that there are no type errors in test/types by opening the files in there\"",
There are slight differences between each of these, read more about them [here](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Differences_from_innerText).
@ -713,7 +719,7 @@ Elements with the `contenteditable` attribute support `innerHTML` and `textConte
---
---
Media elements (`<audio>` and `<video>`) have their own set of bindings — six*readonly* ones...
Media elements (`<audio>` and `<video>`) have their own set of bindings — seven*readonly* ones...
* `duration` (readonly) — the total duration of the video, in seconds
* `duration` (readonly) — the total duration of the video, in seconds
* `buffered` (readonly) — an array of `{start, end}` objects
* `buffered` (readonly) — an array of `{start, end}` objects
@ -721,6 +727,7 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — six
* `seekable` (readonly) — ditto
* `seekable` (readonly) — ditto
* `seeking` (readonly) — boolean
* `seeking` (readonly) — boolean
* `ended` (readonly) — boolean
* `ended` (readonly) — boolean
* `readyState` (readonly) — number between (and including) 0 and 4
...and five *two-way* bindings:
...and five *two-way* bindings:
@ -741,6 +748,7 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
bind:seekable
bind:seekable
bind:seeking
bind:seeking
bind:ended
bind:ended
bind:readyState
bind:currentTime
bind:currentTime
bind:playbackRate
bind:playbackRate
bind:paused
bind:paused
@ -751,6 +759,22 @@ Videos additionally have readonly `videoWidth` and `videoHeight` bindings.
></video>
></video>
```
```
##### Image element bindings
---
Image elements (`<img>`) have two readonly bindings:
* `naturalWidth` (readonly) — the original width of the image, available after the image has loaded
* `naturalHeight` (readonly) — the original height of the image, available after the image has loaded
```sv
<img
bind:naturalWidth
bind:naturalHeight
></img>
```
##### Block-level element bindings
##### Block-level element bindings
---
---
@ -1501,6 +1525,8 @@ The content is exposed in the child component using the `<slot>` element, which
</Widget>
</Widget>
```
```
Note: If you want to render regular `<slot>` element, You can use `<svelte:element this="slot" />`.
#### `<slot name="`*name*`">`
#### `<slot name="`*name*`">`
---
---
@ -1725,6 +1751,25 @@ All except `scrollX` and `scrollY` are readonly.
> Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
> Note that the page will not be scrolled to the initial value to avoid accessibility issues. Only subsequent changes to the bound variable of `scrollX` and `scrollY` will cause scrolling. However, if the scrolling behaviour is desired, call `scrollTo()` in `onMount()`.
### `<svelte:document>`
```sv
<svelte:documenton:event={handler}/>
```
---
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on `document`.
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
```sv
<svelte:document
on:visibilitychange={handleVisibilityChange}
use:someAction
/>
```
### `<svelte:body>`
### `<svelte:body>`
```sv
```sv
@ -1735,7 +1780,7 @@ All except `scrollX` and `scrollY` are readonly.
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on the `<body>` element.
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document.body`, such as `mouseenter` and `mouseleave`, which don't fire on `window`. It also lets you use [actions](/docs#template-syntax-element-directives-use-action) on the `<body>` element.
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
As with `<svelte:window>` and `<svelte:document>`, this element may only appear the top level of your component and must never be inside a block or element.
```sv
```sv
<svelte:body
<svelte:body
@ -1756,7 +1801,7 @@ As with `<svelte:window>`, this element may only appear the top level of your co
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content.
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content.
As with `<svelte:window>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.
As with `<svelte:window>`, `<svelte:document>` and `<svelte:body>`, this element may only appear at the top level of your component and must never be inside a block or element.
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `easing` (`function`, default `cubicOut`) — an [easing function](/docs#run-time-svelte-easing)
* `fallback` (`function`) — A fallback [transition](/docs#template-syntax-element-directives-transition-fn) to use for send when there is no matching element being received, and for receive when there is no element being sent.
* `fallback` (`function`) — A fallback [transition](/docs#template-syntax-element-directives-transition-fn) to use for send when there is no matching element being received, and for receive when there is no element being sent.
@ -55,7 +55,7 @@ Enforce that `autofocus` is not used on elements. Autofocusing elements can caus
### `a11y-click-events-have-key-events`
### `a11y-click-events-have-key-events`
Enforce `on:click` is accompanied by at least one of the following: `onKeyUp`, `onKeyDown`, `onKeyPress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.
Enforce `on:click` is accompanied by at least one of the following: `on:keyup`, `on:keydown`, `on:keypress`. Coding for the keyboard is important for users with physical disabilities who cannot use a mouse, AT compatibility, and screenreader users.
This does not apply for interactive or hidden elements.
This does not apply for interactive or hidden elements.
@ -64,6 +64,8 @@ This does not apply for interactive or hidden elements.
<divon:click={()=> {}} />
<divon:click={()=> {}} />
```
```
Note that the `keypress` event is now deprecated, so it is officially recommended to use either the `keyup` or `keydown` event instead, accordingly.
---
---
### `a11y-distracting-elements`
### `a11y-distracting-elements`
@ -135,6 +137,17 @@ Enforce that attributes important for accessibility have a valid value. For exam
---
---
### `a11y-interactive-supports-focus`
Enforce that elements with an interactive role and interactive handlers (mouse or key press) must be focusable or tabbable.
```sv
<!-- A11y: Elements with the 'button' interactive role must have a tabindex value. -->
<divrole="button"on:keypress={()=> {}} />
```
---
### `a11y-label-has-associated-control`
### `a11y-label-has-associated-control`
Enforce that a label tag has a text label and an associated control.
Enforce that a label tag has a text label and an associated control.
@ -275,6 +288,31 @@ Some HTML elements have default ARIA roles. Giving these elements an ARIA role t
---
---
### `a11y-no-noninteractive-element-interactions`
A non-interactive element does not support event handlers (mouse and key handlers). Non-interactive elements include `<main>`, `<area>`, `<h1>` (,`<h2>`, etc), `<p>`, `<img>`, `<li>`, `<ul>` and `<ol>`. Non-interactive [WAI-ARIA roles](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) include `article`, `banner`, `complementary`, `img`, `listitem`, `main`, `region` and `tooltip`.
```sv
<!-- `A11y: Non-interactive element <li> should not be assigned mouse or keyboard event listeners.` -->
<lion:click={()=> {}} />
<!-- `A11y: Non-interactive element <div> should not be assigned mouse or keyboard event listeners.` -->
[WAI-ARIA](https://www.w3.org/TR/wai-aria-1.1/#usage_intro) roles should not be used to convert a non-interactive element to an interactive element. Interactive ARIA roles include `button`, `link`, `checkbox`, `menuitem`, `menuitemcheckbox`, `menuitemradio`, `option`, `radio`, `searchbox`, `switch` and `textbox`.
```sv
<!-- A11y: Non-interactive element <h3> cannot have interactive role 'searchbox' -->
<h3role="searchbox">Button</h3>
```
---
### `a11y-no-noninteractive-tabindex`
### `a11y-no-noninteractive-tabindex`
Tab key navigation should be limited to elements on the page that can be interacted with.
Tab key navigation should be limited to elements on the page that can be interacted with.
@ -308,6 +346,20 @@ Elements with ARIA roles must have all required attributes for that role.
---
---
### `a11y-role-supports-aria-props`
Elements with explicit or implicit roles defined contain only `aria-*` properties supported by that role.
```sv
<!-- A11y: The attribute 'aria-multiline' is not supported by the role 'link'. -->
<divrole="link"aria-multiline/>
<!-- A11y: The attribute 'aria-required' is not supported by the role 'listitem'. This role is implicit on the element <li>. -->
<liaria-required/>
```
---
### `a11y-structure`
### `a11y-structure`
Enforce that certain DOM elements have the correct structure.
Enforce that certain DOM elements have the correct structure.
By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want.
By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want.
It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice what happens: it does not remove the first `<Thing>` component, but rather the *last* DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji.
It's easier to show why than to explain. Click to expand the `Console`, then click the 'Remove first thing' button a few times, and notice what happens: it does not remove the first `<Thing>` component, but rather the *last* DOM node. Then it updates the `name` value in the remaining DOM nodes, but not the emoji.
Instead, we'd like to remove only the first `<Thing>` component and its DOM node, and leave the others unaffected.
Instead, we'd like to remove only the first `<Thing>` component and its DOM node, and leave the others unaffected.
The `<textarea>` element behaves similarly to a text input in Svelte — use `bind:value` to create a two-way binding between the `<textarea>` content and the `value` variable:
The `<textarea>` element behaves similarly to a text input in Svelte — use `bind:value`:
```html
```html
<textareabind:value={value}></textarea>
<textareabind:value={value}></textarea>
@ -14,4 +13,4 @@ In cases like these, where the names match, we can also use a shorthand form:
There are slight differences between each of these, read more about them [here](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent#Differences_from_innerText).
Similar to `<svelte:window>`, the `<svelte:body>` element allows you to listen for events that fire on `document.body`. This is useful with the `mouseenter` and `mouseleave` events, which don't fire on `window`.
Add the `mouseenter` and `mouseleave` handlers to the `<svelte:body>` tag:
Similar to `<svelte:window>`, the `<svelte:document>` element allows you to listen for events that fire on `document`. This is useful with events like `selectionchange`, which doesn't fire on `window`.
Add the `selectionchange` handler to the `<svelte:document>` tag:
> Avoid `mouseenter` and `mouseleave` handlers on this element, these events are not fired on `document` in all browsers. Use `<svelte:body>` for this instead.
Similar to `<svelte:window>` and `<svelte:document>`, the `<svelte:body>` element allows you to listen for events that fire on `document.body`. This is useful with the `mouseenter` and `mouseleave` events, which don't fire on `window`.
Add the `mouseenter` and `mouseleave` handlers to the `<svelte:body>` tag: