@jielga/tmdatagrid 2.0.0-beta.9 → 2.0.0
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 +5 -212
- package/dist/index.d.ts +1281 -768
- package/dist/index.js +4607 -3250
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/adding-rows.md +132 -0
- package/docs/anatomy.md +119 -0
- package/docs/card-view.md +108 -0
- package/docs/cell-selection.md +194 -0
- package/docs/column-layout.md +182 -0
- package/docs/column-menu.md +66 -0
- package/docs/columns.md +268 -0
- package/docs/components.md +311 -0
- package/docs/draft-store.md +242 -0
- package/docs/editing.md +303 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +319 -0
- package/docs/filtering.md +362 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/migrating-to-2.md +163 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +114 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +179 -0
- package/docs/quick-search.md +84 -0
- package/docs/row-details.md +115 -0
- package/docs/row-interaction.md +149 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +136 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +112 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +744 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +22 -46
- package/skills/appearance/SKILL.md +72 -19
- package/skills/cell-selection/SKILL.md +46 -47
- package/skills/columns/SKILL.md +90 -34
- package/skills/data/SKILL.md +86 -16
- package/skills/editing/SKILL.md +67 -40
- package/skills/editing/references/common-mistakes.md +77 -69
- package/skills/editing/references/editing-api.md +22 -19
- package/skills/editing/references/editors-and-validation.md +24 -17
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +17 -15
- package/skills/grouping/SKILL.md +31 -16
- package/skills/options/SKILL.md +7 -7
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +150 -32
- package/skills/testing-components/SKILL.md +230 -0
- package/skills/testing-editing/SKILL.md +240 -0
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +38 -21
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +54 -8
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +5 -51
- package/src/{tmdatagrid/components → components}/TMDataGridDraftActions.tsx +41 -24
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +12 -59
- package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +164 -92
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/components/TMDataGridFilterPanel.module.css +54 -0
- package/src/components/TMDataGridFilterPanel.tsx +348 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +15 -8
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -90
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +5 -69
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +12 -2
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +58 -21
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +357 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +11 -48
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +69 -56
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +240 -138
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.module.css +5 -0
- package/src/components/TMDataGridToolbar.tsx +181 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridNumberEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +16 -2
- package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
- package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
- package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
- package/src/components/filters/controlLayout.ts +32 -0
- package/src/components/filters/filterControlFor.ts +65 -0
- package/src/components/generatedColumns.tsx +187 -0
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
- package/src/components/useHideableColumns.ts +52 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/columnOptions.ts +60 -8
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/{tmdatagrid/core → core}/editEngine.ts +1107 -460
- package/src/core/export.ts +704 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
- package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
- package/src/core/filterSurface.ts +99 -0
- package/src/{tmdatagrid/core → core}/grouping.ts +21 -0
- package/src/{tmdatagrid/core → core}/labels.ts +51 -6
- package/src/{tmdatagrid/core → core}/labelsSv.ts +27 -6
- package/src/core/pageReset.ts +120 -0
- package/src/core/pagination.ts +81 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/{tmdatagrid/core → core}/summary.ts +20 -4
- package/src/{tmdatagrid/index.ts → index.ts} +69 -35
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +428 -109
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -161
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- /package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/core → core}/capabilities.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/controlledState.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/editorFocus.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/resizePreview.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
- /package/src/{tmdatagrid/core → core}/useSettledTableState.ts +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Clicks and context menus
|
|
2
|
+
|
|
3
|
+
Handling clicks in the body: a row click, a cell click, a double-click, and a
|
|
4
|
+
right-click for a menu.
|
|
5
|
+
|
|
6
|
+
Every handler here **composes** with what the click already does. Setting
|
|
7
|
+
`onRowClick` does not replace selection or the highlight; both still happen,
|
|
8
|
+
and your handler runs as well.
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
<TMDataGrid.Table<Employee> onRowClick={(row) => open(row.original.id)} />
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Pass the row type, as above, and `row.original` is typed.
|
|
15
|
+
|
|
16
|
+
```demo
|
|
17
|
+
file: rows/ClickAndContextMenu.tsx
|
|
18
|
+
hint: Click, double-click and right-click anywhere in the body.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## The click handlers
|
|
22
|
+
|
|
23
|
+
| Prop | Argument | Notes |
|
|
24
|
+
| --- | --- | --- |
|
|
25
|
+
| `onRowClick` | `row` | Rows show a pointer cursor when set. |
|
|
26
|
+
| `onCellClick` | `{ cell, row, column, event }` | The cell cursor still moves. |
|
|
27
|
+
| `onCellDoubleClick` | same | A double-click that opens an editor still does. |
|
|
28
|
+
| `onCellContextMenu` | same | `renderRowContextMenu` and the cell-selection menu still open. |
|
|
29
|
+
|
|
30
|
+
None of the four fires on a group row: a group row is built on its first
|
|
31
|
+
child's record rather than on one of its own.
|
|
32
|
+
|
|
33
|
+
## Context menus
|
|
34
|
+
|
|
35
|
+
Right-clicking a row opens a Mantine `Menu` at the pointer. The grid renders the
|
|
36
|
+
`Menu` and its `Menu.Dropdown`, opens it at the cursor, and closes it on Escape,
|
|
37
|
+
on an outside click, on a body scroll, and after an item is picked. The render
|
|
38
|
+
prop supplies only the contents, so anything valid in a dropdown works:
|
|
39
|
+
`Menu.Item`, `Menu.Label`, `Menu.Divider`, `Menu.Sub`, or your own components.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
<TMDataGrid.Table<Employee>
|
|
43
|
+
renderRowContextMenu={({ row, cell }) => (
|
|
44
|
+
<>
|
|
45
|
+
<Menu.Label>{row.original.firstName}</Menu.Label>
|
|
46
|
+
<Menu.Item onClick={() => open(row.original.id)}>Open</Menu.Item>
|
|
47
|
+
<Menu.Item
|
|
48
|
+
onClick={() =>
|
|
49
|
+
navigator.clipboard.writeText(String(cell?.getValue() ?? ""))
|
|
50
|
+
}
|
|
51
|
+
>
|
|
52
|
+
Copy cell value
|
|
53
|
+
</Menu.Item>
|
|
54
|
+
<Menu.Divider />
|
|
55
|
+
<Menu.Item color="red" onClick={() => remove(row.original.id)}>
|
|
56
|
+
Delete
|
|
57
|
+
</Menu.Item>
|
|
58
|
+
</>
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Argument | Type | Description |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `table` | `Table<TMDataGridFeatures, TData>` | For actions that read wider state, such as `getSelectedRowModel()`. |
|
|
66
|
+
| `row` | `Row<TMDataGridFeatures, TData>` | The right-clicked row. |
|
|
67
|
+
| `cell` | `Cell<…> \| null` | The cell under the pointer, so a per-cell action such as "copy value" is possible. `null` only if a custom cell renderer stopped the event. |
|
|
68
|
+
| `close` | `() => void` | Closes the menu. `Menu.Item` already closes on click, so this is for content that is not a menu item. |
|
|
69
|
+
|
|
70
|
+
The render prop is called **during render**, and only for the row whose menu is
|
|
71
|
+
open. Keep it a pure function of its arguments and do the work in the item
|
|
72
|
+
handlers.
|
|
73
|
+
|
|
74
|
+
Return `null` to leave a row without a menu. The browser's own context menu
|
|
75
|
+
stays suppressed over the grid either way:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
renderRowContextMenu={({ row }) => (row.original.locked ? null : <Menu.Item>Edit</Menu.Item>)}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### The right-clicked row
|
|
82
|
+
|
|
83
|
+
A right-click does not select or highlight the row. The grid marks it with
|
|
84
|
+
`data-context-menu` while its menu is open, which gives it the hover background.
|
|
85
|
+
An action that should apply to a multi-selection can read the selection off
|
|
86
|
+
`table` and fall back to the clicked row:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
renderRowContextMenu={({ table, row }) => {
|
|
90
|
+
const selected = table.getSelectedRowModel().rows;
|
|
91
|
+
const targets = selected.some((r) => r.id === row.id) ? selected : [row];
|
|
92
|
+
return <Menu.Item onClick={() => archive(targets)}>Archive {targets.length}</Menu.Item>;
|
|
93
|
+
}}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Taking the whole menu
|
|
97
|
+
|
|
98
|
+
Under `cellSelection: "range"` a right-click inside the selection opens the
|
|
99
|
+
copy and export items too. By default they appear above a divider and yours
|
|
100
|
+
below, which is what happens when the render prop does not use `internalItems`.
|
|
101
|
+
See [Cell selection](/docs/cell-selection#copy-and-export).
|
|
102
|
+
|
|
103
|
+
`internalItems` is those built-in items. **Using it takes over the
|
|
104
|
+
composition**: the menu becomes exactly what you return, in the order you
|
|
105
|
+
return it.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
renderRowContextMenu={({ row, internalItems }) => (
|
|
109
|
+
<>
|
|
110
|
+
<Menu.Item onClick={() => open(row.id)}>Open</Menu.Item>
|
|
111
|
+
<Menu.Divider />
|
|
112
|
+
{internalItems}
|
|
113
|
+
</>
|
|
114
|
+
)}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Accept `internalItems` without rendering it to drop the built-in items
|
|
118
|
+
entirely.
|
|
119
|
+
|
|
120
|
+
### Menu options
|
|
121
|
+
|
|
122
|
+
`rowContextMenuProps` is passed to the Mantine `Menu` unchanged, apart from its
|
|
123
|
+
open state:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
<TMDataGrid.Table<Employee>
|
|
127
|
+
renderRowContextMenu={items}
|
|
128
|
+
rowContextMenuProps={{ width: 260, shadow: "lg", position: "right-start" }}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
On touch devices a long press (500 ms) opens the same menu. Mantine sets
|
|
133
|
+
`user-select: none` on the element it attaches a context menu to, so body cell
|
|
134
|
+
text is not selectable with the mouse in a grid that has one.
|
|
135
|
+
|
|
136
|
+
## Reference
|
|
137
|
+
|
|
138
|
+
| Name | Kind | Type | Default | What it does |
|
|
139
|
+
| --- | --- | --- | --- | --- |
|
|
140
|
+
| `onRowClick` | Table prop | `(row) => void` | – | Row click. Adds a pointer cursor. |
|
|
141
|
+
| `onCellClick` | Table prop | `(args) => void` | – | Cell click. Receives `{ cell, row, column, event }`. |
|
|
142
|
+
| `onCellDoubleClick` | Table prop | `(args) => void` | – | Cell double-click. |
|
|
143
|
+
| `onCellContextMenu` | Table prop | `(args) => void` | – | Cell right-click. |
|
|
144
|
+
| `renderRowContextMenu` | Table prop | `({ table, row, cell, close, internalItems }) => ReactNode` | – | Contents of the row's context menu. `null` for no menu. |
|
|
145
|
+
| `TMDataGridRowContextMenuArgs` | Type | `{ table, row, cell, close, internalItems }` | – | What `renderRowContextMenu` receives. |
|
|
146
|
+
| `renderColumnMenuItems` | Table prop | `TMDataGridColumnMenuItemsRenderer` | – | Sets the column menu's contents. An empty list removes the menu button. See [Column header menu](/docs/column-menu). |
|
|
147
|
+
| `rowContextMenuProps` | Table prop | `MenuProps` | – | Passed to the Mantine `Menu`. |
|
|
148
|
+
| `TMDataGridCellEventArgs` | Export | type | – | The argument the three cell handlers receive. |
|
|
149
|
+
| `data-context-menu` | Data attribute | – | – | On the row whose menu is open. |
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Row pinning and numbering
|
|
2
|
+
|
|
3
|
+
Two independent features: rows stuck to the top or bottom of the body so they
|
|
4
|
+
stay in view, and a gutter numbering the rows.
|
|
5
|
+
|
|
6
|
+
## Pinning rows
|
|
7
|
+
|
|
8
|
+
Opt in with `enableRowPinning: true`, or a per-row predicate.
|
|
9
|
+
|
|
10
|
+
```tsx
|
|
11
|
+
const grid = useTMDataGrid({ data, columns, enableRowPinning: true });
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Pinned rows leave the scrolling order and render in sticky blocks: top-pinned
|
|
15
|
+
rows under the header (and under the entry block while one is open),
|
|
16
|
+
bottom-pinned rows above the summary row.
|
|
17
|
+
|
|
18
|
+
There is no built-in pin gesture and no pin icon. The grid provides `row.pin()`
|
|
19
|
+
on every row, callable from anywhere a row is rendered. Two places are
|
|
20
|
+
convenient for it.
|
|
21
|
+
|
|
22
|
+
A **lane of your own**, a display column whose cell is a pin button:
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
function PinToggle({ row }: { row: Row<TMDataGridFeatures, Employee> }) {
|
|
26
|
+
// Subscribed rather than called in the component body: the React Compiler
|
|
27
|
+
// caches a bare call along with the stable `row` identity.
|
|
28
|
+
const pinned = useSelector(row.table.store, () => row.getIsPinned());
|
|
29
|
+
return (
|
|
30
|
+
<ActionIcon
|
|
31
|
+
variant={pinned === false ? "subtle" : "light"}
|
|
32
|
+
color={pinned === false ? "gray" : "blue"}
|
|
33
|
+
aria-label={pinned === false ? "Pin to top" : "Unpin"}
|
|
34
|
+
// The row underneath may select or highlight on click.
|
|
35
|
+
onClick={(event) => {
|
|
36
|
+
event.stopPropagation();
|
|
37
|
+
row.pin(pinned === false ? "top" : false);
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
{pinned === false ? <IconPin size={16} /> : <IconPinFilled size={16} />}
|
|
41
|
+
</ActionIcon>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const pinColumn = columnHelper.display({
|
|
46
|
+
id: "pin",
|
|
47
|
+
header: "",
|
|
48
|
+
// Columns are fluid - `minmax(minSize, flex fr)` - so a control lane states
|
|
49
|
+
// one width three times to opt out. See [Sizing](/docs/column-layout#sizing).
|
|
50
|
+
size: 44,
|
|
51
|
+
minSize: 44,
|
|
52
|
+
maxSize: 44,
|
|
53
|
+
meta: { label: "Pin", align: "center" },
|
|
54
|
+
enableResizing: false,
|
|
55
|
+
enableSorting: false,
|
|
56
|
+
cell: ({ row }) => <PinToggle row={row} />,
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or the **row context menu**, which reaches a row at either edge as well as one
|
|
61
|
+
in the body:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<TMDataGrid.Table<Employee>
|
|
65
|
+
renderRowContextMenu={({ row }) => (
|
|
66
|
+
<>
|
|
67
|
+
{row.getIsPinned() !== "top" && (
|
|
68
|
+
<Menu.Item onClick={() => row.pin("top")}>Pin to top</Menu.Item>
|
|
69
|
+
)}
|
|
70
|
+
{row.getIsPinned() !== false && (
|
|
71
|
+
<Menu.Item onClick={() => row.pin(false)}>Unpin</Menu.Item>
|
|
72
|
+
)}
|
|
73
|
+
</>
|
|
74
|
+
)}
|
|
75
|
+
/>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Include a way to unpin.
|
|
79
|
+
|
|
80
|
+
```demo
|
|
81
|
+
file: rows/PinningAndNumbers.tsx
|
|
82
|
+
hint: Click a pin, or right-click a row for either edge, then scroll.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`row.pin("top" | "bottom" | false)`, `row.getIsPinned()` and `row.getCanPin()`
|
|
86
|
+
are TanStack's own APIs; the state is `rowPinning: { top: string[], bottom:
|
|
87
|
+
string[] }`, settable wholesale with `table.setRowPinning()` or seeded through
|
|
88
|
+
`initialState`.
|
|
89
|
+
|
|
90
|
+
### Pinned row behaviour
|
|
91
|
+
|
|
92
|
+
Selection, editing, details, the context menu and per-row styling all behave as
|
|
93
|
+
they do in the body. Pinned rows are excluded only from the features that
|
|
94
|
+
depend on scroll *order* - striping and the cell range - and the row-number
|
|
95
|
+
gutter leaves them unnumbered.
|
|
96
|
+
|
|
97
|
+
Also note:
|
|
98
|
+
|
|
99
|
+
- A pinned row stays at its edge even when a filter or the pager would have
|
|
100
|
+
dropped it from the body.
|
|
101
|
+
- A pinned id whose row leaves `data` (a delete, a server-side page swap) is not
|
|
102
|
+
shown. It stays in state and the row returns to its edge if its data comes
|
|
103
|
+
back.
|
|
104
|
+
- **Group rows never pin.** A leaf whose group is collapsed stays hidden while
|
|
105
|
+
pinned.
|
|
106
|
+
- `rowPinning` is **not** persisted. Row ids are data, and the settings group
|
|
107
|
+
holds layout only.
|
|
108
|
+
|
|
109
|
+
## Numbering rows
|
|
110
|
+
|
|
111
|
+
`enableRowNumbers: true` adds a gutter, outermost left, before every other
|
|
112
|
+
lane.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
const grid = useTMDataGrid({ data, columns, enableRowNumbers: true });
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
It numbers **the current view**: sorted, filtered, and continuing across pages
|
|
119
|
+
rather than restarting on each one. The number is a position, not an identifier
|
|
120
|
+
for the record; for that, add a column of your own over the record's id. Group
|
|
121
|
+
rows and pinned rows take no number.
|
|
122
|
+
|
|
123
|
+
## Reference
|
|
124
|
+
|
|
125
|
+
| Name | Kind | Type | Default | What it does |
|
|
126
|
+
| --- | --- | --- | --- | --- |
|
|
127
|
+
| `enableRowPinning` | Table option | `boolean \| (row) => boolean` | `false` | Whether rows can be pinned. |
|
|
128
|
+
| `initialState.rowPinning` | Table option | `{ top: string[], bottom: string[] }` | empty | Rows pinned at mount. Not persisted. |
|
|
129
|
+
| `enableRowNumbers` | Option | `boolean` | `false` | Adds the row-number gutter. |
|
|
130
|
+
| `row.pin` | Row method | `("top" \| "bottom" \| false) => void` | – | Pins or unpins one row. |
|
|
131
|
+
| `row.getIsPinned` | Row method | `() => "top" \| "bottom" \| false` | – | Where a row is pinned. |
|
|
132
|
+
| `ROW_NUMBER_COLUMN_ID` | Export | `"__rowNumber__"` | – | Id of the generated number gutter. |
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Row selection
|
|
2
|
+
|
|
3
|
+
Picking rows out of the grid, and reading back what was picked. The grid
|
|
4
|
+
separates two things: a set of rows for a bulk action, and a single highlighted
|
|
5
|
+
row. `selectionMode` sets which of them a click drives, and defaults to
|
|
6
|
+
`"checkbox"`.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
const grid = useTMDataGrid({ data, columns }); // "checkbox"
|
|
10
|
+
const rows = useTMDataGrid({ data, columns, selectionMode: "row" });
|
|
11
|
+
const master = useTMDataGrid({ data, columns, selectionMode: "highlight" });
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```demo
|
|
15
|
+
file: rows/SelectionModes.tsx
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## The four modes
|
|
19
|
+
|
|
20
|
+
`selectionMode` sets what selecting looks like and what a bare row click does.
|
|
21
|
+
A click can toggle a multi-selection or move a highlight, not both, so the two
|
|
22
|
+
are one option rather than two.
|
|
23
|
+
|
|
24
|
+
| Mode | Checkbox column | Row click |
|
|
25
|
+
| ---- | --------------- | --------- |
|
|
26
|
+
| `"checkbox"` | yes, multi-select | nothing |
|
|
27
|
+
| `"row"` | no | selects, with the usual modifiers |
|
|
28
|
+
| `"checkboxAndHighlight"` | yes, multi-select | highlights one row |
|
|
29
|
+
| `"highlight"` | no | highlights one row - no selection at all |
|
|
30
|
+
|
|
31
|
+
The first two write to TanStack's `rowSelection`, so the toolbar count,
|
|
32
|
+
`getSelectedRowModel()` and persistence all behave the same either way.
|
|
33
|
+
|
|
34
|
+
Under `"row"` the click follows the usual desktop-list conventions: a plain
|
|
35
|
+
click replaces the selection with this row, Ctrl/Cmd toggles it and leaves the
|
|
36
|
+
rest, Shift selects the range from the anchor, Ctrl+Shift adds that range. Rows are
|
|
37
|
+
focusable in this mode, and Space or Enter toggles the focused row.
|
|
38
|
+
|
|
39
|
+
`enableRowSelection: false` removes the checkbox column and row-click
|
|
40
|
+
selection in any mode. It has no effect under `"highlight"`, which selects
|
|
41
|
+
nothing.
|
|
42
|
+
|
|
43
|
+
## The highlighted row
|
|
44
|
+
|
|
45
|
+
The highlighted row is state of its own rather than a slice of `rowSelection`,
|
|
46
|
+
so `"checkboxAndHighlight"` runs both at once: tick rows for a bulk action,
|
|
47
|
+
click one to open its detail panel beside the grid.
|
|
48
|
+
|
|
49
|
+
`defaultHighlightedRowId` seeds it and `onHighlightedRowChange` follows it,
|
|
50
|
+
typically into a route for a master–detail view:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
const grid = useTMDataGrid({
|
|
54
|
+
data,
|
|
55
|
+
columns,
|
|
56
|
+
selectionMode: "highlight",
|
|
57
|
+
onHighlightedRowChange: (rowId) =>
|
|
58
|
+
navigate({ to: "/employees/$id", params: { id: rowId ?? "" } }),
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For a panel that opens under the row instead of beside the grid, see
|
|
63
|
+
[Row details](/docs/row-details). A grid can use both.
|
|
64
|
+
|
|
65
|
+
## Acting on a selection
|
|
66
|
+
|
|
67
|
+
Read the selection through the table store with TanStack Store's
|
|
68
|
+
[`useSelector`](https://tanstack.com/store/latest/docs/framework/react/reference), rather
|
|
69
|
+
than by calling a method directly. The table identity is stable across renders,
|
|
70
|
+
so the React Compiler caches a bare `getSelectedRowModel()` call and the
|
|
71
|
+
toolbar stops updating.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
const selected = useSelector(
|
|
75
|
+
grid.table.store,
|
|
76
|
+
() => grid.table.getSelectedRowModel().rows,
|
|
77
|
+
);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```demo
|
|
81
|
+
file: rows/SelectionState.tsx
|
|
82
|
+
hint: Tick a few rows - the toolbar turns into a bulk-action bar and back.
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Highlighting selected rows
|
|
86
|
+
|
|
87
|
+
`showSelectedBackground` follows the mode: on for `"row"`, off for
|
|
88
|
+
`"checkbox"`. Set it explicitly for checkboxes and a background, or for row
|
|
89
|
+
selection with no background change.
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
const grid = useTMDataGrid({ data, columns, showSelectedBackground: true });
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The colour is `--dg-row-selected-bg`, which defaults to
|
|
96
|
+
`--mantine-primary-color-light`. Change it on the grid element rather than
|
|
97
|
+
touching the flag:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
<TMDataGrid
|
|
101
|
+
{...grid}
|
|
102
|
+
style={{ "--dg-row-selected-bg": "color-mix(in srgb, var(--mantine-color-blue-6) 12%, transparent)" }}
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Rows carry `data-selected` whenever they are selected, `data-selected-bg` when
|
|
107
|
+
they also take the background, and `data-highlighted` on the highlighted row.
|
|
108
|
+
[Custom styling](/docs/row-styling) can key off any of them.
|
|
109
|
+
|
|
110
|
+
## Group rows
|
|
111
|
+
|
|
112
|
+
A group row's checkbox selects every record under it, at any depth, including
|
|
113
|
+
records inside collapsed sub-groups. It shows a tick once all of them are
|
|
114
|
+
selected and a dash while only some are. Only the records are written to
|
|
115
|
+
`rowSelection`. See [Grouping](/docs/grouping#selection).
|
|
116
|
+
|
|
117
|
+
## Reference
|
|
118
|
+
|
|
119
|
+
| Name | Kind | Type | Default | What it does |
|
|
120
|
+
| --- | --- | --- | --- | --- |
|
|
121
|
+
| `selectionMode` | Option | `"checkbox" \| "row" \| "checkboxAndHighlight" \| "highlight"` | `"checkbox"` | What selecting looks like and what a row click does. |
|
|
122
|
+
| `TMDataGridSelectionMode` | Type | – | – | The type of `selectionMode`. |
|
|
123
|
+
| `enableRowSelection` | Table option | `boolean \| (row) => boolean` | `true` | `false` removes the checkbox column and row-click selection. |
|
|
124
|
+
| `enableMultiRowSelection` | Table option | `boolean` | `true` | `false` limits the selection to one row and drops group checkboxes. |
|
|
125
|
+
| `showSelectedBackground` | Option | `boolean` | Follows the mode | Whether selected rows take a background tint. |
|
|
126
|
+
| `defaultHighlightedRowId` | Option | `string \| null` | `null` | Row highlighted at mount. |
|
|
127
|
+
| `onHighlightedRowChange` | Callback | `(rowId: string \| null) => void` | – | Fires when the highlight moves. |
|
|
128
|
+
| `SELECT_COLUMN_ID` | Export | `"__select__"` | – | Id of the generated checkbox column. |
|
|
129
|
+
| `getSelectableRowIds` | Export | `(table) => string[]` | – | Ids the header checkbox would select. |
|
|
130
|
+
| `resolveRowSelectionClick` | Export | `(args) => ResolvedRowSelection` | – | The desktop-list click rules, for a custom surface. |
|
|
131
|
+
| `ResolveRowSelectionClickArgs` · `TMDataGridRowClickModifiers` | Types | – | – | What `resolveRowSelectionClick` takes, and its `modifiers`: `{ toggle, extend }`. |
|
|
132
|
+
| `--dg-row-selected-bg` | CSS variable | colour | `--mantine-primary-color-light` | Selected row background. |
|
|
133
|
+
| `--dg-row-highlight-bg` | CSS variable | colour | Themed | Highlighted row background. |
|
|
134
|
+
| `data-selected` | Data attribute | – | – | On every selected row. |
|
|
135
|
+
| `data-selected-bg` | Data attribute | – | – | On selected rows that also take the background. |
|
|
136
|
+
| `data-highlighted` | Data attribute | – | – | On the highlighted row. |
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Row styling
|
|
2
|
+
|
|
3
|
+
Colouring rows by their contents, such as an overdue invoice in red.
|
|
4
|
+
|
|
5
|
+
```tsx
|
|
6
|
+
<TMDataGrid.Table<Employee>
|
|
7
|
+
rowStyle={(row) =>
|
|
8
|
+
!row.getIsGrouped() && row.original.status === "Terminated"
|
|
9
|
+
? { "--row-bg": "color-mix(in srgb, var(--mantine-color-red-6) 12%, transparent)" }
|
|
10
|
+
: undefined
|
|
11
|
+
}
|
|
12
|
+
/>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Group rows are handed to `rowStyle` and `rowClassName` too, and a group row's `original` is an arbitrary child's record.
|
|
16
|
+
Guard a callback that reads `original` with `row.getIsGrouped()`, or match `data-grouped="true"` to style the group rows themselves.
|
|
17
|
+
|
|
18
|
+
```demo
|
|
19
|
+
file: rows/RowStyling.tsx
|
|
20
|
+
hint: Select and hover a coloured row - both still show through the row background.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Set the row background
|
|
24
|
+
|
|
25
|
+
Set `--row-bg` rather than `background`. Hover, selection, the highlight, the
|
|
26
|
+
cell range and striping each add a background over the row and are composed
|
|
27
|
+
against `--row-bg`; `background` overrides all of them, so a coloured row stops
|
|
28
|
+
responding to hover and selection.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
rowStyle={() => ({ background: "pink" })} // hover and selection hidden
|
|
32
|
+
rowStyle={() => ({ "--row-bg": "pink" })} // both still show
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`rowStyle` accepts `CSSProperties` or an object of custom properties. The type
|
|
36
|
+
is a union, so a callback returning either compiles.
|
|
37
|
+
|
|
38
|
+
Pick a colour that reads under both colour schemes. A `-0` Mantine shade
|
|
39
|
+
(`red-0`) is near-white, which turns unreadable behind light text in the dark
|
|
40
|
+
scheme; mixing a mid shade into transparency tints both schemes evenly:
|
|
41
|
+
`color-mix(in srgb, var(--mantine-color-red-6) 12%, transparent)`.
|
|
42
|
+
|
|
43
|
+
The grid composes `--row-bg` over the theme's body colour, so a translucent value tints the row and stays opaque under the pinned columns and the pinned rows.
|
|
44
|
+
|
|
45
|
+
## One cell, not the row
|
|
46
|
+
|
|
47
|
+
There is no `cellStyle` or `cellClassName`. Style a single cell from the
|
|
48
|
+
column's own `cell` renderer, which owns the element you want to colour:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
columnHelper.accessor("age", {
|
|
52
|
+
cell: ({ getValue }) => {
|
|
53
|
+
const age = getValue();
|
|
54
|
+
return <span style={{ color: age > 60 ? "var(--mantine-color-red-6)" : undefined }}>{age}</span>;
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
From a stylesheet, match the cell's `data-column-id` under a `rowClassName`.
|
|
60
|
+
Body cells carry no `data-dg-part`; the coordinate attributes identify them:
|
|
61
|
+
|
|
62
|
+
```css
|
|
63
|
+
.overdue [data-column-id="dueDate"] {
|
|
64
|
+
font-weight: 600;
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Classes instead
|
|
69
|
+
|
|
70
|
+
`rowClassName` takes the same shape and adds to the grid's own classes, for
|
|
71
|
+
when the styling belongs in a stylesheet:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<TMDataGrid.Table<Invoice>
|
|
75
|
+
rowClassName={(row) => (row.original.overdue ? classes.overdue : undefined)}
|
|
76
|
+
/>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```css
|
|
80
|
+
.overdue {
|
|
81
|
+
--row-bg: color-mix(in srgb, var(--mantine-color-red-6) 12%, transparent);
|
|
82
|
+
font-weight: 600;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Striping
|
|
87
|
+
|
|
88
|
+
`striped` gives every second row `--dg-row-striped-bg`. Striping follows the
|
|
89
|
+
row's **position in the view**, so it survives sorting, filtering and
|
|
90
|
+
virtualization rather than sticking to particular records.
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<TMDataGrid.Table striped />
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Pinned rows are not striped: they have left the scrolling order.
|
|
97
|
+
|
|
98
|
+
## Styling by state
|
|
99
|
+
|
|
100
|
+
Rows carry data attributes for their state, so a stylesheet can target any of
|
|
101
|
+
it without a callback:
|
|
102
|
+
|
|
103
|
+
| Attribute | On |
|
|
104
|
+
| --- | --- |
|
|
105
|
+
| `data-selected` | Selected rows |
|
|
106
|
+
| `data-selected-bg` | Selected rows that also take the background |
|
|
107
|
+
| `data-highlighted` | The highlighted row |
|
|
108
|
+
| `data-grouped` | Group rows |
|
|
109
|
+
| `data-depth` | Every row. The nesting level |
|
|
110
|
+
| `data-context-menu` | The row whose context menu is open |
|
|
111
|
+
| `data-row-id` | Every row. Its id, which [tests](/docs/testing) key off |
|
|
112
|
+
|
|
113
|
+
The state attributes are present, with the value `"true"`, only on the rows
|
|
114
|
+
they apply to, so the bare attribute and the value match the same rows:
|
|
115
|
+
|
|
116
|
+
```css
|
|
117
|
+
[data-dg-part="row"][data-grouped="true"] {
|
|
118
|
+
--row-bg: color-mix(in srgb, var(--mantine-color-gray-6) 12%, transparent);
|
|
119
|
+
font-weight: 600;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Reference
|
|
124
|
+
|
|
125
|
+
| Name | Kind | Type | Default | What it does |
|
|
126
|
+
| --- | --- | --- | --- | --- |
|
|
127
|
+
| `rowStyle` | Table prop | `TMDataGridRowStyle \| (row) => TMDataGridRowStyle` | – | Inline style for a body row. |
|
|
128
|
+
| `rowClassName` | Table prop | `string \| (row) => string \| undefined` | – | Class for a body row, added after the grid's own. |
|
|
129
|
+
| `striped` | Table prop | `boolean` | `false` | Every second row takes `--dg-row-striped-bg`. |
|
|
130
|
+
| `TMDataGridRowStyle` | Export | type | – | `CSSProperties` or an object of `--*` custom properties. |
|
|
131
|
+
| `--row-bg` | CSS variable | colour | – | The row's own background, composed over the body colour and under hover, selection and range. |
|
|
132
|
+
| `--dg-row-striped-bg` | CSS variable | colour | Themed | The stripe colour. |
|
|
133
|
+
| `--dg-row-height` | CSS variable | length | From `size` | Row height. `meta.rowHeight` is the supported way to change it. |
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Scrolling and virtualization
|
|
2
|
+
|
|
3
|
+
Virtualization is **always on**. There is no flag and no threshold: only the
|
|
4
|
+
rows within the viewport, plus a small overscan, are mounted, at any row
|
|
5
|
+
count.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
const grid = useTMDataGrid({ data, columns }); // 200 rows or 200 000
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Rows only. Columns are not virtualized: every column that is visible is in the
|
|
12
|
+
DOM, header and body alike, however far off-screen it sits. A grid with a few
|
|
13
|
+
dozen columns is fine; hide the ones a user does not need rather than relying
|
|
14
|
+
on the viewport to do it.
|
|
15
|
+
|
|
16
|
+
## Overscan
|
|
17
|
+
|
|
18
|
+
How many rows stay mounted on each side of the viewport. Defaults to `6`.
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
const grid = useTMDataGrid({ data, columns, overscan: 12 });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Raise it if a fast scroll flashes blank rows; lower it when rows are expensive
|
|
25
|
+
to render.
|
|
26
|
+
|
|
27
|
+
## Row height
|
|
28
|
+
|
|
29
|
+
Taken from `meta.rowHeight`, or from the `size` prop when that is not set. Rows
|
|
30
|
+
are **fixed height**, so the virtualizer's estimate is exact and the scrollbar
|
|
31
|
+
does not drift as you scroll.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
const grid = useTMDataGrid({ data, columns, meta: { rowHeight: 64 } });
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
[Row details](/docs/row-details) are the exception: a row showing a panel is as
|
|
38
|
+
tall as the panel, so those rows are measured after they mount.
|
|
39
|
+
`renderDetailsEstHeight` is what the virtualizer assumes for one it has not
|
|
40
|
+
measured yet.
|
|
41
|
+
|
|
42
|
+
## Scrolling to a row
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
const { scrollToRow } = useTMDataGrid({ data, columns, getRowId });
|
|
46
|
+
|
|
47
|
+
scrollToRow({ rowId: "42", align: "center" });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Under virtualization the target row may not be mounted, so
|
|
51
|
+
`element.scrollIntoView()` cannot find it. `align` is `"start"`, `"center"`,
|
|
52
|
+
`"end"` or `"auto"`, which scrolls only if the row is out of view.
|
|
53
|
+
|
|
54
|
+
It answers whether the row could be reached. `false` means the row is not in
|
|
55
|
+
the current view - filtered out, on another page, or an id matching no row -
|
|
56
|
+
and nothing scrolled. A pinned row answers `true` without scrolling.
|
|
57
|
+
|
|
58
|
+
The hook reaches the virtualizer through `scrollerRef`, which `TMDataGrid.Table`
|
|
59
|
+
fills in. That is internal wiring rather than an API: spread the whole grid
|
|
60
|
+
object onto `<TMDataGrid>`, because a hand-assembled prop list that leaves it
|
|
61
|
+
out has no scrolling.
|
|
62
|
+
|
|
63
|
+
While the draft store is running, `TMDataGrid.DraftActions` hands its
|
|
64
|
+
`renderActions` slot an `actions.scrollToFirstOpenRow(align?)` that goes to the
|
|
65
|
+
first row [left open](/docs/draft-store), without your having to
|
|
66
|
+
track the ids.
|
|
67
|
+
|
|
68
|
+
## Edge callbacks
|
|
69
|
+
|
|
70
|
+
`TMDataGrid.Table` reports arrivals at each edge, firing **once** when the
|
|
71
|
+
scroll reaches it rather than on every scroll event:
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
<TMDataGrid.Table
|
|
75
|
+
onScrollToBottom={() => console.log("at the end")}
|
|
76
|
+
onScrollToRight={() => console.log("at the last column")}
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For loading more rows, use [`onReachEnd`](/docs/server-side#infinite-scroll)
|
|
81
|
+
instead. It fires a number of rows before the bottom, and latches per row count
|
|
82
|
+
so a pending fetch is not requested twice.
|
|
83
|
+
|
|
84
|
+
## Scroll shadows
|
|
85
|
+
|
|
86
|
+
Two soft shadows, both driven by `animation-timeline: scroll(…)` rather than by
|
|
87
|
+
a scroll listener.
|
|
88
|
+
|
|
89
|
+
**Under the header.** Once body rows scroll beneath the sticky header, a shadow
|
|
90
|
+
appears along its bottom edge, indicating rows above the viewport. A grid with
|
|
91
|
+
nothing to scroll shows none. `--dg-header-shadow-color` recolours it.
|
|
92
|
+
|
|
93
|
+
**Beside a pinned lane.** A [pinned column](/docs/column-layout#pinning) shows a
|
|
94
|
+
band over the data next to it, and only while it is covering content: it fades
|
|
95
|
+
in over the first 20px of horizontal scroll and fades out again at the far
|
|
96
|
+
end.
|
|
97
|
+
|
|
98
|
+
Where `animation-timeline` is unsupported, the header's own border draws the
|
|
99
|
+
boundary and the pinned band is always on.
|
|
100
|
+
|
|
101
|
+
## Reference
|
|
102
|
+
|
|
103
|
+
| Name | Kind | Type | Default | What it does |
|
|
104
|
+
| --- | --- | --- | --- | --- |
|
|
105
|
+
| `overscan` | Option | `number` | `6` | Rows kept mounted beyond each edge of the viewport. |
|
|
106
|
+
| `meta.rowHeight` | Option | `number` | From `size` | Row height, in pixels. The virtualizer needs a number. |
|
|
107
|
+
| `scrollToRow` | Hook return | `({ rowId, align? }) => boolean` | `align: "auto"` | Scrolls a row into view, mounted or not. Answers whether it could be reached. |
|
|
108
|
+
| `TMDataGridScrollToRowArgs` | Type | `{ rowId, align? }` | – | What `scrollToRow` takes. |
|
|
109
|
+
| `onScrollToTop` · `onScrollToBottom` · `onScrollToLeft` · `onScrollToRight` | Table props | `() => void` | – | Fire once on arriving at that edge. |
|
|
110
|
+
| `TMDataGridScrollAlign` | Export | `"start" \| "center" \| "end" \| "auto"` | – | The `align` argument. |
|
|
111
|
+
| `--dg-header-shadow-color` | CSS variable | colour | Themed | The shadow under the sticky header. |
|
|
112
|
+
| `--dg-sticky-edge-range` | CSS variable | length | `20px` | How far the pinned-lane band takes to fade in. |
|