@tanstack/svelte-table 9.0.0-alpha.4 → 9.0.0-alpha.42

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.
Files changed (53) hide show
  1. package/README.md +117 -0
  2. package/dist/AppCell.svelte +13 -0
  3. package/dist/AppCell.svelte.d.ts +9 -0
  4. package/dist/AppHeader.svelte +13 -0
  5. package/dist/AppHeader.svelte.d.ts +9 -0
  6. package/dist/AppTable.svelte +11 -0
  7. package/dist/AppTable.svelte.d.ts +7 -0
  8. package/dist/FlexRender.svelte +103 -0
  9. package/dist/FlexRender.svelte.d.ts +51 -0
  10. package/dist/context-keys.d.ts +3 -0
  11. package/dist/context-keys.js +3 -0
  12. package/dist/createTable.svelte.d.ts +13 -0
  13. package/dist/createTable.svelte.js +54 -0
  14. package/dist/createTableHook.svelte.d.ts +235 -0
  15. package/dist/createTableHook.svelte.js +170 -0
  16. package/dist/createTableState.svelte.d.ts +2 -0
  17. package/dist/createTableState.svelte.js +12 -0
  18. package/dist/flex-render.d.ts +1 -0
  19. package/dist/flex-render.js +2 -0
  20. package/dist/index.d.ts +8 -3
  21. package/dist/index.js +6 -3
  22. package/dist/merge-objects.d.ts +8 -0
  23. package/dist/merge-objects.js +29 -0
  24. package/dist/reactivity.svelte.d.ts +2 -0
  25. package/dist/reactivity.svelte.js +45 -0
  26. package/dist/render-component.d.ts +64 -9
  27. package/dist/render-component.js +60 -4
  28. package/dist/static-functions.d.ts +1 -0
  29. package/dist/static-functions.js +1 -0
  30. package/dist/subscribe.d.ts +9 -0
  31. package/dist/subscribe.js +9 -0
  32. package/package.json +27 -9
  33. package/src/AppCell.svelte +13 -0
  34. package/src/AppHeader.svelte +13 -0
  35. package/src/AppTable.svelte +11 -0
  36. package/src/FlexRender.svelte +103 -0
  37. package/src/context-keys.ts +3 -0
  38. package/src/createTable.svelte.ts +103 -0
  39. package/src/createTableHook.svelte.ts +636 -0
  40. package/src/createTableState.svelte.ts +15 -0
  41. package/src/flex-render.ts +3 -0
  42. package/src/index.ts +20 -3
  43. package/src/merge-objects.ts +43 -0
  44. package/src/reactivity.svelte.ts +64 -0
  45. package/src/render-component.ts +74 -10
  46. package/src/static-functions.ts +1 -0
  47. package/src/subscribe.ts +23 -0
  48. package/dist/flex-render.svelte +0 -35
  49. package/dist/flex-render.svelte.d.ts +0 -28
  50. package/dist/table.svelte.d.ts +0 -28
  51. package/dist/table.svelte.js +0 -87
  52. package/src/flex-render.svelte +0 -35
  53. package/src/table.svelte.ts +0 -117
@@ -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,3 @@
1
+ export const tableContextKey = '__tanstack_table_context_key'
2
+ export const cellContextKey = '__tanstack_cell_context_key'
3
+ export const headerContextKey = '__tanstack_header_context_key'
@@ -0,0 +1,103 @@
1
+ import { constructTable } from '@tanstack/table-core'
2
+ import { useSelector } from '@tanstack/svelte-store'
3
+ import { untrack } from 'svelte'
4
+ import { mergeObjects } from './merge-objects'
5
+ import { svelteReactivity } from './reactivity.svelte'
6
+ import type {
7
+ RowData,
8
+ Table,
9
+ TableFeatures,
10
+ TableOptions,
11
+ TableState,
12
+ } from '@tanstack/table-core'
13
+
14
+ export type SvelteTable<
15
+ TFeatures extends TableFeatures,
16
+ TData extends RowData,
17
+ TSelected = {},
18
+ > = Table<TFeatures, TData> & {
19
+ /**
20
+ * The selected state of the table. This state may not match the structure of `table.store.state` because it is selected by the `selector` function that you pass as the 2nd argument to `createTable`.
21
+ *
22
+ * @example
23
+ * const table = createTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
24
+ *
25
+ * console.log(table.state.globalFilter)
26
+ */
27
+ readonly state: Readonly<TSelected>
28
+ }
29
+
30
+ export function createTable<
31
+ TFeatures extends TableFeatures,
32
+ TData extends RowData,
33
+ TSelected = {},
34
+ >(
35
+ tableOptions: TableOptions<TFeatures, TData>,
36
+ selector: (state: TableState<TFeatures>) => TSelected = () =>
37
+ ({}) as TSelected,
38
+ ): SvelteTable<TFeatures, TData, TSelected> {
39
+ // 1. Merge reactivity into options using mergeObjects (preserves getters)
40
+ const mergedOptions = mergeObjects(tableOptions, {
41
+ _features: {
42
+ coreReativityFeature: svelteReactivity(),
43
+ ...tableOptions._features,
44
+ },
45
+ }) as TableOptions<TFeatures, TData>
46
+
47
+ // 2. Set up resolved options with mergeOptions handler
48
+ const resolvedOptions = mergeObjects(
49
+ {
50
+ mergeOptions: (
51
+ defaultOptions: TableOptions<TFeatures, TData>,
52
+ newOptions: Partial<TableOptions<TFeatures, TData>>,
53
+ ) => {
54
+ return mergeObjects(defaultOptions, newOptions)
55
+ },
56
+ },
57
+ mergedOptions,
58
+ ) as TableOptions<TFeatures, TData>
59
+
60
+ // 3. Construct table
61
+ const table = constructTable(resolvedOptions) as SvelteTable<
62
+ TFeatures,
63
+ TData,
64
+ TSelected
65
+ >
66
+
67
+ // 4. Sync options reactively. When controlled state changes (e.g., $state
68
+ // inside createTableState), the effect re-runs and calls setOptions.
69
+ // Use $effect.pre so the table sees updated options BEFORE the DOM renders,
70
+ // ensuring getRowModel() returns current data (not stale, one-frame-behind data).
71
+ // The reactive reads (state getters, data getter) happen OUTSIDE untrack
72
+ // so they become dependencies. The setOptions call is INSIDE untrack so
73
+ // option writes do not subscribe this effect to table internals.
74
+ $effect.pre(() => {
75
+ // Read reactive getters to create $effect dependencies on external state
76
+ const state: Record<string, unknown> | undefined = mergedOptions.state
77
+ if (state) {
78
+ for (const key in state) {
79
+ void state[key]
80
+ }
81
+ }
82
+ void mergedOptions.data
83
+
84
+ untrack(() => {
85
+ table.setOptions((prev) => {
86
+ return mergeObjects(prev, mergedOptions)
87
+ })
88
+ })
89
+ })
90
+
91
+ // 5. State selector
92
+ const stateStore = useSelector(table.store, selector)
93
+
94
+ Object.defineProperty(table, 'state', {
95
+ get() {
96
+ return stateStore.current
97
+ },
98
+ configurable: true,
99
+ enumerable: true,
100
+ })
101
+
102
+ return table
103
+ }