Skip to content

docs: add inline documentation for svelte/reactivity #15722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions documentation/docs/98-reference/21-svelte-reactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,6 @@
title: svelte/reactivity
---

Svelte provides reactive versions of various built-ins like `SvelteMap`, `SvelteSet` and `SvelteURL`. These can be imported from `svelte/reactivity` and used just like their native counterparts.

```svelte
<script>
import { SvelteURL } from 'svelte/reactivity';

const url = new SvelteURL('https://example.com/path');
</script>

<!-- changes to these... -->
<input bind:value={url.protocol} />
<input bind:value={url.hostname} />
<input bind:value={url.pathname} />

<hr />

<!-- will update `href` and vice versa -->
<input bind:value={url.href} />
```
Svelte provides reactive versions of various built-ins like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) that can be used just like their native counterparts, as well as a handful of additional utilities for handling reactivity.

> MODULE: svelte/reactivity
32 changes: 32 additions & 0 deletions packages/svelte/src/reactivity/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,38 @@ import { active_reaction, get, set_active_reaction } from '../internal/client/ru

var inited = false;

/**
* A reactive version of the built-in [`Date`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) object.
* Reading the date (whether with methods like `date.getTime()` or `date.toString()`, or via things like [`Intl.DateTimeFormat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat))
* in an [effect](https://svelte.dev/docs/svelte/$effect) or [derived](https://svelte.dev/docs/svelte/$derived)
* will cause it to be re-evaluated when the value of the date changes.
*
* ```svelte
* <script>
* import { SvelteDate } from 'svelte/reactivity';
*
* const date = new SvelteDate();
*
* const formatter = new Intl.DateTimeFormat(undefined, {
* hour: 'numeric',
* minute: 'numeric',
* second: 'numeric'
* });
*
* $effect(() => {
* const interval = setInterval(() => {
* date.setTime(Date.now());
* }, 1000);
*
* return () => {
* clearInterval(interval);
* };
* });
* </script>
*
* <p>The time is {formatter.format(date)}</p>
* ```
*/
export class SvelteDate extends Date {
#time = source(super.getTime());

Expand Down
41 changes: 41 additions & 0 deletions packages/svelte/src/reactivity/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,47 @@ import { get } from '../internal/client/runtime.js';
import { increment } from './utils.js';

/**
* A reactive version of the built-in [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) object.
* Reading contents of the map (by iterating, or by reading `map.size` or calling `map.get(...)` or `map.has(...)` as in the [tic-tac-toe example](https://svelte.dev/playground/0b0ff4aa49c9443f9b47fe5203c78293) below) in an [effect](https://svelte.dev/docs/svelte/$effect) or [derived](https://svelte.dev/docs/svelte/$derived)
* will cause it to be re-evaluated as necessary when the map is updated.
*
* Note that values in a reactive map are _not_ made [deeply reactive](https://svelte.dev/docs/svelte/$state#Deep-state).
*
* ```svelte
* <script>
* import { SvelteMap } from 'svelte/reactivity';
* import { result } from './game.js';
*
* let board = new SvelteMap();
* let player = $state('x');
* let winner = $derived(result(board));
*
* function reset() {
* player = 'x';
* board.clear();
* }
* </script>
*
* <div class="board">
* {#each Array(9), i}
* <button
* disabled={board.has(i) || winner}
* onclick={() => {
* board.set(i, player);
* player = player === 'x' ? 'o' : 'x';
* }}
* >{board.get(i)}</button>
* {/each}
* </div>
*
* {#if winner}
* <p>{winner} wins!</p>
* <button onclick={reset}>reset</button>
* {:else}
* <p>{player} is next</p>
* {/if}
* ```
*
* @template K
* @template V
* @extends {Map<K, V>}
Expand Down
31 changes: 31 additions & 0 deletions packages/svelte/src/reactivity/set.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,37 @@ var set_like_methods = ['difference', 'intersection', 'symmetricDifference', 'un
var inited = false;

/**
* A reactive version of the built-in [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) object.
* Reading contents of the set (by iterating, or by reading `set.size` or calling `set.has(...)` as in the [example](https://svelte.dev/playground/53438b51194b4882bcc18cddf9f96f15) below) in an [effect](https://svelte.dev/docs/svelte/$effect) or [derived](https://svelte.dev/docs/svelte/$derived)
* will cause it to be re-evaluated as necessary when the set is updated.
*
* Note that values in a reactive set are _not_ made [deeply reactive](https://svelte.dev/docs/svelte/$state#Deep-state).
*
* ```svelte
* <script>
* import { SvelteSet } from 'svelte/reactivity';
* let monkeys = new SvelteSet();
*
* function toggle(monkey) {
* if (monkeys.has(monkey)) {
* monkeys.delete(monkey);
* } else {
* monkeys.add(monkey);
* }
* }
* </script>
*
* {#each ['🙈', '🙉', '🙊'] as monkey}
* <button onclick={() => toggle(monkey)}>{monkey}</button>
* {/each}
*
* <button onclick={() => monkeys.clear()}>clear</button>
*
* {#if monkeys.has('🙈')}<p>see no evil</p>{/if}
* {#if monkeys.has('🙉')}<p>hear no evil</p>{/if}
* {#if monkeys.has('🙊')}<p>speak no evil</p>{/if}
* ```
*
* @template T
* @extends {Set<T>}
*/
Expand Down
27 changes: 27 additions & 0 deletions packages/svelte/src/reactivity/url-search-params.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,32 @@ import { increment } from './utils.js';

export const REPLACE = Symbol();

/**
* A reactive version of the built-in [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object.
* Reading its contents (by iterating, or by calling `params.get(...)` or `params.getAll(...)` as in the [example](https://svelte.dev/playground/b3926c86c5384bab9f2cf993bc08c1c8) below) in an [effect](https://svelte.dev/docs/svelte/$effect) or [derived](https://svelte.dev/docs/svelte/$derived)
* will cause it to be re-evaluated as necessary when the params are updated.
*
* ```svelte
* <script>
* import { SvelteURLSearchParams } from 'svelte/reactivity';
*
* const params = new SvelteURLSearchParams('message=hello');
*
* let key = $state('key');
* let value = $state('value');
* </script>
*
* <input bind:value={key} />
* <input bind:value={value} />
* <button onclick={() => params.append(key, value)}>append</button>
*
* <p>?{params.toString()}</p>
*
* {#each params as [key, value]}
* <p>{key}: {value}</p>
* {/each}
* ```
*/
export class SvelteURLSearchParams extends URLSearchParams {
#version = source(0);
#url = get_current_url();
Expand All @@ -23,6 +49,7 @@ export class SvelteURLSearchParams extends URLSearchParams {

/**
* @param {URLSearchParams} params
* @internal
*/
[REPLACE](params) {
if (this.#updating) return;
Expand Down
27 changes: 27 additions & 0 deletions packages/svelte/src/reactivity/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,33 @@ export function get_current_url() {
return current_url;
}

/**
* A reactive version of the built-in [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) object.
* Reading properties of the URL (such as `url.href` or `url.pathname`) in an [effect](https://svelte.dev/docs/svelte/$effect) or [derived](https://svelte.dev/docs/svelte/$derived)
* will cause it to be re-evaluated as necessary when the URL changes.
*
* The `searchParams` property is an instance of [SvelteURLSearchParams](https://svelte.dev/docs/svelte/svelte-reactivity#SvelteURLSearchParams).
*
* [Example](https://svelte.dev/playground/5a694758901b448c83dc40dc31c71f2a):
*
* ```svelte
* <script>
* import { SvelteURL } from 'svelte/reactivity';
*
* const url = new SvelteURL('https://example.com/path');
* </script>
*
* <!-- changes to these... -->
* <input bind:value={url.protocol} />
* <input bind:value={url.hostname} />
* <input bind:value={url.pathname} />
*
* <hr />
*
* <!-- will update `href` and vice versa -->
* <input bind:value={url.href} size="65" />
* ```
*/
export class SvelteURL extends URL {
#protocol = source(super.protocol);
#username = source(super.username);
Expand Down
Loading