@tanstack/vue-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/FlexRender.cjs.map +1 -1
- package/dist/FlexRender.d.cts +30 -12
- package/dist/FlexRender.d.ts +30 -12
- package/dist/FlexRender.js.map +1 -1
- package/dist/createTableHook.cjs +23 -64
- package/dist/createTableHook.cjs.map +1 -1
- package/dist/createTableHook.d.cts +52 -28
- package/dist/createTableHook.d.ts +52 -28
- package/dist/createTableHook.js +23 -64
- package/dist/createTableHook.js.map +1 -1
- package/dist/flex-render.d.cts +2 -2
- package/dist/flex-render.d.ts +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/reactivity.cjs +10 -19
- package/dist/reactivity.cjs.map +1 -1
- package/dist/reactivity.js +10 -19
- package/dist/reactivity.js.map +1 -1
- package/dist/useTable.cjs +12 -20
- package/dist/useTable.cjs.map +1 -1
- package/dist/useTable.d.cts +11 -51
- package/dist/useTable.d.ts +11 -51
- package/dist/useTable.js +13 -21
- package/dist/useTable.js.map +1 -1
- package/package.json +4 -4
- package/skills/vue/client-to-server/SKILL.md +21 -26
- package/skills/vue/compose-with-tanstack-form/SKILL.md +4 -4
- package/skills/vue/compose-with-tanstack-pacer/SKILL.md +6 -3
- package/skills/vue/compose-with-tanstack-query/SKILL.md +18 -20
- package/skills/vue/compose-with-tanstack-store/SKILL.md +7 -6
- package/skills/vue/compose-with-tanstack-virtual/SKILL.md +8 -4
- package/skills/vue/getting-started/SKILL.md +55 -49
- package/skills/vue/migrate-v8-to-v9/SKILL.md +50 -32
- package/skills/vue/production-readiness/SKILL.md +28 -21
- package/skills/vue/table-state/SKILL.md +22 -26
- package/src/FlexRender.ts +28 -13
- package/src/createTableHook.ts +126 -90
- package/src/reactivity.ts +17 -43
- package/src/useTable.ts +23 -101
package/src/reactivity.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
getCurrentScope,
|
|
4
|
-
onScopeDispose,
|
|
5
|
-
shallowRef,
|
|
6
|
-
watch,
|
|
7
|
-
} from 'vue'
|
|
8
|
-
import { batch, createAtom } from '@tanstack/vue-store'
|
|
1
|
+
import { computed, shallowRef, watch } from 'vue'
|
|
2
|
+
import { batch } from '@tanstack/store'
|
|
9
3
|
import type {
|
|
10
4
|
TableAtomOptions,
|
|
11
5
|
TableReactivityBindings,
|
|
12
6
|
} from '@tanstack/table-core/reactivity'
|
|
13
|
-
import type {
|
|
7
|
+
import type {
|
|
8
|
+
Atom,
|
|
9
|
+
Observer,
|
|
10
|
+
ReadonlyAtom,
|
|
11
|
+
Subscription,
|
|
12
|
+
} from '@tanstack/store'
|
|
14
13
|
import type { ComputedRef, ShallowRef } from 'vue'
|
|
15
14
|
|
|
16
|
-
const optionsStoreDebugName = 'table/optionsStore'
|
|
17
|
-
|
|
18
15
|
function observerToCallback<T>(
|
|
19
16
|
observerOrNext: Observer<T> | ((value: T) => void),
|
|
20
17
|
): (value: T) => void {
|
|
@@ -64,50 +61,27 @@ function refToWritableAtom<T>(source: ShallowRef<T>): Atom<T> {
|
|
|
64
61
|
* refs.
|
|
65
62
|
*/
|
|
66
63
|
export function vueReactivity(): TableReactivityBindings {
|
|
64
|
+
const subscriptions = new Set<Subscription>()
|
|
65
|
+
|
|
67
66
|
return {
|
|
68
67
|
createOptionsStore: true,
|
|
69
|
-
wrapExternalAtoms:
|
|
70
|
-
addSubscription: () => {
|
|
71
|
-
|
|
72
|
-
'Feature not supported in current reactivity implementation',
|
|
73
|
-
)
|
|
68
|
+
wrapExternalAtoms: true,
|
|
69
|
+
addSubscription: (subscription) => {
|
|
70
|
+
subscriptions.add(subscription)
|
|
74
71
|
},
|
|
75
72
|
unmount: () => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
73
|
+
subscriptions.forEach((s) => s.unsubscribe())
|
|
74
|
+
subscriptions.clear()
|
|
79
75
|
},
|
|
80
76
|
schedule: (fn) => queueMicrotask(() => fn()),
|
|
81
77
|
createReadonlyAtom: <T>(fn: () => T, _options?: TableAtomOptions<T>) => {
|
|
82
|
-
|
|
83
|
-
compare: _options?.compare,
|
|
84
|
-
})
|
|
85
|
-
const version = shallowRef(0)
|
|
86
|
-
const subscription = storeAtom.subscribe(() => {
|
|
87
|
-
version.value += 1
|
|
88
|
-
})
|
|
89
|
-
if (getCurrentScope()) {
|
|
90
|
-
onScopeDispose(() => subscription.unsubscribe())
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return refToReadonlyAtom(
|
|
94
|
-
computed(() => {
|
|
95
|
-
version.value
|
|
96
|
-
return storeAtom.get()
|
|
97
|
-
}),
|
|
98
|
-
)
|
|
78
|
+
return refToReadonlyAtom(computed(() => fn()))
|
|
99
79
|
},
|
|
100
80
|
createWritableAtom: <T>(
|
|
101
81
|
value: T,
|
|
102
82
|
_options?: TableAtomOptions<T>,
|
|
103
83
|
): Atom<T> => {
|
|
104
|
-
|
|
105
|
-
return refToWritableAtom(shallowRef(value) as ShallowRef<T>)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return createAtom(value, {
|
|
109
|
-
compare: _options?.compare,
|
|
110
|
-
})
|
|
84
|
+
return refToWritableAtom(shallowRef(value) as ShallowRef<T>)
|
|
111
85
|
},
|
|
112
86
|
untrack: (fn) => fn(),
|
|
113
87
|
batch,
|
package/src/useTable.ts
CHANGED
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
import { unref, watch } from 'vue'
|
|
1
|
+
import { getCurrentScope, onScopeDispose, unref, watch } from 'vue'
|
|
2
2
|
import { constructTable } from '@tanstack/table-core'
|
|
3
|
-
import { shallow, useSelector } from '@tanstack/vue-store'
|
|
4
3
|
import { flatMerge, mergeProxy } from './merge-proxy'
|
|
5
4
|
import { vueReactivity } from './reactivity'
|
|
6
5
|
import type {
|
|
7
|
-
Atom,
|
|
8
|
-
ReadonlyAtom,
|
|
9
|
-
ReadonlyStore,
|
|
10
|
-
Store,
|
|
11
|
-
} from '@tanstack/vue-store'
|
|
12
|
-
import type {
|
|
13
|
-
NoInfer,
|
|
14
6
|
RowData,
|
|
15
7
|
Table,
|
|
16
8
|
TableFeatures,
|
|
17
9
|
TableOptions,
|
|
18
|
-
TableState,
|
|
19
10
|
} from '@tanstack/table-core'
|
|
20
11
|
import type { MaybeRef, VNode } from 'vue'
|
|
21
12
|
|
|
22
|
-
export type SubscribeSource<TValue> =
|
|
23
|
-
| Atom<TValue>
|
|
24
|
-
| ReadonlyAtom<TValue>
|
|
25
|
-
| Store<TValue>
|
|
26
|
-
| ReadonlyStore<TValue>
|
|
27
|
-
|
|
28
13
|
export type TableOptionsWithReactiveData<
|
|
29
14
|
TFeatures extends TableFeatures,
|
|
30
15
|
TData extends RowData,
|
|
@@ -61,57 +46,13 @@ function getReactiveOptionDeps<
|
|
|
61
46
|
export type VueTable<
|
|
62
47
|
TFeatures extends TableFeatures,
|
|
63
48
|
TData extends RowData,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* @deprecated Prefer `table.state` for render reads,
|
|
68
|
-
* `table.atoms.<slice>.get()` for slice snapshots, or
|
|
69
|
-
* `table.Subscribe` / `useSelector(table.store, selector)` for explicit
|
|
70
|
-
* subscriptions. `table.store.state` is a current-value snapshot and is easy
|
|
71
|
-
* to misuse in render code.
|
|
72
|
-
*/
|
|
73
|
-
readonly store: Table<TFeatures, TData>['store']
|
|
74
|
-
/**
|
|
75
|
-
* Store mode: `selector` required. Source mode: pass `source` (atom or store); omit
|
|
76
|
-
* `selector` for the whole value (identity), or pass `selector` to project. Split
|
|
77
|
-
* overloads so source-only infers `TSourceValue` for `children` (see React `Subscribe`).
|
|
49
|
+
> = Table<TFeatures, TData> & {
|
|
50
|
+
/** Creates a reactive render boundary. The child function reads the table
|
|
51
|
+
* atoms it needs, so Vue only tracks those atom reads.
|
|
78
52
|
*/
|
|
79
|
-
Subscribe: {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
selector?: undefined
|
|
83
|
-
children:
|
|
84
|
-
| ((state: Readonly<TSourceValue>) => VNode | Array<VNode>)
|
|
85
|
-
| VNode
|
|
86
|
-
| Array<VNode>
|
|
87
|
-
}): VNode | Array<VNode>
|
|
88
|
-
<TSourceValue, TSubSelected>(props: {
|
|
89
|
-
source: SubscribeSource<TSourceValue>
|
|
90
|
-
selector: (state: TSourceValue) => TSubSelected
|
|
91
|
-
children:
|
|
92
|
-
| ((state: Readonly<TSubSelected>) => VNode | Array<VNode>)
|
|
93
|
-
| VNode
|
|
94
|
-
| Array<VNode>
|
|
95
|
-
}): VNode | Array<VNode>
|
|
96
|
-
<TSubSelected>(props: {
|
|
97
|
-
selector: (state: NoInfer<TableState<TFeatures>>) => TSubSelected
|
|
98
|
-
children:
|
|
99
|
-
| ((state: Readonly<TSubSelected>) => VNode | Array<VNode>)
|
|
100
|
-
| VNode
|
|
101
|
-
| Array<VNode>
|
|
102
|
-
}): VNode | Array<VNode>
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The selected state of the table. This state may not match the structure of
|
|
106
|
-
* the full table state because it is selected by the selector function that
|
|
107
|
-
* you pass as the 2nd argument to `useTable`.
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* const table = useTable(options, (state) => ({ globalFilter: state.globalFilter })) // only globalFilter is part of the selected state
|
|
111
|
-
*
|
|
112
|
-
* console.log(table.state.globalFilter)
|
|
113
|
-
*/
|
|
114
|
-
readonly state: Readonly<TSelected>
|
|
53
|
+
Subscribe: (props: {
|
|
54
|
+
children: (atoms: Table<TFeatures, TData>['atoms']) => VNode | Array<VNode>
|
|
55
|
+
}) => VNode | Array<VNode>
|
|
115
56
|
}
|
|
116
57
|
|
|
117
58
|
/**
|
|
@@ -119,34 +60,28 @@ export type VueTable<
|
|
|
119
60
|
*
|
|
120
61
|
* Table options may contain Vue refs or computed values. The adapter unwraps
|
|
121
62
|
* those reactive inputs, watches them with synchronous flushing, and keeps the
|
|
122
|
-
* table options in sync.
|
|
123
|
-
*
|
|
63
|
+
* table options in sync. Use `table.Subscribe` or native Vue computed values
|
|
64
|
+
* around `table.atoms.<slice>.get()` for selected reactive reads.
|
|
124
65
|
*
|
|
125
66
|
* @example
|
|
126
67
|
* ```ts
|
|
127
68
|
* const table = useTable(
|
|
128
69
|
* {
|
|
129
70
|
* features,
|
|
130
|
-
* rowModels: {},
|
|
131
71
|
* columns,
|
|
132
72
|
* data,
|
|
133
73
|
* },
|
|
134
|
-
* (state) => ({ pagination: state.pagination }),
|
|
135
74
|
* )
|
|
136
|
-
*
|
|
137
|
-
* table.state.pagination
|
|
138
75
|
* ```
|
|
139
76
|
*/
|
|
140
77
|
export function useTable<
|
|
141
78
|
TFeatures extends TableFeatures,
|
|
142
79
|
TData extends RowData,
|
|
143
|
-
TSelected = TableState<TFeatures>,
|
|
144
80
|
>(
|
|
145
81
|
tableOptions:
|
|
146
82
|
| TableOptions<TFeatures, TData>
|
|
147
83
|
| TableOptionsWithReactiveData<TFeatures, TData>,
|
|
148
|
-
|
|
149
|
-
): VueTable<TFeatures, TData, TSelected> {
|
|
84
|
+
): VueTable<TFeatures, TData> {
|
|
150
85
|
const syncTableOptions = (
|
|
151
86
|
table: Table<TFeatures, TData>,
|
|
152
87
|
options: TableOptionsWithReactiveData<TFeatures, TData>,
|
|
@@ -156,9 +91,11 @@ export function useTable<
|
|
|
156
91
|
)
|
|
157
92
|
}
|
|
158
93
|
|
|
94
|
+
const reactivity = vueReactivity()
|
|
95
|
+
|
|
159
96
|
const mergedOptions = mergeProxy(tableOptions, {
|
|
160
97
|
features: {
|
|
161
|
-
|
|
98
|
+
coreReactivityFeature: reactivity,
|
|
162
99
|
...(unref(tableOptions.features) ?? {}),
|
|
163
100
|
},
|
|
164
101
|
}) as TableOptionsWithReactiveData<TFeatures, TData>
|
|
@@ -177,7 +114,11 @@ export function useTable<
|
|
|
177
114
|
) as TableOptions<TFeatures, TData>
|
|
178
115
|
|
|
179
116
|
const coreTable = constructTable(resolvedOptions)
|
|
180
|
-
const table = coreTable as unknown as VueTable<TFeatures, TData
|
|
117
|
+
const table = coreTable as unknown as VueTable<TFeatures, TData>
|
|
118
|
+
|
|
119
|
+
if (getCurrentScope()) {
|
|
120
|
+
onScopeDispose(() => reactivity.unmount?.())
|
|
121
|
+
}
|
|
181
122
|
|
|
182
123
|
watch(
|
|
183
124
|
() => getReactiveOptionDeps(mergedOptions),
|
|
@@ -222,30 +163,11 @@ export function useTable<
|
|
|
222
163
|
{ immediate: true },
|
|
223
164
|
)
|
|
224
165
|
|
|
225
|
-
table.Subscribe = (
|
|
226
|
-
|
|
227
|
-
selector?: ((state: unknown) => unknown) | undefined
|
|
228
|
-
children:
|
|
229
|
-
| ((state: Readonly<unknown>) => VNode | Array<VNode>)
|
|
230
|
-
| VNode
|
|
231
|
-
| Array<VNode>
|
|
166
|
+
table.Subscribe = (props: {
|
|
167
|
+
children: (atoms: Table<TFeatures, TData>['atoms']) => VNode | Array<VNode>
|
|
232
168
|
}) => {
|
|
233
|
-
|
|
234
|
-
const selected = useSelector(source as never, props.selector as never, {
|
|
235
|
-
compare: shallow,
|
|
236
|
-
})
|
|
237
|
-
if (typeof props.children === 'function') {
|
|
238
|
-
return props.children(selected.value as Readonly<unknown>)
|
|
239
|
-
}
|
|
240
|
-
return props.children
|
|
241
|
-
}) as VueTable<TFeatures, TData, TSelected>['Subscribe']
|
|
242
|
-
|
|
243
|
-
const stateStore = useSelector(table.store, selector)
|
|
244
|
-
|
|
245
|
-
return {
|
|
246
|
-
...table,
|
|
247
|
-
get state() {
|
|
248
|
-
return stateStore.value
|
|
249
|
-
},
|
|
169
|
+
return props.children(table.atoms as Table<TFeatures, TData>['atoms'])
|
|
250
170
|
}
|
|
171
|
+
|
|
172
|
+
return table
|
|
251
173
|
}
|