Skip to content

Commit 12acce0

Browse files
committed
[svelte] Guides
1 parent de7dd12 commit 12acce0

3 files changed

Lines changed: 277 additions & 2 deletions

File tree

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Building UIs With Svelte
2+
3+
This guide describes how to use the `tinybase/ui-svelte` module to build
4+
reactive user interfaces in Svelte 5 applications.
5+
6+
## Installation
7+
8+
Install TinyBase and Svelte together:
9+
10+
```bash
11+
npm install tinybase svelte
12+
```
13+
14+
Then import hooks and components directly from the `tinybase/ui-svelte` module
15+
in your component's `<script>` block.
16+
17+
## Reactive Hooks
18+
19+
Every hook in the `ui-svelte` module returns a reactive object with a `current`
20+
property. Because `current` is backed by Svelte's `$state` rune, any part of
21+
your template that reads it will automatically update when the underlying Store
22+
data changes.
23+
24+
Here is the `useCell` hook reading the color of a pet and displaying it in a
25+
paragraph:
26+
27+
```svelte
28+
<script>
29+
import {createStore} from 'tinybase';
30+
import {useCell} from 'tinybase/ui-svelte';
31+
32+
const store = createStore().setCell('pets', 'fido', 'color', 'brown');
33+
const color = useCell('pets', 'fido', 'color', store);
34+
</script>
35+
36+
<p>Color: {color.current}</p>
37+
<!-- Renders: <p>Color: brown</p> -->
38+
```
39+
40+
When `store.setCell('pets', 'fido', 'color', 'walnut')` is called anywhere, the
41+
paragraph immediately re-renders to show `walnut`. No manual subscriptions, no
42+
`$:` labels, no `onDestroy` cleanup — the hook registers and removes TinyBase
43+
listeners automatically using Svelte's `$effect` lifecycle.
44+
45+
There are hooks corresponding to every Store reading method:
46+
47+
- `useValues` — reactive equivalent of `getValues`
48+
- `useValueIds` — reactive equivalent of `getValueIds`
49+
- `useValue` — reactive equivalent of `getValue`
50+
- `useHasValues` — reactive equivalent of `hasValues`
51+
- `useTables` — reactive equivalent of `getTables`
52+
- `useTableIds` — reactive equivalent of `getTableIds`
53+
- `useTable` — reactive equivalent of `getTable`
54+
- `useRowIds` — reactive equivalent of `getRowIds`
55+
- `useSortedRowIds` — reactive equivalent of `getSortedRowIds`
56+
- `useRow` — reactive equivalent of `getRow`
57+
- `useCellIds` — reactive equivalent of `getCellIds`
58+
- `useCell` — reactive equivalent of `getCell`
59+
60+
There are also hooks for the higher-level TinyBase objects: `useMetric`,
61+
`useMetricIds`, `useSliceIds`, `useSliceRowIds`, `useResultCell`,
62+
`useResultRow`, `useResultTable`, `useResultRowIds`, `useCheckpointIds`,
63+
`useCheckpoint`, and more.
64+
65+
## Reactive Parameters With R
66+
67+
All hook parameters accept either a plain value or a reactive getter function.
68+
This is the `R<T>` type: `T | (() => T)`.
69+
70+
Passing a getter function that reads a `$state` variable makes the hook
71+
reactively track which data it fetches. In this example, `rowId` is a prop and
72+
the hook refetches automatically when it changes:
73+
74+
```svelte
75+
<script>
76+
import {useCell} from 'tinybase/ui-svelte';
77+
78+
let {rowId, store} = $props();
79+
const color = useCell('pets', () => rowId, 'color', store);
80+
</script>
81+
82+
<p>{color.current}</p>
83+
```
84+
85+
Without the `() => rowId` wrapper, changing the `rowId` prop would not cause
86+
the hook to re-read the Store for the new row.
87+
88+
## Writable State With useCellState
89+
90+
The `useCellState` and `useValueState` hooks expose a writable `current`
91+
property. Writing to it calls `store.setCell()` or `store.setValue()`. This
92+
makes Svelte's `bind:value` directive work for two-way binding:
93+
94+
```svelte
95+
<script>
96+
import {createStore} from 'tinybase';
97+
import {useCellState} from 'tinybase/ui-svelte';
98+
99+
const store = createStore().setCell('pets', 'fido', 'color', 'brown');
100+
const color = useCellState('pets', 'fido', 'color', store);
101+
</script>
102+
103+
<input bind:value={color.current} />
104+
<p>Current color: {color.current}</p>
105+
```
106+
107+
Typing in the `<input>` updates the Store, which is immediately reflected
108+
in the paragraph — without any additional event handling.
109+
110+
## Context With Provider
111+
112+
For larger apps, passing the `store` object to every hook as the last argument
113+
gets repetitive. The `Provider` component sets a context that all descendant
114+
hooks use automatically when no explicit reference is given:
115+
116+
```svelte
117+
<!-- App.svelte -->
118+
<script>
119+
import {createStore} from 'tinybase';
120+
import {Provider} from 'tinybase/ui-svelte';
121+
import Pane from './Pane.svelte';
122+
123+
const store = createStore().setTables({
124+
pets: {fido: {species: 'dog', color: 'brown'}},
125+
});
126+
</script>
127+
128+
<Provider {store}>
129+
<Pane />
130+
</Provider>
131+
```
132+
133+
```svelte
134+
<!-- Pane.svelte -->
135+
<script>
136+
import {useCell} from 'tinybase/ui-svelte';
137+
138+
// No store argument — resolved automatically from the nearest Provider
139+
const species = useCell('pets', 'fido', 'species');
140+
const color = useCell('pets', 'fido', 'color');
141+
</script>
142+
143+
<p>{species.current} ({color.current})</p>
144+
```
145+
146+
`Provider` accepts `store`, `storesById`, `metrics`, `metricsById`, and
147+
equivalent props for every TinyBase object type. When multiple stores are
148+
provided, hooks reference them by Id:
149+
150+
```svelte
151+
<script>
152+
import {useCell} from 'tinybase/ui-svelte';
153+
154+
const color = useCell('pets', 'fido', 'color', 'petStore');
155+
</script>
156+
```
157+
158+
Descendant components can register additional objects into the nearest Provider
159+
context at runtime using `provideStore`, `provideMetrics`, and similar
160+
functions.
161+
162+
## View Components
163+
164+
For common rendering tasks, the module provides pre-built view components that
165+
wrap the hooks and render data directly. These make it easy to compose UIs from
166+
Store data:
167+
168+
```svelte
169+
<script>
170+
import {createStore} from 'tinybase';
171+
import {CellView, RowView, TablesView} from 'tinybase/ui-svelte';
172+
173+
const store = createStore().setTables({
174+
pets: {
175+
fido: {species: 'dog', color: 'brown'},
176+
felix: {species: 'cat', color: 'black'},
177+
},
178+
});
179+
</script>
180+
181+
<!-- Renders the value of a single cell -->
182+
<CellView tableId="pets" rowId="fido" cellId="species" {store} />
183+
184+
<!-- Renders all cells in a row concatenated -->
185+
<RowView tableId="pets" rowId="fido" {store} />
186+
187+
<!-- Renders the entire tables structure -->
188+
<TablesView {store} />
189+
```
190+
191+
Components accept a `cellComponent` or `rowComponent` snippet prop to customize
192+
how individual cells or rows are rendered:
193+
194+
```svelte
195+
<script>
196+
import {RowView} from 'tinybase/ui-svelte';
197+
</script>
198+
199+
<RowView tableId="pets" rowId="fido" {store}>
200+
{#snippet cellComponent(tableId, rowId, cellId)}
201+
<span class="cell">{cellId}</span>
202+
{/snippet}
203+
</RowView>
204+
```
205+
206+
The full set of view components covers every level of the Store hierarchy and
207+
the higher-level TinyBase objects:
208+
209+
- `CellView`, `RowView`, `TableView`, `TablesView`
210+
- `ValueView`, `ValuesView`
211+
- `SliceView`, `IndexView`
212+
- `ResultCellView`, `ResultRowView`, `ResultTableView`, `ResultSortedTableView`
213+
- `SortedTableView`
214+
- `MetricView`
215+
- `CheckpointView`, `BackwardCheckpointsView`, `CurrentCheckpointView`,
216+
`ForwardCheckpointsView`
217+
- `RemoteRowView`, `LocalRowsView`, `LinkedRowsView`
218+
219+
That completes the overview of the `ui-svelte` module. For API reference, see
220+
the [ui-svelte](/api/ui-svelte/) documentation.

site/guides/17_releases.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,61 @@ highlighted features.
55

66
---
77

8+
# v8.1
9+
10+
## Svelte 5 Support
11+
12+
This release introduces the new `tinybase/ui-svelte` module, bringing native
13+
Svelte 5 runes-based reactive bindings to TinyBase. The module provides hooks
14+
and view components for building reactive UIs without any additional state
15+
management.
16+
17+
Hooks return a reactive `{ current }` object backed by Svelte's `$state` rune.
18+
Any component that reads `hook.current` will automatically re-render when the
19+
underlying TinyBase data changes:
20+
21+
```svelte
22+
<script>
23+
import {createStore} from 'tinybase';
24+
import {useCell} from 'tinybase/ui-svelte';
25+
26+
const store = createStore().setCell('pets', 'fido', 'color', 'brown');
27+
const color = useCell('pets', 'fido', 'color', store);
28+
</script>
29+
30+
<p>Color: {color.current}</p>
31+
```
32+
33+
The `useCellState` and `useValueState` hooks go further, providing a writable
34+
`current` property that pairs naturally with Svelte's `bind:` directive for
35+
two-way data binding:
36+
37+
```svelte
38+
<script>
39+
import {useCellState} from 'tinybase/ui-svelte';
40+
41+
const color = useCellState('pets', 'fido', 'color', store);
42+
</script>
43+
44+
<input bind:value={color.current} />
45+
```
46+
47+
All hooks accept reactive getter functions as parameters — the `R<T>` type
48+
(`T | (() => T)`) — so passing `() => rowId` from a `$state` variable causes
49+
the hook to reactively track which row it reads, without unmounting and
50+
remounting.
51+
52+
The module further includes a `Provider` component and context helpers
53+
(`useStore`, `useMetrics`, etc.) for sharing TinyBase objects across a component
54+
tree, and ~23 built-in view components (`CellView`, `RowView`, `TablesView`,
55+
and more) for assembling UIs directly from Store data.
56+
57+
Read more in the new
58+
[Building UIs With Svelte](/guides/building-uis/building-uis-with-svelte/)
59+
guide.
60+
61+
---
62+
863
# v8.0
964

1065
## Object And Array Types

site/home/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
</h2>
77
</section>
88

9-
<a href='/guides/releases/#v8-0'><em>NEW!</em> v8.0 release</a>
9+
<a href='/guides/releases/#v8-1'><em>NEW!</em> v8.1 release</a>
1010

11-
<span id="one-with">"The one with objects, arrays & middleware!"</span>
11+
<span id="one-with">"The one with Svelte 5 support!"</span>
1212

1313
<a class='start' href='/guides/the-basics/getting-started/'>Get started</a>
1414

0 commit comments

Comments
 (0)