From 68b124eb10a8eab19e1ddf47e1e275b062f6c169 Mon Sep 17 00:00:00 2001 From: riccardoperra Date: Tue, 2 Jun 2026 11:53:26 +0200 Subject: [PATCH 1/6] feat: refactor reactivity bindings to work without tanstack-store --- .../basic-external-atoms/src/app/app.ts | 4 - packages/angular-table/src/injectTable.ts | 18 +- packages/angular-table/src/reactivity.ts | 160 +++++++----------- packages/lit-table/src/reactivity.ts | 11 ++ packages/preact-table/src/reactivity.ts | 11 ++ packages/react-table/src/reactivity.ts | 11 ++ packages/solid-table/src/createTable.ts | 14 +- packages/solid-table/src/reactivity.ts | 71 +++----- .../svelte-table/src/reactivity.svelte.ts | 11 ++ .../reactivity/coreReactivityFeature.types.ts | 13 +- .../src/core/table/constructTable.ts | 25 ++- .../src/store-reactivity-bindings.ts | 11 ++ packages/vue-table/src/reactivity.ts | 11 ++ 13 files changed, 213 insertions(+), 158 deletions(-) diff --git a/examples/angular/basic-external-atoms/src/app/app.ts b/examples/angular/basic-external-atoms/src/app/app.ts index 56a3eac4b1..8ce89bacb6 100644 --- a/examples/angular/basic-external-atoms/src/app/app.ts +++ b/examples/angular/basic-external-atoms/src/app/app.ts @@ -51,10 +51,6 @@ export class App { injectTanStackTableDevtools(() => ({ table: this.table, })) - - effect(() => { - console.log('atom', this.paginationAtom.get()) - }) } readonly data = signal(makeData(1_000)) diff --git a/packages/angular-table/src/injectTable.ts b/packages/angular-table/src/injectTable.ts index 6800969c61..4f59232b03 100644 --- a/packages/angular-table/src/injectTable.ts +++ b/packages/angular-table/src/injectTable.ts @@ -1,4 +1,5 @@ import { + DestroyRef, Injector, NgZone, assertInInjectionContext, @@ -9,12 +10,6 @@ import { import { constructTable } from '@tanstack/table-core' import { lazyInit } from './lazySignalInitializer' import { angularReactivity } from './reactivity' -import type { - Atom, - ReadonlyAtom, - ReadonlyStore, - Store, -} from '@tanstack/angular-store' import type { RowData, Table, @@ -22,6 +17,12 @@ import type { TableOptions, TableState, } from '@tanstack/table-core' +import type { + Atom, + ReadonlyAtom, + ReadonlyStore, + Store, +} from '@tanstack/angular-store' export type SubscribeSource = | Atom @@ -172,6 +173,11 @@ export function injectTable< ...options()._features, }, }) as AngularTable + + injector.get(DestroyRef).onDestroy(() => { + table._reactivity.unmount?.() + }) + const stateProxy = createStateProxy(table) Object.defineProperty(table, 'state', { diff --git a/packages/angular-table/src/reactivity.ts b/packages/angular-table/src/reactivity.ts index 6ce4be8927..d35e0269ce 100644 --- a/packages/angular-table/src/reactivity.ts +++ b/packages/angular-table/src/reactivity.ts @@ -1,80 +1,62 @@ -import { - DestroyRef, - NgZone, - computed, - effect, - signal, - untracked, -} from '@angular/core' -import { batch, createAtom } from '@tanstack/angular-store' -import type { Atom, Observer, ReadonlyAtom } from '@tanstack/angular-store' +import { NgZone, computed, signal, untracked } from '@angular/core' +import { toObservable } from '@angular/core/rxjs-interop' +import type { Injector, Signal, WritableSignal } from '@angular/core' +import type { + Atom, + Observer, + ReadonlyAtom, + Subscription, +} from '@tanstack/angular-store' import type { TableAtomOptions, TableReactivityBindings, } from '@tanstack/table-core/reactivity' -import type { Injector, Signal, WritableSignal } from '@angular/core' - -const optionsStoreDebugName = 'table/optionsStore' - -function observerToCallback( - observerOrNext: Observer | ((value: T) => void), -): (value: T) => void { - return typeof observerOrNext === 'function' - ? observerOrNext - : (value) => observerOrNext.next?.(value) -} function signalToReadonlyAtom( - source: Signal, - getSource: () => T, - subscribeSource: (observerOrNext: Observer | ((value: T) => void)) => { - unsubscribe: () => void - }, + signal: Signal, + injector: Injector, + debugName?: string, ): ReadonlyAtom { - return Object.assign(source, { - get: () => { - const value = getSource() - source() - return value + const _signal = Object.assign(signal, { + get: () => signal(), + subscribe: (observer: Observer) => { + return untracked(() => + toObservable(computed(signal), { injector: injector }).subscribe( + observer, + ), + ) }, - subscribe: subscribeSource as ReadonlyAtom['subscribe'], }) + if (debugName) { + _signal.toString = () => debugName + } + return _signal } function signalToWritableAtom( - source: WritableSignal, + signal: WritableSignal, injector: Injector, + debugName?: string, ): Atom { - const observers = new Set<(value: T) => void>() - let observed = false - effect( - () => { - const value = source() - if (!observed) { - observed = true - return - } - observers.forEach((observer) => observer(value)) - }, - { injector }, - ) - - return Object.assign(source.asReadonly(), { + const _signal = Object.assign(signal.asReadonly(), { set: (updater: T | ((prevVal: T) => T)) => { typeof updater === 'function' - ? source.update(updater as (val: T) => T) - : source.set(updater) + ? signal.update(updater as (val: T) => T) + : signal.set(updater) + }, + get: () => signal(), + subscribe: (observer: Observer) => { + return untracked(() => + toObservable(computed(signal), { injector: injector }).subscribe( + observer, + ), + ) }, - get: () => source(), - subscribe: ((observerOrNext: Observer | ((value: T) => void)) => { - const observer = observerToCallback(observerOrNext) - observers.add(observer) - - return { - unsubscribe: () => observers.delete(observer), - } - }) as Atom['subscribe'], }) + if (debugName) { + _signal.toString = () => debugName + } + return _signal } /** @@ -87,61 +69,37 @@ function signalToWritableAtom( */ export function angularReactivity(injector: Injector): TableReactivityBindings { const ngZone = injector.get(NgZone) - const destroyRef = injector.get(DestroyRef) + const subscriptions = new Set() return { createOptionsStore: true, + wrapExternalAtoms: true, + addSubscription: (subscription) => { + subscriptions.add(subscription) + }, + unmount: () => { + subscriptions.forEach((s) => s.unsubscribe()) + subscriptions.clear() + }, schedule: (fn) => ngZone.runOutsideAngular(() => queueMicrotask(fn)), createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { - const storeAtom = createAtom(() => fn(), { - compare: options?.compare, - }) - const version = signal(0, { - equal: () => false, + const signal = computed(() => fn(), { + equal: options?.compare, + debugName: options?.debugName, }) - const subscription = storeAtom.subscribe(() => { - version.update((value) => value + 1) - }) - destroyRef.onDestroy(() => subscription.unsubscribe()) - - const value = computed( - () => { - version() - return storeAtom.get() - }, - { - equal: options?.compare, - debugName: options?.debugName, - }, - ) - return signalToReadonlyAtom( - value, - () => storeAtom.get(), - (observerOrNext) => { - const observer = observerToCallback(observerOrNext) - return storeAtom.subscribe(() => { - observer(storeAtom.get()) - }) - }, - ) + return signalToReadonlyAtom(signal, injector, options?.debugName) }, createWritableAtom: ( value: T, options?: TableAtomOptions, ): Atom => { - if (options?.debugName === optionsStoreDebugName) { - const writableSignal = signal(value, { - equal: options.compare, - debugName: options.debugName, - }) - return signalToWritableAtom(writableSignal, injector) - } - - return createAtom(value, { - compare: options?.compare, + const writableSignal = signal(value, { + equal: options?.compare, + debugName: options?.debugName, }) + return signalToWritableAtom(writableSignal, injector, options?.debugName) }, untrack: untracked, - batch, + batch: (fn) => fn(), } } diff --git a/packages/lit-table/src/reactivity.ts b/packages/lit-table/src/reactivity.ts index fb7d6c5d4f..01e180e246 100644 --- a/packages/lit-table/src/reactivity.ts +++ b/packages/lit-table/src/reactivity.ts @@ -13,6 +13,17 @@ import type { export function litReactivity(): TableReactivityBindings { return { createOptionsStore: true, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, schedule: (fn) => queueMicrotask(() => fn()), batch, untrack: (fn) => fn(), diff --git a/packages/preact-table/src/reactivity.ts b/packages/preact-table/src/reactivity.ts index e362b691f4..57ecd811b3 100644 --- a/packages/preact-table/src/reactivity.ts +++ b/packages/preact-table/src/reactivity.ts @@ -13,6 +13,17 @@ import type { export function preactReactivity(): TableReactivityBindings { return { createOptionsStore: false, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, schedule: (fn) => queueMicrotask(() => fn()), batch, untrack: (fn) => fn(), diff --git a/packages/react-table/src/reactivity.ts b/packages/react-table/src/reactivity.ts index 34de5af37a..bd86dab0fc 100644 --- a/packages/react-table/src/reactivity.ts +++ b/packages/react-table/src/reactivity.ts @@ -13,6 +13,17 @@ import type { export function reactReactivity(): TableReactivityBindings { return { createOptionsStore: false, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, schedule: (fn) => queueMicrotask(fn), batch, untrack: (fn) => fn(), diff --git a/packages/solid-table/src/createTable.ts b/packages/solid-table/src/createTable.ts index f29ce6c75d..b6d452a7c4 100644 --- a/packages/solid-table/src/createTable.ts +++ b/packages/solid-table/src/createTable.ts @@ -1,5 +1,12 @@ import { constructTable } from '@tanstack/table-core' -import { createComputed, getOwner, mergeProps, untrack } from 'solid-js' +import { + createComputed, + getOwner, + mergeProps, + onCleanup, + runWithOwner, + untrack, +} from 'solid-js' import { shallow, useSelector } from '@tanstack/solid-store' import { FlexRender } from './FlexRender' import { solidReactivity } from './reactivity' @@ -115,10 +122,11 @@ export function createTable< selector?: (state: TableState) => TSelected, ): SolidTable { const owner = getOwner()! + const reactivity = solidReactivity(owner) const mergedOptions = mergeProps(tableOptions, { _features: { - coreReativityFeature: solidReactivity(owner), + coreReativityFeature: reactivity, ...tableOptions._features, }, }) as any @@ -156,6 +164,8 @@ export function createTable< }) }) + onCleanup(() => reactivity.unmount?.()) + table.Subscribe = ((props: { source?: SubscribeSource selector?: ((state: unknown) => unknown) | undefined diff --git a/packages/solid-table/src/reactivity.ts b/packages/solid-table/src/reactivity.ts index 736bbea9bf..2034103938 100644 --- a/packages/solid-table/src/reactivity.ts +++ b/packages/solid-table/src/reactivity.ts @@ -1,32 +1,31 @@ import { + batch, createMemo, createSignal, observable, - onCleanup, runWithOwner, untrack, } from 'solid-js' -import { batch, createAtom } from '@tanstack/solid-store' +import type { + Atom, + Observer, + ReadonlyAtom, + Subscription, +} from '@tanstack/solid-store' import type { Accessor, Owner, Setter } from 'solid-js' import type { TableAtomOptions, TableReactivityBindings, } from '@tanstack/table-core/reactivity' -import type { Atom, Observer, ReadonlyAtom } from '@tanstack/solid-store' const optionsStoreDebugName = 'table/optionsStore' function signalToReadonlyAtom( signal: Accessor, - getSource: () => T, owner: Owner, ): ReadonlyAtom { return Object.assign(signal, { - get: () => { - const value = getSource() - signal() - return value - }, + get: () => signal(), subscribe: (observer: Observer) => { return runWithOwner(owner, () => observable(signal))!.subscribe(observer) }, @@ -34,10 +33,10 @@ function signalToReadonlyAtom( } function signalToWritableAtom( - signal: Accessor, - setSignal: Setter, + signalTuple: [Accessor, Setter], owner: Owner, ): Atom { + const [signal, setSignal] = signalTuple return Object.assign(signal, { set: (updater: T | ((prevVal: T) => T)) => { typeof updater === 'function' @@ -59,49 +58,35 @@ function signalToWritableAtom( * render. Readonly table atoms bridge Store dependency tracking into Solid memos. */ export function solidReactivity(owner: Owner): TableReactivityBindings { + const subscriptions = new Set() + return { createOptionsStore: true, + wrapExternalAtoms: true, + addSubscription: (subscription) => { + subscriptions.add(subscription) + }, + unmount: () => { + subscriptions.forEach((s) => s.unsubscribe()) + subscriptions.clear() + }, schedule: (fn) => queueMicrotask(() => fn()), createReadonlyAtom: (fn: () => T, options?: TableAtomOptions) => { - const storeAtom = createAtom(() => fn(), { - compare: options?.compare, - }) - const [version, setVersion] = createSignal(0, { equals: false }) - runWithOwner(owner, () => { - const subscription = storeAtom.subscribe(() => { - setVersion((value) => value + 1) - }) - onCleanup(() => subscription.unsubscribe()) + const signal = createMemo(() => fn(), { + equals: options?.compare, + name: options?.debugName, }) - - const signal = createMemo( - () => { - version() - return storeAtom.get() - }, - undefined, - { - equals: options?.compare, - name: options?.debugName, - }, - ) - return signalToReadonlyAtom(signal, () => storeAtom.get(), owner) + return signalToReadonlyAtom(signal, owner) }, createWritableAtom: ( value: T, options?: TableAtomOptions, ): Atom => { - if (options?.debugName === optionsStoreDebugName) { - const [signal, setSignal] = createSignal(value, { - equals: options.compare, - name: options.debugName, - }) - return signalToWritableAtom(signal, setSignal, owner) - } - - return createAtom(value, { - compare: options?.compare, + const writableSignal = createSignal(value, { + equals: options?.compare, + name: options?.debugName, }) + return signalToWritableAtom(writableSignal, owner) }, untrack: untrack, batch: batch, diff --git a/packages/svelte-table/src/reactivity.svelte.ts b/packages/svelte-table/src/reactivity.svelte.ts index 8549be44a9..bfe5bef784 100644 --- a/packages/svelte-table/src/reactivity.svelte.ts +++ b/packages/svelte-table/src/reactivity.svelte.ts @@ -58,6 +58,17 @@ function createRuneWritableAtom(initialValue: T): Atom { export function svelteReactivity(): TableReactivityBindings { return { createOptionsStore: true, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, schedule: (fn) => queueMicrotask(() => fn()), createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => { const storeAtom = createAtom(() => fn(), { diff --git a/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts index 213bd3f7b9..c69b74b239 100644 --- a/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts +++ b/packages/table-core/src/core/reactivity/coreReactivityFeature.types.ts @@ -1,4 +1,9 @@ -import type { Atom, AtomOptions, ReadonlyAtom } from '@tanstack/store' +import type { + Atom, + AtomOptions, + ReadonlyAtom, + Subscription, +} from '@tanstack/store' export interface TableAtomOptions extends AtomOptions { /** @@ -16,6 +21,8 @@ export interface TableAtomOptions extends AtomOptions { */ export interface TableReactivityBindings { createOptionsStore: boolean + wrapExternalAtoms: boolean + addSubscription: (subscription: Subscription) => void /** * Creates a writable atom with an initial value. */ @@ -42,4 +49,8 @@ export interface TableReactivityBindings { * Schedules a function to run. This is used to defer updates after the current call stack (render, etc.) has finished */ schedule: (fn: () => void) => void + /** + * Unmounts the table, performing any necessary cleanup. This is called when the table is destroyed or unmounted in the framework adapter. + */ + unmount?: () => void } diff --git a/packages/table-core/src/core/table/constructTable.ts b/packages/table-core/src/core/table/constructTable.ts index 964ba6dba7..ba20cc9b15 100644 --- a/packages/table-core/src/core/table/constructTable.ts +++ b/packages/table-core/src/core/table/constructTable.ts @@ -2,6 +2,7 @@ import { coreFeatures } from '../coreFeatures' import { cloneState } from '../../utils' import { atomToStore } from '../reactivity/coreReactivityFeature.utils' import { table_syncExternalStateToBaseAtoms } from './coreTablesFeature.utils' +import type { Atom } from '@tanstack/store' import type { RowData } from '../../types/type-utils' import type { TableFeature, TableFeatures } from '../../types/TableFeatures' import type { Table, Table_Internal } from '../../types/Table' @@ -51,6 +52,29 @@ export function constructTable< const mergedOptions = { ...defaultOptions, ...tableOptions } + if (_reactivity.wrapExternalAtoms && mergedOptions.atoms) { + for (const [atomKey, _atom] of Object.entries(mergedOptions.atoms)) { + const atom = _atom as Atom + const wrappedAtom = _reactivity.createWritableAtom(atom.get(), { + debugName: `externalAtom/${atomKey}`, + }) + ;(mergedOptions.atoms as any)[atomKey] = wrappedAtom + // Two-way syncing between the original atom and the wrapped one. + let syncExternal = false + const syncAtomToWrappedSub = atom.subscribe((value) => { + if (syncExternal) return + wrappedAtom.set(value) + }) + const syncWrappedToAtomSub = wrappedAtom.subscribe((value) => { + syncExternal = true + atom.set(value) + syncExternal = false + }) + _reactivity.addSubscription(syncAtomToWrappedSub) + _reactivity.addSubscription(syncWrappedToAtomSub) + } + } + if (_reactivity.createOptionsStore) { // @ts-ignore - direct set table.optionsStore = _reactivity.createWritableAtom< @@ -81,7 +105,6 @@ export function constructTable< for (let i = 0; i < stateKeys.length; i++) { const key = stateKeys[i]! - // create writable base atom table.baseAtoms[key] = _reactivity.createWritableAtom( table.initialState[key], { diff --git a/packages/table-core/src/store-reactivity-bindings.ts b/packages/table-core/src/store-reactivity-bindings.ts index 3ad9a9b4d1..db246192bc 100644 --- a/packages/table-core/src/store-reactivity-bindings.ts +++ b/packages/table-core/src/store-reactivity-bindings.ts @@ -19,6 +19,17 @@ import type { TableReactivityBindings } from './core/reactivity/coreReactivityFe export function storeReactivityBindings(): TableReactivityBindings { return { createOptionsStore: true, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, batch, schedule: (fn) => queueMicrotask(fn), untrack: (fn) => fn(), diff --git a/packages/vue-table/src/reactivity.ts b/packages/vue-table/src/reactivity.ts index 2f27ddaecf..836569b58f 100644 --- a/packages/vue-table/src/reactivity.ts +++ b/packages/vue-table/src/reactivity.ts @@ -66,6 +66,17 @@ function refToWritableAtom(source: ShallowRef): Atom { export function vueReactivity(): TableReactivityBindings { return { createOptionsStore: true, + wrapExternalAtoms: false, + addSubscription: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, + unmount: () => { + throw new Error( + 'Feature not supported in current reactivity implementation', + ) + }, schedule: (fn) => queueMicrotask(() => fn()), createReadonlyAtom: (fn: () => T, _options?: TableAtomOptions) => { const storeAtom = createAtom(() => fn(), { From 065ee4814dfdef7634a1186f320ef7cc9713c097 Mon Sep 17 00:00:00 2001 From: Kevin Van Cott Date: Wed, 3 Jun 2026 09:24:45 -0500 Subject: [PATCH 2/6] consistent json stringified state in all examples --- .../column-resizing-performant/src/app/app.html | 2 +- .../angular/column-resizing-performant/src/app/app.ts | 10 ++-------- examples/lit/basic-external-atoms/src/main.ts | 2 +- examples/lit/basic-external-state/src/main.ts | 8 +------- examples/lit/expanding/src/main.ts | 9 --------- examples/lit/filters/src/main.ts | 2 +- examples/lit/row-pinning/src/main.ts | 11 +---------- examples/lit/sorting-dynamic-data/src/main.ts | 2 +- examples/lit/sorting/src/main.ts | 2 +- examples/preact/basic-external-atoms/src/main.tsx | 2 +- examples/preact/basic-external-state/src/main.tsx | 2 +- examples/preact/row-pinning/src/main.tsx | 2 +- examples/preact/with-tanstack-query/src/main.tsx | 2 +- examples/react/basic-external-atoms/src/main.tsx | 11 +---------- examples/react/basic-external-state/src/main.tsx | 2 +- examples/react/row-pinning/src/main.tsx | 2 +- examples/react/with-tanstack-query/src/main.tsx | 2 +- examples/solid/basic-external-atoms/src/App.tsx | 8 +------- examples/solid/basic-external-state/src/App.tsx | 8 +------- examples/solid/row-pinning/src/App.tsx | 2 +- examples/solid/with-tanstack-query/src/App.tsx | 2 +- examples/svelte/basic-external-atoms/src/App.svelte | 2 +- examples/svelte/basic-external-state/src/App.svelte | 8 +------- examples/svelte/column-ordering/src/App.svelte | 8 +------- examples/svelte/column-pinning-split/src/App.svelte | 6 ------ examples/svelte/column-pinning-sticky/src/App.svelte | 6 ------ examples/svelte/column-pinning/src/App.svelte | 8 +------- examples/svelte/column-visibility/src/App.svelte | 2 +- examples/svelte/expanding/src/App.svelte | 4 ---- examples/svelte/filters-fuzzy/src/App.svelte | 4 ---- examples/svelte/grouping/src/App.svelte | 4 ---- examples/svelte/pagination/src/App.svelte | 4 ---- examples/svelte/row-pinning/src/App.svelte | 11 +---------- examples/svelte/row-selection/src/App.svelte | 8 -------- examples/svelte/sorting/src/App.svelte | 4 ---- examples/vue/basic-external-atoms/src/App.tsx | 9 +-------- examples/vue/basic-external-state/src/App.tsx | 11 +---------- examples/vue/with-tanstack-query/src/App.tsx | 2 +- 38 files changed, 30 insertions(+), 164 deletions(-) diff --git a/examples/angular/column-resizing-performant/src/app/app.html b/examples/angular/column-resizing-performant/src/app/app.html index fa66af84b2..319e5994fc 100644 --- a/examples/angular/column-resizing-performant/src/app/app.html +++ b/examples/angular/column-resizing-performant/src/app/app.html @@ -3,7 +3,7 @@
-    {{ columnSizingDebugInfo() }}
+    {{ stringifiedState() }}
   
diff --git a/examples/angular/column-resizing-performant/src/app/app.ts b/examples/angular/column-resizing-performant/src/app/app.ts index 442f0d7194..cca7837651 100644 --- a/examples/angular/column-resizing-performant/src/app/app.ts +++ b/examples/angular/column-resizing-performant/src/app/app.ts @@ -111,14 +111,8 @@ export class App { return colSizes }) - readonly columnSizingDebugInfo = computed(() => - JSON.stringify( - { - columnSizing: this.table.atoms.columnSizing.get(), - }, - null, - 2, - ), + readonly stringifiedState = computed(() => + JSON.stringify(this.table.state, null, 2), ) refreshData = () => this.data.set(makeData(200)) diff --git a/examples/lit/basic-external-atoms/src/main.ts b/examples/lit/basic-external-atoms/src/main.ts index 8890416c38..87809292a7 100644 --- a/examples/lit/basic-external-atoms/src/main.ts +++ b/examples/lit/basic-external-atoms/src/main.ts @@ -231,7 +231,7 @@ class LitTableExample extends LitElement {
-
${JSON.stringify({ sorting, pagination }, null, 2)}
+
${JSON.stringify(table.state, null, 2)}