Skip to content

Commit 15a425a

Browse files
authored
feat: Row Pinning (#5074)
* recreate row pinning feature, example and docs * upgrade example version * default keepPinnedRows to true * add some row pinning unit tests * add row pinning example to config
1 parent 057563f commit 15a425a

File tree

19 files changed

+1211
-34
lines changed

19 files changed

+1211
-34
lines changed

docs/api/features/column-pinning.md docs/api/features/pinning.md

+129-3
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,44 @@
11
---
2-
title: Column Pinning
3-
id: column-pinning
2+
title: Pinning
3+
id: pinning
44
---
55

66
## Can-Pin
77

88
The ability for a column to be **pinned** is determined by the following:
99

1010
- `options.enablePinning` is not set to `false`
11+
- `options.enableColumnPinning` is not set to `false`
1112
- `columnDefinition.enablePinning` is not set to `false`
1213

14+
The ability for a row to be **pinned** is determined by the following:
15+
16+
- `options.enableRowPinning` resolves to `true`
17+
- `options.enablePinning` is not set to `false`
18+
1319
## State
1420

15-
Column pinning state is stored on the table using the following shape:
21+
Pinning state is stored on the table using the following shape:
1622

1723
```tsx
1824
export type ColumnPinningPosition = false | 'left' | 'right'
25+
export type RowPinningPosition = false | 'top' | 'bottom'
1926

2027
export type ColumnPinningState = {
2128
left?: string[]
2229
right?: string[]
2330
}
31+
export type RowPinningState = {
32+
top?: boolean
33+
bottom?: boolean
34+
}
2435

2536
export type ColumnPinningTableState = {
2637
columnPinning: ColumnPinningState
2738
}
39+
export type RowPinningRowState = {
40+
rowPinning: RowPinningState
41+
}
2842
```
2943
3044
## Table Options
@@ -37,6 +51,30 @@ enablePinning?: boolean
3751
3852
Enables/disables all pinning for the table.
3953
54+
### `enableColumnPinning`
55+
56+
```tsx
57+
enableColumnPinning?: boolean
58+
```
59+
60+
Enables/disables column pinning for all columns in the table.
61+
62+
### `enableRowPinning`
63+
64+
```tsx
65+
enableRowPinning?: boolean | ((row: Row<TData>) => boolean)
66+
```
67+
68+
Enables/disables row pinning for all rows in the table.
69+
70+
### `keepPinnedRows`
71+
72+
```tsx
73+
keepPinnedRows?: boolean
74+
```
75+
76+
When `false`, pinned rows will not be visible if they are filtered or paginated out of the table. When `true`, pinned rows will always be visible regardless of filtering or pagination. Defaults to `true`.
77+
4078
### `onColumnPinningChange`
4179
4280
```tsx
@@ -45,6 +83,14 @@ onColumnPinningChange?: OnChangeFn<ColumnPinningState>
4583
4684
If provided, this function will be called with an `updaterFn` when `state.columnPinning` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
4785
86+
### `onRowPinningChange`
87+
88+
```tsx
89+
onRowPinningChange?: OnChangeFn<RowPinningState>
90+
```
91+
92+
If provided, this function will be called with an `updaterFn` when `state.rowPinning` changes. This overrides the default internal state management, so you will need to persist the state change either fully or partially outside of the table.
93+
4894
## Column Def Options
4995
5096
### `enablePinning`
@@ -65,6 +111,14 @@ setColumnPinning: (updater: Updater<ColumnPinningState>) => void
65111
66112
Sets or updates the `state.columnPinning` state.
67113
114+
### `setRowPinning`
115+
116+
```tsx
117+
setRowPinning: (updater: Updater<RowPinningState>) => void
118+
```
119+
120+
Sets or updates the `state.rowPinning` state.
121+
68122
### `resetColumnPinning`
69123
70124
```tsx
@@ -73,6 +127,14 @@ resetColumnPinning: (defaultState?: boolean) => void
73127
74128
Resets the **columnPinning** state to `initialState.columnPinning`, or `true` can be passed to force a default blank state reset to `{ left: [], right: [], }`.
75129
130+
### `resetRowPinning`
131+
132+
```tsx
133+
resetRowPinning: (defaultState?: boolean) => void
134+
```
135+
136+
Resets the **rowPinning** state to `initialState.rowPinning`, or `true` can be passed to force a default blank state reset to `{}`.
137+
76138
### `getIsSomeColumnsPinned`
77139
78140
```tsx
@@ -83,6 +145,14 @@ Returns whether or not any columns are pinned. Optionally specify to only check
83145
84146
_Note: Does not account for column visibility_
85147
148+
### `getIsSomeRowsPinned`
149+
150+
```tsx
151+
getIsSomeRowsPinned: (position?: RowPinningPosition) => boolean
152+
```
153+
154+
Returns whether or not any rows are pinned. Optionally specify to only check for pinned rows in either the `top` or `bottom` position.
155+
86156
### `getLeftHeaderGroups`
87157
88158
```tsx
@@ -203,6 +273,30 @@ getCenterLeafColumns: () => Column < TData > []
203273
204274
Returns all center pinned (unpinned) leaf columns.
205275
276+
### `getTopRows`
277+
278+
```tsx
279+
getTopRows: () => Row < TData > []
280+
```
281+
282+
Returns all top pinned rows.
283+
284+
### `getBottomRows`
285+
286+
```tsx
287+
getBottomRows: () => Row < TData > []
288+
```
289+
290+
Returns all bottom pinned rows.
291+
292+
### `getCenterRows`
293+
294+
```tsx
295+
getCenterRows: () => Row < TData > []
296+
```
297+
298+
Returns all rows that are not pinned to the top or bottom.
299+
206300
## Column API
207301
208302
### `getCanPin`
@@ -239,6 +333,38 @@ Pins a column to the `'left'` or `'right'`, or unpins the column to the center i
239333
240334
## Row API
241335
336+
### `pin`
337+
338+
```tsx
339+
pin: (position: RowPinningPosition) => void
340+
```
341+
342+
Pins a row to the `'top'` or `'bottom'`, or unpins the row to the center if `false` is passed.
343+
344+
### `getCanPin`
345+
346+
```tsx
347+
getCanPin: () => boolean
348+
```
349+
350+
Returns whether or not the row can be pinned.
351+
352+
### `getIsPinned`
353+
354+
```tsx
355+
getIsPinned: () => RowPinningPosition
356+
```
357+
358+
Returns the pinned position of the row. (`'top'`, `'bottom'` or `false`)
359+
360+
### `getPinnedIndex`
361+
362+
```tsx
363+
getPinnedIndex: () => number
364+
```
365+
366+
Returns the numeric pinned index of the row within a pinned row group.
367+
242368
### `getLeftVisibleCells`
243369
244370
```tsx

docs/config.json

+13-9
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,6 @@
7777
"label": "Column Ordering",
7878
"to": "guide/column-ordering"
7979
},
80-
{
81-
"label": "Column Pinning",
82-
"to": "guide/column-pinning"
83-
},
8480
{
8581
"label": "Column Sizing",
8682
"to": "guide/column-sizing"
@@ -109,6 +105,10 @@
109105
"label": "Pagination",
110106
"to": "guide/pagination"
111107
},
108+
{
109+
"label": "Pinning",
110+
"to": "guide/pinning"
111+
},
112112
{
113113
"label": "Row Selection",
114114
"to": "guide/row-selection"
@@ -155,10 +155,6 @@
155155
"label": "Column Ordering",
156156
"to": "api/features/column-ordering"
157157
},
158-
{
159-
"label": "Column Pinning",
160-
"to": "api/features/column-pinning"
161-
},
162158
{
163159
"label": "Column Sizing",
164160
"to": "api/features/column-sizing"
@@ -187,6 +183,10 @@
187183
"label": "Pagination",
188184
"to": "api/features/pagination"
189185
},
186+
{
187+
"label": "Pinning",
188+
"to": "api/features/pinning"
189+
},
190190
{
191191
"label": "Row Selection",
192192
"to": "api/features/row-selection"
@@ -269,6 +269,10 @@
269269
"to": "examples/react/row-dnd",
270270
"label": "Row DnD"
271271
},
272+
{
273+
"to": "examples/react/row-pinning",
274+
"label": "Row Pinning"
275+
},
272276
{
273277
"to": "examples/react/row-selection",
274278
"label": "Row Selection"
@@ -396,4 +400,4 @@
396400
]
397401
}
398402
]
399-
}
403+
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
---
2-
title: Column Pinning
2+
title: Pinning
33
---
44

55
## Examples
66

77
Want to skip to the implementation? Check out these examples:
88

99
- [column-pinning](../examples/react/column-pinning)
10+
- [row-pinning](../examples/react/row-pinning)
1011

1112
## API
1213

13-
[Column Pinning API](../api/features/column-pinning)
14+
[Pinning API](../api/features/pinning)
1415

1516
## Overview
1617

@@ -19,3 +20,8 @@ There are 3 table features that can reorder columns, which happen in the followi
1920
1. **Column Pinning** - If pinning, columns are split into left, center (unpinned), and right pinned columns.
2021
2. Manual [Column Ordering](../guide/column-ordering) - A manually specified column order is applied.
2122
3. [Grouping](../guide/grouping) - If grouping is enabled, a grouping state is active, and `tableOptions.columnGroupingMode` is set to `'reorder' | 'remove'`, then the grouped columns are reordered to the start of the column flow.
23+
24+
There are 2 table features that can reorder rows, which happen in the following order:
25+
26+
1. **Row Pinning** - If pinning, rows are split into top, center (unpinned), and bottom pinned rows.
27+
2. [Sorting](../guide/sorting)

examples/react/row-pinning/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local

examples/react/row-pinning/README.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Example
2+
3+
To run this example:
4+
5+
- `npm install` or `yarn`
6+
- `npm run start` or `yarn start`

examples/react/row-pinning/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Vite App</title>
7+
<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "tanstack-table-example-row-pinning",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"serve": "vite preview --port 3000",
9+
"start": "vite"
10+
},
11+
"dependencies": {
12+
"@faker-js/faker": "^8.0.2",
13+
"@tanstack/react-table": "8.9.11",
14+
"react": "^18.2.0",
15+
"react-dom": "^18.2.0"
16+
},
17+
"devDependencies": {
18+
"@rollup/plugin-replace": "^5.0.1",
19+
"@vitejs/plugin-react": "^2.2.0",
20+
"vite": "^3.2.3"
21+
}
22+
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
html {
2+
font-family: sans-serif;
3+
font-size: 14px;
4+
}
5+
6+
table {
7+
border: 1px solid lightgray;
8+
}
9+
10+
tbody {
11+
border-bottom: 1px solid lightgray;
12+
}
13+
14+
th {
15+
border-bottom: 1px solid lightgray;
16+
border-right: 1px solid lightgray;
17+
padding: 2px 4px;
18+
}
19+
20+
td {
21+
border-right: 1px solid lightgray;
22+
padding: 2px 4px;
23+
}
24+
25+
td:last-child {
26+
border-right: 0;
27+
}
28+
29+
tfoot {
30+
color: gray;
31+
}
32+
33+
tfoot th {
34+
font-weight: normal;
35+
}

0 commit comments

Comments
 (0)