@tanstack/svelte-table 9.0.0-alpha.9 → 9.0.0-beta.2
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 +127 -0
- package/dist/AppCell.svelte +13 -0
- package/dist/AppCell.svelte.d.ts +9 -0
- package/dist/AppHeader.svelte +13 -0
- package/dist/AppHeader.svelte.d.ts +9 -0
- package/dist/AppTable.svelte +11 -0
- package/dist/AppTable.svelte.d.ts +7 -0
- package/dist/FlexRender.svelte +103 -0
- package/dist/FlexRender.svelte.d.ts +51 -0
- package/dist/context-keys.d.ts +3 -0
- package/dist/context-keys.js +3 -0
- package/dist/createTable.svelte.d.ts +48 -0
- package/dist/createTable.svelte.js +79 -0
- package/dist/createTableHook.svelte.d.ts +235 -0
- package/dist/createTableHook.svelte.js +170 -0
- package/dist/createTableState.svelte.d.ts +17 -0
- package/dist/createTableState.svelte.js +27 -0
- package/dist/flex-render.d.ts +1 -0
- package/dist/flex-render.js +2 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.js +6 -3
- package/dist/merge-objects.d.ts +24 -0
- package/dist/merge-objects.js +45 -0
- package/dist/reactivity.svelte.d.ts +9 -0
- package/dist/reactivity.svelte.js +89 -0
- package/dist/render-component.d.ts +66 -9
- package/dist/render-component.js +62 -4
- package/dist/static-functions.d.ts +1 -0
- package/dist/static-functions.js +1 -0
- package/dist/subscribe.d.ts +24 -0
- package/dist/subscribe.js +4 -0
- package/package.json +31 -11
- package/skills/svelte/client-to-server/SKILL.md +238 -0
- package/skills/svelte/compose-with-tanstack-form/SKILL.md +295 -0
- package/skills/svelte/compose-with-tanstack-pacer/SKILL.md +176 -0
- package/skills/svelte/compose-with-tanstack-query/SKILL.md +299 -0
- package/skills/svelte/compose-with-tanstack-store/SKILL.md +277 -0
- package/skills/svelte/compose-with-tanstack-virtual/SKILL.md +286 -0
- package/skills/svelte/getting-started/SKILL.md +340 -0
- package/skills/svelte/migrate-v8-to-v9/SKILL.md +256 -0
- package/skills/svelte/production-readiness/SKILL.md +256 -0
- package/skills/svelte/table-state/SKILL.md +441 -0
- package/src/AppCell.svelte +13 -0
- package/src/AppHeader.svelte +13 -0
- package/src/AppTable.svelte +11 -0
- package/src/FlexRender.svelte +103 -0
- package/src/context-keys.ts +3 -0
- package/src/createTable.svelte.ts +137 -0
- package/src/createTableHook.svelte.ts +639 -0
- package/src/createTableState.svelte.ts +30 -0
- package/src/flex-render.ts +3 -0
- package/src/index.ts +20 -3
- package/src/merge-objects.ts +79 -0
- package/src/reactivity.svelte.ts +118 -0
- package/src/render-component.ts +75 -9
- package/src/static-functions.ts +1 -0
- package/src/subscribe.ts +46 -0
- package/dist/flex-render.svelte +0 -35
- package/dist/flex-render.svelte.d.ts +0 -28
- package/dist/table.svelte.d.ts +0 -28
- package/dist/table.svelte.js +0 -87
- package/src/flex-render.svelte +0 -35
- package/src/table.svelte.ts +0 -117
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./media/header_table.png" alt="TanStack Table">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<br />
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
<a href="https://npmjs.com/package/@tanstack/react-table" target="\_parent">
|
|
9
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/@tanstack/react-table.svg" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/tanstack/table" target="\_parent">
|
|
12
|
+
<img alt="github stars" src="https://img.shields.io/github/stars/tanstack/react-table.svg?style=social&label=Star" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://bundlephobia.com/result?p=@tanstack/react-table@latest" target="\_parent">
|
|
15
|
+
<img alt="bundle size" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-table@latest" />
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div align="center">
|
|
20
|
+
<a href="#badge">
|
|
21
|
+
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
|
22
|
+
</a>
|
|
23
|
+
<a href="https://bestofjs.org/projects/tanstack-table"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Ftable%26since=daily" /></a>
|
|
24
|
+
<a href="https://twitter.com/tan_stack"><img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/></a>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
# TanStack Table
|
|
32
|
+
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> You may know TanStack Table by the adapter names:
|
|
35
|
+
>
|
|
36
|
+
> - [Angular Table](https://tanstack.com/table/alpha/docs/framework/angular/angular-table)
|
|
37
|
+
> - [Lit Table](https://tanstack.com/table/alpha/docs/framework/lit/lit-table)
|
|
38
|
+
> - [React Table](https://tanstack.com/table/alpha/docs/framework/react/react-table)
|
|
39
|
+
> - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table)
|
|
40
|
+
> - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table)
|
|
41
|
+
> - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table)
|
|
42
|
+
|
|
43
|
+
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
|
|
44
|
+
|
|
45
|
+
- Framework‑agnostic core with bindings for React, Vue & Solid
|
|
46
|
+
- 100% customizable — bring your own UI, components, and styles
|
|
47
|
+
- Sorting, filtering, grouping, aggregation & row selection
|
|
48
|
+
- Lightweight, virtualizable & server‑side friendly
|
|
49
|
+
|
|
50
|
+
### <a href="https://tanstack.com/table">Read the Docs →</a>
|
|
51
|
+
|
|
52
|
+
## Using an AI Coding Agent?
|
|
53
|
+
|
|
54
|
+
TanStack Table ships [TanStack Intent](https://github.com/TanStack/intent) skills inside each adapter package. After installing the library, run:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
npx @tanstack/intent@latest install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
to add skill-loading guidance for your agent (Claude Code, Cursor, Copilot, etc.). The same CLI also exposes `intent list` to browse available skills and `intent load <skill>` to print one for inspection. Skills version with the library — your agent gets guidance that matches the version of `@tanstack/<framework>-table` you installed. Only available for v9 and above.
|
|
61
|
+
|
|
62
|
+
## Get Involved
|
|
63
|
+
|
|
64
|
+
- We welcome issues and pull requests!
|
|
65
|
+
- Participate in [GitHub discussions](https://github.com/TanStack/table/discussions)
|
|
66
|
+
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
|
|
67
|
+
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions
|
|
68
|
+
|
|
69
|
+
## Partners
|
|
70
|
+
|
|
71
|
+
<table align="center">
|
|
72
|
+
<tr>
|
|
73
|
+
<td>
|
|
74
|
+
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS">
|
|
75
|
+
<picture>
|
|
76
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-CMcuvjEy.svg" height="40" />
|
|
77
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" />
|
|
78
|
+
<img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" />
|
|
79
|
+
</picture>
|
|
80
|
+
</a>
|
|
81
|
+
</td>
|
|
82
|
+
<td padding="20">
|
|
83
|
+
<a href="https://www.cloudflare.com?utm_source=tanstack">
|
|
84
|
+
<picture>
|
|
85
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-DQDB7UaL.svg" height="60" />
|
|
86
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" />
|
|
87
|
+
<img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" />
|
|
88
|
+
</picture>
|
|
89
|
+
</a>
|
|
90
|
+
</td>
|
|
91
|
+
<td>
|
|
92
|
+
<a href="https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable" style="display: flex; align-items: center; border: none;">
|
|
93
|
+
<picture>
|
|
94
|
+
<source media="(prefers-color-scheme: dark)" srcset="./media/ag-grid-dark.svg" height="40" />
|
|
95
|
+
<source media="(prefers-color-scheme: light)" srcset="./media/ag-grid-light.svg" height="40" />
|
|
96
|
+
<img src="https://raw.githubusercontent.com/tannerlinsley/files/master/partners/ag-grid.svg" height="60" alt="AG Grid" />
|
|
97
|
+
</picture>
|
|
98
|
+
</a>
|
|
99
|
+
</td>
|
|
100
|
+
</tr>
|
|
101
|
+
</table>
|
|
102
|
+
|
|
103
|
+
<div align="center">
|
|
104
|
+
<img src="./media/partner_logo.svg" alt="Table & you?" height="65">
|
|
105
|
+
<p>
|
|
106
|
+
We're looking for TanStack Table Partners to join our mission! Partner with us to push the boundaries of TanStack Table and build amazing things together.
|
|
107
|
+
</p>
|
|
108
|
+
<a href="mailto:partners@tanstack.com?subject=TanStack Table Partnership"><b>LET'S CHAT</b></a>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
## Explore the TanStack Ecosystem
|
|
112
|
+
|
|
113
|
+
- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> – Tooling for JS/TS packages
|
|
114
|
+
- <a href="https://github.com/tanstack/db"><b>TanStack DB</b></a> – Reactive sync client store
|
|
115
|
+
- <a href="https://github.com/tanstack/devtools"><b>TanStack DevTools</b></a> – Unified devtools panel
|
|
116
|
+
- <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> – Type‑safe form state
|
|
117
|
+
- <a href="https://github.com/tanstack/pacer"><b>TanStack Pacer</b></a> – Debouncing, throttling, batching <br/>
|
|
118
|
+
- <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> – Async state & caching
|
|
119
|
+
- <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> – Range & slider primitives
|
|
120
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> – Type‑safe routing, caching & URL state
|
|
121
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Start</b></a> – Full‑stack SSR & streaming
|
|
122
|
+
- <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> – Reactive data store
|
|
123
|
+
- <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> – Virtualized rendering
|
|
124
|
+
|
|
125
|
+
… and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>
|
|
126
|
+
|
|
127
|
+
<!-- USE THE FORCE LUKE -->
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
cell: any
|
|
6
|
+
cellComponents: any
|
|
7
|
+
children: Snippet<[any]>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { children, cell, cellComponents }: Props = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{@render children?.(Object.assign(cell, cellComponents))}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
cell: any;
|
|
4
|
+
cellComponents: any;
|
|
5
|
+
children: Snippet<[any]>;
|
|
6
|
+
}
|
|
7
|
+
declare const AppCell: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type AppCell = ReturnType<typeof AppCell>;
|
|
9
|
+
export default AppCell;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte'
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
header: any
|
|
6
|
+
headerComponents: any
|
|
7
|
+
children: Snippet<[any]>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { children, header, headerComponents }: Props = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
{@render children?.(Object.assign(header, headerComponents))}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
header: any;
|
|
4
|
+
headerComponents: any;
|
|
5
|
+
children: Snippet<[any]>;
|
|
6
|
+
}
|
|
7
|
+
declare const AppHeader: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type AppHeader = ReturnType<typeof AppHeader>;
|
|
9
|
+
export default AppHeader;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script
|
|
2
|
+
lang="ts"
|
|
3
|
+
generics="TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData"
|
|
4
|
+
>
|
|
5
|
+
import { isFunction } from '@tanstack/table-core'
|
|
6
|
+
import {
|
|
7
|
+
RenderComponentConfig,
|
|
8
|
+
RenderSnippetConfig,
|
|
9
|
+
} from './render-component'
|
|
10
|
+
import type {
|
|
11
|
+
Cell,
|
|
12
|
+
CellContext,
|
|
13
|
+
CellData,
|
|
14
|
+
ColumnDefTemplate,
|
|
15
|
+
Header,
|
|
16
|
+
HeaderContext,
|
|
17
|
+
RowData,
|
|
18
|
+
TableFeatures,
|
|
19
|
+
} from '@tanstack/table-core'
|
|
20
|
+
|
|
21
|
+
type Props =
|
|
22
|
+
| {
|
|
23
|
+
/** The cell or header field of the current cell's column definition. */
|
|
24
|
+
content?: ColumnDefTemplate<
|
|
25
|
+
| HeaderContext<TFeatures, TData, TValue>
|
|
26
|
+
| CellContext<TFeatures, TData, TValue>
|
|
27
|
+
>
|
|
28
|
+
/** The result of the `getContext()` function of the header or cell */
|
|
29
|
+
context:
|
|
30
|
+
| HeaderContext<TFeatures, TData, TValue>
|
|
31
|
+
| CellContext<TFeatures, TData, TValue>
|
|
32
|
+
cell?: never
|
|
33
|
+
header?: never
|
|
34
|
+
footer?: never
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
cell: Cell<TFeatures, TData, TValue>
|
|
38
|
+
content?: never
|
|
39
|
+
context?: never
|
|
40
|
+
header?: never
|
|
41
|
+
footer?: never
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
header: Header<TFeatures, TData, TValue>
|
|
45
|
+
content?: never
|
|
46
|
+
context?: never
|
|
47
|
+
cell?: never
|
|
48
|
+
footer?: never
|
|
49
|
+
}
|
|
50
|
+
| {
|
|
51
|
+
footer: Header<TFeatures, TData, TValue>
|
|
52
|
+
content?: never
|
|
53
|
+
context?: never
|
|
54
|
+
cell?: never
|
|
55
|
+
header?: never
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let props: Props = $props()
|
|
59
|
+
|
|
60
|
+
// Resolve content and context from either the new cell/header/footer props
|
|
61
|
+
// or the legacy content/context props.
|
|
62
|
+
const resolved = $derived.by(() => {
|
|
63
|
+
if ('cell' in props && props.cell) {
|
|
64
|
+
return {
|
|
65
|
+
content: props.cell.column.columnDef.cell,
|
|
66
|
+
context: props.cell.getContext(),
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if ('header' in props && props.header) {
|
|
70
|
+
return {
|
|
71
|
+
content: props.header.column.columnDef.header,
|
|
72
|
+
context: props.header.getContext(),
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if ('footer' in props && props.footer) {
|
|
76
|
+
return {
|
|
77
|
+
content: props.footer.column.columnDef.footer,
|
|
78
|
+
context: props.footer.getContext(),
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
content: props.content,
|
|
83
|
+
context: props.context,
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
// Compute the render result reactively
|
|
88
|
+
const result = $derived(
|
|
89
|
+
isFunction(resolved.content)
|
|
90
|
+
? resolved.content(resolved.context as any)
|
|
91
|
+
: undefined,
|
|
92
|
+
)
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
{#if typeof resolved.content === 'string'}
|
|
96
|
+
{resolved.content}
|
|
97
|
+
{:else if result instanceof RenderComponentConfig}
|
|
98
|
+
<result.component {...result.props} />
|
|
99
|
+
{:else if result instanceof RenderSnippetConfig}
|
|
100
|
+
{@render result.snippet(result.params)}
|
|
101
|
+
{:else if result !== undefined}
|
|
102
|
+
{result}
|
|
103
|
+
{/if}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Cell, CellContext, CellData, ColumnDefTemplate, Header, HeaderContext, RowData, TableFeatures } from '@tanstack/table-core';
|
|
2
|
+
declare function $$render<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData>(): {
|
|
3
|
+
props: {
|
|
4
|
+
/** The cell or header field of the current cell's column definition. */
|
|
5
|
+
content?: ColumnDefTemplate<HeaderContext<TFeatures, TData, TValue> | CellContext<TFeatures, TData, TValue>>;
|
|
6
|
+
/** The result of the `getContext()` function of the header or cell */
|
|
7
|
+
context: HeaderContext<TFeatures, TData, TValue> | CellContext<TFeatures, TData, TValue>;
|
|
8
|
+
cell?: never;
|
|
9
|
+
header?: never;
|
|
10
|
+
footer?: never;
|
|
11
|
+
} | {
|
|
12
|
+
cell: Cell<TFeatures, TData, TValue>;
|
|
13
|
+
content?: never;
|
|
14
|
+
context?: never;
|
|
15
|
+
header?: never;
|
|
16
|
+
footer?: never;
|
|
17
|
+
} | {
|
|
18
|
+
header: Header<TFeatures, TData, TValue>;
|
|
19
|
+
content?: never;
|
|
20
|
+
context?: never;
|
|
21
|
+
cell?: never;
|
|
22
|
+
footer?: never;
|
|
23
|
+
} | {
|
|
24
|
+
footer: Header<TFeatures, TData, TValue>;
|
|
25
|
+
content?: never;
|
|
26
|
+
context?: never;
|
|
27
|
+
cell?: never;
|
|
28
|
+
header?: never;
|
|
29
|
+
};
|
|
30
|
+
exports: {};
|
|
31
|
+
bindings: "";
|
|
32
|
+
slots: {};
|
|
33
|
+
events: {};
|
|
34
|
+
};
|
|
35
|
+
declare class __sveltets_Render<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> {
|
|
36
|
+
props(): ReturnType<typeof $$render<TFeatures, TData, TValue>>['props'];
|
|
37
|
+
events(): ReturnType<typeof $$render<TFeatures, TData, TValue>>['events'];
|
|
38
|
+
slots(): ReturnType<typeof $$render<TFeatures, TData, TValue>>['slots'];
|
|
39
|
+
bindings(): "";
|
|
40
|
+
exports(): {};
|
|
41
|
+
}
|
|
42
|
+
interface $$IsomorphicComponent {
|
|
43
|
+
new <TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TFeatures, TData, TValue>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TFeatures, TData, TValue>['props']>, ReturnType<__sveltets_Render<TFeatures, TData, TValue>['events']>, ReturnType<__sveltets_Render<TFeatures, TData, TValue>['slots']>> & {
|
|
44
|
+
$$bindings?: ReturnType<__sveltets_Render<TFeatures, TData, TValue>['bindings']>;
|
|
45
|
+
} & ReturnType<__sveltets_Render<TFeatures, TData, TValue>['exports']>;
|
|
46
|
+
<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData>(internal: unknown, props: ReturnType<__sveltets_Render<TFeatures, TData, TValue>['props']> & {}): ReturnType<__sveltets_Render<TFeatures, TData, TValue>['exports']>;
|
|
47
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any, any>['bindings']>;
|
|
48
|
+
}
|
|
49
|
+
declare const FlexRender: $$IsomorphicComponent;
|
|
50
|
+
type FlexRender<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> = InstanceType<typeof FlexRender<TFeatures, TData, TValue>>;
|
|
51
|
+
export default FlexRender;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RowData, Table, TableFeatures, TableOptions, TableState } from '@tanstack/table-core';
|
|
2
|
+
export type SvelteTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>> = Omit<Table<TFeatures, TData>, 'store'> & {
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Prefer `table.state` for render reads,
|
|
5
|
+
* `table.atoms.<slice>.get()` for slice snapshots, or
|
|
6
|
+
* `useSelector(table.store, selector)` for explicit subscriptions.
|
|
7
|
+
* `table.store.state` is a current-value snapshot and is easy to misuse in
|
|
8
|
+
* render code.
|
|
9
|
+
*/
|
|
10
|
+
readonly store: Table<TFeatures, TData>['store'];
|
|
11
|
+
/**
|
|
12
|
+
* The selected state of the table. This state may not match the structure of
|
|
13
|
+
* the full table state because it is selected by the selector function that
|
|
14
|
+
* you pass as the 2nd argument to `createTable`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
|
|
18
|
+
*
|
|
19
|
+
* console.log(table.state.globalFilter)
|
|
20
|
+
*/
|
|
21
|
+
readonly state: Readonly<TSelected>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Creates a Svelte 5 table instance backed by rune-aware TanStack Store atoms.
|
|
25
|
+
*
|
|
26
|
+
* The optional selector projects from `table.store`; the selected value is
|
|
27
|
+
* exposed on `table.state`. The adapter syncs options in `$effect.pre`, so
|
|
28
|
+
* reactive option getters and external `$state` values are applied before DOM
|
|
29
|
+
* updates read table APIs such as `getRowModel()`.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```svelte
|
|
33
|
+
* <script lang="ts">
|
|
34
|
+
* const table = createTable(
|
|
35
|
+
* {
|
|
36
|
+
* features,
|
|
37
|
+
* rowModels: {},
|
|
38
|
+
* columns,
|
|
39
|
+
* data,
|
|
40
|
+
* },
|
|
41
|
+
* (state) => ({ pagination: state.pagination }),
|
|
42
|
+
* )
|
|
43
|
+
* </script>
|
|
44
|
+
*
|
|
45
|
+
* {table.state.pagination.pageIndex}
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function createTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>>(tableOptions: TableOptions<TFeatures, TData>, selector?: (state: TableState<TFeatures>) => TSelected): SvelteTable<TFeatures, TData, TSelected>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { constructTable } from '@tanstack/table-core';
|
|
2
|
+
import { useSelector } from '@tanstack/svelte-store';
|
|
3
|
+
import { untrack } from 'svelte';
|
|
4
|
+
import { flatMerge, mergeObjects } from './merge-objects';
|
|
5
|
+
import { svelteReactivity } from './reactivity.svelte';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Svelte 5 table instance backed by rune-aware TanStack Store atoms.
|
|
8
|
+
*
|
|
9
|
+
* The optional selector projects from `table.store`; the selected value is
|
|
10
|
+
* exposed on `table.state`. The adapter syncs options in `$effect.pre`, so
|
|
11
|
+
* reactive option getters and external `$state` values are applied before DOM
|
|
12
|
+
* updates read table APIs such as `getRowModel()`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```svelte
|
|
16
|
+
* <script lang="ts">
|
|
17
|
+
* const table = createTable(
|
|
18
|
+
* {
|
|
19
|
+
* features,
|
|
20
|
+
* rowModels: {},
|
|
21
|
+
* columns,
|
|
22
|
+
* data,
|
|
23
|
+
* },
|
|
24
|
+
* (state) => ({ pagination: state.pagination }),
|
|
25
|
+
* )
|
|
26
|
+
* </script>
|
|
27
|
+
*
|
|
28
|
+
* {table.state.pagination.pageIndex}
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function createTable(tableOptions, selector) {
|
|
32
|
+
// 1. Merge reactivity into options using mergeObjects (preserves getters)
|
|
33
|
+
const mergedOptions = mergeObjects(tableOptions, {
|
|
34
|
+
features: {
|
|
35
|
+
coreReativityFeature: svelteReactivity(),
|
|
36
|
+
...tableOptions.features,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
// 2. Set up resolved options with mergeOptions handler
|
|
40
|
+
const resolvedOptions = mergeObjects({
|
|
41
|
+
mergeOptions: (defaultOptions, newOptions) => {
|
|
42
|
+
return flatMerge(defaultOptions, newOptions);
|
|
43
|
+
},
|
|
44
|
+
}, mergedOptions);
|
|
45
|
+
// 3. Construct table
|
|
46
|
+
const table = constructTable(resolvedOptions);
|
|
47
|
+
// 4. Sync options reactively. When controlled state changes (e.g., $state
|
|
48
|
+
// inside createTableState), the effect re-runs and calls setOptions.
|
|
49
|
+
// Use $effect.pre so the table sees updated options BEFORE the DOM renders,
|
|
50
|
+
// ensuring getRowModel() returns current data (not stale, one-frame-behind data).
|
|
51
|
+
// The reactive reads (state getters, data getter) happen OUTSIDE untrack
|
|
52
|
+
// so they become dependencies. The setOptions call is INSIDE untrack so
|
|
53
|
+
// option writes do not subscribe this effect to table internals.
|
|
54
|
+
$effect.pre(() => {
|
|
55
|
+
// Read reactive getters to create $effect dependencies on external state
|
|
56
|
+
const state = mergedOptions.state;
|
|
57
|
+
if (state) {
|
|
58
|
+
for (const key in state) {
|
|
59
|
+
void state[key];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
void mergedOptions.data;
|
|
63
|
+
untrack(() => {
|
|
64
|
+
table.setOptions((prev) => {
|
|
65
|
+
return flatMerge(prev, mergedOptions);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
// 5. State selector
|
|
70
|
+
const stateStore = useSelector(table.store, selector);
|
|
71
|
+
Object.defineProperty(table, 'state', {
|
|
72
|
+
get() {
|
|
73
|
+
return stateStore.current;
|
|
74
|
+
},
|
|
75
|
+
configurable: true,
|
|
76
|
+
enumerable: true,
|
|
77
|
+
});
|
|
78
|
+
return table;
|
|
79
|
+
}
|