Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Dec 14, 2024
2 parents c3428fc + 64a32ce commit e69c992
Show file tree
Hide file tree
Showing 308 changed files with 7,385 additions and 11,774 deletions.
2 changes: 0 additions & 2 deletions documentation/docs/03-template-syntax/03-each.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ Iterating over values can be done with an each block. The values in question can
</ul>
```

You can use each blocks to iterate over any array or array-like value — that is, any object with a `length` property.

An each block can also specify an _index_, equivalent to the second argument in an `array.map(...)` callback:

```svelte
Expand Down
6 changes: 3 additions & 3 deletions documentation/docs/03-template-syntax/06-snippet.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Snippets can reference themselves and each other ([demo](/playground/untitled#H4

## Passing snippets to components

Within the template, snippets are values just like any other. As such, they can be passed to components as props ([demo](/playground/untitled#H4sIAAAAAAAAE41SwY6bMBD9lRGplKQlYRMpF5ZF7T_0ttmDwSZYJbZrT9pGlv-9g4Fkk-xhxYV5vHlvhjc-aWQnXJK_-kSxo0jy5IcxSZrg2fSF-yM6FFQ7fbJ1jxSuttJguVd7lEejLcJPVnUCGquPMF9nsVoPjfNnohGx1sohMU4SHbzAa4_t0UNvmcOcGUNDzFP4jeccdikYK2v6sIWQ3lErpui5cDdPF_LmkVy3wlp5Vd5e2U_rHYSe_kYjFtl1KeVnTkljBEIrGBd2sYy8AtsyLlBk9DYhJHtTR_UbBDWybkR8NkqHWyOr_y74ZMNLz9f9AoG6ePkOJLMHLBp-xISvcPf11r0YUuMM2Ysfkgngh5XphUYKkJWU_FFz2UjBkxztSYT0cihR4LOn0tGaPrql439N-7Uh0Dl8MVYbt1jeJ1Fg7xDb_Uw2Y18YQqZ_S2U5FH1pS__dCkWMa3C0uR0pfQRTg89kE4bLLLDS_Dxy_Eywuo1TAnPAw4fqY1rvtH3W9w35ZZMgvU3jq8LhedwkguCHRhT_cMU6eVA5dKLB5wGutCWjlTOslupAxxrxceKoD2hzhe2qbmXHF1v1bbOcNCtW_zpYfVI8h5kQ4qY3mueHTlesW2C7TOEO4hcdwzgf3Nc7cZxUKKC4yuNhvIX_MlV_Xk0EAAA=)):
Within the template, snippets are values just like any other. As such, they can be passed to components as props ([demo](/playground/untitled#H4sIAAAAAAAAE3VS247aMBD9lZGpBGwDASRegonaPvQL2qdlH5zYEKvBNvbQLbL875VzAcKyj3PmzJnLGU8UOwqSkd8KJdaCk4TsZS0cyV49wYuJuQiQpGd-N2bu_ooaI1YwJ57hpVYoFDqSEepKKw3mO7VDeTTaIvxiRS1gb_URxvO0ibrS8WanIrHUyiHs7Vmigy28RmyHHmKvDMbMmFq4cQInvGSwTsBYWYoMVhCSB2rBFFPsyl0uruTlR3JZCWvlTXl1Yy_mawiR_rbZKZrellJ-5JQ0RiBUgnFhJ9OGR7HKmwVoilXeIye8DOJGfYCgRlZ3iE876TBsZPX7hPdteO75PC4QaIo8vwNPePmANQ2fMeEFHrLD7rR1jTNkW986E8C3KwfwVr8HSHOSEBT_kGRozyIkn_zQveXDL3rIfPJHtUDwzShJd_Qk3gQCbOGLsdq4yfTRJopRuin3I7nv6kL7ARRjmLdBDG3uv1mhuLA3V2mKtqNEf_oCn8p9aN-WYqH5peP4kWBl1UwJzAEPT9U7K--0fRrrWnPTXpCm1_EVdXjpNmlA8G1hPPyM1fKgMqjFHjctXGjLhZ05w0qpDhksGrybuNEHtJnCalZWsuaTlfq6nPaaBSv_HKw-K57BjzOiVj9ZKQYKzQjZodYFqydYTRN4gPhVzTDO2xnma3HsVWjaLjT8nbfwHy7Q5f2dBAAA)):

```svelte
<script>
Expand Down Expand Up @@ -144,7 +144,7 @@ Within the template, snippets are values just like any other. As such, they can

Think about it like passing content instead of data to a component. The concept is similar to slots in web components.

As an authoring convenience, snippets declared directly _inside_ a component implicitly become props _on_ the component ([demo](/playground/untitled#H4sIAAAAAAAAE41Sy27bMBD8lYVcwHYrW4kBXxRFaP-htzgHSqQsojLJkuu2BqF_74qUrfhxCHQRh7MzO9z1SSM74ZL8zSeKHUSSJz-MSdIET2Y4uD-iQ0Fnp4-2HpDC1VYaLHdqh_JgtEX4yapOQGP1AebrLJzWsXD-QjQi1lo5JMZRooNXeBuwHXoYLHOYM2OoiXkKv_GUwzYFY2VNFxvo0xtqxRR9F-7z04X8fE-uW2GtnJQ3E_tpvYV-oL9Ti0U2hVJFjMMZslcfW-5DWj9zShojEFrBuLCLZR_9CmzLQCwy-psw8rxBgvkNhhpZd8F8NppE7Stbq_8u-GTKS8_XQ9Keqnl5BZP1AzTYP2bDV7i7_9hLEeda0iocNJeNFDzJ0R5Fn142JzA-uzsdBfLhldPxPdMhIPS0H1-M1cYtlnejwdBDfBXZjHXTFOg4BhuOtvTfrVDEmAZG2ew5ezYV-Ew2fVzVAivNTyPHzwSr29AlMAe8f6g-zuWDts-GusAmdBSkv3P7qnB4GpMEEHwsRPEPV6yTe5VDJxp8iXClLRmtnGG1VHva3oCPHQd9QJsrbFd1Kzu-2Khvz8uzZsXqX3urj4rnMBNCXNUG83zf6Yp1C2yXKdxA_KJjGOfRfb0Vh7MKDShEuV-M9_4_nq6svF4EAAA=)):
As an authoring convenience, snippets declared directly _inside_ a component implicitly become props _on_ the component ([demo](/playground/untitled#H4sIAAAAAAAAE3VSTa_aMBD8Kyu_SkAbCA-JSzBR20N_QXt6vIMTO8SqsY29tI2s_PcqTiB8vaPHs7MzuxuIZgdBMvJLo0QlOElIJZXwJHsLBBvb_XUASc7Mb9Yu_B-hsMMK5sUzvDQahUZPMkJ96aTFfKd3KA_WOISfrFACKmcOMFmk8TWUTjY73RFLoz1C5U4SPWzhrcN2GKDrlcGEWauEnyRwxCaDdQLWyVJksII2uaMWTDPNLtzX5YX8-kgua-GcHJVXI3u5WEPb0d83O03TMZSmfRzOkG1Db7mNacOL19JagVALxoWbztq-H8U6j0SaYp2P2BGbOyQ2v8PQIFMXLKRDk177pq0zf6d8bMrzwBdd0pamyPMb-IjNEzS2f86Gz_Dwf-2F9nvNSUJQ_EOSoTuJNvngqK5v4Pas7n4-OCwlEEJcQTIMO-nSQwtb-GSdsX46e9gbRoP9yGQ11I0rEuycunu6PHx1QnPhxm3SFN15MOlYEFJZtf0dUywMbwZOeBGsrKNLYB54-1R9WNqVdki7usim6VmQphf7mnpshiQRhNAXdoOfMyX3OgMlKtz0cGEcF27uLSul3mewjPjgOOoDukxjPS9rqfh0pb-8zs6aBSt_7505aZ7B9xOi0T9YKW4UooVsr0zB1BTrWQJ3EL-oWcZ572GxFoezCk37QLe3897-B2i2U62uBAAA)):

```svelte
<!-- this is semantically the same as the above -->
Expand All @@ -165,7 +165,7 @@ As an authoring convenience, snippets declared directly _inside_ a component imp
</Table>
```

Any content inside the component tags that is _not_ a snippet declaration implicitly becomes part of the `children` snippet ([demo](/playground/untitled#H4sIAAAAAAAAE41S247aMBD9lVFYCegGsiDxks1G7T_0bdkHJ3aI1cR27aEtsvzvtZ0LZeGhiiJ5js-cmTMemzS8YybJ320iSM-SPPmmVJImeFEhML9Yh8zHRp51HZDC1JorLI_iiLxXUiN8J1XHoNGyh-U2i9F2SFy-epon1lIY9IwzRwNv8B6wI1oIJXNYEqV8E8sUfuIlh0MKSvPaX-zBpZ-oFRH-m7m7l5m8uyfXLdOaX5X3V_bL9gAu0D98i0V2NSWKwQ4lSN7s0LKLbgtsyxgXmT9NiBe-iaP-DYISSTcj4bcLI7hSDEHL3yu6dkPfBdLS0m1o3nk-LW9gX-gBGss9ZsMXuLu32VjZBdfRaelft5eUN5zRJEd9Zi6dlyEy_ncdOm_IxsGlULe8o5qJNFgE5x_9SWmpzGp9N2-MXQxz4c2cOQ-lZWQyF0Jd2q_-mjI9U1fr4FBPE8iuKTbjjRt2sMBK0svIsQtG6jb2CsQAdQ_1x9f5R9tmIS-yPToK-tNkQRQGL6ObCIIdEpH9wQ3p-Enk0LEGXwe4ktoX2hhFai5Ofi0jPnYc9QF1LrDdRK-rvXjerSfNitQ_TlqeBc1hwRi7yY3F81MnK9KtsF2n8Amis44ilA7VtwfWTyr-kaKV-_X4cH8BTOhfRzcEAAA=)):
Any content inside the component tags that is _not_ a snippet declaration implicitly becomes part of the `children` snippet ([demo](/playground/untitled#H4sIAAAAAAAAE3WOQQrCMBBFrzIMggql3ddY1Du4si5sOmIwnYRkFKX07lKqglqX8_7_w2uRDw1hjlsWI5ZqTPBoLEXMdy3K3fdZDzB5Ndfep_FKVnpWHSKNce1YiCVijirqYLwUJQOYxrsgsLmIOIZjcA1M02w4n-PpomSVvTclqyEutDX6DA2pZ7_ABIVugrmEC3XJH92P55_G39GodCmWBFrQJ2PrQAwdLGHig_NxNv9xrQa1dhWIawrv1Wzeqawa8953D-8QOmaEAQAA)):

```svelte
<!--- file: App.svelte --->
Expand Down
24 changes: 24 additions & 0 deletions documentation/docs/03-template-syntax/11-bind.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,34 @@ The general syntax is `bind:property={expression}`, where `expression` is an _lv
<input bind:value />
```


Svelte creates an event listener that updates the bound value. If an element already has a listener for the same event, that listener will be fired before the bound value is updated.

Most bindings are _two-way_, meaning that changes to the value will affect the element and vice versa. A few bindings are _readonly_, meaning that changing their value will have no effect on the element.

## Function bindings

You can also use `bind:property={get, set}`, where `get` and `set` are functions, allowing you to perform validation and transformation:

```svelte
<input bind:value={
() => value,
(v) => value = v.toLowerCase()}
/>
```

In the case of readonly bindings like [dimension bindings](#Dimensions), the `get` value should be `null`:

```svelte
<div
bind:clientWidth={null, redraw}
bind:clientHeight={null, redraw}
>...</div>
```

> [!NOTE]
> Function bindings are available in Svelte 5.9.0 and newer.
## `<input bind:value>`

A `bind:value` directive on an `<input>` element binds the input's `value` property:
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/06-runtime/01-stores.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const userState = $state({
```svelte
<!--- file: App.svelte --->
<script>
import { userState } from './state.svelte';
import { userState } from './state.svelte.js';
</script>
<p>User name: {userState.name}</p>
Expand Down
2 changes: 1 addition & 1 deletion documentation/docs/06-runtime/02-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const myGlobalState = $state({
```svelte
<!--- file: App.svelte --->
<script>
import { myGlobalState } from './state.svelte';
import { myGlobalState } from './state.svelte.js';
// ...
</script>
```
Expand Down
11 changes: 7 additions & 4 deletions documentation/docs/06-runtime/04-imperative-component-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,22 @@ Note that unlike calling `new App(...)` in Svelte 4, things like effects (includ

## `unmount`

Unmounts a component created with [`mount`](#mount) or [`hydrate`](#hydrate):
Unmounts a component that was previously created with [`mount`](#mount) or [`hydrate`](#hydrate).

If `options.outro` is `true`, [transitions](transition) will play before the component is removed from the DOM:

```js
// @errors: 1109
import { mount, unmount } from 'svelte';
import App from './App.svelte';

const app = mount(App, {...});
const app = mount(App, { target: document.body });

// later
unmount(app);
unmount(app, { outro: true });
```

Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise.

## `render`

Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app:
Expand Down
2 changes: 2 additions & 0 deletions documentation/docs/07-misc/07-v5-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,8 @@ The `foreign` namespace was only useful for Svelte Native, which we're planning

`afterUpdate` callbacks in a parent component will now run after `afterUpdate` callbacks in any child components.

`beforeUpdate/afterUpdate` no longer run when the component contains a `<slot>` and its content is updated.

Both functions are disallowed in runes mode — use `$effect.pre(...)` and `$effect(...)` instead.

### `contenteditable` behavior change
Expand Down
106 changes: 75 additions & 31 deletions documentation/docs/98-reference/.generated/client-warnings.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ The easiest way to log a value as it changes over time is to use the [`$inspect`
The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value
```

Certain attributes like `src` on an `<img>` element will not be repaired during hydration, i.e. the server value will be kept. That's because updating these attributes can cause the image to be refetched (or in the case of an `<iframe>`, for the frame to be reloaded), even if they resolve to the same resource.

To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:

```svelte
<script>
let { src } = $props();

if (typeof window !== 'undefined') {
// stash the value...
const initial = src;

// unset it...
src = undefined;

$effect(() => {
// ...and reset after we've mounted
src = initial;
});
}
</script>

<img {src} />
```
### hydration_html_changed
```
Expand All @@ -76,6 +101,31 @@ The value of an `{@html ...}` block changed between server and client renders. T
The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value
```
If the `{@html ...}` value changes between the server and the client, it will not be repaired during hydration, i.e. the server value will be kept. That's because change detection during hydration is expensive and usually unnecessary.
To fix this, either silence the warning with a [`svelte-ignore`](basic-markup#Comments) comment, or ensure that the value stays the same between server and client. If you really need the value to change on hydration, you can force an update like this:
```svelte
<script>
let { markup } = $props();

if (typeof window !== 'undefined') {
// stash the value...
const initial = markup;

// unset it...
markup = undefined;

$effect(() => {
// ...and reset after we've mounted
markup = initial;
});
}
</script>

{@html markup}
```
### hydration_mismatch
```
Expand All @@ -86,6 +136,10 @@ Hydration failed because the initial UI does not match what was rendered on the
Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location%
```
This warning is thrown when Svelte encounters an error while hydrating the HTML from the server. During hydration, Svelte walks the DOM, expecting a certain structure. If that structure is different (for example because the HTML was repaired by the DOM because of invalid HTML), then Svelte will run into issues, resulting in this warning.
During development, this error is often preceeded by a `console.error` detailing the offending HTML, which needs fixing.
### invalid_raw_snippet_render
```
Expand All @@ -110,6 +164,10 @@ Tried to unmount a component that was not mounted
%parent% passed a value to %child% with `bind:`, but the value is owned by %owner%. Consider creating a binding between %owner% and %parent%
```

Consider three components `GrandParent`, `Parent` and `Child`. If you do `<GrandParent bind:value>`, inside `GrandParent` pass on the variable via `<Parent {value} />` (note the missing `bind:`) and then do `<Child bind:value>` inside `Parent`, this warning is thrown.

To fix it, `bind:` to the value instead of just passing a property (i.e. in this example do `<Parent bind:value />`).

### ownership_invalid_mutation

```
Expand All @@ -120,45 +178,31 @@ Mutating a value outside the component that created it is strongly discouraged.
%component% mutated a value owned by %owner%. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead
```

### reactive_declaration_non_reactive_property

```
A `$:` statement (%location%) read reactive state that was not visible to the compiler. Updates to this state will not cause the statement to re-run. The behaviour of this code will change if you migrate it to runes mode
```

In legacy mode, a `$:` [reactive statement](https://svelte.dev/docs/svelte/legacy-reactive-assignments) re-runs when the state it _references_ changes. This is determined at compile time, by analysing the code.

In runes mode, effects and deriveds re-run when there are changes to the values that are read during the function's _execution_.
Consider the following code:

Often, the result is the same — for example these can be considered equivalent:

```js
let a = 1, b = 2, sum = 3;
// ---cut---
$: sum = a + b;
```
```svelte
<!--- file: App.svelte --->
<script>
import Child from './Child.svelte';
let person = $state({ name: 'Florida', surname: 'Man' });
</script>

```js
let a = 1, b = 2;
// ---cut---
const sum = $derived(a + b);
<Child {person} />
```
In some cases — such as the one that triggered the above warning — they are _not_ the same:

```js
let a = 1, b = 2, sum = 3;
// ---cut---
const add = () => a + b;
```svelte
<!--- file: Child.svelte --->
<script>
let { person } = $props();
</script>

// the compiler can't 'see' that `sum` depends on `a` and `b`, but
// they _would_ be read while executing the `$derived` version
$: sum = add();
<input bind:value={person.name}>
<input bind:value={person.surname}>
```
Similarly, reactive properties of [deep state](https://svelte.dev/docs/svelte/$state#Deep-state) are not visible to the compiler. As such, changes to these properties will cause effects and deriveds to re-run but will _not_ cause `$:` statements to re-run.
`Child` is mutating `person` which is owned by `App` without being explicitly "allowed" to do so. This is strongly discouraged since it can create code that is hard to reason about at scale ("who mutated this value?"), hence the warning.
When you [migrate this component](https://svelte.dev/docs/svelte/v5-migration-guide) to runes mode, the behaviour will change accordingly.
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
### state_proxy_equality_mismatch
Expand Down
14 changes: 13 additions & 1 deletion documentation/docs/98-reference/.generated/compile-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,16 @@ Sequence expressions are not allowed as attribute/directive values in runes mode
Attribute values containing `{...}` must be enclosed in quote marks, unless the value only contains the expression
```

### bind_group_invalid_expression

```
`bind:group` can only bind to an Identifier or MemberExpression
```

### bind_invalid_expression

```
Can only bind to an Identifier or MemberExpression
Can only bind to an Identifier or MemberExpression or a `{get, set}` pair
```

### bind_invalid_name
Expand All @@ -94,6 +100,12 @@ Can only bind to an Identifier or MemberExpression
`bind:%name%` is not a valid binding. %explanation%
```

### bind_invalid_parens

```
`bind:%name%={get, set}` must not have surrounding parentheses
```

### bind_invalid_target

```
Expand Down
Loading

0 comments on commit e69c992

Please sign in to comment.