@tanstack/svelte-table 9.0.0-beta.3 → 9.0.0-beta.30
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 +1 -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 +13 -5
- package/dist/index.d.ts +1 -1
- package/package.json +4 -4
- package/skills/svelte/client-to-server/SKILL.md +8 -10
- package/skills/svelte/compose-with-tanstack-form/SKILL.md +3 -4
- package/skills/svelte/compose-with-tanstack-pacer/SKILL.md +1 -1
- package/skills/svelte/compose-with-tanstack-query/SKILL.md +0 -3
- package/skills/svelte/compose-with-tanstack-store/SKILL.md +1 -8
- package/skills/svelte/compose-with-tanstack-virtual/SKILL.md +6 -3
- package/skills/svelte/getting-started/SKILL.md +22 -24
- package/skills/svelte/migrate-v8-to-v9/SKILL.md +33 -25
- package/skills/svelte/production-readiness/SKILL.md +7 -5
- package/skills/svelte/table-state/SKILL.md +11 -15
- package/src/createTable.svelte.ts +1 -2
- package/src/createTableHook.svelte.ts +124 -18
- package/src/index.ts +1 -0
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
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)
|
|
42
43
|
|
|
43
44
|
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
|
|
44
45
|
|
|
@@ -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
|
/**
|
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/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.30",
|
|
4
4
|
"description": "Headless UI for building powerful tables & datagrids for Svelte.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@tanstack/svelte-store": "^0.12.0",
|
|
56
|
-
"@tanstack/table-core": "
|
|
56
|
+
"@tanstack/table-core": "9.0.0-beta.30"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@sveltejs/package": "^2.5.8",
|
|
60
60
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
61
61
|
"eslint-plugin-svelte": "^3.19.0",
|
|
62
|
-
"svelte": "^5.56.
|
|
63
|
-
"svelte-check": "^4.
|
|
62
|
+
"svelte": "^5.56.2",
|
|
63
|
+
"svelte-check": "^4.6.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"svelte": "^5.0.0"
|
|
@@ -3,9 +3,9 @@ name: svelte/client-to-server
|
|
|
3
3
|
description: >
|
|
4
4
|
Convert a client-side Svelte table to server-side (manual) modes. Toggle `manualPagination`,
|
|
5
5
|
`manualSorting`, `manualFiltering`, `manualGrouping`, `manualExpanding` for whatever the server
|
|
6
|
-
owns, drop the matching `
|
|
7
|
-
`rowCount` for the pager, then drive the request from `table.atoms.pagination`
|
|
8
|
-
`table.atoms.sorting` / etc. (or external atoms you own)
|
|
6
|
+
owns, drop the matching row-model factory slots from `tableFeatures` and any `features` you no
|
|
7
|
+
longer need, supply `rowCount` for the pager, then drive the request from `table.atoms.pagination`
|
|
8
|
+
/ `table.atoms.sorting` / etc. (or external atoms you own) using rune-aware getters
|
|
9
9
|
(`get data()`, `get rowCount()`) so the table re-syncs in `$effect.pre`. Svelte 5+ only.
|
|
10
10
|
type: lifecycle
|
|
11
11
|
library: tanstack-table
|
|
@@ -44,8 +44,7 @@ already-paged window is perfectly valid for medium datasets.
|
|
|
44
44
|
| `manualGrouping` | Server returns already-grouped rows | Pre-shaped data |
|
|
45
45
|
| `manualExpanding` | Server resolves sub-rows | Server-provided sub-row tree |
|
|
46
46
|
|
|
47
|
-
When a stage is manual, you can drop its row-model factory
|
|
48
|
-
need `paginatedRowModel: createPaginatedRowModel()`.
|
|
47
|
+
When a stage is manual, you can drop its row-model factory slot from `tableFeatures`. `manualPagination: true` does not need `paginatedRowModel: createPaginatedRowModel()` in the features object.
|
|
49
48
|
|
|
50
49
|
## Step 1 — Identify what's moving server-side
|
|
51
50
|
|
|
@@ -111,7 +110,6 @@ const filters = useSelector(filtersAtom)
|
|
|
111
110
|
// No row-model factories for these — server owns them.
|
|
112
111
|
const table = createTable({
|
|
113
112
|
features,
|
|
114
|
-
rowModels: {},
|
|
115
113
|
columns,
|
|
116
114
|
get data() {
|
|
117
115
|
return query.data?.rows ?? []
|
|
@@ -196,11 +194,11 @@ const table = createTable({
|
|
|
196
194
|
columnFilteringFeature,
|
|
197
195
|
rowPaginationFeature,
|
|
198
196
|
rowSortingFeature,
|
|
197
|
+
filteredRowModel: createFilteredRowModel(), // client filters the page
|
|
198
|
+
sortedRowModel: createSortedRowModel(), // client sorts the page
|
|
199
|
+
filterFns,
|
|
200
|
+
sortFns,
|
|
199
201
|
}),
|
|
200
|
-
rowModels: {
|
|
201
|
-
filteredRowModel: createFilteredRowModel(filterFns), // client filters the page
|
|
202
|
-
sortedRowModel: createSortedRowModel(sortFns), // client sorts the page
|
|
203
|
-
},
|
|
204
202
|
columns,
|
|
205
203
|
get data() {
|
|
206
204
|
return query.data?.rows ?? []
|
|
@@ -116,6 +116,9 @@ Each cell type is a small Svelte component that knows which row + field it edits
|
|
|
116
116
|
const features = tableFeatures({
|
|
117
117
|
rowPaginationFeature,
|
|
118
118
|
columnFilteringFeature,
|
|
119
|
+
filteredRowModel: createFilteredRowModel(),
|
|
120
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
121
|
+
filterFns,
|
|
119
122
|
})
|
|
120
123
|
|
|
121
124
|
const columnHelper = createColumnHelper<typeof features, Person>()
|
|
@@ -170,10 +173,6 @@ Each cell type is a small Svelte component that knows which row + field it edits
|
|
|
170
173
|
|
|
171
174
|
const table = createTable({
|
|
172
175
|
features,
|
|
173
|
-
rowModels: {
|
|
174
|
-
filteredRowModel: createFilteredRowModel(filterFns),
|
|
175
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
176
|
-
},
|
|
177
176
|
columns,
|
|
178
177
|
get data() {
|
|
179
178
|
// The form is the source of truth.
|
|
@@ -95,7 +95,7 @@ Same shape, calling `table.setGlobalFilter`:
|
|
|
95
95
|
|
|
96
96
|
## Throttle column resizing
|
|
97
97
|
|
|
98
|
-
`columnResizingFeature` writes to `columnSizing` continuously. v9 supports `columnResizeMode:
|
|
98
|
+
`columnResizingFeature` (which requires `columnSizingFeature` to also be registered in `tableFeatures`) writes to `columnSizing` continuously. v9 supports `columnResizeMode:
|
|
99
99
|
'onChange' | 'onEnd'` — the default is `'onChange'` (commit per-frame). For very heavy tables,
|
|
100
100
|
either:
|
|
101
101
|
|
|
@@ -58,7 +58,6 @@ the affected pipeline stages, pipe the result back through reactive getters.
|
|
|
58
58
|
|
|
59
59
|
const table = createTable({
|
|
60
60
|
features,
|
|
61
|
-
rowModels: {},
|
|
62
61
|
columns,
|
|
63
62
|
get data() {
|
|
64
63
|
return dataQuery.data?.rows ?? []
|
|
@@ -115,7 +114,6 @@ const dataQuery = createQuery(() => ({
|
|
|
115
114
|
|
|
116
115
|
const table = createTable({
|
|
117
116
|
features,
|
|
118
|
-
rowModels: {},
|
|
119
117
|
columns,
|
|
120
118
|
get data() {
|
|
121
119
|
return dataQuery.data?.rows ?? []
|
|
@@ -152,7 +150,6 @@ const table = createTable({
|
|
|
152
150
|
rowSortingFeature,
|
|
153
151
|
columnFilteringFeature,
|
|
154
152
|
}),
|
|
155
|
-
rowModels: {},
|
|
156
153
|
columns,
|
|
157
154
|
get data() {
|
|
158
155
|
return dataQuery.data?.rows ?? []
|
|
@@ -46,7 +46,7 @@ If a slice is supplied externally via `atoms`, `table.atoms.<slice>` reads from
|
|
|
46
46
|
|
|
47
47
|
## The Svelte bindings (what `svelteReactivity()` actually does)
|
|
48
48
|
|
|
49
|
-
The Svelte adapter ships `svelteReactivity()` and installs it as `
|
|
49
|
+
The Svelte adapter ships `svelteReactivity()` and installs it as `coreReactivityFeature`. It
|
|
50
50
|
maps Store primitives to runes:
|
|
51
51
|
|
|
52
52
|
- Readonly atoms → `$derived.by(fn)`
|
|
@@ -83,7 +83,6 @@ The second argument to `createTable` is a TanStack Store selector. The result is
|
|
|
83
83
|
const table = createTable(
|
|
84
84
|
{
|
|
85
85
|
features,
|
|
86
|
-
rowModels: { paginatedRowModel: createPaginatedRowModel() },
|
|
87
86
|
columns,
|
|
88
87
|
get data() {
|
|
89
88
|
return data
|
|
@@ -161,9 +160,6 @@ const pagination = useSelector(paginationAtom)
|
|
|
161
160
|
|
|
162
161
|
const table = createTable({
|
|
163
162
|
features,
|
|
164
|
-
rowModels: {
|
|
165
|
-
/* ... */
|
|
166
|
-
},
|
|
167
163
|
columns,
|
|
168
164
|
get data() {
|
|
169
165
|
return data
|
|
@@ -215,9 +211,6 @@ export const rowSelectionAtom = createAtom<RowSelectionState>({})
|
|
|
215
211
|
|
|
216
212
|
const table = createTable({
|
|
217
213
|
features,
|
|
218
|
-
rowModels: {
|
|
219
|
-
/* ... */
|
|
220
|
-
},
|
|
221
214
|
columns,
|
|
222
215
|
get data() {
|
|
223
216
|
return data
|
|
@@ -59,13 +59,17 @@ pnpm add @tanstack/svelte-virtual
|
|
|
59
59
|
import { createVirtualizer } from '@tanstack/svelte-virtual'
|
|
60
60
|
import { get } from 'svelte/store'
|
|
61
61
|
|
|
62
|
-
const features = tableFeatures({
|
|
62
|
+
const features = tableFeatures({
|
|
63
|
+
columnSizingFeature,
|
|
64
|
+
rowSortingFeature,
|
|
65
|
+
sortedRowModel: createSortedRowModel(),
|
|
66
|
+
sortFns,
|
|
67
|
+
})
|
|
63
68
|
|
|
64
69
|
let data = $state<Person[]>(makeData(200_000))
|
|
65
70
|
|
|
66
71
|
const table = createTable({
|
|
67
72
|
features,
|
|
68
|
-
rowModels: { sortedRowModel: createSortedRowModel(sortFns) },
|
|
69
73
|
columns,
|
|
70
74
|
get data() {
|
|
71
75
|
return data
|
|
@@ -218,7 +222,6 @@ const flatData = $derived(
|
|
|
218
222
|
|
|
219
223
|
const table = createTable({
|
|
220
224
|
features: tableFeatures({}),
|
|
221
|
-
rowModels: {},
|
|
222
225
|
columns,
|
|
223
226
|
get data() {
|
|
224
227
|
return flatData
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: svelte/getting-started
|
|
3
3
|
description: >
|
|
4
4
|
End-to-end first-table journey for `@tanstack/svelte-table@9` on Svelte 5. Install the adapter,
|
|
5
|
-
declare `features` with `tableFeatures()
|
|
6
|
-
|
|
5
|
+
declare `features` with `tableFeatures()` (including row-model factories and `*Fns` registries as
|
|
6
|
+
feature slots), build a typed column helper with both `TFeatures` and `TData` generics, instantiate
|
|
7
7
|
the table with `createTable(options)` using `$state` data and `get data()` reactive option getters,
|
|
8
8
|
and render with `FlexRender`. Svelte 5+ only — Svelte 3/4 must use v8.
|
|
9
9
|
type: lifecycle
|
|
@@ -51,18 +51,17 @@ pnpm add @tanstack/svelte-store
|
|
|
51
51
|
You do **not** install `@tanstack/table-core` separately — the Svelte adapter re-exports
|
|
52
52
|
everything you need (column helpers, feature objects, row-model factories, types).
|
|
53
53
|
|
|
54
|
-
## 2. Define `features`
|
|
54
|
+
## 2. Define `features`
|
|
55
55
|
|
|
56
56
|
v9 is explicit. You opt in to every feature and every row model. The core row model is
|
|
57
57
|
included by default, so the minimum viable table is:
|
|
58
58
|
|
|
59
59
|
```ts
|
|
60
60
|
const features = tableFeatures({})
|
|
61
|
-
const rowModels = {}
|
|
62
61
|
```
|
|
63
62
|
|
|
64
|
-
For anything beyond a flat table, register the features you'll use
|
|
65
|
-
row-model factories
|
|
63
|
+
For anything beyond a flat table, register the features you'll use along with the matching
|
|
64
|
+
row-model factories and `*Fns` registries — all as slots inside `tableFeatures`:
|
|
66
65
|
|
|
67
66
|
```ts
|
|
68
67
|
import {
|
|
@@ -81,13 +80,12 @@ const features = tableFeatures({
|
|
|
81
80
|
rowPaginationFeature,
|
|
82
81
|
rowSortingFeature,
|
|
83
82
|
columnFilteringFeature,
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
const rowModels = {
|
|
87
83
|
paginatedRowModel: createPaginatedRowModel(),
|
|
88
|
-
sortedRowModel: createSortedRowModel(
|
|
89
|
-
filteredRowModel: createFilteredRowModel(
|
|
90
|
-
|
|
84
|
+
sortedRowModel: createSortedRowModel(),
|
|
85
|
+
filteredRowModel: createFilteredRowModel(),
|
|
86
|
+
sortFns,
|
|
87
|
+
filterFns,
|
|
88
|
+
})
|
|
91
89
|
```
|
|
92
90
|
|
|
93
91
|
**Skipping a feature** in `features` means its state slice does not exist on `table.atoms`,
|
|
@@ -166,7 +164,6 @@ option (`columns`, `rowCount`, `state.*`).
|
|
|
166
164
|
|
|
167
165
|
const table = createTable({
|
|
168
166
|
features,
|
|
169
|
-
rowModels: {},
|
|
170
167
|
columns,
|
|
171
168
|
get data() {
|
|
172
169
|
return data
|
|
@@ -230,13 +227,13 @@ focus, scroll, and any per-row component state.
|
|
|
230
227
|
tableFeatures,
|
|
231
228
|
} from '@tanstack/svelte-table'
|
|
232
229
|
|
|
233
|
-
const features = tableFeatures({
|
|
230
|
+
const features = tableFeatures({
|
|
231
|
+
rowPaginationFeature,
|
|
232
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
233
|
+
})
|
|
234
234
|
|
|
235
235
|
const table = createTable({
|
|
236
236
|
features,
|
|
237
|
-
rowModels: {
|
|
238
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
239
|
-
},
|
|
240
237
|
columns,
|
|
241
238
|
get data() {
|
|
242
239
|
return data
|
|
@@ -273,8 +270,7 @@ const pagination = subscribeTable(table.atoms.pagination)
|
|
|
273
270
|
|
|
274
271
|
## 7. `createTableHook` (when you have more than one table)
|
|
275
272
|
|
|
276
|
-
For apps with multiple tables, define
|
|
277
|
-
once:
|
|
273
|
+
For apps with multiple tables, define `features` (including row-model factories) and shared components once:
|
|
278
274
|
|
|
279
275
|
```ts
|
|
280
276
|
// hooks/table.ts
|
|
@@ -289,11 +285,13 @@ import {
|
|
|
289
285
|
} from '@tanstack/svelte-table'
|
|
290
286
|
|
|
291
287
|
export const { createAppTable, createAppColumnHelper } = createTableHook({
|
|
292
|
-
features: tableFeatures({
|
|
293
|
-
|
|
288
|
+
features: tableFeatures({
|
|
289
|
+
rowPaginationFeature,
|
|
290
|
+
rowSortingFeature,
|
|
294
291
|
paginatedRowModel: createPaginatedRowModel(),
|
|
295
|
-
sortedRowModel: createSortedRowModel(
|
|
296
|
-
|
|
292
|
+
sortedRowModel: createSortedRowModel(),
|
|
293
|
+
sortFns,
|
|
294
|
+
}),
|
|
297
295
|
})
|
|
298
296
|
```
|
|
299
297
|
|
|
@@ -319,7 +317,7 @@ export const { createAppTable, createAppColumnHelper } = createTableHook({
|
|
|
319
317
|
|
|
320
318
|
- **Svelte 3/4.** Adapter will not work. See top of file.
|
|
321
319
|
- **`createSvelteTable` / `useSvelteTable` / `getCoreRowModel`** — all v8 names. v9 uses
|
|
322
|
-
`createTable`
|
|
320
|
+
`createTable` with row-model factories registered as slots in `tableFeatures({ paginatedRowModel: createPaginatedRowModel(), ... })`.
|
|
323
321
|
- **Plain `data` instead of `get data()` getter.** Table will not see data updates. Always
|
|
324
322
|
pass a reactive getter for state that lives in `$state`.
|
|
325
323
|
- **Missing feature in `features`.** `table.setSorting` / `column.getCanSort` won't exist.
|
|
@@ -3,10 +3,11 @@ name: svelte/migrate-v8-to-v9
|
|
|
3
3
|
description: >
|
|
4
4
|
Mechanical migration from `@tanstack/svelte-table@8` to `@tanstack/svelte-table@9`. v9 in Svelte
|
|
5
5
|
is a full rewrite — Svelte 5 runes only (no Svelte 3/4), no `/legacy` adapter (unlike React),
|
|
6
|
-
`createSvelteTable` → `createTable`, `getCoreRowModel` / `getSortedRowModel` factories →
|
|
7
|
-
|
|
8
|
-
writable-store `state` → rune-based getters / external atoms,
|
|
9
|
-
`on[State]Change` or `atoms`. Plan a feature-by-feature audit, not a
|
|
6
|
+
`createSvelteTable` → `createTable`, `getCoreRowModel` / `getSortedRowModel` factories →
|
|
7
|
+
row-model factories registered as slots inside `tableFeatures({...})`, `flexRender` helper →
|
|
8
|
+
`<FlexRender>` component, writable-store `state` → rune-based getters / external atoms,
|
|
9
|
+
`onStateChange` → per-slice `on[State]Change` or `atoms`. Plan a feature-by-feature audit, not a
|
|
10
|
+
search-and-replace.
|
|
10
11
|
type: lifecycle
|
|
11
12
|
library: tanstack-table
|
|
12
13
|
framework: svelte
|
|
@@ -46,11 +47,11 @@ There is no third option. Trying to install v9 on a Svelte 4 codebase will error
|
|
|
46
47
|
| -------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
47
48
|
| `createSvelteTable(options)` | `createTable(options, selector?)` |
|
|
48
49
|
| `getCoreRowModel()` | included by default; no factory |
|
|
49
|
-
| `getPaginationRowModel()` | `
|
|
50
|
-
| `getSortedRowModel()` | `
|
|
51
|
-
| `getFilteredRowModel()` | `
|
|
52
|
-
| `getExpandedRowModel()` | `
|
|
53
|
-
| `getGroupedRowModel()` | `
|
|
50
|
+
| `getPaginationRowModel()` | `tableFeatures({ paginatedRowModel: createPaginatedRowModel() })` |
|
|
51
|
+
| `getSortedRowModel()` | `tableFeatures({ sortedRowModel: createSortedRowModel(), sortFns })` |
|
|
52
|
+
| `getFilteredRowModel()` | `tableFeatures({ filteredRowModel: createFilteredRowModel(), filterFns })` |
|
|
53
|
+
| `getExpandedRowModel()` | `tableFeatures({ expandedRowModel: createExpandedRowModel() })` |
|
|
54
|
+
| `getGroupedRowModel()` | `tableFeatures({ groupedRowModel: createGroupedRowModel(), aggregationFns })` |
|
|
54
55
|
| `getFacetedRowModel()` / `MinMax` / `UniqueValues` | facet APIs auto-derived when `*Facet*Feature` registered |
|
|
55
56
|
| `flexRender(template, ctx)` helper | `<FlexRender header={h} />` / `<FlexRender cell={c} />` / `<FlexRender footer={h} />` |
|
|
56
57
|
| `ColumnDef<TData>` | `ColumnDef<TFeatures, TData>` (extra generic) |
|
|
@@ -79,8 +80,7 @@ For each Svelte component that uses the table:
|
|
|
79
80
|
`import { createTable, FlexRender, tableFeatures, ... }`.
|
|
80
81
|
4. **Add `features`.** Create `const features = tableFeatures({ ... only the features this
|
|
81
82
|
table uses ... })`.
|
|
82
|
-
5. **Move row-model factories
|
|
83
|
-
entry with the matching `create*RowModel(*Fns)` factory.
|
|
83
|
+
5. **Move row-model factories into `tableFeatures`.** Every `get*RowModel: get*RowModel()` becomes a slot inside `tableFeatures({ ..., create*RowModel() })`. Any `*Fns` registry that was passed as a factory argument is now also a named slot in the same `tableFeatures` call.
|
|
84
84
|
6. **Generic columns.** Add `<typeof features, TData>` to `ColumnDef<>` and
|
|
85
85
|
`createColumnHelper<>()`. TypeScript will tell you when you missed one.
|
|
86
86
|
7. **`data` as a getter.** `data: data` → `get data() { return data }`. Same for any other
|
|
@@ -99,7 +99,7 @@ table uses ... })`.
|
|
|
99
99
|
<script lang="ts">
|
|
100
100
|
// v8
|
|
101
101
|
import { writable } from 'svelte/store'
|
|
102
|
-
const options = writable({
|
|
102
|
+
const options = writable({ data, columns })
|
|
103
103
|
$: $options.state = $state
|
|
104
104
|
</script>
|
|
105
105
|
```
|
|
@@ -111,7 +111,6 @@ table uses ... })`.
|
|
|
111
111
|
```ts
|
|
112
112
|
const table = createTable({
|
|
113
113
|
features,
|
|
114
|
-
rowModels: { paginatedRowModel: createPaginatedRowModel() },
|
|
115
114
|
columns,
|
|
116
115
|
get data() {
|
|
117
116
|
return data
|
|
@@ -131,12 +130,17 @@ const table = createTable({
|
|
|
131
130
|
|
|
132
131
|
const table = createTable({
|
|
133
132
|
features,
|
|
134
|
-
rowModels: { ... },
|
|
135
133
|
columns,
|
|
136
|
-
get data() {
|
|
134
|
+
get data() {
|
|
135
|
+
return data
|
|
136
|
+
},
|
|
137
137
|
state: {
|
|
138
|
-
get sorting() {
|
|
139
|
-
|
|
138
|
+
get sorting() {
|
|
139
|
+
return sorting
|
|
140
|
+
},
|
|
141
|
+
get pagination() {
|
|
142
|
+
return pagination
|
|
143
|
+
},
|
|
140
144
|
},
|
|
141
145
|
onSortingChange: (updater) => {
|
|
142
146
|
sorting = updater instanceof Function ? updater(sorting) : updater
|
|
@@ -154,16 +158,20 @@ const table = createTable({
|
|
|
154
158
|
import { createAtom, useSelector } from '@tanstack/svelte-store'
|
|
155
159
|
|
|
156
160
|
const sortingAtom = createAtom<SortingState>([])
|
|
157
|
-
const paginationAtom = createAtom<PaginationState>({
|
|
161
|
+
const paginationAtom = createAtom<PaginationState>({
|
|
162
|
+
pageIndex: 0,
|
|
163
|
+
pageSize: 10,
|
|
164
|
+
})
|
|
158
165
|
|
|
159
166
|
const sorting = useSelector(sortingAtom)
|
|
160
167
|
const pagination = useSelector(paginationAtom)
|
|
161
168
|
|
|
162
169
|
const table = createTable({
|
|
163
170
|
features,
|
|
164
|
-
rowModels: { ... },
|
|
165
171
|
columns,
|
|
166
|
-
get data() {
|
|
172
|
+
get data() {
|
|
173
|
+
return data
|
|
174
|
+
},
|
|
167
175
|
atoms: {
|
|
168
176
|
sorting: sortingAtom,
|
|
169
177
|
pagination: paginationAtom,
|
|
@@ -221,8 +229,8 @@ import { renderSnippet } from '@tanstack/svelte-table'
|
|
|
221
229
|
## After the rewrite — verify
|
|
222
230
|
|
|
223
231
|
- `pnpm test:types` (or `svelte-check`) catches missing `<typeof features, TData>` generics,
|
|
224
|
-
missing `features`
|
|
225
|
-
them.
|
|
232
|
+
missing `features` or row-model factory slots, and feature APIs called on tables that didn't
|
|
233
|
+
register them.
|
|
226
234
|
- `pnpm build` should pass with the new `features` set. Bundle should shrink — only the
|
|
227
235
|
features you register are included.
|
|
228
236
|
- Click through every table screen. Reset buttons, multi-sort, pagination reset on filter,
|
|
@@ -241,9 +249,9 @@ import { renderSnippet } from '@tanstack/svelte-table'
|
|
|
241
249
|
changed" bugs during migration.
|
|
242
250
|
- **Plain `features: { rowPaginationFeature }` instead of `tableFeatures({...})`.** Loses
|
|
243
251
|
inference; you'll get `any` everywhere.
|
|
244
|
-
- **Forgetting feature registration after
|
|
245
|
-
`paginatedRowModel: createPaginatedRowModel()`
|
|
246
|
-
`
|
|
252
|
+
- **Forgetting feature registration after adding the row-model factory slot.** Adding
|
|
253
|
+
`paginatedRowModel: createPaginatedRowModel()` to `tableFeatures` without also including
|
|
254
|
+
`rowPaginationFeature` does nothing.
|
|
247
255
|
- **Reimplementing v8 helpers** (`flexRender`-style functions, manual store subscriptions,
|
|
248
256
|
hand-rolled selectors) instead of using `FlexRender` / `subscribeTable` / atom selectors.
|
|
249
257
|
That's the #1 AI tell on this migration.
|
|
@@ -69,8 +69,9 @@ If you find yourself running a table without a feature's UI ever showing, drop t
|
|
|
69
69
|
`createTable` syncs options in `$effect.pre`. If any of these identities flip every component
|
|
70
70
|
run, the table re-syncs more than it needs to.
|
|
71
71
|
|
|
72
|
-
- **`features
|
|
73
|
-
|
|
72
|
+
- **`features`**: declare at module scope, not inside the component function, and never
|
|
73
|
+
inside `$derived` / `$effect`. The `features` object now also carries row-model factories
|
|
74
|
+
and `*Fns` registries, so keeping it stable prevents unnecessary re-sync.
|
|
74
75
|
- **`columns`**: same — module scope or `$state.frozen` / a non-reactive `const` in the
|
|
75
76
|
component. Reactive recompute of columns is rare and almost always a bug.
|
|
76
77
|
- **`data`**: pass with a getter (`get data()`) so the reference is stable when the data
|
|
@@ -80,8 +81,10 @@ run, the table re-syncs more than it needs to.
|
|
|
80
81
|
```svelte
|
|
81
82
|
<script lang="ts">
|
|
82
83
|
// module scope is fine in .svelte too, when truly static
|
|
83
|
-
const features = tableFeatures({
|
|
84
|
-
|
|
84
|
+
const features = tableFeatures({
|
|
85
|
+
rowPaginationFeature,
|
|
86
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
87
|
+
})
|
|
85
88
|
const columns = columnHelper.columns([
|
|
86
89
|
/* ... */
|
|
87
90
|
])
|
|
@@ -91,7 +94,6 @@ run, the table re-syncs more than it needs to.
|
|
|
91
94
|
|
|
92
95
|
const table = createTable({
|
|
93
96
|
features,
|
|
94
|
-
rowModels,
|
|
95
97
|
columns,
|
|
96
98
|
get data() {
|
|
97
99
|
return data
|
|
@@ -48,7 +48,7 @@ A table instance has three (and a half) state surfaces:
|
|
|
48
48
|
- `table.state` — the value returned by the optional selector passed as the second argument to
|
|
49
49
|
`createTable`. **Svelte-only surface.**
|
|
50
50
|
|
|
51
|
-
The Svelte adapter installs `svelteReactivity()` as the `
|
|
51
|
+
The Svelte adapter installs `svelteReactivity()` as the `coreReactivityFeature`:
|
|
52
52
|
|
|
53
53
|
| Core concept | Svelte binding |
|
|
54
54
|
| ------------- | --------------- |
|
|
@@ -81,14 +81,13 @@ import {
|
|
|
81
81
|
const features = tableFeatures({
|
|
82
82
|
rowPaginationFeature,
|
|
83
83
|
rowSortingFeature,
|
|
84
|
+
paginatedRowModel: createPaginatedRowModel(),
|
|
85
|
+
sortedRowModel: createSortedRowModel(),
|
|
86
|
+
sortFns,
|
|
84
87
|
})
|
|
85
88
|
|
|
86
89
|
const table = createTable({
|
|
87
90
|
features,
|
|
88
|
-
rowModels: {
|
|
89
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
90
|
-
sortedRowModel: createSortedRowModel(sortFns),
|
|
91
|
-
},
|
|
92
91
|
columns,
|
|
93
92
|
get data() {
|
|
94
93
|
return data
|
|
@@ -122,7 +121,6 @@ exposed as `table.state`. The default selector returns the full registered state
|
|
|
122
121
|
const table = createTable(
|
|
123
122
|
{
|
|
124
123
|
features,
|
|
125
|
-
rowModels: { paginatedRowModel: createPaginatedRowModel() },
|
|
126
124
|
columns,
|
|
127
125
|
get data() {
|
|
128
126
|
return data
|
|
@@ -186,7 +184,6 @@ The default: set starting values, let the table own the rest. `initialState` als
|
|
|
186
184
|
```ts
|
|
187
185
|
const table = createTable({
|
|
188
186
|
features,
|
|
189
|
-
rowModels: {},
|
|
190
187
|
columns,
|
|
191
188
|
get data() {
|
|
192
189
|
return data
|
|
@@ -231,7 +228,6 @@ const pagination = useSelector(paginationAtom)
|
|
|
231
228
|
|
|
232
229
|
const table = createTable({
|
|
233
230
|
features,
|
|
234
|
-
rowModels: {},
|
|
235
231
|
columns,
|
|
236
232
|
get data() {
|
|
237
233
|
return data
|
|
@@ -266,7 +262,6 @@ updates.
|
|
|
266
262
|
|
|
267
263
|
const table = createTable({
|
|
268
264
|
features,
|
|
269
|
-
rowModels: {},
|
|
270
265
|
columns,
|
|
271
266
|
get data() {
|
|
272
267
|
return data
|
|
@@ -340,8 +335,7 @@ Always key `{#each}` blocks on stable ids (`headerGroup.id`, `header.id`, `row.i
|
|
|
340
335
|
|
|
341
336
|
## `createTableHook` — app-wide composition
|
|
342
337
|
|
|
343
|
-
Create one configured hook per app: shared `features
|
|
344
|
-
component registries.
|
|
338
|
+
Create one configured hook per app: shared `features` (including row-model factories), defaults, and pre-bound component registries.
|
|
345
339
|
|
|
346
340
|
```ts
|
|
347
341
|
import {
|
|
@@ -363,11 +357,13 @@ export const {
|
|
|
363
357
|
useCellContext,
|
|
364
358
|
useHeaderContext,
|
|
365
359
|
} = createTableHook({
|
|
366
|
-
features: tableFeatures({
|
|
367
|
-
|
|
360
|
+
features: tableFeatures({
|
|
361
|
+
rowPaginationFeature,
|
|
362
|
+
rowSortingFeature,
|
|
368
363
|
paginatedRowModel: createPaginatedRowModel(),
|
|
369
|
-
sortedRowModel: createSortedRowModel(
|
|
370
|
-
|
|
364
|
+
sortedRowModel: createSortedRowModel(),
|
|
365
|
+
sortFns,
|
|
366
|
+
}),
|
|
371
367
|
cellComponents: { TextCell },
|
|
372
368
|
headerComponents: { SortIndicator },
|
|
373
369
|
})
|
|
@@ -51,7 +51,6 @@ export type SvelteTable<
|
|
|
51
51
|
* const table = createTable(
|
|
52
52
|
* {
|
|
53
53
|
* features,
|
|
54
|
-
* rowModels: {},
|
|
55
54
|
* columns,
|
|
56
55
|
* data,
|
|
57
56
|
* },
|
|
@@ -73,7 +72,7 @@ export function createTable<
|
|
|
73
72
|
// 1. Merge reactivity into options using mergeObjects (preserves getters)
|
|
74
73
|
const mergedOptions = mergeObjects(tableOptions, {
|
|
75
74
|
features: {
|
|
76
|
-
|
|
75
|
+
coreReactivityFeature: svelteReactivity(),
|
|
77
76
|
...tableOptions.features,
|
|
78
77
|
},
|
|
79
78
|
}) as TableOptions<TFeatures, TData>
|
|
@@ -376,6 +376,84 @@ export type AppSvelteTable<
|
|
|
376
376
|
FlexRender: typeof FlexRenderSvelte
|
|
377
377
|
}
|
|
378
378
|
|
|
379
|
+
export interface CreateTableHookResult<
|
|
380
|
+
TFeatures extends TableFeatures,
|
|
381
|
+
TTableComponents extends Record<string, ComponentType<any>>,
|
|
382
|
+
TCellComponents extends Record<string, ComponentType<any>>,
|
|
383
|
+
THeaderComponents extends Record<string, ComponentType<any>>,
|
|
384
|
+
> {
|
|
385
|
+
/** The features object that was passed to `createTableHook`. */
|
|
386
|
+
appFeatures: TFeatures
|
|
387
|
+
/**
|
|
388
|
+
* A column helper pre-bound to `TFeatures` and the registered components, so
|
|
389
|
+
* the cell/header/footer render props expose the bound components.
|
|
390
|
+
*/
|
|
391
|
+
createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<
|
|
392
|
+
TFeatures,
|
|
393
|
+
TData,
|
|
394
|
+
TCellComponents,
|
|
395
|
+
THeaderComponents
|
|
396
|
+
>
|
|
397
|
+
/**
|
|
398
|
+
* Creates a table with the `App*` wrapper components and registered
|
|
399
|
+
* `tableComponents` attached. `TData` is inferred from the `data` option.
|
|
400
|
+
*/
|
|
401
|
+
createAppTable: <TData extends RowData, TSelected = TableState<TFeatures>>(
|
|
402
|
+
tableOptions: Omit<TableOptions<TFeatures, TData>, 'features'>,
|
|
403
|
+
selector?: (state: TableState<TFeatures>) => TSelected,
|
|
404
|
+
) => AppSvelteTable<
|
|
405
|
+
TFeatures,
|
|
406
|
+
TData,
|
|
407
|
+
TSelected,
|
|
408
|
+
TTableComponents,
|
|
409
|
+
TCellComponents,
|
|
410
|
+
THeaderComponents
|
|
411
|
+
>
|
|
412
|
+
/**
|
|
413
|
+
* Reads the table provided by the nearest `<table.AppTable>`. This is the same
|
|
414
|
+
* extended instance `createAppTable` returns, so the `App*` components and your
|
|
415
|
+
* `tableComponents` are available on it.
|
|
416
|
+
*
|
|
417
|
+
* Pass `TSelected` to match the selector you gave `createAppTable`, so
|
|
418
|
+
* `table.state` is typed as the selected slice. It cannot be inferred
|
|
419
|
+
* automatically (context does not carry the provider's generics), so it
|
|
420
|
+
* defaults to the full table state, which is correct for the common case of
|
|
421
|
+
* `createAppTable` without a selector.
|
|
422
|
+
*/
|
|
423
|
+
useTableContext: <
|
|
424
|
+
TData extends RowData = RowData,
|
|
425
|
+
TSelected = TableState<TFeatures>,
|
|
426
|
+
>() => AppSvelteTable<
|
|
427
|
+
TFeatures,
|
|
428
|
+
TData,
|
|
429
|
+
TSelected,
|
|
430
|
+
TTableComponents,
|
|
431
|
+
TCellComponents,
|
|
432
|
+
THeaderComponents
|
|
433
|
+
>
|
|
434
|
+
/**
|
|
435
|
+
* Reads the cell provided by the nearest `<table.AppCell>`, extended with your
|
|
436
|
+
* `cellComponents` and a context-bound `FlexRender`.
|
|
437
|
+
*/
|
|
438
|
+
useCellContext: <TValue extends CellData = CellData>() => Cell<
|
|
439
|
+
TFeatures,
|
|
440
|
+
any,
|
|
441
|
+
TValue
|
|
442
|
+
> &
|
|
443
|
+
TCellComponents & { FlexRender: typeof FlexRenderSvelte }
|
|
444
|
+
/**
|
|
445
|
+
* Reads the header provided by the nearest `<table.AppHeader>` /
|
|
446
|
+
* `<table.AppFooter>`, extended with your `headerComponents` and a
|
|
447
|
+
* context-bound `FlexRender`.
|
|
448
|
+
*/
|
|
449
|
+
useHeaderContext: <TValue extends CellData = CellData>() => Header<
|
|
450
|
+
TFeatures,
|
|
451
|
+
any,
|
|
452
|
+
TValue
|
|
453
|
+
> &
|
|
454
|
+
THeaderComponents & { FlexRender: typeof FlexRenderSvelte }
|
|
455
|
+
}
|
|
456
|
+
|
|
379
457
|
// =============================================================================
|
|
380
458
|
// createTableHook Factory
|
|
381
459
|
// =============================================================================
|
|
@@ -404,12 +482,12 @@ export type AppSvelteTable<
|
|
|
404
482
|
* rowPaginationFeature,
|
|
405
483
|
* rowSortingFeature,
|
|
406
484
|
* columnFilteringFeature,
|
|
407
|
-
* }),
|
|
408
|
-
* rowModels: {
|
|
409
485
|
* paginatedRowModel: createPaginatedRowModel(),
|
|
410
|
-
* sortedRowModel: createSortedRowModel(
|
|
411
|
-
* filteredRowModel: createFilteredRowModel(
|
|
412
|
-
*
|
|
486
|
+
* sortedRowModel: createSortedRowModel(),
|
|
487
|
+
* filteredRowModel: createFilteredRowModel(),
|
|
488
|
+
* sortFns,
|
|
489
|
+
* filterFns,
|
|
490
|
+
* }),
|
|
413
491
|
* tableComponents: { PaginationControls, RowCount },
|
|
414
492
|
* cellComponents: { TextCell, NumberCell },
|
|
415
493
|
* headerComponents: { SortIndicator, ColumnFilter },
|
|
@@ -431,7 +509,12 @@ export function createTableHook<
|
|
|
431
509
|
TTableComponents,
|
|
432
510
|
TCellComponents,
|
|
433
511
|
THeaderComponents
|
|
434
|
-
>)
|
|
512
|
+
>): CreateTableHookResult<
|
|
513
|
+
TFeatures,
|
|
514
|
+
TTableComponents,
|
|
515
|
+
TCellComponents,
|
|
516
|
+
THeaderComponents
|
|
517
|
+
> {
|
|
435
518
|
/**
|
|
436
519
|
* Create a column helper pre-bound to the features and components configured in this table hook.
|
|
437
520
|
* The cell, header, and footer contexts include pre-bound components (e.g., `cell.TextCell`).
|
|
@@ -455,9 +538,16 @@ export function createTableHook<
|
|
|
455
538
|
* Use this in custom `tableComponents` passed to `createTableHook`.
|
|
456
539
|
* TFeatures is already known from the createTableHook call.
|
|
457
540
|
*/
|
|
458
|
-
function useTableContext<
|
|
541
|
+
function useTableContext<
|
|
542
|
+
TData extends RowData = RowData,
|
|
543
|
+
TSelected = TableState<TFeatures>,
|
|
544
|
+
>(): AppSvelteTable<
|
|
459
545
|
TFeatures,
|
|
460
|
-
TData
|
|
546
|
+
TData,
|
|
547
|
+
TSelected,
|
|
548
|
+
TTableComponents,
|
|
549
|
+
TCellComponents,
|
|
550
|
+
THeaderComponents
|
|
461
551
|
> {
|
|
462
552
|
const table = getContext(tableContextKey)
|
|
463
553
|
|
|
@@ -468,7 +558,17 @@ export function createTableHook<
|
|
|
468
558
|
)
|
|
469
559
|
}
|
|
470
560
|
|
|
471
|
-
|
|
561
|
+
// `<table.AppTable>` provides the extended table (the App* wrapper
|
|
562
|
+
// components and `tableComponents` are Object.assign-ed onto the same
|
|
563
|
+
// instance `createAppTable` returns), so this asserts the runtime shape.
|
|
564
|
+
return table as unknown as AppSvelteTable<
|
|
565
|
+
TFeatures,
|
|
566
|
+
TData,
|
|
567
|
+
TSelected,
|
|
568
|
+
TTableComponents,
|
|
569
|
+
TCellComponents,
|
|
570
|
+
THeaderComponents
|
|
571
|
+
>
|
|
472
572
|
}
|
|
473
573
|
|
|
474
574
|
/**
|
|
@@ -480,7 +580,8 @@ export function createTableHook<
|
|
|
480
580
|
TFeatures,
|
|
481
581
|
any,
|
|
482
582
|
TValue
|
|
483
|
-
>
|
|
583
|
+
> &
|
|
584
|
+
TCellComponents & { FlexRender: typeof FlexRenderSvelte } {
|
|
484
585
|
const cell = getContext(cellContextKey)
|
|
485
586
|
|
|
486
587
|
if (!cell) {
|
|
@@ -490,7 +591,11 @@ export function createTableHook<
|
|
|
490
591
|
)
|
|
491
592
|
}
|
|
492
593
|
|
|
493
|
-
|
|
594
|
+
// `<table.AppCell>` Object.assign-es `cellComponents` and `FlexRender` onto
|
|
595
|
+
// the same cell instance it puts in context, so this asserts the runtime
|
|
596
|
+
// shape.
|
|
597
|
+
return cell as unknown as Cell<TFeatures, any, TValue> &
|
|
598
|
+
TCellComponents & { FlexRender: typeof FlexRenderSvelte }
|
|
494
599
|
}
|
|
495
600
|
|
|
496
601
|
/**
|
|
@@ -502,7 +607,8 @@ export function createTableHook<
|
|
|
502
607
|
TFeatures,
|
|
503
608
|
any,
|
|
504
609
|
TValue
|
|
505
|
-
>
|
|
610
|
+
> &
|
|
611
|
+
THeaderComponents & { FlexRender: typeof FlexRenderSvelte } {
|
|
506
612
|
const header = getContext(headerContextKey)
|
|
507
613
|
|
|
508
614
|
if (!header) {
|
|
@@ -511,7 +617,10 @@ export function createTableHook<
|
|
|
511
617
|
)
|
|
512
618
|
}
|
|
513
619
|
|
|
514
|
-
|
|
620
|
+
// `<table.AppHeader>` / `<table.AppFooter>` Object.assign `headerComponents`
|
|
621
|
+
// and `FlexRender` onto the same header instance they put in context.
|
|
622
|
+
return header as unknown as Header<TFeatures, any, TValue> &
|
|
623
|
+
THeaderComponents & { FlexRender: typeof FlexRenderSvelte }
|
|
515
624
|
}
|
|
516
625
|
|
|
517
626
|
/**
|
|
@@ -527,10 +636,7 @@ export function createTableHook<
|
|
|
527
636
|
TData extends RowData,
|
|
528
637
|
TSelected = TableState<TFeatures>,
|
|
529
638
|
>(
|
|
530
|
-
tableOptions: Omit<
|
|
531
|
-
TableOptions<TFeatures, TData>,
|
|
532
|
-
'features' | 'rowModels'
|
|
533
|
-
>,
|
|
639
|
+
tableOptions: Omit<TableOptions<TFeatures, TData>, 'features'>,
|
|
534
640
|
selector?: (state: TableState<TFeatures>) => TSelected,
|
|
535
641
|
): AppSvelteTable<
|
|
536
642
|
TFeatures,
|
|
@@ -629,7 +735,7 @@ export function createTableHook<
|
|
|
629
735
|
}
|
|
630
736
|
|
|
631
737
|
return {
|
|
632
|
-
appFeatures: defaultTableOptions.features
|
|
738
|
+
appFeatures: defaultTableOptions.features,
|
|
633
739
|
createAppColumnHelper,
|
|
634
740
|
createAppTable,
|
|
635
741
|
useTableContext,
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type {
|
|
|
14
14
|
AppSvelteTable,
|
|
15
15
|
ComponentType,
|
|
16
16
|
CreateTableHookOptions,
|
|
17
|
+
CreateTableHookResult,
|
|
17
18
|
} from './createTableHook.svelte'
|
|
18
19
|
export { createTableState } from './createTableState.svelte'
|
|
19
20
|
export { default as FlexRender } from './FlexRender.svelte'
|