@tanstack/preact-table 9.0.0-alpha.47 → 9.0.0-alpha.49

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.
@@ -0,0 +1,371 @@
1
+ ---
2
+ name: preact/getting-started
3
+ description: >
4
+ End-to-end first-table journey for `@tanstack/preact-table` v9: install the
5
+ adapter, declare `_features` via `tableFeatures()`, declare `_rowModels` with
6
+ their factories and *Fns parameters, build a typed column helper, call
7
+ `useTable` with stable references, and render with `table.FlexRender`.
8
+ Routing keywords: install preact-table, first table, getting started,
9
+ tableFeatures, _features, _rowModels, useTable, FlexRender, basic-use-table.
10
+ type: lifecycle
11
+ library: tanstack-table
12
+ framework: preact
13
+ library_version: '9.0.0-alpha.48'
14
+ requires:
15
+ - setup
16
+ - column-definitions
17
+ - state-management
18
+ - preact/table-state
19
+ sources:
20
+ - TanStack/table:docs/installation.md
21
+ - TanStack/table:docs/framework/preact/preact-table.md
22
+ - TanStack/table:examples/preact/basic-use-table/src/main.tsx
23
+ - TanStack/table:packages/preact-table/src/useTable.ts
24
+ ---
25
+
26
+ This skill walks through a first working Preact v9 table end-to-end. It assumes you have read `tanstack-table/setup` and `tanstack-table/state-management` for core concepts and `tanstack-table/preact/table-state` for adapter wiring.
27
+
28
+ ## Install
29
+
30
+ `@tanstack/preact-table` is the Preact adapter. It pulls in `@tanstack/table-core` and `@tanstack/preact-store` (used internally for atom-backed state).
31
+
32
+ ```bash
33
+ npm install @tanstack/preact-table
34
+ ```
35
+
36
+ Peer dependency: `preact >=10`.
37
+
38
+ Source: `packages/preact-table/package.json`.
39
+
40
+ ## Step 1 — Declare `_features`
41
+
42
+ v9 is explicit about what a table uses. `_features` is a registry of every feature the table needs. Use `tableFeatures({...})` to get an object whose TypeScript shape drives state inference, API surface, and tree-shaking.
43
+
44
+ ```tsx
45
+ import {
46
+ tableFeatures,
47
+ rowPaginationFeature,
48
+ rowSortingFeature,
49
+ } from '@tanstack/preact-table'
50
+
51
+ const _features = tableFeatures({
52
+ rowPaginationFeature,
53
+ rowSortingFeature,
54
+ })
55
+ ```
56
+
57
+ If `_features` does not include `rowSelectionFeature`, then `table.atoms.rowSelection`, `table.setRowSelection`, `table.getIsAllRowsSelected()`, etc. all become TypeScript errors — and the runtime won't ship that logic. Pass `tableFeatures({})` for a minimum-overhead table with just the core row model.
58
+
59
+ Source: `docs/framework/preact/preact-table.md`; `docs/guide/features.md`.
60
+
61
+ ## Step 2 — Declare `_rowModels`
62
+
63
+ Each registered feature that needs a row-model stage maps to a factory under `_rowModels`. The factory takes a record of \*Fns (predicates, comparators, etc.) for that stage.
64
+
65
+ ```tsx
66
+ import {
67
+ createPaginatedRowModel,
68
+ createSortedRowModel,
69
+ sortFns,
70
+ } from '@tanstack/preact-table'
71
+
72
+ const _rowModels = {
73
+ paginatedRowModel: createPaginatedRowModel(),
74
+ sortedRowModel: createSortedRowModel(sortFns),
75
+ }
76
+ ```
77
+
78
+ The core row model is always included — `_rowModels: {}` is valid for a feature-free table.
79
+
80
+ Source: `docs/framework/preact/preact-table.md`.
81
+
82
+ ## Step 3 — Type your data and build columns
83
+
84
+ Declare your row shape once and feed it to `createColumnHelper<typeof _features, TData>()`. This is the type-safe path; `ColumnDef<typeof _features, Person>[]` also works.
85
+
86
+ ```tsx
87
+ import { createColumnHelper, type ColumnDef } from '@tanstack/preact-table'
88
+
89
+ type Person = {
90
+ firstName: string
91
+ lastName: string
92
+ age: number
93
+ visits: number
94
+ status: string
95
+ progress: number
96
+ }
97
+
98
+ const columnHelper = createColumnHelper<typeof _features, Person>()
99
+
100
+ const columns = columnHelper.columns([
101
+ columnHelper.accessor('firstName', {
102
+ header: 'First Name',
103
+ cell: (info) => info.getValue(),
104
+ }),
105
+ columnHelper.accessor('lastName', { header: () => <span>Last Name</span> }),
106
+ columnHelper.accessor('age', { header: 'Age' }),
107
+ columnHelper.accessor('visits', { header: 'Visits' }),
108
+ columnHelper.accessor('status', { header: 'Status' }),
109
+ columnHelper.accessor('progress', { header: 'Profile Progress' }),
110
+ ])
111
+ ```
112
+
113
+ Source: `examples/preact/basic-use-table/src/main.tsx`.
114
+
115
+ ## Step 4 — Call `useTable` and render
116
+
117
+ `useTable` takes options and an optional selector. Render headers, cells, and footers with `table.FlexRender` so column defs can be strings or Preact components.
118
+
119
+ ```tsx
120
+ import { render } from 'preact'
121
+ import { useState } from 'preact/hooks'
122
+ import { useTable } from '@tanstack/preact-table'
123
+
124
+ const defaultData: Person[] = [
125
+ {
126
+ firstName: 'tanner',
127
+ lastName: 'linsley',
128
+ age: 24,
129
+ visits: 100,
130
+ status: 'In Relationship',
131
+ progress: 50,
132
+ },
133
+ {
134
+ firstName: 'kevin',
135
+ lastName: 'vandy',
136
+ age: 12,
137
+ visits: 100,
138
+ status: 'Single',
139
+ progress: 70,
140
+ },
141
+ ]
142
+
143
+ function App() {
144
+ const [data] = useState(() => [...defaultData])
145
+
146
+ const table = useTable(
147
+ {
148
+ _features,
149
+ _rowModels,
150
+ columns,
151
+ data,
152
+ debugTable: true,
153
+ },
154
+ (state) => state, // default selector
155
+ )
156
+
157
+ return (
158
+ <table>
159
+ <thead>
160
+ {table.getHeaderGroups().map((hg) => (
161
+ <tr key={hg.id}>
162
+ {hg.headers.map((h) => (
163
+ <th key={h.id} onClick={h.column.getToggleSortingHandler()}>
164
+ {h.isPlaceholder ? null : <table.FlexRender header={h} />}
165
+ </th>
166
+ ))}
167
+ </tr>
168
+ ))}
169
+ </thead>
170
+ <tbody>
171
+ {table.getRowModel().rows.map((row) => (
172
+ <tr key={row.id}>
173
+ {row.getAllCells().map((cell) => (
174
+ <td key={cell.id}>
175
+ <table.FlexRender cell={cell} />
176
+ </td>
177
+ ))}
178
+ </tr>
179
+ ))}
180
+ </tbody>
181
+ <tfoot>
182
+ {table.getFooterGroups().map((fg) => (
183
+ <tr key={fg.id}>
184
+ {fg.headers.map((h) => (
185
+ <th key={h.id}>
186
+ {h.isPlaceholder ? null : <table.FlexRender footer={h} />}
187
+ </th>
188
+ ))}
189
+ </tr>
190
+ ))}
191
+ </tfoot>
192
+ </table>
193
+ )
194
+ }
195
+
196
+ render(<App />, document.getElementById('root')!)
197
+ ```
198
+
199
+ Source: `examples/preact/basic-use-table/src/main.tsx`.
200
+
201
+ ## Step 5 — Drive features with feature APIs
202
+
203
+ Reach for `table.setSorting(...)`, `table.setPageIndex(...)`, `table.nextPage()`, `column.toggleVisibility()`, `row.toggleSelected()`, etc. — never edit `table.store.state` directly.
204
+
205
+ ```tsx
206
+ <button onClick={() => table.setPageIndex(0)} disabled={!table.getCanPreviousPage()}>First</button>
207
+ <button onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>Next</button>
208
+ ```
209
+
210
+ For starting values, use `initialState`. For controlled slices, use `atoms` (preferred) or `state` + `on*Change` — see `tanstack-table/preact/table-state`.
211
+
212
+ ## Common Mistakes
213
+
214
+ ### CRITICAL Calling a feature API when the feature is not in `_features`
215
+
216
+ Wrong:
217
+
218
+ ```tsx
219
+ const _features = tableFeatures({}) // no rowPaginationFeature
220
+ const table = useTable({ _features, _rowModels: {}, columns, data })
221
+
222
+ table.setPageIndex(0) // TypeScript error AND runtime no-op
223
+ ```
224
+
225
+ Correct:
226
+
227
+ ```tsx
228
+ const _features = tableFeatures({ rowPaginationFeature })
229
+ const table = useTable({
230
+ _features,
231
+ _rowModels: { paginatedRowModel: createPaginatedRowModel() },
232
+ columns,
233
+ data,
234
+ })
235
+
236
+ table.setPageIndex(0)
237
+ ```
238
+
239
+ v9 generates feature APIs and state slices only for registered features. The missing-feature failure mode (calling `setSorting`, accessing `state.pagination`, etc. before registering the feature) is the #1 v9 trap.
240
+ Source: `docs/guide/features.md`; `docs/framework/preact/guide/table-state.md`.
241
+
242
+ ### HIGH Forgetting the matching row-model factory
243
+
244
+ Wrong:
245
+
246
+ ```tsx
247
+ const _features = tableFeatures({ rowSortingFeature })
248
+ const table = useTable({ _features, _rowModels: {}, columns, data })
249
+ table.setSorting([{ id: 'age', desc: true }])
250
+ // table.getRowModel().rows is still unsorted — no sortedRowModel registered
251
+ ```
252
+
253
+ Correct:
254
+
255
+ ```tsx
256
+ const _features = tableFeatures({ rowSortingFeature })
257
+ const table = useTable({
258
+ _features,
259
+ _rowModels: { sortedRowModel: createSortedRowModel(sortFns) },
260
+ columns,
261
+ data,
262
+ })
263
+ ```
264
+
265
+ Each row-model feature (sorting, filtering, pagination, grouping, expanding, faceting) requires its row-model factory in `_rowModels` to actually transform the rows.
266
+ Source: `docs/framework/preact/preact-table.md`.
267
+
268
+ ### HIGH Unstable `_features` / `columns` / `data` references
269
+
270
+ Wrong:
271
+
272
+ ```tsx
273
+ function MyTable({ rows }) {
274
+ const _features = tableFeatures({ rowSortingFeature }) // new every render
275
+ const columns = [
276
+ /* … */
277
+ ] // new every render
278
+ const data = rows ?? [] // new [] every render
279
+ const table = useTable({ _features, _rowModels: {}, columns, data })
280
+ }
281
+ ```
282
+
283
+ Correct:
284
+
285
+ ```tsx
286
+ const _features = tableFeatures({ rowSortingFeature })
287
+ const columns: ColumnDef<typeof _features, Person>[] = [
288
+ /* … */
289
+ ]
290
+ const EMPTY: Person[] = []
291
+
292
+ function MyTable({ rows }) {
293
+ const data = rows ?? EMPTY
294
+ const table = useTable({ _features, _rowModels: {}, columns, data })
295
+ }
296
+ ```
297
+
298
+ Internal memos key off identity. Fresh references bust everything every render.
299
+ Source: `docs/framework/preact/guide/table-state.md` (FAQ #1).
300
+
301
+ ### HIGH Reimplementing built-in feature logic
302
+
303
+ Wrong:
304
+
305
+ ```tsx
306
+ const sorted = useMemo(() => [...data].sort(/* … */), [data, sorting]) // duplicates rowSortingFeature
307
+ ```
308
+
309
+ Correct:
310
+
311
+ ```tsx
312
+ const _features = tableFeatures({ rowSortingFeature })
313
+ const table = useTable({
314
+ _features,
315
+ _rowModels: { sortedRowModel: createSortedRowModel(sortFns) },
316
+ columns,
317
+ data,
318
+ })
319
+ const rows = table.getRowModel().rows // already sorted
320
+ ```
321
+
322
+ v9 ships built-ins for sorting, filtering, pagination, grouping, expanding, faceting, row selection, column visibility/order/pinning/sizing, and row pinning. Use them.
323
+ Source: `docs/guide/features.md`.
324
+
325
+ ### MEDIUM Using v8 hook names (`getCoreRowModel`, `useReactTable`, etc.)
326
+
327
+ Wrong:
328
+
329
+ ```tsx
330
+ import {
331
+ useReactTable,
332
+ getCoreRowModel,
333
+ getSortedRowModel,
334
+ } from '@tanstack/preact-table'
335
+ const table = useReactTable({
336
+ columns,
337
+ data,
338
+ getCoreRowModel: getCoreRowModel(),
339
+ getSortedRowModel: getSortedRowModel(),
340
+ })
341
+ ```
342
+
343
+ Correct:
344
+
345
+ ```tsx
346
+ import {
347
+ useTable,
348
+ tableFeatures,
349
+ rowSortingFeature,
350
+ createSortedRowModel,
351
+ sortFns,
352
+ } from '@tanstack/preact-table'
353
+
354
+ const _features = tableFeatures({ rowSortingFeature })
355
+
356
+ const table = useTable({
357
+ _features,
358
+ _rowModels: { sortedRowModel: createSortedRowModel(sortFns) },
359
+ columns,
360
+ data,
361
+ })
362
+ ```
363
+
364
+ v8 used `useReactTable` and `get*RowModel` options. v9 uses `useTable` plus `_features` + `_rowModels`. See `tanstack-table/preact/migrate-v8-to-v9` for the full mapping.
365
+ Source: `docs/framework/preact/preact-table.md`.
366
+
367
+ ## See Also
368
+
369
+ - `tanstack-table/preact/table-state` — atoms, Subscribe, createTableHook.
370
+ - `tanstack-table/preact/migrate-v8-to-v9` — moving an existing v8 codebase over.
371
+ - `tanstack-table/preact/production-readiness` — perf, tree-shaking, stable refs.
@@ -0,0 +1,322 @@
1
+ ---
2
+ name: preact/migrate-v8-to-v9
3
+ description: >
4
+ Mechanical breaking-change migration from TanStack Table v8 to v9 for
5
+ `@tanstack/preact-table`. Maps every old-shaped option, helper, type, and
6
+ method an agent will reproduce from v8 muscle memory to its v9 equivalent:
7
+ `useReactTable` → `useTable`, per-row-model `get*RowModel` options →
8
+ `_features` + `_rowModels`, plain column helpers → typed column helpers,
9
+ `state` + `on*Change` → `atoms`, `flexRender` → `table.FlexRender`, and core
10
+ type renames. Routing keywords: v8 to v9, migration, useReactTable, table
11
+ v8 preact, get*RowModel, _features.
12
+ type: lifecycle
13
+ library: tanstack-table
14
+ framework: preact
15
+ library_version: '9.0.0-alpha.48'
16
+ requires:
17
+ - setup
18
+ - state-management
19
+ - column-definitions
20
+ sources:
21
+ - TanStack/table:docs/framework/preact/preact-table.md
22
+ - TanStack/table:docs/framework/preact/guide/table-state.md
23
+ - TanStack/table:docs/framework/react/guide/use-legacy-table.md
24
+ - TanStack/table:packages/preact-table/src/useTable.ts
25
+ ---
26
+
27
+ The Preact adapter mirrors the React v9 surface, so any v8 → v9 migration guide for React applies almost line-for-line. There is no `useLegacyTable` shim in `@tanstack/preact-table` — migrate directly.
28
+
29
+ ## The Core Mapping
30
+
31
+ | v8 (Preact / React-compatible) | v9 (`@tanstack/preact-table`) |
32
+ | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33
+ | `useReactTable(opts)` | `useTable(opts, selector?)` |
34
+ | `getCoreRowModel: getCoreRowModel()` | included by default — `_rowModels: {}` is valid |
35
+ | `getSortedRowModel: getSortedRowModel()` | `_features: { rowSortingFeature }` + `_rowModels: { sortedRowModel: createSortedRowModel(sortFns) }` |
36
+ | `getFilteredRowModel: getFilteredRowModel()` | `_features: { columnFilteringFeature, globalFilteringFeature }` + `_rowModels: { filteredRowModel: createFilteredRowModel(filterFns) }` |
37
+ | `getPaginationRowModel: getPaginationRowModel()` | `_features: { rowPaginationFeature }` + `_rowModels: { paginatedRowModel: createPaginatedRowModel() }` |
38
+ | `getGroupedRowModel: getGroupedRowModel()` | `_features: { columnGroupingFeature }` + `_rowModels: { groupedRowModel: createGroupedRowModel(aggregationFns) }` |
39
+ | `getExpandedRowModel: getExpandedRowModel()` | `_features: { rowExpandingFeature }` + `_rowModels: { expandedRowModel: createExpandedRowModel() }` |
40
+ | `getFacetedRowModel`, `getFacetedUniqueValues`, `getFacetedMinMaxValues` | `_features: { columnFacetingFeature, globalFacetingFeature }` + `_rowModels: { facetedRowModel: createFacetedRowModel(facetedFns), facetedUniqueValues: createFacetedUniqueValues(), facetedMinMaxValues: createFacetedMinMaxValues() }` |
41
+ | `flexRender(def, ctx)` | `<table.FlexRender cell={cell} />` / `header={...}` / `footer={...}` |
42
+ | `state`, `on*Change` (only) | still supported, plus `atoms` (preferred per slice) |
43
+ | `createColumnHelper<TData>()` | `createColumnHelper<typeof _features, TData>()` — both generics required |
44
+ | `ColumnDef<TData, TValue>` | `ColumnDef<TFeatures, TData, TValue>` — `TFeatures` is now the first generic |
45
+ | `Table<TData>` | `Table<TFeatures, TData>` |
46
+
47
+ Source: `docs/framework/preact/preact-table.md`; `docs/framework/preact/guide/table-state.md`.
48
+
49
+ ## Migration Steps
50
+
51
+ ### 1. Update the package import
52
+
53
+ ```tsx
54
+ // v8
55
+ import {
56
+ useReactTable,
57
+ getCoreRowModel,
58
+ getSortedRowModel,
59
+ flexRender,
60
+ type ColumnDef,
61
+ } from '@tanstack/preact-table'
62
+
63
+ // v9
64
+ import {
65
+ useTable,
66
+ tableFeatures,
67
+ rowSortingFeature,
68
+ createSortedRowModel,
69
+ sortFns,
70
+ type ColumnDef,
71
+ } from '@tanstack/preact-table'
72
+ ```
73
+
74
+ ### 2. Declare `_features` and `_rowModels`
75
+
76
+ Replace each `get*RowModel: get*RowModel()` option with a feature import + a row-model factory.
77
+
78
+ ```tsx
79
+ // v8
80
+ const table = useReactTable({
81
+ columns,
82
+ data,
83
+ getCoreRowModel: getCoreRowModel(),
84
+ getSortedRowModel: getSortedRowModel(),
85
+ getFilteredRowModel: getFilteredRowModel(),
86
+ getPaginationRowModel: getPaginationRowModel(),
87
+ })
88
+
89
+ // v9
90
+ const _features = tableFeatures({
91
+ rowSortingFeature,
92
+ columnFilteringFeature,
93
+ rowPaginationFeature,
94
+ })
95
+
96
+ const table = useTable({
97
+ _features,
98
+ _rowModels: {
99
+ sortedRowModel: createSortedRowModel(sortFns),
100
+ filteredRowModel: createFilteredRowModel(filterFns),
101
+ paginatedRowModel: createPaginatedRowModel(),
102
+ },
103
+ columns,
104
+ data,
105
+ })
106
+ ```
107
+
108
+ Move `_features` to module scope. Reference stability matters — see `tanstack-table/preact/production-readiness`.
109
+
110
+ ### 3. Update column types and helpers
111
+
112
+ `TFeatures` is now the first generic on `ColumnDef`, `Table`, and `createColumnHelper`.
113
+
114
+ ```tsx
115
+ // v8
116
+ const columnHelper = createColumnHelper<Person>()
117
+ const columns: ColumnDef<Person>[] = columnHelper.columns([
118
+ /* … */
119
+ ])
120
+
121
+ // v9
122
+ const columnHelper = createColumnHelper<typeof _features, Person>()
123
+ const columns: Array<ColumnDef<typeof _features, Person>> =
124
+ columnHelper.columns([
125
+ /* … */
126
+ ])
127
+ ```
128
+
129
+ ### 4. Replace `flexRender` calls with `table.FlexRender`
130
+
131
+ ```tsx
132
+ // v8
133
+ <th>{flexRender(header.column.columnDef.header, header.getContext())}</th>
134
+ <td>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
135
+
136
+ // v9
137
+ <th>{header.isPlaceholder ? null : <table.FlexRender header={header} />}</th>
138
+ <td><table.FlexRender cell={cell} /></td>
139
+ ```
140
+
141
+ `flexRender` is still exported for advanced cases, but `table.FlexRender` (or the standalone `FlexRender` component) handles grouping placeholder/aggregated branches for you.
142
+
143
+ Source: `packages/preact-table/src/FlexRender.tsx`.
144
+
145
+ ### 5. Move external state to atoms (recommended)
146
+
147
+ `state` + `on*Change` still works, but v9 prefers slice atoms for fine-grained reactivity.
148
+
149
+ ```tsx
150
+ // v8 / v9 fallback
151
+ const [sorting, setSorting] = useState<SortingState>([])
152
+ const table = useTable({
153
+ _features,
154
+ _rowModels,
155
+ columns,
156
+ data,
157
+ state: { sorting },
158
+ onSortingChange: setSorting,
159
+ })
160
+
161
+ // v9 preferred — external atom
162
+ import { useCreateAtom } from '@tanstack/preact-store'
163
+ const sortingAtom = useCreateAtom<SortingState>([])
164
+ const table = useTable({
165
+ _features,
166
+ _rowModels,
167
+ columns,
168
+ data,
169
+ atoms: { sorting: sortingAtom },
170
+ // no onSortingChange needed
171
+ })
172
+ ```
173
+
174
+ Source: `examples/preact/basic-external-atoms/src/main.tsx`.
175
+
176
+ ### 6. Drop `onStateChange`
177
+
178
+ The v8-style global `onStateChange` is gone. Subscribe per-slice with `on*Change`, an external atom, or `table.store.subscribe(...)` if you really need every change.
179
+
180
+ Source: `docs/framework/preact/guide/table-state.md`.
181
+
182
+ ## Common Mistakes
183
+
184
+ ### CRITICAL Keeping `get*RowModel` options after upgrading
185
+
186
+ Wrong:
187
+
188
+ ```tsx
189
+ const table = useTable({
190
+ _features,
191
+ _rowModels: {},
192
+ columns,
193
+ data,
194
+ getSortedRowModel: getSortedRowModel(), // v8 leftover — silently ignored
195
+ })
196
+ table.setSorting([{ id: 'age', desc: true }]) // rows are NOT sorted
197
+ ```
198
+
199
+ Correct:
200
+
201
+ ```tsx
202
+ const _features = tableFeatures({ rowSortingFeature })
203
+ const table = useTable({
204
+ _features,
205
+ _rowModels: { sortedRowModel: createSortedRowModel(sortFns) },
206
+ columns,
207
+ data,
208
+ })
209
+ ```
210
+
211
+ v9 doesn't read the `get*RowModel` options. The row model only runs for stages registered in `_rowModels`, and the feature only mounts if it is in `_features`.
212
+ Source: `docs/framework/preact/preact-table.md`.
213
+
214
+ ### CRITICAL Forgetting to register a feature whose API you are calling
215
+
216
+ Wrong:
217
+
218
+ ```tsx
219
+ const _features = tableFeatures({}) // no rowSelectionFeature
220
+ const table = useTable({ _features, _rowModels: {}, columns, data })
221
+ table.getIsAllRowsSelected() // TypeScript error / runtime no-op
222
+ row.toggleSelected(true) // same
223
+ ```
224
+
225
+ Correct:
226
+
227
+ ```tsx
228
+ const _features = tableFeatures({ rowSelectionFeature })
229
+ const table = useTable({
230
+ _features,
231
+ _rowModels: {},
232
+ columns,
233
+ data,
234
+ enableRowSelection: true,
235
+ })
236
+ table.getIsAllRowsSelected()
237
+ ```
238
+
239
+ v9 generates feature APIs and state slices only for registered features. This is the #1 v9 trap.
240
+ Source: `docs/guide/features.md`.
241
+
242
+ ### HIGH Re-using `getCoreRowModel: getCoreRowModel()` from v8
243
+
244
+ Wrong:
245
+
246
+ ```tsx
247
+ const table = useTable({
248
+ _features,
249
+ _rowModels: {},
250
+ columns,
251
+ data,
252
+ getCoreRowModel: getCoreRowModel(), // no-op in v9
253
+ })
254
+ ```
255
+
256
+ Correct:
257
+
258
+ ```tsx
259
+ const table = useTable({ _features, _rowModels: {}, columns, data })
260
+ ```
261
+
262
+ The core row model is always included in v9. There is no `getCoreRowModel` option.
263
+ Source: `docs/framework/preact/preact-table.md`.
264
+
265
+ ### HIGH Single-generic column helper / `ColumnDef`
266
+
267
+ Wrong:
268
+
269
+ ```tsx
270
+ const columnHelper = createColumnHelper<Person>() // v8 shape
271
+ const columns: ColumnDef<Person>[] = [
272
+ /* … */
273
+ ] // v8 shape
274
+ ```
275
+
276
+ Correct:
277
+
278
+ ```tsx
279
+ const columnHelper = createColumnHelper<typeof _features, Person>()
280
+ const columns: Array<ColumnDef<typeof _features, Person>> = [
281
+ /* … */
282
+ ]
283
+ ```
284
+
285
+ `TFeatures` is the first generic for nearly every public type in v9. Without it, types degrade to `any` for feature methods.
286
+ Source: `docs/framework/preact/preact-table.md`.
287
+
288
+ ### HIGH Reimplementing built-ins (the #1 AI tell)
289
+
290
+ Wrong:
291
+
292
+ ```tsx
293
+ // Manual sorting, manual filtering, manual pagination, manual row-selection objects
294
+ ```
295
+
296
+ Correct: register the matching feature in `_features`, register its factory in `_rowModels`, and use the feature API. v9 ships built-ins for sorting, filtering, pagination, grouping, expanding, faceting, row selection, column visibility/order/pinning/sizing, and row pinning.
297
+ Source: `docs/guide/features.md`.
298
+
299
+ ### MEDIUM Calling `flexRender` directly when grouping is on
300
+
301
+ Wrong:
302
+
303
+ ```tsx
304
+ <td>{flexRender(cell.column.columnDef.cell, cell.getContext())}</td>
305
+ ```
306
+
307
+ Correct:
308
+
309
+ ```tsx
310
+ <td>
311
+ <table.FlexRender cell={cell} />
312
+ </td>
313
+ ```
314
+
315
+ `<table.FlexRender cell={...}>` handles aggregated / placeholder cells when `columnGroupingFeature` is registered. Raw `flexRender` does not.
316
+ Source: `packages/preact-table/src/FlexRender.tsx`.
317
+
318
+ ## See Also
319
+
320
+ - `tanstack-table/preact/getting-started` — green-field v9 setup.
321
+ - `tanstack-table/preact/table-state` — atom model and Subscribe patterns.
322
+ - `tanstack-table/preact/production-readiness` — perf, tree-shaking, stable refs.