UNPKG

@tanstack/vue-table

Version:

Headless UI for building powerful tables & datagrids for Vue.

72 lines (70 loc) 2.55 kB
import { flatMerge, mergeProxy } from "./merge-proxy.js"; import { vueReactivity } from "./reactivity.js"; import { getCurrentScope, onScopeDispose, unref, watch } from "vue"; import { constructTable } from "@tanstack/table-core"; //#region src/useTable.ts function getOptionsWithReactiveValues(options) { const resolvedOptions = {}; for (const key of Object.keys(options)) resolvedOptions[key] = unref(options[key]); return mergeProxy(options, resolvedOptions); } function getReactiveOptionDeps(options) { return Object.keys(options).map((key) => unref(options[key])); } /** * Creates a Vue table instance backed by Vue-aware TanStack Store atoms. * * Table options may contain Vue refs or computed values. The adapter unwraps * those reactive inputs, watches them with synchronous flushing, and keeps the * table options in sync. Use `table.Subscribe` or native Vue computed values * around `table.atoms.<slice>.get()` for selected reactive reads. * * @example * ```ts * const table = useTable( * { * features, * columns, * data, * }, * ) * ``` */ function useTable(tableOptions) { const syncTableOptions = (table, options) => { table.setOptions((prev) => flatMerge(prev, getOptionsWithReactiveValues(options))); }; const reactivity = vueReactivity(); const mergedOptions = mergeProxy(tableOptions, { features: { coreReactivityFeature: reactivity, ...unref(tableOptions.features) ?? {} } }); const resolvedOptions = mergeProxy(getOptionsWithReactiveValues(mergedOptions), { mergeOptions: (defaultOptions, newOptions) => { return flatMerge(defaultOptions, newOptions); } }); const coreTable = constructTable(resolvedOptions); const table = coreTable; if (getCurrentScope()) onScopeDispose(() => reactivity.unmount?.()); watch(() => getReactiveOptionDeps(mergedOptions), () => { syncTableOptions(coreTable, mergedOptions); }, { immediate: true }); watch(() => { const controlledState = unref(tableOptions.state); const controlledAtoms = unref(tableOptions.atoms); if (!controlledState) return []; const controlledValues = []; for (const key of Object.keys(table.initialState)) { if (!(key in controlledState) || controlledAtoms?.[key] !== void 0) continue; controlledValues.push(controlledState[key]); } return controlledValues; }, (controlledValues) => { if (controlledValues.length > 0) syncTableOptions(coreTable, mergedOptions); }, { immediate: true }); table.Subscribe = (props) => { return props.children(table.atoms); }; return table; } //#endregion export { useTable };