Skip to content

Commit

Permalink
regenerate
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Dec 6, 2024
2 parents 9115eca + 60c0dc7 commit 6acaddc
Show file tree
Hide file tree
Showing 110 changed files with 2,315 additions and 414 deletions.
142 changes: 135 additions & 7 deletions documentation/docs/02-runes/02-$state.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@ let todos = $state([
...modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:

```js
// @filename: ambient.d.ts
declare global {
const todos: Array<{ done: boolean, text: string }>
}

// @filename: index.js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
todos[0].done = !todos[0].done;
```
Expand All @@ -64,6 +59,17 @@ todos.push({

> [!NOTE] When you update properties of proxies, the original object is _not_ mutated.
Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:

```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
let { done, text } = todos[0];

// this will not affect the value of `done`
todos[0].done = !todos[0].done;
```

### Classes

You can also use `$state` in class fields (whether public or private):
Expand All @@ -85,7 +91,42 @@ class Todo {
}
```

> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields.
> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.
When calling methods in JavaScript, the value of [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) matters. This won't work, because `this` inside the `reset` method will be the `<button>` rather than the `Todo`:

```svelte
<button onclick={todo.reset}>
reset
</button>
```

You can either use an inline function...

```svelte
<button onclick=+++{() => todo.reset()}>+++
reset
</button>
```

...or use an arrow function in the class definition:

```js
// @errors: 7006 2554
class Todo {
done = $state(false);
text = $state();

constructor(text) {
this.text = text;
}

+++reset = () => {+++
this.text = '';
this.done = false;
}
}
```

## `$state.raw`

Expand Down Expand Up @@ -127,3 +168,90 @@ To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snaps
```

This is handy when you want to pass some state to an external library or API that doesn't expect a proxy, such as `structuredClone`.

## Passing state into functions

JavaScript is a _pass-by-value_ language — when you call a function, the arguments are the _values_ rather than the _variables_. In other words:

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {number} a
* @param {number} b
*/
function add(a, b) {
return a + b;
}

let a = 1;
let b = 2;
let total = add(a, b);
console.log(total); // 3

a = 3;
b = 4;
console.log(total); // still 3!
```

If `add` wanted to have access to the _current_ values of `a` and `b`, and to return the current `total` value, you would need to use functions instead:

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {() => number} getA
* @param {() => number} getB
*/
function add(+++getA, getB+++) {
return +++() => getA() + getB()+++;
}

let a = 1;
let b = 2;
let total = add+++(() => a, () => b)+++;
console.log(+++total()+++); // 3

a = 3;
b = 4;
console.log(+++total()+++); // 7
```

State in Svelte is no different — when you reference something declared with the `$state` rune...

```js
let a = +++$state(1)+++;
let b = +++$state(2)+++;
```

...you're accessing its _current value_.

Note that 'functions' is broad — it encompasses properties of proxies and [`get`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/[`set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) properties...

```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {{ a: number, b: number }} input
*/
function add(input) {
return {
get value() {
return input.a + input.b;
}
};
}

let input = $state({ a: 1, b: 2 });
let total = add(input);
console.log(total.value); // 3

input.a = 3;
input.b = 4;
console.log(total.value); // 7
```

...though if you find yourself writing code like that, consider using [classes](#Classes) instead.
43 changes: 41 additions & 2 deletions documentation/docs/03-template-syntax/11-bind.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ In the case of a numeric input (`type="number"` or `type="range"`), the value wi

If the input is empty or invalid (in the case of `type="number"`), the value is `undefined`.

Since 5.6.0, if an `<input>` has a `defaultValue` and is part of a form, it will revert to that value instead of the empty string when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```svelte
<script>
let value = $state('');
</script>
<form>
<input bind:value defaultValue="not the empty string">
<input type="reset" value="Reset">
</form>
```

> [!NOTE]
> Use reset buttons sparingly, and ensure that users won't accidentally click them while trying to submit the form.
## `<input bind:checked>`

Checkbox and radio inputs can be bound with `bind:checked`:
Expand All @@ -64,16 +80,29 @@ Checkbox and radio inputs can be bound with `bind:checked`:
</label>
```

Since 5.6.0, if an `<input>` has a `defaultChecked` attribute and is part of a form, it will revert to that value instead of `false` when the form is reset. Note that for the initial render the value of the binding takes precedence unless it is `null` or `undefined`.

```svelte
<script>
let checked = $state(true);
</script>
<form>
<input type="checkbox" bind:checked defaultChecked={true}>
<input type="reset" value="Reset">
</form>
```

## `<input bind:group>`

Inputs that work together can use `bind:group`.

```svelte
<script>
let tortilla = 'Plain';
let tortilla = $state('Plain');
/** @type {Array<string>} */
let fillings = [];
let fillings = $state([]);
</script>
<!-- grouped radio inputs are mutually exclusive -->
Expand Down Expand Up @@ -146,6 +175,16 @@ When the value of an `<option>` matches its text content, the attribute can be o
</select>
```

You can give the `<select>` a default value by adding a `selected` attribute to the`<option>` (or options, in the case of `<select multiple>`) that should be initially selected. If the `<select>` is part of a form, it will revert to that selection when the form is reset. Note that for the initial render the value of the binding takes precedence if it's not `undefined`.

```svelte
<select bind:value={selected}>
<option value={a}>a</option>
<option value={b} selected>b</option>
<option value={c}>c</option>
</select>
```

## `<audio>`

`<audio>` elements have their own set of bindings — five two-way ones...
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
6 changes: 6 additions & 0 deletions documentation/docs/07-misc/99-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ If you need hash-based routing on the client side, check out [svelte-spa-router]

You can see a [community-maintained list of routers on sveltesociety.dev](https://sveltesociety.dev/packages?category=routers).

## How do I write a mobile app with Svelte?

While most mobile apps are written without using JavaScript, if you'd like to leverage your existing Svelte components and knowledge of Svelte when building mobile apps, you can turn a [SvelteKit SPA](https://kit.svelte.dev/docs/single-page-apps) into a mobile app with [Tauri](https://v2.tauri.app/start/frontend/sveltekit/) or [Capacitor](https://capacitorjs.com/solution/svelte). Mobile features like the camera, geolocation, and push notifications are available via plugins for both platforms.

Svelte Native was an option available for Svelte 4, but note that Svelte 5 does not currently support it. Svelte Native lets you write NativeScript apps using Svelte components that contain [NativeScript UI components](https://docs.nativescript.org/ui/) rather than DOM elements, which may be familiar for users coming from React Native.

## Can I tell Svelte not to remove my unused styles?

No. Svelte removes the styles from the component and warns you about them in order to prevent issues that would otherwise arise.
Expand Down
74 changes: 74 additions & 0 deletions documentation/docs/98-reference/.generated/client-warnings.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
<!-- This file is generated by scripts/process-messages/index.js. Do not edit! -->

### assignment_value_stale

```
Assignment to `%property%` property (%location%) will evaluate to the right-hand side, not the value of `%property%` following the assignment. This may result in unexpected behaviour.
```

Given a case like this...

```svelte
<script>
let object = $state({ array: null });
function add() {
(object.array ??= []).push(object.array.length);
}
</script>
<button onclick={add}>add</button>
<p>items: {JSON.stringify(object.items)}</p>
```

...the array being pushed to when the button is first clicked is the `[]` on the right-hand side of the assignment, but the resulting value of `object.array` is an empty state proxy. As a result, the pushed value will be discarded.

You can fix this by separating it into two statements:

```js
let object = { array: [0] };
// ---cut---
function add() {
object.array ??= [];
object.array.push(object.array.length);
}
```
### binding_property_non_reactive
```
Expand Down Expand Up @@ -86,6 +120,46 @@ 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_.

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;
```

```js
let a = 1, b = 2;
// ---cut---
const sum = $derived(a + b);
```

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;

// the compiler can't 'see' that `sum` depends on `a` and `b`, but
// they _would_ be read while executing the `$derived` version
$: sum = add();
```

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.

When you [migrate this component](https://svelte.dev/docs/svelte/v5-migration-guide) to runes mode, the behaviour will change accordingly.

### state_proxy_equality_mismatch

```
Expand Down
4 changes: 2 additions & 2 deletions documentation/docs/98-reference/.generated/compile-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,12 @@ A component cannot have a default export
### node_invalid_placement

```
%thing% is invalid inside `<%parent%>`
%message%. The browser will 'repair' the HTML (by moving, removing, or inserting elements) which breaks Svelte's assumptions about the structure of your components.
```

HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:

- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` for example (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
- `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

Expand Down
10 changes: 2 additions & 8 deletions documentation/docs/98-reference/.generated/compile-warnings.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,12 +643,12 @@ Svelte 5 components are no longer classes. Instantiate them using `mount` or `hy
### node_invalid_placement_ssr

```
%thing% is invalid inside `<%parent%>`. When rendering this component on the server, the resulting HTML will be modified by the browser, likely resulting in a `hydration_mismatch` warning
%message%. When rendering this component on the server, the resulting HTML will be modified by the browser (by moving, removing, or inserting elements), likely resulting in a `hydration_mismatch` warning
```

HTML restricts where certain elements can appear. In case of a violation the browser will 'repair' the HTML in a way that breaks Svelte's assumptions about the structure of your components. Some examples:

- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` for example (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<p>hello <div>world</div></p>` will result in `<p>hello </p><div>world</div><p></p>` (the `<div>` autoclosed the `<p>` because `<p>` cannot contain block-level elements)
- `<option><div>option a</div></option>` will result in `<option>option a</option>` (the `<div>` is removed)
- `<table><tr><td>cell</td></tr></table>` will result in `<table><tbody><tr><td>cell</td></tr></tbody></table>` (a `<tbody>` is auto-inserted)

Expand Down Expand Up @@ -726,12 +726,6 @@ Reactive declarations only exist at the top level of the instance script
Reassignments of module-level declarations will not cause reactive statements to update
```

### reactive_declaration_non_reactive_property

```
Properties of objects and arrays are not reactive unless in runes mode. Changes to this property will not cause the reactive statement to update
```

### script_context_deprecated

```
Expand Down
Loading

0 comments on commit 6acaddc

Please sign in to comment.