@tanstack/table-core 9.0.0-beta.37 → 9.0.0-beta.42
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/core/headers/buildHeaderGroups.cjs.map +1 -1
- package/dist/core/headers/buildHeaderGroups.d.cts +1 -1
- package/dist/core/headers/buildHeaderGroups.d.ts +1 -1
- package/dist/core/headers/buildHeaderGroups.js.map +1 -1
- package/dist/core/headers/coreHeadersFeature.utils.cjs +7 -7
- package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
- package/dist/core/headers/coreHeadersFeature.utils.js +7 -7
- package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.cjs +1 -1
- package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.js +1 -1
- package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.types.d.cts +5 -5
- package/dist/features/column-ordering/columnOrderingFeature.types.d.ts +5 -5
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +6 -6
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.cts +3 -3
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.ts +3 -3
- package/dist/features/column-ordering/columnOrderingFeature.utils.js +6 -6
- package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.cjs +44 -39
- package/dist/features/column-pinning/columnPinningFeature.cjs.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.d.cts +6 -1
- package/dist/features/column-pinning/columnPinningFeature.d.ts +6 -1
- package/dist/features/column-pinning/columnPinningFeature.js +45 -40
- package/dist/features/column-pinning/columnPinningFeature.js.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.types.d.cts +49 -38
- package/dist/features/column-pinning/columnPinningFeature.types.d.ts +49 -38
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs +154 -146
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.utils.d.cts +81 -73
- package/dist/features/column-pinning/columnPinningFeature.utils.d.ts +81 -73
- package/dist/features/column-pinning/columnPinningFeature.utils.js +141 -133
- package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.cjs +4 -4
- package/dist/features/column-sizing/columnSizingFeature.cjs.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.js +5 -5
- package/dist/features/column-sizing/columnSizingFeature.js.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.types.d.cts +18 -12
- package/dist/features/column-sizing/columnSizingFeature.types.d.ts +18 -12
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs +24 -20
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.utils.d.cts +18 -14
- package/dist/features/column-sizing/columnSizingFeature.utils.d.ts +18 -14
- package/dist/features/column-sizing/columnSizingFeature.utils.js +24 -20
- package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +16 -16
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.cts +3 -3
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.ts +3 -3
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js +16 -16
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
- package/dist/static-functions.cjs +16 -16
- package/dist/static-functions.d.cts +3 -3
- package/dist/static-functions.d.ts +3 -3
- package/dist/static-functions.js +3 -3
- package/package.json +1 -1
- package/skills/api-not-found/SKILL.md +113 -0
- package/skills/client-vs-server/SKILL.md +164 -0
- package/skills/column-faceting/SKILL.md +91 -0
- package/skills/column-filtering/SKILL.md +82 -0
- package/skills/column-ordering/SKILL.md +75 -0
- package/skills/column-pinning/SKILL.md +89 -0
- package/skills/column-resizing/SKILL.md +91 -0
- package/skills/column-sizing/SKILL.md +72 -0
- package/skills/column-visibility/SKILL.md +75 -0
- package/skills/core/SKILL.md +140 -0
- package/skills/custom-features/SKILL.md +207 -0
- package/skills/expanding/SKILL.md +80 -0
- package/skills/global-filtering/SKILL.md +84 -0
- package/skills/grouping/SKILL.md +50 -394
- package/skills/migrate-v8-to-v9/SKILL.md +230 -390
- package/skills/pagination/SKILL.md +35 -344
- package/skills/row-pinning/SKILL.md +47 -238
- package/skills/row-selection/SKILL.md +39 -351
- package/skills/sorting/SKILL.md +35 -299
- package/skills/table-features/SKILL.md +153 -0
- package/skills/typescript/SKILL.md +126 -0
- package/src/core/headers/buildHeaderGroups.ts +1 -1
- package/src/core/headers/coreHeadersFeature.utils.ts +7 -7
- package/src/core/table/coreTablesFeature.utils.ts +1 -1
- package/src/features/column-ordering/columnOrderingFeature.types.ts +5 -5
- package/src/features/column-ordering/columnOrderingFeature.utils.ts +9 -9
- package/src/features/column-pinning/columnPinningFeature.ts +64 -59
- package/src/features/column-pinning/columnPinningFeature.types.ts +49 -38
- package/src/features/column-pinning/columnPinningFeature.utils.ts +163 -155
- package/src/features/column-sizing/columnSizingFeature.ts +6 -6
- package/src/features/column-sizing/columnSizingFeature.types.ts +18 -12
- package/src/features/column-sizing/columnSizingFeature.utils.ts +31 -27
- package/src/features/column-visibility/columnVisibilityFeature.utils.ts +15 -15
- package/skills/column-definitions/SKILL.md +0 -330
- package/skills/column-layout/SKILL.md +0 -326
- package/skills/column-layout/references/subsystems.md +0 -220
- package/skills/customizing-feature-behavior/SKILL.md +0 -423
- package/skills/filtering/SKILL.md +0 -375
- package/skills/filtering/references/faceting-and-fuzzy.md +0 -218
- package/skills/row-expanding/SKILL.md +0 -356
- package/skills/setup/SKILL.md +0 -390
- package/skills/state-management/SKILL.md +0 -403
|
@@ -1,273 +1,82 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: row-pinning
|
|
3
3
|
description: >
|
|
4
|
-
Pin
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
Sorting.
|
|
13
|
-
type: core
|
|
14
|
-
library: tanstack-table
|
|
15
|
-
library_version: '9.0.0-alpha.48'
|
|
16
|
-
requires:
|
|
17
|
-
- state-management
|
|
4
|
+
Pin stable row IDs into top, center, and bottom collections with rowPinningFeature and keepPinnedRows. Load for filtering/pagination visibility, explicit region rendering, or renderer-owned sticky CSS.
|
|
5
|
+
metadata:
|
|
6
|
+
{
|
|
7
|
+
type: sub-skill,
|
|
8
|
+
library: '@tanstack/table-core',
|
|
9
|
+
library_version: '9.0.0-beta.42',
|
|
10
|
+
}
|
|
11
|
+
requires: ['core', 'table-features']
|
|
18
12
|
sources:
|
|
19
|
-
- TanStack/table:docs/guide/row-pinning.md
|
|
20
|
-
- TanStack/table:packages/table-core/src/features/row-pinning
|
|
21
|
-
- TanStack/table:examples/react/row-pinning
|
|
13
|
+
- 'TanStack/table:docs/framework/react/guide/row-pinning.md'
|
|
14
|
+
- 'TanStack/table:packages/table-core/src/features/row-pinning'
|
|
15
|
+
- 'TanStack/table:examples/react/row-pinning'
|
|
22
16
|
---
|
|
23
17
|
|
|
24
|
-
This skill builds on `
|
|
18
|
+
This skill builds on `core` and `table-features`. Pinning creates row regions; the renderer controls order and sticky layout.
|
|
25
19
|
|
|
26
20
|
## Setup
|
|
27
21
|
|
|
28
22
|
```ts
|
|
29
|
-
import {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const features = tableFeatures({
|
|
39
|
-
rowPinningFeature,
|
|
40
|
-
rowPaginationFeature,
|
|
41
|
-
paginatedRowModel: createPaginatedRowModel(),
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
const table = constructTable({
|
|
45
|
-
features,
|
|
46
|
-
columns,
|
|
47
|
-
data,
|
|
48
|
-
getRowId: (row) => row.userId, // ← essentially mandatory
|
|
49
|
-
initialState: {
|
|
50
|
-
rowPinning: { top: [], bottom: [] } satisfies RowPinningState,
|
|
51
|
-
},
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
// Pin a row
|
|
55
|
-
row.pin('top') // or 'bottom' | false
|
|
23
|
+
import { rowPinningFeature, tableFeatures } from '@tanstack/table-core'
|
|
24
|
+
|
|
25
|
+
type Person = { id: string; name: string }
|
|
26
|
+
export const features = tableFeatures({ rowPinningFeature })
|
|
27
|
+
export const options = {
|
|
28
|
+
getRowId: (row: Person) => row.id,
|
|
29
|
+
keepPinnedRows: true,
|
|
30
|
+
}
|
|
56
31
|
```
|
|
57
32
|
|
|
58
33
|
## Core Patterns
|
|
59
34
|
|
|
60
|
-
### Pin/unpin buttons in a cell
|
|
61
|
-
|
|
62
|
-
```tsx
|
|
63
|
-
// From examples/react/row-pinning/src/main.tsx
|
|
64
|
-
<button onClick={() => row.pin('top')} disabled={!row.getCanPin()}>📌⬆</button>
|
|
65
|
-
<button onClick={() => row.pin('bottom')} disabled={!row.getCanPin()}>📌⬇</button>
|
|
66
|
-
{row.getIsPinned() && <button onClick={() => row.pin(false)}>✖ Unpin</button>}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
For grouped/expanded data, pass include flags:
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
row.pin('top', /* includeLeafRows */ true, /* includeParentRows */ false)
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Render pinned rows separately
|
|
76
|
-
|
|
77
|
-
```tsx
|
|
78
|
-
<tbody>
|
|
79
|
-
{table.getTopRows().map((row) => (
|
|
80
|
-
<PinnedRow key={row.id} row={row} table={table} />
|
|
81
|
-
))}
|
|
82
|
-
{table.getCenterRows().map((row) => (
|
|
83
|
-
<tr key={row.id}>
|
|
84
|
-
{row.getAllCells().map((cell) => (
|
|
85
|
-
<td key={cell.id}>
|
|
86
|
-
<table.FlexRender cell={cell} />
|
|
87
|
-
</td>
|
|
88
|
-
))}
|
|
89
|
-
</tr>
|
|
90
|
-
))}
|
|
91
|
-
{table.getBottomRows().map((row) => (
|
|
92
|
-
<PinnedRow key={row.id} row={row} table={table} />
|
|
93
|
-
))}
|
|
94
|
-
</tbody>
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Disable persistence across pagination
|
|
98
|
-
|
|
99
35
|
```ts
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}),
|
|
107
|
-
columns,
|
|
108
|
-
data,
|
|
109
|
-
getRowId: (row) => row.id,
|
|
110
|
-
keepPinnedRows: false, // pinned rows disappear when filtered/paginated out
|
|
111
|
-
})
|
|
36
|
+
const regions = [
|
|
37
|
+
table.getTopRows(),
|
|
38
|
+
table.getCenterRows(),
|
|
39
|
+
table.getBottomRows(),
|
|
40
|
+
]
|
|
41
|
+
for (const rows of regions) rows.forEach(renderRow)
|
|
112
42
|
```
|
|
113
43
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
### Conditional pin permission
|
|
117
|
-
|
|
118
|
-
```ts
|
|
119
|
-
const table = constructTable({
|
|
120
|
-
features,
|
|
121
|
-
columns,
|
|
122
|
-
data,
|
|
123
|
-
enableRowPinning: (row) => !row.original.archived, // predicate form
|
|
124
|
-
})
|
|
125
|
-
```
|
|
44
|
+
Render each region explicitly if the visual order matters.
|
|
126
45
|
|
|
127
46
|
## Common Mistakes
|
|
128
47
|
|
|
129
|
-
### [HIGH]
|
|
130
|
-
|
|
131
|
-
Wrong:
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
// row.id defaults to row.index; pin survives wrong rows after refetch
|
|
135
|
-
const table = useTable({
|
|
136
|
-
features: tableFeatures({ rowPinningFeature, rowPaginationFeature }),
|
|
137
|
-
data, // refetched periodically
|
|
138
|
-
})
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Correct:
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
|
-
const table = useTable({
|
|
145
|
-
features: tableFeatures({ rowPinningFeature, rowPaginationFeature }),
|
|
146
|
-
data,
|
|
147
|
-
getRowId: (row) => row.userId, // or row.uuid, row.id from API, etc.
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
// For grouped/expanded data, pass the include flags too:
|
|
151
|
-
row.pin('top', includeLeafRows, includeParentRows)
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
`rowPinning.top` and `rowPinning.bottom` are arrays of string row ids. Default `row.id` is the data array index — refetched data reuses index 3 for a different record, but the pinning state still pins index 3.
|
|
155
|
-
|
|
156
|
-
Source: docs/guide/row-selection.md (same root principle); examples/react/row-pinning/src/main.tsx
|
|
157
|
-
|
|
158
|
-
### [MEDIUM] Surprise behavior from `keepPinnedRows: true` default
|
|
159
|
-
|
|
160
|
-
Wrong:
|
|
161
|
-
|
|
162
|
-
```ts
|
|
163
|
-
// Expecting pinned rows to vanish on filter, but they don't (default)
|
|
164
|
-
const table = useTable({
|
|
165
|
-
features: tableFeatures({ rowPinningFeature, columnFilteringFeature }),
|
|
166
|
-
// keepPinnedRows defaults to true; pinned rows survive filtering
|
|
167
|
-
})
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Correct:
|
|
171
|
-
|
|
172
|
-
```ts
|
|
173
|
-
// Be explicit about the UX you want
|
|
174
|
-
const table = useTable({
|
|
175
|
-
features: tableFeatures({ rowPinningFeature, columnFilteringFeature }),
|
|
176
|
-
keepPinnedRows: false, // pinned rows disappear when filtered/paginated out
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
// Or keep the default and render pinned separately:
|
|
180
|
-
<tbody>
|
|
181
|
-
{table.getTopRows().map((row) => <PinnedRow row={row} key={row.id} />)}
|
|
182
|
-
{table.getCenterRows().map((row) => <Row row={row} key={row.id} />)}
|
|
183
|
-
{table.getBottomRows().map((row) => <PinnedRow row={row} key={row.id} />)}
|
|
184
|
-
</tbody>
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
`keepPinnedRows: true` makes `getTopRows()` / `getBottomRows()` search the full pre-pagination row set; `false` only finds rows currently in the row model.
|
|
188
|
-
|
|
189
|
-
Source: packages/table-core/src/features/row-pinning/rowPinningFeature.utils.ts; examples/react/row-pinning/src/main.tsx
|
|
190
|
-
|
|
191
|
-
### [MEDIUM] Rendering pinned rows TWICE (once at top/bottom, once in main flow)
|
|
48
|
+
### [HIGH] Persisting index-based IDs
|
|
192
49
|
|
|
193
|
-
Wrong:
|
|
50
|
+
Wrong: `const options = { getRowId: (_row: Person, index: number) => String(index) }`
|
|
194
51
|
|
|
195
|
-
|
|
196
|
-
<tbody>
|
|
197
|
-
{table.getTopRows().map((row) => (
|
|
198
|
-
<PinnedRow row={row} key={row.id} />
|
|
199
|
-
))}
|
|
200
|
-
{table.getRowModel().rows.map(
|
|
201
|
-
(
|
|
202
|
-
row, // ← still includes pinned rows
|
|
203
|
-
) => (
|
|
204
|
-
<tr key={row.id}>...</tr>
|
|
205
|
-
),
|
|
206
|
-
)}
|
|
207
|
-
{table.getBottomRows().map((row) => (
|
|
208
|
-
<PinnedRow row={row} key={row.id} />
|
|
209
|
-
))}
|
|
210
|
-
</tbody>
|
|
211
|
-
```
|
|
52
|
+
Correct: `const options = { getRowId: (row: Person) => row.id }`
|
|
212
53
|
|
|
213
|
-
|
|
54
|
+
Indexes change under sorting, filtering, pagination, and insertion.
|
|
214
55
|
|
|
215
|
-
|
|
216
|
-
<tbody>
|
|
217
|
-
{table.getTopRows().map((row) => (
|
|
218
|
-
<PinnedRow key={row.id} row={row} table={table} />
|
|
219
|
-
))}
|
|
220
|
-
{table.getCenterRows().map((row) => (
|
|
221
|
-
<tr key={row.id}>
|
|
222
|
-
{row.getAllCells().map((cell) => (
|
|
223
|
-
<td key={cell.id}>
|
|
224
|
-
<table.FlexRender cell={cell} />
|
|
225
|
-
</td>
|
|
226
|
-
))}
|
|
227
|
-
</tr>
|
|
228
|
-
))}
|
|
229
|
-
{table.getBottomRows().map((row) => (
|
|
230
|
-
<PinnedRow key={row.id} row={row} table={table} />
|
|
231
|
-
))}
|
|
232
|
-
</tbody>
|
|
233
|
-
```
|
|
56
|
+
Source: `docs/framework/react/guide/row-pinning.md`
|
|
234
57
|
|
|
235
|
-
|
|
58
|
+
### [HIGH] Expecting sticky rows automatically
|
|
236
59
|
|
|
237
|
-
|
|
60
|
+
Wrong: `row.pin('top')`
|
|
238
61
|
|
|
239
|
-
|
|
62
|
+
Correct: `topRowElement.style.position = 'sticky'`
|
|
240
63
|
|
|
241
|
-
|
|
64
|
+
Pinning state does not style or place DOM elements.
|
|
242
65
|
|
|
243
|
-
|
|
244
|
-
// Hand-rolled "pinned" map + manual filter on render
|
|
245
|
-
const [pinned, setPinned] = useState<Record<string, true>>({})
|
|
246
|
-
const pinnedRows = rows.filter((r) => pinned[r.id])
|
|
247
|
-
const otherRows = rows.filter((r) => !pinned[r.id])
|
|
248
|
-
```
|
|
66
|
+
Source: `examples/react/row-pinning/src/main.tsx`
|
|
249
67
|
|
|
250
|
-
|
|
68
|
+
## Choose the pinned-row visibility policy
|
|
251
69
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
getRowId: (row) => row.id,
|
|
258
|
-
})
|
|
70
|
+
- `keepPinnedRows: true` is the default. Pinned rows stay visible in their
|
|
71
|
+
pinned region even when filtering or pagination removes them from the center
|
|
72
|
+
row model.
|
|
73
|
+
- `keepPinnedRows: false` limits pinned rows to those present in the current
|
|
74
|
+
filtered and paginated row model.
|
|
259
75
|
|
|
260
|
-
|
|
261
|
-
table.setRowPinning({ top: ['a', 'b'], bottom: [] }) // bulk set
|
|
262
|
-
table.getTopRows()
|
|
263
|
-
table.getCenterRows()
|
|
264
|
-
table.getBottomRows()
|
|
265
|
-
```
|
|
76
|
+
Choose explicitly based on product behavior; neither value is inherently wrong.
|
|
266
77
|
|
|
267
|
-
Source:
|
|
78
|
+
Source: `packages/table-core/src/features/row-pinning/rowPinningFeature.types.ts`
|
|
268
79
|
|
|
269
|
-
##
|
|
80
|
+
## API Discovery
|
|
270
81
|
|
|
271
|
-
|
|
272
|
-
- `tanstack-table/row-selection` — same `getRowId` stability concern
|
|
273
|
-
- `tanstack-table/column-layout` — column pinning sits in a separate, more complex pipeline
|
|
82
|
+
Inspect `node_modules/@tanstack/table-core/src/features/row-pinning/` for region getters, row APIs, and `keepPinnedRows` semantics.
|