Skip to content

Commit 6d97e80

Browse files
committed
fix(table-devtools): fix table state reactivity
Refactor devtools panel with a more solid-idiomatic approach, using memo and dynamic `useTableState` subscription via Accessor getter to not break reactivity.
1 parent 84848ff commit 6d97e80

12 files changed

Lines changed: 2934 additions & 2588 deletions
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
// @ts-check
22

3+
import solid from 'eslint-plugin-solid/configs/recommended'
34
import rootConfig from '../../eslint.config.js'
45

56
/** @type {any} */
6-
const config = [
7-
...rootConfig,
8-
{
9-
rules: {},
10-
},
11-
]
7+
const config = [...rootConfig, solid]
128

139
export default config

packages/table-devtools/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
},
6060
"devDependencies": {
6161
"@tanstack/table-core": "workspace:*",
62+
"eslint-plugin-solid": "^0.14.5",
6263
"vite-plugin-solid": "^2.11.12"
6364
}
6465
}

packages/table-devtools/src/TableContextProvider.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type { RowData, Table, TableFeatures } from '@tanstack/table-core'
1515
import type { TableDevtoolsRegistration } from './tableTarget'
1616

1717
type TableDevtoolsTabId = 'features' | 'state' | 'options' | 'rows' | 'columns'
18-
type AnyTable = Table<TableFeatures, RowData>
18+
type AnyTable = Table<{}, RowData>
1919

2020
interface TableDevtoolsContextValue {
2121
targets: Accessor<Array<TableDevtoolsRegistration>>
@@ -31,12 +31,12 @@ const TableDevtoolsContext = createContext<
3131
>(undefined)
3232

3333
export const TableContextProvider: ParentComponent = (props) => {
34-
const [targets, setTargets] = createSignal<Array<TableDevtoolsRegistration>>(
35-
getTableDevtoolsTargets(),
36-
)
34+
const initialTargets = getTableDevtoolsTargets()
35+
const [targets, setTargets] =
36+
createSignal<Array<TableDevtoolsRegistration>>(initialTargets)
3737
const [selectedTargetId, setSelectedTargetId] = createSignal<
3838
string | undefined
39-
>(targets()[0]?.id)
39+
>(initialTargets[0]?.id)
4040
const [activeTab, setActiveTab] = createSignal<TableDevtoolsTabId>('features')
4141

4242
const selectedTarget = createMemo(() =>
Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { For } from 'solid-js'
1+
import { For, Show, createMemo } from 'solid-js'
22
import { useTableDevtoolsContext } from '../TableContextProvider'
33
import { useTableStore } from '../useTableStore'
44
import { useStyles } from '../styles/use-styles'
@@ -32,65 +32,57 @@ export function ColumnsPanel() {
3232
const styles = useStyles()
3333
const { table } = useTableDevtoolsContext()
3434

35-
const tableInstance = table()
3635
const tableState = useTableStore(
37-
tableInstance ? tableInstance.store : undefined,
36+
() => table()?.store,
3837
(state) => state,
3938
)
4039

41-
if (!tableInstance) {
42-
return <NoTableConnected title="Columns" />
43-
}
44-
45-
const getColumns = (): Array<AnyColumn> => {
46-
tableState?.()
47-
const tableWithColumnFns = tableInstance as unknown as {
48-
getAllFlatColumns?: () => Array<AnyColumn>
49-
getAllLeafColumns?: () => Array<AnyColumn>
40+
const columns = createMemo<Array<AnyColumn>>(() => {
41+
const tableInstance = table()
42+
if (!tableInstance) {
43+
return []
5044
}
5145

52-
return (
53-
tableWithColumnFns.getAllFlatColumns?.() ??
54-
tableWithColumnFns.getAllLeafColumns?.() ??
55-
[]
56-
)
57-
}
46+
tableState()
5847

59-
const columns = getColumns()
48+
return tableInstance.getAllFlatColumns()
49+
})
6050

6151
return (
62-
<div class={styles().panelScroll}>
63-
<div class={styles().sectionTitle}>Columns ({columns.length})</div>
64-
<div class={styles().tableWrapper}>
65-
<table class={styles().rowsTable}>
66-
<thead>
67-
<tr>
68-
<th class={styles().headerCell}>#</th>
69-
<th class={styles().headerCell}>id</th>
70-
<th class={styles().headerCell}>depth</th>
71-
<th class={styles().headerCell}>accessor</th>
72-
<th class={styles().headerCell}>columnDef</th>
73-
</tr>
74-
</thead>
75-
<tbody>
76-
<For each={columns}>
77-
{(column, index) => (
78-
<tr>
79-
<td class={styles().bodyCellMono}>{index() + 1}</td>
80-
<td class={styles().bodyCellMono}>{column.id}</td>
81-
<td class={styles().bodyCellMono}>{column.depth}</td>
82-
<td class={styles().bodyCellMono}>
83-
{column.accessorFn ? '✓' : '○'}
84-
</td>
85-
<td class={styles().bodyCell}>
86-
{getColumnDefSummary(column)}
87-
</td>
88-
</tr>
89-
)}
90-
</For>
91-
</tbody>
92-
</table>
52+
<Show fallback={<NoTableConnected title={'Columns'} />} when={table()}>
53+
<div class={styles().panelScroll}>
54+
<div class={styles().sectionTitle}>Columns ({columns().length})</div>
55+
<div class={styles().tableWrapper}>
56+
<table class={styles().rowsTable}>
57+
<thead>
58+
<tr>
59+
<th class={styles().headerCell}>#</th>
60+
<th class={styles().headerCell}>id</th>
61+
<th class={styles().headerCell}>depth</th>
62+
<th class={styles().headerCell}>accessor</th>
63+
<th class={styles().headerCell}>columnDef</th>
64+
</tr>
65+
</thead>
66+
<tbody>
67+
<For each={columns()}>
68+
{(column, index) => (
69+
<tr>
70+
<td class={styles().bodyCellMono}>{index() + 1}</td>
71+
<td class={styles().bodyCellMono}>{column.id}</td>
72+
<td class={styles().bodyCellMono}>{column.depth}</td>
73+
<td class={styles().bodyCellMono}>
74+
{column.accessorFn ? '✓' : '○'}
75+
</td>
76+
<td class={styles().bodyCell}>
77+
{getColumnDefSummary(column)}
78+
</td>
79+
</tr>
80+
)}
81+
</For>
82+
</tbody>
83+
</table>
84+
</div>
9385
</div>
94-
</div>
86+
</Show>
9587
)
9688
}

0 commit comments

Comments
 (0)