You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: documentation/docs/02-runes/02-$state.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,9 +20,7 @@ Unlike other frameworks you may have encountered, there is no API for interactin
20
20
21
21
If `$state` is used with an array or a simple object, the result is a deeply reactive _state proxy_. [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) allow Svelte to run code when you read or write properties, including via methods like `array.push(...)`, triggering granular updates.
22
22
23
-
> [!NOTE] Class instances are not proxied. You can create [reactive state fields](#Classes) on classes that you define. Svelte provides reactive implementations of built-ins like `Set` and `Map` that can be imported from [`svelte/reactivity`](svelte-reactivity).
24
-
25
-
State is proxified recursively until Svelte finds something other than an array or simple object. In a case like this...
23
+
State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with `Object.create`). In a case like this...
You can also use `$state` in class fields (whether public or private):
68
+
Class instances are not proxied. Instead, you can use `$state` in class fields (whether public or private), or as the first assignment to a property immediately inside the `constructor`:
71
69
72
70
```js
73
71
// @errors: 7006 2554
74
72
classTodo {
75
73
done =$state(false);
76
-
text =$state();
77
74
78
75
constructor(text) {
79
-
this.text= text;
76
+
this.text=$state(text);
80
77
}
81
78
82
79
reset() {
@@ -110,10 +107,9 @@ You can either use an inline function...
110
107
// @errors: 7006 2554
111
108
classTodo {
112
109
done =$state(false);
113
-
text =$state();
114
110
115
111
constructor(text) {
116
-
this.text= text;
112
+
this.text=$state(text);
117
113
}
118
114
119
115
+++reset= () => {+++
@@ -123,6 +119,8 @@ class Todo {
123
119
}
124
120
```
125
121
122
+
> Svelte provides reactive implementations of built-in classes like `Set` and `Map` that can be imported from [`svelte/reactivity`](svelte-reactivity).
123
+
126
124
## `$state.raw`
127
125
128
126
In cases where you don't want objects and arrays to be deeply reactive you can use `$state.raw`.
@@ -147,6 +145,8 @@ person = {
147
145
148
146
This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can _contain_ reactive state (for example, a raw array of reactive objects).
149
147
148
+
As with `$state`, you can declare class fields using `$state.raw`.
149
+
150
150
## `$state.snapshot`
151
151
152
152
To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:
Copy file name to clipboardExpand all lines: documentation/docs/02-runes/04-$effect.md
+9-15Lines changed: 9 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -269,11 +269,11 @@ In general, `$effect` is best considered something of an escape hatch — useful
269
269
270
270
If you're using an effect because you want to be able to reassign the derived value (to build an optimistic UI, for example) note that [deriveds can be directly overridden]($derived#Overriding-derived-values) as of Svelte 5.25.
271
271
272
-
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/playground/untitled#H4sIAAAAAAAACpVRy26DMBD8FcvKgUhtoIdeHBwp31F6MGSJkBbHwksEQvx77aWQqooq9bgzOzP7mGTdIHipPiZJowOpGJAv0po2VmfnDv4OSBErjYdneHWzBJaCjcx91TWOToUtCIEE3cig0OIty44r5l1oDtjOkyFIsv3GINQ_CNYyGegd1DVUlCR7oU9iilDUcP8S8roYs9n8p2wdYNVFm4csTx872BxNCcjr5I11fdgonEkXsjP2CoUUZWMv6m6wBz2x7yxaM-iJvWeRsvSbSVeUy5i0uf8vKA78NIeJLSZWv1I8jQjLdyK4XuTSeIdmVKJGGI4LdjVOiezwDu1yG74My8PLCQaSiroe5s_5C2PHrkVGAgAA)):
272
+
You might be tempted to do something convoluted with effects to link one value to another. The following example shows two inputs for "money spent" and "money left" that are connected to each other. If you update one, the other should update accordingly. Don't use effects for this ([demo](/playground/untitled#H4sIAAAAAAAAE5WRTWrDMBCFryKGLBJoY3fRjWIHeoiu6i6UZBwEY0VE49TB-O6VxrFTSih0qe_Ne_OjHpxpEDS8O7ZMeIAnqC1hAP3RA1990hKI_Fb55v06XJA4sZ0J-IjvT47RcYyBIuzP1vO2chVHHFjxiQ2pUr3k-SZRQlbBx_LIFoEN4zJfzQph_UMQr4hRXmBd456Xy5Uqt6pPKHmkfmzyPAZL2PCnbRpg8qWYu63I7lu4gswOSRYqrPNt3CgeqqzgbNwRK1A76w76YqjFspfcQTWmK3vJHlQm1puSTVSeqdOc_r9GaeCHfUSY26TXry6Br4RSK3C6yMEGT-aqVU3YbUZ2NF6rfP2KzXgbuYzY46czdgyazy0On_FlLH3F-UDXhgIO35UGlA1rAgAA)):
273
273
274
274
```svelte
275
275
<script>
276
-
let total = 100;
276
+
const total = 100;
277
277
let spent = $state(0);
278
278
let left = $state(total);
279
279
@@ -297,32 +297,26 @@ You might be tempted to do something convoluted with effects to link one value t
297
297
</label>
298
298
```
299
299
300
-
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE51SsW6DMBT8FcvqABINdOhCIFKXTt06lg4GHpElYyz8iECIf69tcIIipo6-u3f3fPZMJWuBpvRzkBXyTpKSy5rLq6YRbbgATdOfmeKkrMgCBt9GPpQ66RsItFjJNBzhVScRJBobmumq5wovhSxQABLskAmSk7ckOXtMKyM22ItGhhAk4Z0R0OwIN-tIQzd-90HVhvy2HsGNiQFCMltBgd7XoecV2xzXNV7XaEcth7ZfRv7kujnsTX2Qd7USb5rFjwZkJlgJwpWRcakG04cpOS9oz-QVCuoeInXW-RyEJL-sG0b7Wy6kZWM-u7CFxM5tdrIl9qg72vB74H-y7T2iXROHyVb0CLanp1yNk4D1A1jQ91hzrQSbUtIIGLcir0ylJDm9Q7urz42bX4UwIk2xH2D5Xf4A7SeMcMQCAAA=)):
300
+
Instead, use `oninput` callbacks or — better still — [function bindings](bind#Function-bindings) where possible ([demo](/playground/untitled#H4sIAAAAAAAAE5VRvW7CMBB-FcvqECQK6dDFJEgsnfoGTQdDLsjSxVjxhYKivHvPBwFUsXS8774_nwftbQva6I_e78gdvNo6Xzu_j3quG4cQtfkaNJ1DIiWA8atkE8IiHgEpYVsb4Rm-O3gCT2yji7jrXKB15StiOJKiA1lUpXrL81VCEUjFwHTGXiJZgiyf3TYIjSxq6NwR6uyifr0ohMbEZnpHH2rWf7ImS8KZGtK6osl_UqelRIyVL5b3ir5AuwWUtoXzoee6fIWy0p31e6i0XMocLfZQDuI6qtaeykGcR7UU6XWznFAZU9LN_X9B2UyVayk9f3ji0-REugen6U9upDOCcAWcLlS7GNCejWoQTqsLtrfBqHzxDu3DrUTOf0xwIm2o62H85sk6_OHG2jQWI4y_3byXXGMCAAA=)):
Copy file name to clipboardExpand all lines: documentation/docs/03-template-syntax/[email protected]
+37-2Lines changed: 37 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,9 @@
2
2
title: {@attach ...}
3
3
---
4
4
5
-
Attachments are functions that run when an element is mounted to the DOM. Optionally, they can return a function that is called when the element is later removed from the DOM.
5
+
Attachments are functions that run in an [effect]($effect) when an element is mounted to the DOM or when [state]($state) read inside the function updates.
6
+
7
+
Optionally, they can return a function that is called before the attachment re-runs, or after the element is later removed from the DOM.
6
8
7
9
> [!NOTE]
8
10
> Attachments are available in Svelte 5.29 and newer.
@@ -55,7 +57,7 @@ A useful pattern is for a function, such as `tooltip` in this example, to _retur
55
57
</button>
56
58
```
57
59
58
-
Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes.
60
+
Since the `tooltip(content)` expression runs inside an [effect]($effect), the attachment will be destroyed and recreated whenever `content` changes. The same thing would happen for any state read _inside_ the attachment function when it first runs. (If this isn't what you want, see [Controlling when attachments re-run](#Controlling-when-attachments-re-run).)
59
61
60
62
## Inline attachments
61
63
@@ -126,6 +128,39 @@ This allows you to create _wrapper components_ that augment elements ([demo](/pl
126
128
</Button>
127
129
```
128
130
131
+
## Controlling when attachments re-run
132
+
133
+
Attachments, unlike [actions](use), are fully reactive: `{@attach foo(bar)}` will re-run on changes to `foo`_or_`bar` (or any state read inside `foo`):
134
+
135
+
```js
136
+
// @errors: 7006 2304 2552
137
+
functionfoo(bar) {
138
+
return (node) => {
139
+
veryExpensiveSetupWork(node);
140
+
update(node, bar);
141
+
};
142
+
}
143
+
```
144
+
145
+
In the rare case that this is a problem (for example, if `foo` does expensive and unavoidable setup work) consider passing the data inside a function and reading it in a child effect:
146
+
147
+
```js
148
+
// @errors: 7006 2304 2552
149
+
functionfoo(+++getBar+++) {
150
+
return (node) => {
151
+
veryExpensiveSetupWork(node);
152
+
153
+
+++$effect(() => {
154
+
update(node, getBar());
155
+
});+++
156
+
}
157
+
}
158
+
```
159
+
129
160
## Creating attachments programmatically
130
161
131
162
To add attachments to an object that will be spread onto a component or element, use [`createAttachmentKey`](svelte-attachments#createAttachmentKey).
163
+
164
+
## Converting actions to attachments
165
+
166
+
If you're using a library that only provides actions, you can convert them to attachments with [`fromAction`](svelte-attachments#fromAction), allowing you to (for example) use them with components.
Copy file name to clipboardExpand all lines: documentation/docs/03-template-syntax/12-bind.md
+11-10Lines changed: 11 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ title: bind:
4
4
5
5
Data ordinarily flows down, from parent to child. The `bind:` directive allows data to flow the other way, from child to parent.
6
6
7
-
The general syntax is `bind:property={expression}`, where `expression` is an _lvalue_ (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
7
+
The general syntax is `bind:property={expression}`, where `expression` is an [_lvalue_](https://press.rebus.community/programmingfundamentals/chapter/lvalue-and-rvalue/) (i.e. a variable or an object property). When the expression is an identifier with the same name as the property, we can omit the expression — in other words these are equivalent:
8
8
9
9
<!-- prettier-ignore -->
10
10
```svelte
@@ -142,26 +142,27 @@ Checkboxes can be in an [indeterminate](https://developer.mozilla.org/en-US/docs
142
142
143
143
## `<input bind:group>`
144
144
145
-
Inputs that work together can use `bind:group`.
145
+
Inputs that work together can use `bind:group` ([demo](/playground/untitled#H4sIAAAAAAAAE62T32_TMBDH_5XDQkpbrct7SCMGEvCEECDxsO7BSW6L2c227EvbKOv_jp0f6jYhQKJv5_P3PvdL1wstH1Bk4hMSGdgbRzUssFaM9VJciFtF6EV23QvubNRFR_BPUVfWXvodEkdfKT3-zl8Zzag5YETuK6csF1u9ZUIGNo4VkYQNvPYsGRfJF5JKJ8s3QRJE6WoFb2Nq6K-ck13u2Sl9Vxxhlc6QUBIFnz9Brm9ifJ6esun81XoNd860FmtwslYGlLYte5AO4aHlVhJ1gIeKWq92COt1iMtJlkhFPkgh1rHZiiF6K6BUus4G5KafGznCTlIbVUMfQZUWMJh5OrL-C_qjMYSwb1DyiH7iOEuCb1ZpWTUjfHqcwC_GWDVY3ZfmME_SGttSmD9IHaYatvWHIc6xLyqad3mq6KuqcCwnWn9p8p-p71BqP2IH81zc9w2in-od7XORP7ayCpd5YCeXI_-p59mObPF9WmwGpx3nqS2Gzw8TO3zOaS5_GqUXyQUkS3h8hOSz0ZhMESHGc0c4Hm3MAn00t1wrb0l2GZRkqvt4sXwczm6Qh8vnUJzI2LV4vAkvqWgfehTZrSSPx19WiVfFfAQAAA==)):
146
146
147
147
```svelte
148
+
<!--- file: BurritoChooser.svelte --->
148
149
<script>
149
150
let tortilla = $state('Plain');
150
151
151
-
/** @type {Array<string>} */
152
+
/** @type {string[]} */
152
153
let fillings = $state([]);
153
154
</script>
154
155
155
156
<!-- grouped radio inputs are mutually exclusive -->
Copy file name to clipboardExpand all lines: documentation/docs/05-special-elements/04-svelte-body.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ title: <svelte:body>
8
8
9
9
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](use) on the `<body>` element.
10
10
11
-
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.
11
+
As with `<svelte:window>` and `<svelte:document>`, this element may only appear at the top level of your component and must never be inside a block or element.
Copy file name to clipboardExpand all lines: documentation/docs/07-misc/04-custom-elements.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -114,6 +114,8 @@ When constructing a custom element, you can tailor several aspects by defining `
114
114
...
115
115
```
116
116
117
+
> [!NOTE] While Typescript is supported in the `extend` function, it is subject to limitations: you need to set `lang="ts"` on one of the scripts AND you can only use [erasable syntax](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly) in it. They are not processed by script preprocessors.
118
+
117
119
## Caveats and limitations
118
120
119
121
Custom elements can be a useful way to package components for consumption in a non-Svelte app, as they will work with vanilla HTML and JavaScript as well as [most frameworks](https://custom-elements-everywhere.com/). There are, however, some important differences to be aware of:
Copy file name to clipboardExpand all lines: documentation/docs/07-misc/07-v5-migration-guide.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -833,9 +833,9 @@ Svelte 5 is more strict about the HTML structure and will throw a compiler error
833
833
834
834
Assignments to destructured parts of a `@const` declaration are no longer allowed. It was an oversight that this was ever allowed.
835
835
836
-
### :is(...) and :where(...) are scoped
836
+
### :is(...), :has(...), and :where(...) are scoped
837
837
838
-
Previously, Svelte did not analyse selectors inside `:is(...)`and `:where(...)`, effectively treating them as global. Svelte5 analyses them in the context of the current component. As such, some selectors may now be treated as unused if they were relying on thistreatment. To fix this, use `:global(...)` inside the `:is(...)/:where(...)` selectors.
838
+
Previously, Svelte did not analyse selectors inside `:is(...)`, `:has(...)`, and `:where(...)`, effectively treating them as global. Svelte5 analyses them in the context of the current component. As such, some selectors may now be treated as unused if they were relying on thistreatment. To fix this, use `:global(...)` inside the `:is(...)/:has(...)/:where(...)` selectors.
839
839
840
840
When using Tailwind's `@apply` directive, add a `:global` selector to preserve rules that use Tailwind-generated `:is(...)` selectors:
Copy file name to clipboardExpand all lines: documentation/docs/98-reference/.generated/client-warnings.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -200,6 +200,19 @@ Consider the following code:
200
200
201
201
To fix it, either create callback props to communicate changes, or mark `person` as [`$bindable`]($bindable).
202
202
203
+
### select_multiple_invalid_value
204
+
205
+
```
206
+
The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is.
207
+
```
208
+
209
+
When using `<select multiple value={...}>`, Svelte will mark all selected `<option>` elements as selected by iterating over the array passed to `value`. If `value` is not an array, Svelte will emit this warning and keep the selected options as they are.
210
+
211
+
To silence the warning, ensure that `value`:
212
+
213
+
- is an array for an explicit selection
214
+
- is `null` or `undefined` to keep the selection as is
0 commit comments