@tanstack/svelte-table 9.0.0-beta.5 → 9.0.0-beta.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/createTable.svelte.d.ts +0 -1
- package/dist/createTable.svelte.js +1 -2
- package/dist/createTableHook.svelte.d.ts +47 -13
- package/dist/createTableHook.svelte.js +16 -8
- package/dist/experimental-worker-plugin.d.ts +1 -0
- package/dist/experimental-worker-plugin.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/render-component.js +4 -0
- package/package.json +10 -5
- package/skills/create-table-hook/SKILL.md +168 -0
- package/skills/getting-started/SKILL.md +172 -0
- package/skills/migrate-v8-to-v9/SKILL.md +195 -0
- package/skills/table-state/SKILL.md +205 -0
- package/skills/with-tanstack-query/SKILL.md +147 -0
- package/skills/with-tanstack-virtual/SKILL.md +150 -0
- package/src/createTable.svelte.ts +1 -2
- package/src/createTableHook.svelte.ts +127 -21
- package/src/experimental-worker-plugin.ts +1 -0
- package/src/index.ts +1 -0
- package/skills/svelte/client-to-server/SKILL.md +0 -238
- package/skills/svelte/compose-with-tanstack-form/SKILL.md +0 -295
- package/skills/svelte/compose-with-tanstack-pacer/SKILL.md +0 -176
- package/skills/svelte/compose-with-tanstack-query/SKILL.md +0 -299
- package/skills/svelte/compose-with-tanstack-store/SKILL.md +0 -277
- package/skills/svelte/compose-with-tanstack-virtual/SKILL.md +0 -286
- package/skills/svelte/getting-started/SKILL.md +0 -340
- package/skills/svelte/migrate-v8-to-v9/SKILL.md +0 -256
- package/skills/svelte/production-readiness/SKILL.md +0 -256
- package/skills/svelte/table-state/SKILL.md +0 -441
package/README.md
CHANGED
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
> - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table)
|
|
40
40
|
> - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table)
|
|
41
41
|
> - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table)
|
|
42
|
+
> - [Alpine Table](https://tanstack.com/table/alpha/docs/framework/alpine/alpine-table)
|
|
43
|
+
> - [Ember Table](https://tanstack.com/table/alpha/docs/framework/ember/ember-table)
|
|
42
44
|
|
|
43
45
|
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
|
|
44
46
|
|
|
@@ -17,7 +17,6 @@ import { svelteReactivity } from './reactivity.svelte';
|
|
|
17
17
|
* const table = createTable(
|
|
18
18
|
* {
|
|
19
19
|
* features,
|
|
20
|
-
* rowModels: {},
|
|
21
20
|
* columns,
|
|
22
21
|
* data,
|
|
23
22
|
* },
|
|
@@ -32,7 +31,7 @@ export function createTable(tableOptions, selector) {
|
|
|
32
31
|
// 1. Merge reactivity into options using mergeObjects (preserves getters)
|
|
33
32
|
const mergedOptions = mergeObjects(tableOptions, {
|
|
34
33
|
features: {
|
|
35
|
-
|
|
34
|
+
coreReactivityFeature: svelteReactivity(),
|
|
36
35
|
...tableOptions.features,
|
|
37
36
|
},
|
|
38
37
|
});
|
|
@@ -189,6 +189,47 @@ export type AppSvelteTable<TFeatures extends TableFeatures, TData extends RowDat
|
|
|
189
189
|
*/
|
|
190
190
|
FlexRender: typeof FlexRenderSvelte;
|
|
191
191
|
};
|
|
192
|
+
export interface CreateTableHookResult<TFeatures extends TableFeatures, TTableComponents extends Record<string, ComponentType<any>>, TCellComponents extends Record<string, ComponentType<any>>, THeaderComponents extends Record<string, ComponentType<any>>> {
|
|
193
|
+
/** The features object that was passed to `createTableHook`. */
|
|
194
|
+
appFeatures: TFeatures;
|
|
195
|
+
/**
|
|
196
|
+
* A column helper pre-bound to `TFeatures` and the registered components, so
|
|
197
|
+
* the cell/header/footer render props expose the bound components.
|
|
198
|
+
*/
|
|
199
|
+
createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<TFeatures, TData, TCellComponents, THeaderComponents>;
|
|
200
|
+
/**
|
|
201
|
+
* Creates a table with the `App*` wrapper components and registered
|
|
202
|
+
* `tableComponents` attached. `TData` is inferred from the `data` option.
|
|
203
|
+
*/
|
|
204
|
+
createAppTable: <TData extends RowData, TSelected = TableState<TFeatures>>(tableOptions: Omit<TableOptions<TFeatures, TData>, 'features'>, selector?: (state: TableState<TFeatures>) => TSelected) => AppSvelteTable<TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents>;
|
|
205
|
+
/**
|
|
206
|
+
* Reads the table provided by the nearest `<table.AppTable>`. This is the same
|
|
207
|
+
* extended instance `createAppTable` returns, so the `App*` components and your
|
|
208
|
+
* `tableComponents` are available on it.
|
|
209
|
+
*
|
|
210
|
+
* Pass `TSelected` to match the selector you gave `createAppTable`, so
|
|
211
|
+
* `table.state` is typed as the selected slice. It cannot be inferred
|
|
212
|
+
* automatically (context does not carry the provider's generics), so it
|
|
213
|
+
* defaults to the full table state, which is correct for the common case of
|
|
214
|
+
* `createAppTable` without a selector.
|
|
215
|
+
*/
|
|
216
|
+
useTableContext: <TData extends RowData = RowData, TSelected = TableState<TFeatures>>() => AppSvelteTable<TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents>;
|
|
217
|
+
/**
|
|
218
|
+
* Reads the cell provided by the nearest `<table.AppCell>`, extended with your
|
|
219
|
+
* `cellComponents` and a context-bound `FlexRender`.
|
|
220
|
+
*/
|
|
221
|
+
useCellContext: <TValue extends CellData = CellData>() => Cell<TFeatures, any, TValue> & TCellComponents & {
|
|
222
|
+
FlexRender: typeof FlexRenderSvelte;
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Reads the header provided by the nearest `<table.AppHeader>` /
|
|
226
|
+
* `<table.AppFooter>`, extended with your `headerComponents` and a
|
|
227
|
+
* context-bound `FlexRender`.
|
|
228
|
+
*/
|
|
229
|
+
useHeaderContext: <TValue extends CellData = CellData>() => Header<TFeatures, any, TValue> & THeaderComponents & {
|
|
230
|
+
FlexRender: typeof FlexRenderSvelte;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
192
233
|
/**
|
|
193
234
|
* Creates a custom table hook with pre-bound components for composition.
|
|
194
235
|
*
|
|
@@ -213,23 +254,16 @@ export type AppSvelteTable<TFeatures extends TableFeatures, TData extends RowDat
|
|
|
213
254
|
* rowPaginationFeature,
|
|
214
255
|
* rowSortingFeature,
|
|
215
256
|
* columnFilteringFeature,
|
|
216
|
-
* }),
|
|
217
|
-
* rowModels: {
|
|
218
257
|
* paginatedRowModel: createPaginatedRowModel(),
|
|
219
|
-
* sortedRowModel: createSortedRowModel(
|
|
220
|
-
* filteredRowModel: createFilteredRowModel(
|
|
221
|
-
*
|
|
258
|
+
* sortedRowModel: createSortedRowModel(),
|
|
259
|
+
* filteredRowModel: createFilteredRowModel(),
|
|
260
|
+
* sortFns,
|
|
261
|
+
* filterFns,
|
|
262
|
+
* }),
|
|
222
263
|
* tableComponents: { PaginationControls, RowCount },
|
|
223
264
|
* cellComponents: { TextCell, NumberCell },
|
|
224
265
|
* headerComponents: { SortIndicator, ColumnFilter },
|
|
225
266
|
* })
|
|
226
267
|
* ```
|
|
227
268
|
*/
|
|
228
|
-
export declare function createTableHook<TFeatures extends TableFeatures, const TTableComponents extends Record<string, ComponentType<any>>, const TCellComponents extends Record<string, ComponentType<any>>, const THeaderComponents extends Record<string, ComponentType<any>>>({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableHookOptions<TFeatures, TTableComponents, TCellComponents, THeaderComponents>):
|
|
229
|
-
appFeatures: TFeatures;
|
|
230
|
-
createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<TFeatures, TData, TCellComponents, THeaderComponents>;
|
|
231
|
-
createAppTable: <TData extends RowData, TSelected = TableState<TFeatures>>(tableOptions: Omit<TableOptions<TFeatures, TData>, "features" | "rowModels">, selector?: (state: TableState<TFeatures>) => TSelected) => AppSvelteTable<TFeatures, TData, TSelected, TTableComponents, TCellComponents, THeaderComponents>;
|
|
232
|
-
useTableContext: <TData extends RowData = RowData>() => SvelteTable<TFeatures, TData>;
|
|
233
|
-
useCellContext: <TValue extends CellData = unknown>() => Cell<TFeatures, any, TValue>;
|
|
234
|
-
useHeaderContext: <TValue extends CellData = unknown>() => Header<TFeatures, any, TValue>;
|
|
235
|
-
};
|
|
269
|
+
export declare function createTableHook<TFeatures extends TableFeatures, const TTableComponents extends Record<string, ComponentType<any>>, const TCellComponents extends Record<string, ComponentType<any>>, const THeaderComponents extends Record<string, ComponentType<any>>>({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableHookOptions<TFeatures, TTableComponents, TCellComponents, THeaderComponents>): CreateTableHookResult<TFeatures, TTableComponents, TCellComponents, THeaderComponents>;
|
|
@@ -34,12 +34,12 @@ import FlexRenderSvelte from './FlexRender.svelte';
|
|
|
34
34
|
* rowPaginationFeature,
|
|
35
35
|
* rowSortingFeature,
|
|
36
36
|
* columnFilteringFeature,
|
|
37
|
-
* }),
|
|
38
|
-
* rowModels: {
|
|
39
37
|
* paginatedRowModel: createPaginatedRowModel(),
|
|
40
|
-
* sortedRowModel: createSortedRowModel(
|
|
41
|
-
* filteredRowModel: createFilteredRowModel(
|
|
42
|
-
*
|
|
38
|
+
* sortedRowModel: createSortedRowModel(),
|
|
39
|
+
* filteredRowModel: createFilteredRowModel(),
|
|
40
|
+
* sortFns,
|
|
41
|
+
* filterFns,
|
|
42
|
+
* }),
|
|
43
43
|
* tableComponents: { PaginationControls, RowCount },
|
|
44
44
|
* cellComponents: { TextCell, NumberCell },
|
|
45
45
|
* headerComponents: { SortIndicator, ColumnFilter },
|
|
@@ -65,6 +65,9 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
65
65
|
throw new Error('`useTableContext` must be used within an `AppTable` component. ' +
|
|
66
66
|
'Make sure your component is wrapped with `<table.AppTable>...</table.AppTable>`.');
|
|
67
67
|
}
|
|
68
|
+
// `<table.AppTable>` provides the extended table (the App* wrapper
|
|
69
|
+
// components and `tableComponents` are Object.assign-ed onto the same
|
|
70
|
+
// instance `createAppTable` returns), so this asserts the runtime shape.
|
|
68
71
|
return table;
|
|
69
72
|
}
|
|
70
73
|
/**
|
|
@@ -78,6 +81,9 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
78
81
|
throw new Error('`useCellContext` must be used within an `AppCell` component. ' +
|
|
79
82
|
'Make sure your component is wrapped with `<table.AppCell cell={cell}>...</table.AppCell>`.');
|
|
80
83
|
}
|
|
84
|
+
// `<table.AppCell>` Object.assign-es `cellComponents` and `FlexRender` onto
|
|
85
|
+
// the same cell instance it puts in context, so this asserts the runtime
|
|
86
|
+
// shape.
|
|
81
87
|
return cell;
|
|
82
88
|
}
|
|
83
89
|
/**
|
|
@@ -90,6 +96,8 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
90
96
|
if (!header) {
|
|
91
97
|
throw new Error('`useHeaderContext` must be used within an `AppHeader` or `AppFooter` component.');
|
|
92
98
|
}
|
|
99
|
+
// `<table.AppHeader>` / `<table.AppFooter>` Object.assign `headerComponents`
|
|
100
|
+
// and `FlexRender` onto the same header instance they put in context.
|
|
93
101
|
return header;
|
|
94
102
|
}
|
|
95
103
|
/**
|
|
@@ -124,7 +132,7 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
124
132
|
setContext(tableContextKey, table);
|
|
125
133
|
return AppTableSvelte(internal, { ...props });
|
|
126
134
|
});
|
|
127
|
-
const AppCell = ((internal, { children, cell
|
|
135
|
+
const AppCell = ((internal, { children, cell }) => {
|
|
128
136
|
setContext(cellContextKey, cell);
|
|
129
137
|
return AppCellSvelte(internal, {
|
|
130
138
|
cell,
|
|
@@ -132,7 +140,7 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
132
140
|
children,
|
|
133
141
|
});
|
|
134
142
|
});
|
|
135
|
-
const AppHeader = ((internal, { children, header
|
|
143
|
+
const AppHeader = ((internal, { children, header }) => {
|
|
136
144
|
setContext(headerContextKey, header);
|
|
137
145
|
return AppHeaderSvelte(internal, {
|
|
138
146
|
header,
|
|
@@ -141,7 +149,7 @@ export function createTableHook({ tableComponents, cellComponents, headerCompone
|
|
|
141
149
|
});
|
|
142
150
|
});
|
|
143
151
|
// AppFooter reuses AppHeaderSvelte (footers use Header type in table-core)
|
|
144
|
-
const AppFooter = ((internal, { children, header
|
|
152
|
+
const AppFooter = ((internal, { children, header }) => {
|
|
145
153
|
setContext(headerContextKey, header);
|
|
146
154
|
return AppHeaderSvelte(internal, {
|
|
147
155
|
header,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@tanstack/table-core/experimental-worker-plugin';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@tanstack/table-core/experimental-worker-plugin';
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from '@tanstack/table-core';
|
|
|
2
2
|
export { createTable } from './createTable.svelte';
|
|
3
3
|
export type { SvelteTable } from './createTable.svelte';
|
|
4
4
|
export { createTableHook } from './createTableHook.svelte';
|
|
5
|
-
export type { AppCellContext, AppColumnDefBase, AppColumnDefTemplate, AppColumnHelper, AppDisplayColumnDef, AppGroupColumnDef, AppHeaderContext, AppSvelteTable, ComponentType, CreateTableHookOptions, } from './createTableHook.svelte';
|
|
5
|
+
export type { AppCellContext, AppColumnDefBase, AppColumnDefTemplate, AppColumnHelper, AppDisplayColumnDef, AppGroupColumnDef, AppHeaderContext, AppSvelteTable, ComponentType, CreateTableHookOptions, CreateTableHookResult, } from './createTableHook.svelte';
|
|
6
6
|
export { createTableState } from './createTableState.svelte';
|
|
7
7
|
export { default as FlexRender } from './FlexRender.svelte';
|
|
8
8
|
export { subscribeTable, type SubscribeSource } from './subscribe';
|
package/dist/render-component.js
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
* */
|
|
17
17
|
export class RenderComponentConfig {
|
|
18
|
+
component;
|
|
19
|
+
props;
|
|
18
20
|
constructor(component, props) {
|
|
19
21
|
this.component = component;
|
|
20
22
|
this.props = props;
|
|
@@ -36,6 +38,8 @@ export class RenderComponentConfig {
|
|
|
36
38
|
* ```
|
|
37
39
|
* */
|
|
38
40
|
export class RenderSnippetConfig {
|
|
41
|
+
snippet;
|
|
42
|
+
params;
|
|
39
43
|
constructor(snippet, params) {
|
|
40
44
|
this.snippet = snippet;
|
|
41
45
|
this.params = params;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/svelte-table",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.50",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Svelte.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
"svelte": "./dist/static-functions.js",
|
|
37
37
|
"import": "./dist/static-functions.js"
|
|
38
38
|
},
|
|
39
|
+
"./experimental-worker-plugin": {
|
|
40
|
+
"types": "./dist/experimental-worker-plugin.d.ts",
|
|
41
|
+
"svelte": "./dist/experimental-worker-plugin.js",
|
|
42
|
+
"import": "./dist/experimental-worker-plugin.js"
|
|
43
|
+
},
|
|
39
44
|
"./flex-render": {
|
|
40
45
|
"types": "./dist/flex-render.d.ts",
|
|
41
46
|
"svelte": "./dist/flex-render.js",
|
|
@@ -44,7 +49,7 @@
|
|
|
44
49
|
"./package.json": "./package.json"
|
|
45
50
|
},
|
|
46
51
|
"engines": {
|
|
47
|
-
"node": ">=
|
|
52
|
+
"node": ">=20"
|
|
48
53
|
},
|
|
49
54
|
"files": [
|
|
50
55
|
"dist",
|
|
@@ -53,14 +58,14 @@
|
|
|
53
58
|
],
|
|
54
59
|
"dependencies": {
|
|
55
60
|
"@tanstack/svelte-store": "^0.12.0",
|
|
56
|
-
"@tanstack/table-core": "
|
|
61
|
+
"@tanstack/table-core": "9.0.0-beta.50"
|
|
57
62
|
},
|
|
58
63
|
"devDependencies": {
|
|
59
64
|
"@sveltejs/package": "^2.5.8",
|
|
60
65
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
61
66
|
"eslint-plugin-svelte": "^3.19.0",
|
|
62
|
-
"svelte": "^5.56.
|
|
63
|
-
"svelte-check": "^4.
|
|
67
|
+
"svelte": "^5.56.2",
|
|
68
|
+
"svelte-check": "^4.6.0"
|
|
64
69
|
},
|
|
65
70
|
"peerDependencies": {
|
|
66
71
|
"svelte": "^5.0.0"
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-table-hook
|
|
3
|
+
description: >
|
|
4
|
+
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.
|
|
5
|
+
metadata:
|
|
6
|
+
type: framework
|
|
7
|
+
library: '@tanstack/svelte-table'
|
|
8
|
+
framework: svelte
|
|
9
|
+
library_version: '9.0.0-beta.50'
|
|
10
|
+
requires:
|
|
11
|
+
- '@tanstack/table-core#core'
|
|
12
|
+
- getting-started
|
|
13
|
+
- table-state
|
|
14
|
+
sources:
|
|
15
|
+
- 'TanStack/table:docs/framework/svelte/guide/composable-tables.md'
|
|
16
|
+
- 'TanStack/table:examples/svelte/composable-tables'
|
|
17
|
+
- 'TanStack/table:packages/svelte-table/src/createTableHook.svelte.ts'
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
This skill builds on `@tanstack/table-core#core`, `getting-started`, and `table-state`. Use it when multiple tables share conventions; keep one-off tables on `createTable`.
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
Use the shipped `createTableHook`; its implementation is rune-capable. The app hook module itself may be a normal `.ts` module, as in the maintained example.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import {
|
|
28
|
+
createTableHook,
|
|
29
|
+
rowSortingFeature,
|
|
30
|
+
tableFeatures,
|
|
31
|
+
} from '@tanstack/svelte-table'
|
|
32
|
+
|
|
33
|
+
export const {
|
|
34
|
+
createAppTable,
|
|
35
|
+
createAppColumnHelper,
|
|
36
|
+
useTableContext,
|
|
37
|
+
useCellContext,
|
|
38
|
+
useHeaderContext,
|
|
39
|
+
} = createTableHook({
|
|
40
|
+
features: tableFeatures({ rowSortingFeature }),
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```svelte
|
|
45
|
+
<script lang="ts">
|
|
46
|
+
import { createAppColumnHelper, createAppTable } from './app-table.svelte'
|
|
47
|
+
type Person = { name: string }
|
|
48
|
+
const helper = createAppColumnHelper<Person>()
|
|
49
|
+
const columns = helper.columns([helper.accessor('name', { header: 'Name' })])
|
|
50
|
+
let data = $state<Person[]>([{ name: 'Ada' }])
|
|
51
|
+
const table = createAppTable({
|
|
52
|
+
columns,
|
|
53
|
+
get data() {
|
|
54
|
+
return data
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
</script>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Core Patterns
|
|
61
|
+
|
|
62
|
+
### Register reusable components once
|
|
63
|
+
|
|
64
|
+
Pass stable `tableComponents`, `cellComponents`, and `headerComponents` to `createTableHook`. Render them through the returned `AppTable`, `AppCell`, and `AppHeader` wrappers so their typed context hooks have a provider.
|
|
65
|
+
|
|
66
|
+
### Prefer context inside registered components
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { useCellContext } from './app-table.svelte'
|
|
70
|
+
|
|
71
|
+
const cell = useCellContext<string>()
|
|
72
|
+
const value = cell.getValue()
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This avoids prop drilling and keeps feature/component types bound to the app hook.
|
|
76
|
+
|
|
77
|
+
## Common Mistakes
|
|
78
|
+
|
|
79
|
+
### CRITICAL Reimplementing the rune-aware hook
|
|
80
|
+
|
|
81
|
+
Wrong:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
// app-table.ts
|
|
85
|
+
export function createAppTable(options) {
|
|
86
|
+
return constructTable(options)
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Correct:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// app-table.ts
|
|
94
|
+
export const { createAppTable } = createTableHook({ features })
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The shipped implementation supplies Svelte rune reactivity, option synchronization, wrappers, and context plumbing that a plain core wrapper omits.
|
|
98
|
+
|
|
99
|
+
Source: `packages/svelte-table/src/createTableHook.svelte.ts`
|
|
100
|
+
|
|
101
|
+
### HIGH Freezing per-table rune inputs
|
|
102
|
+
|
|
103
|
+
Wrong:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const table = createAppTable({ columns, data })
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Correct:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const table = createAppTable({
|
|
113
|
+
columns,
|
|
114
|
+
get data() {
|
|
115
|
+
return data
|
|
116
|
+
},
|
|
117
|
+
})
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Shared defaults are static, but each table must still expose current reactive values.
|
|
121
|
+
|
|
122
|
+
Source: `docs/framework/svelte/guide/composable-tables.md`
|
|
123
|
+
|
|
124
|
+
### HIGH Reading context outside its wrapper
|
|
125
|
+
|
|
126
|
+
Wrong:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
const cell = useCellContext()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Correct:
|
|
133
|
+
|
|
134
|
+
```svelte
|
|
135
|
+
<table.AppCell {cell}><cell.TextCell /></table.AppCell>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Context helpers require the matching App wrapper in the rendered ancestor tree.
|
|
139
|
+
|
|
140
|
+
Source: `packages/svelte-table/src/createTableHook.svelte.ts`
|
|
141
|
+
|
|
142
|
+
### MEDIUM Abstracting a single table too early
|
|
143
|
+
|
|
144
|
+
Wrong:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const hook = createTableHook({ features: tableFeatures({}) })
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Correct:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const table = createTable({
|
|
154
|
+
features: tableFeatures({}),
|
|
155
|
+
columns,
|
|
156
|
+
get data() {
|
|
157
|
+
return data
|
|
158
|
+
},
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Use the hook for recurring app conventions, not merely to rename standalone construction.
|
|
163
|
+
|
|
164
|
+
Source: `docs/framework/svelte/guide/composable-tables.md`
|
|
165
|
+
|
|
166
|
+
## API Discovery
|
|
167
|
+
|
|
168
|
+
Inspect `node_modules/@tanstack/svelte-table/src/createTableHook.svelte.ts` and the `App*.svelte` wrappers for exact returned helpers and component contracts.
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: getting-started
|
|
3
|
+
description: >
|
|
4
|
+
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.
|
|
5
|
+
metadata:
|
|
6
|
+
type: framework
|
|
7
|
+
library: '@tanstack/svelte-table'
|
|
8
|
+
framework: svelte
|
|
9
|
+
library_version: '9.0.0-beta.50'
|
|
10
|
+
requires:
|
|
11
|
+
- '@tanstack/table-core#core'
|
|
12
|
+
- '@tanstack/table-core#table-features'
|
|
13
|
+
sources:
|
|
14
|
+
- 'TanStack/table:docs/framework/svelte/guide/migrating.md'
|
|
15
|
+
- 'TanStack/table:examples/svelte/basic-create-table'
|
|
16
|
+
- 'TanStack/table:packages/svelte-table/src/index.ts'
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
This skill builds on `@tanstack/table-core#core` and `@tanstack/table-core#table-features`. Read them first for the headless model and feature registration.
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
Keep features and columns outside reactive work; expose changing rune values through getters.
|
|
24
|
+
|
|
25
|
+
```svelte
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
import {
|
|
28
|
+
createTable,
|
|
29
|
+
FlexRender,
|
|
30
|
+
tableFeatures,
|
|
31
|
+
} from '@tanstack/svelte-table'
|
|
32
|
+
|
|
33
|
+
type Person = { firstName: string; age: number }
|
|
34
|
+
const features = tableFeatures({})
|
|
35
|
+
const columns = [
|
|
36
|
+
{ accessorKey: 'firstName', header: 'First name' },
|
|
37
|
+
{ accessorKey: 'age', header: 'Age' },
|
|
38
|
+
]
|
|
39
|
+
let data = $state<Person[]>([{ firstName: 'Ada', age: 36 }])
|
|
40
|
+
|
|
41
|
+
const table = createTable({
|
|
42
|
+
features,
|
|
43
|
+
columns,
|
|
44
|
+
get data() {
|
|
45
|
+
return data
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<table>
|
|
51
|
+
<thead>
|
|
52
|
+
{#each table.getHeaderGroups() as group (group.id)}
|
|
53
|
+
<tr
|
|
54
|
+
>{#each group.headers as header (header.id)}<th
|
|
55
|
+
>{#if !header.isPlaceholder}<FlexRender {header} />{/if}</th
|
|
56
|
+
>{/each}</tr
|
|
57
|
+
>
|
|
58
|
+
{/each}
|
|
59
|
+
</thead>
|
|
60
|
+
<tbody>
|
|
61
|
+
{#each table.getRowModel().rows as row (row.id)}
|
|
62
|
+
<tr
|
|
63
|
+
>{#each row.getAllCells() as cell (cell.id)}<td
|
|
64
|
+
><FlexRender {cell} /></td
|
|
65
|
+
>{/each}</tr
|
|
66
|
+
>
|
|
67
|
+
{/each}
|
|
68
|
+
</tbody>
|
|
69
|
+
</table>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Core Patterns
|
|
73
|
+
|
|
74
|
+
### Add only the processing feature you need
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import {
|
|
78
|
+
createSortedRowModel,
|
|
79
|
+
rowSortingFeature,
|
|
80
|
+
sortFn_alphanumeric,
|
|
81
|
+
tableFeatures,
|
|
82
|
+
} from '@tanstack/svelte-table'
|
|
83
|
+
|
|
84
|
+
export const features = tableFeatures({
|
|
85
|
+
rowSortingFeature,
|
|
86
|
+
sortedRowModel: createSortedRowModel(),
|
|
87
|
+
sortFns: { alphanumeric: sortFn_alphanumeric },
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The row-model slot follows its prerequisite feature in the same call. Import individual `sortFn_*` built-ins and register only the ones your columns reference; the full `sortFns` registry object still works but bundles every built-in.
|
|
92
|
+
|
|
93
|
+
### Treat markup and styles as application code
|
|
94
|
+
|
|
95
|
+
With core-only `tableFeatures({})`, render `row.getAllCells()`. Use visibility-aware APIs such as `row.getVisibleCells()` only after registering `columnVisibilityFeature`. Call feature APIs from real Svelte event handlers. Table supplies no component-library markup, CSS, or accessibility behavior.
|
|
96
|
+
|
|
97
|
+
## Common Mistakes
|
|
98
|
+
|
|
99
|
+
### HIGH Passing a rune snapshot as data
|
|
100
|
+
|
|
101
|
+
Wrong:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
const table = createTable({ features, columns, data })
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Correct:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const table = createTable({
|
|
111
|
+
features,
|
|
112
|
+
columns,
|
|
113
|
+
get data() {
|
|
114
|
+
return data
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The getter makes `$effect.pre` observe current rune data rather than the value captured at construction.
|
|
120
|
+
|
|
121
|
+
Source: `packages/svelte-table/src/createTable.svelte.ts`
|
|
122
|
+
|
|
123
|
+
### HIGH Using the removed v8 constructor
|
|
124
|
+
|
|
125
|
+
Wrong:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const table = createSvelteTable({
|
|
129
|
+
data,
|
|
130
|
+
columns,
|
|
131
|
+
getCoreRowModel: getCoreRowModel(),
|
|
132
|
+
})
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Correct:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const table = createTable({
|
|
139
|
+
features,
|
|
140
|
+
columns,
|
|
141
|
+
get data() {
|
|
142
|
+
return data
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
V9 requires Svelte 5, `createTable`, and explicit features; the core row model is automatic.
|
|
148
|
+
|
|
149
|
+
Source: `docs/framework/svelte/guide/migrating.md`
|
|
150
|
+
|
|
151
|
+
### HIGH Omitting a feature behind an API
|
|
152
|
+
|
|
153
|
+
Wrong:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const features = tableFeatures({})
|
|
157
|
+
table.setSorting([{ id: 'age', desc: true }])
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Correct:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const features = tableFeatures({ rowSortingFeature })
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Feature state and APIs exist only when that feature is registered.
|
|
167
|
+
|
|
168
|
+
Source: `docs/framework/svelte/guide/migrating.md`
|
|
169
|
+
|
|
170
|
+
## API Discovery
|
|
171
|
+
|
|
172
|
+
Inspect `node_modules/@tanstack/svelte-table/src/index.ts`, then the exported implementation. Inspect core and feature APIs through `node_modules/@tanstack/table-core/src/index.ts` and `src/features/<feature>/`.
|