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
{{ message }}
Repository navigation
Commit 8b60e08
Browse filesBrowse the repository at this point in the historyBrowse files
purpose: 'Use rune-backed atoms, selected table.state, controlled slices, and external atoms without reactivity mismatches.'
912
+
purpose: 'Use rune-aware table atoms and stores, native $derived projections, controlled $state or createTableState slices, and external atoms without broad invalidation or snapshot mismatches.'
- 'Reading or passing non-reactive snapshots where createTable options need getters over $state or $derived values.'
922
+
- 'Keeping the removed beta.58 createTable/createAppTable selector argument, selected table.state property, subscribeTable helper, or SubscribeSource type after beta.59.'
923
+
- 'Reading atom or store snapshots outside a tracked Svelte scope and expecting the read itself to keep a consumer reactive.'
924
+
- 'Reading table.store.get() in an effect that only needs one atom slice, causing unrelated state changes to rerun the effect.'
922
925
- 'Pairing onSliceChange with a controlled state slice that is not actually written back with value-or-updater semantics.'
923
926
- 'Blaming pagination reactivity when autoResetPageIndex immediately overwrites an externally requested page.'
924
927
@@ -937,6 +940,7 @@ skills:
937
940
failure_modes:
938
941
- 'Attempting the v9 adapter migration without first adopting Svelte 5-compatible component and reactivity syntax.'
939
942
- 'Keeping readable-store assumptions or v8 row-model table options after switching to createTable.'
943
+
- 'Keeping beta.58 creation selectors, table.state, subscribeTable, or their removed selected-state generic parameters after beta.59.'
This specification is the generation contract for a deliberately smaller, foot-gun-first TanStack Intent skill set. It is not a documentation outline. The complete evidence and failure-mode inventory is in domain_map.yaml.
@@ -305,8 +305,11 @@ All Devtools skills must emphasize the required non-empty table options.key, lif
305
305
### Svelte
306
306
307
307
- V9 targets Svelte 5 and runes.
308
+
- Read a slice with `table.atoms.<slice>.get()` and the complete state with `table.store.get()` inside templates, `$derived`, `$derived.by`, or `$effect`; reads outside tracked scopes are current snapshots.
309
+
- Starting in beta.59, Svelte has no table-creation selector, selected `table.state`, `subscribeTable`, or `SubscribeSource`; use native `$derived` projections instead.
310
+
- Prefer `$state` plus getter-backed controlled slices, or `createTableState` for an updater-compatible getter/setter pair. Keep `useSelector` only for raw external atoms consumed outside the table.
308
311
- Reactive data and controlled values commonly need getters; avoid passing snapshots.
309
-
- createTableHook implementation belongs in a rune-capable module.
312
+
-The shipped `createTableHook` implementation supplies rune semantics, so an app hook that calls it may live in a normal `.ts` module.
310
313
311
314
### Vue
312
315
@@ -342,7 +345,7 @@ All Devtools skills must emphasize the required non-empty table options.key, lif
342
345
343
346
## Cross-cutting placement rules
344
347
345
-
- Performance: stable inputs in getting-started/core; selectors in table-state; CSS variables in resizing; measurement/overscan in Virtual; row ownership in client-vs-server.
348
+
- Performance: stable inputs in getting-started/core; adapter-specific fine-grained state reads or selectors in table-state; CSS variables in resizing; measurement/overscan in Virtual; row ownership in client-vs-server.
346
349
- CSS: pinning, sizing, resizing, and Virtual skills only. Core may state that CSS is user-owned.
347
350
- Accessibility: core/getting-started may remind that headless rendering leaves semantics and interaction accessibility with the renderer; do not create a component-library integration skill.
348
351
- Query: data source and manual processing boundaries, not Table rendering.
description: 'Create a Svelte 5 TanStack Table v9 table with createTable, explicit tableFeatures, rune-backed data getters, stable static inputs, snippets, and headless markup. Load when replacing createSvelteTable or pre-rune patterns.'
610
+
description: 'Create a Svelte 5 TanStack Table v9 table with createTable, explicit tableFeatures, rune-backed data getters, stable static inputs, FlexRender, and headless markup. Load when replacing createSvelteTable or pre-rune patterns.'
description: 'Define a Svelte createAppTable/createAppColumnHelper in a rune-capable module with shared features/defaults, reactive per-table getters, optional App component registries, and typed table/cell/header context hooks.'
657
+
description: "Define a Svelte createAppTable/createAppColumnHelper using the adapter's rune-capable createTableHook implementation, shared features/defaults, reactive per-table getters, optional App component registries, and typed table/cell/header context hooks."
In event handlers or other non-render code, you can also read the current snapshot with `table.atoms.cellSelection.get()`. This read does not subscribe a component to future changes, so prefer `table.state.cellSelection` in render positions.
54
+
Use the same atom read in markup or a native derived value:
Outside a tracked context, `table.atoms.cellSelection.get()` is simply the current snapshot.
55
62
56
63
The expansion APIs (`getSelectedCellIds`, `getSelectedCellRangesData`) are memoized and pull-based. They cost nothing unless you actually call them, so a table that only highlights cells never pays to enumerate a large selection.
57
64
@@ -313,8 +320,8 @@ Because a reorder can widen a selection onto columns the user never picked, some
313
320
let isFirstColumnLayout =true
314
321
315
322
$effect(() => {
316
-
//read the atoms, not table.state: the selector rebuilds that object on every
317
-
//selected slice change, so reading it here would re-fire on every selection
323
+
//Read only the layout atoms. A full table.store.get() read would re-run for
324
+
//every table state change, including selection changes.
318
325
voidtable.atoms.columnOrder.get()
319
326
voidtable.atoms.columnPinning.get()
320
327
voidtable.atoms.columnVisibility.get()
@@ -343,21 +350,8 @@ const table = createTable({
343
350
344
351
### Performance
345
352
346
-
Svelte's runes track these reads and the compiler updates only the DOM nodes
347
-
that actually changed, so the example renders its cells plainly.
353
+
Svelte's runes track atom reads and the compiler updates only the DOM nodes that actually changed, so the example renders its cells plainly.
348
354
349
-
Measured on a table with a thousand rows and twelve columns, a drag updates in
350
-
roughly 16ms per move with plain reads.
351
-
352
-
`subscribeTable` is available if you want an explicit fine-grained subscription:
Measured on a table with a thousand rows and twelve columns, a drag updates in roughly 16ms per move with plain reads.
358
356
359
-
One trap worth knowing: do not read `table.state` inside an `$effect` that also
360
-
writes selection state. The selector rebuilds that object whenever any selected
361
-
slice changes, so an effect meant to watch the column layout will re-fire on
362
-
every selection change and clear the selection you just made. Read
363
-
`table.atoms.<slice>.get()` instead.
357
+
One trap worth knowing: do not read `table.store.get()` inside an `$effect` that also writes selection state unless the effect truly depends on every state slice. An effect meant to watch column layout would otherwise re-run on every selection change and clear the selection you just made. Read only the required `table.atoms.<slice>.get()` values instead.
Copy file name to clipboardExpand all lines: docs/framework/svelte/guide/column-filtering.md
+6-3Lines changed: 6 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -138,7 +138,7 @@ Since the column filter state is an array of objects, you can have multiple colu
138
138
139
139
#### Accessing Column Filter State
140
140
141
-
For reactive reads that should update your UI, use `table.state.columnFilters` (selected by the `createTable` selector) or `subscribeTable`. In event handlers or other non-reactive code, you can read the current snapshot with `table.atoms.columnFilters.get()`, but this read only participates in Svelte dependency tracking when called in a rune-tracked context.
141
+
Read column filters from `table.atoms.columnFilters.get()`. The call returns the current value in event handlers and becomes reactive when it runs in a template, `$derived`, `$derived.by`, or `$effect`.
142
142
143
143
```ts
144
144
const table =createTable({
@@ -148,8 +148,11 @@ const table = createTable({
148
148
//...
149
149
})
150
150
151
-
table.state.columnFilters// reactive read
152
-
table.atoms.columnFilters.get() // snapshot read in event handlers
@@ -253,4 +253,4 @@ Svelte 5's fine-grained reactivity means a resize does not re-render whole compo
253
253
1.**Derive all column widths in one `$derived` value.** Build a single style string that maps each header and column id to a CSS variable, then bind it on the `<table>` element (`<table style={tableStyle}>`). `header.getSize()` reads the rune-backed `columnSizing` atom, so a drag re-runs only this derived and its single attribute effect.
254
254
2.**Reference the variables in cell styles** (`width: calc(var(--col-firstName-size) * 1px)`) so the browser applies new widths without Svelte re-evaluating each cell.
255
255
256
-
Because nothing in the table body reads resize state, no body memoization is needed, and you do not need a `createTable` selector for this pattern; the resizer's highlight is its own inline binding.
256
+
Because nothing in the table body reads resize state, no body memoization is needed; the resizer's highlight is its own narrow inline atom binding.
Copy file name to clipboardExpand all lines: docs/framework/svelte/guide/custom-features.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
@@ -330,10 +330,10 @@ const table = createTable({
330
330
331
331
### Step 5: Use the Feature in Your Application
332
332
333
-
Now that the feature is added to the table instance, you can use the new instance APIs, options, and state in your application. `table.state.density` reads the new state slice reactively in your markup, and `table.setDensity` / `table.toggleDensity` update it.
333
+
Now that the feature is added to the table instance, you can use the new instance APIs, options, and state in your application. `table.atoms.density.get()` reads the new state slice reactively in your markup, and `table.setDensity` / `table.toggleDensity` update it.
0 commit comments