@jielga/tmdatagrid 2.2.0 → 2.3.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/dist/index.d.ts +41 -4
- package/dist/index.js +2087 -1968
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/columns.md +2 -1
- package/docs/components.md +1 -0
- package/docs/filtering.md +3 -0
- package/docs/persistence.md +101 -2
- package/docs/row-details.md +5 -0
- package/docs/row-interaction.md +1 -1
- package/docs/row-styling.md +17 -0
- package/docs/use-tm-data-grid.md +6 -2
- package/package.json +1 -1
- package/skills/appearance/SKILL.md +1 -1
- package/skills/cell-selection/SKILL.md +1 -1
- package/skills/columns/SKILL.md +3 -3
- package/skills/columns/references/columns-api.md +1 -0
- package/skills/data/SKILL.md +1 -1
- package/skills/editing/SKILL.md +1 -1
- package/skills/filtering/SKILL.md +24 -12
- package/skills/getting-started/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +1 -1
- package/skills/migrating-to-2/SKILL.md +1 -1
- package/skills/options/SKILL.md +81 -10
- package/skills/rows/SKILL.md +18 -9
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +1 -1
- package/skills/testing-components/SKILL.md +1 -1
- package/skills/testing-editing/SKILL.md +1 -1
- package/src/components/TMDataGridFilterPills.module.css +9 -7
- package/src/components/TMDataGridTable.module.css +15 -6
- package/src/components/TMDataGridTable.tsx +23 -11
- package/src/components/sticky.module.css +27 -7
- package/src/core/filterControls.ts +8 -0
- package/src/core/filterOperators.ts +13 -0
- package/src/core/persistence.ts +322 -26
- package/src/index.ts +1 -0
- package/src/useTMDataGrid.tsx +95 -14
package/skills/options/SKILL.md
CHANGED
|
@@ -9,16 +9,16 @@ description: >
|
|
|
9
9
|
labels, editing, filters, exportOptions, enableColumnOrdering,
|
|
10
10
|
enablePagination, resetPageOnQueryChange, enableRowNumbers, selectionMode,
|
|
11
11
|
showSelectedBackground, cellSelection, renderDetails, overscan,
|
|
12
|
-
quickSearchMode), persist with dataKey/settingsKey slices
|
|
13
|
-
returned api (table, ui, edit, features, labels,
|
|
14
|
-
ui actions, and reading grid state with
|
|
15
|
-
table.getState() does not exist in v9.
|
|
16
|
-
up an option's default, persisting
|
|
17
|
-
state from a parent.
|
|
12
|
+
quickSearchMode), persist with dataKey/settingsKey slices, storageMode and
|
|
13
|
+
urlKey deep links, the returned api (table, ui, edit, features, labels,
|
|
14
|
+
resetSettings, scrollToRow), ui actions, and reading grid state with
|
|
15
|
+
useSelector over table.store, since table.getState() does not exist in v9.
|
|
16
|
+
Load when configuring the hook, looking up an option's default, persisting
|
|
17
|
+
layout or filters, or reacting to grid state from a parent.
|
|
18
18
|
metadata:
|
|
19
19
|
type: core
|
|
20
20
|
library: '@jielga/tmdatagrid'
|
|
21
|
-
library_version: '2.
|
|
21
|
+
library_version: '2.3.0'
|
|
22
22
|
sources:
|
|
23
23
|
- 'Jielga/react:packages/tmdatagrid/docs/use-tm-data-grid.md'
|
|
24
24
|
- 'Jielga/react:packages/tmdatagrid/docs/persistence.md'
|
|
@@ -160,14 +160,17 @@ const grid = useTMDataGrid({
|
|
|
160
160
|
## persist
|
|
161
161
|
|
|
162
162
|
Restores table state on mount and writes it back on every change. State is split
|
|
163
|
-
across
|
|
164
|
-
stays valid indefinitely,
|
|
165
|
-
changes
|
|
163
|
+
across three keys because the groups have different lifetimes: column configuration
|
|
164
|
+
stays valid indefinitely, filters and pagination go stale as the data
|
|
165
|
+
changes, and a deep link has to travel with the page URL. Separate keys let one
|
|
166
|
+
group be cleared without touching the others.
|
|
166
167
|
|
|
167
168
|
| Field | Type | Default | Description |
|
|
168
169
|
| --- | --- | --- | --- |
|
|
169
170
|
| `dataKey` | `TMDataGridPersistKey<TMDataGridDataSlice>`: `string \| [string, DataSlice[]]` | – | Storage key for the data group. |
|
|
170
171
|
| `settingsKey` | `TMDataGridPersistKey<TMDataGridSettingsSlice>`: `string \| [string, SettingsSlice[]]` | – | Storage key for the settings group. |
|
|
172
|
+
| `urlKey` | `TMDataGridPersistKey<TMDataGridDataSlice>`: `string \| [string, DataSlice[]]` | – | Search param for data slices kept in the URL. See [Deep links](#deep-links). |
|
|
173
|
+
| `urlStorage` | `TMDataGridUrlStorage`: `{ get(name): string \| null; set(name, value: string \| null): void }` | `location.search` and `history.replaceState` | Reads and writes the URL param. |
|
|
171
174
|
| `storageMode` | `TMDataGridStorageMode`: `"localStorage" \| "sessionStorage"` | `"localStorage"` | Storage area. `"sessionStorage"` is per tab. |
|
|
172
175
|
| `serialize` | `(value) => string` | `JSON.stringify` | Serializes before storing. |
|
|
173
176
|
| `deserialize` | `(value: string) => unknown` | `JSON.parse` | Parses a stored payload. |
|
|
@@ -203,6 +206,7 @@ const persist = {
|
|
|
203
206
|
| Group | Available slices |
|
|
204
207
|
| --- | --- |
|
|
205
208
|
| `dataKey` | `columnFilters`, `globalFilter`, `sorting`, `pagination`, `expanded` |
|
|
209
|
+
| `urlKey` | The data slices. A slice listed here is taken out of `dataKey`. |
|
|
206
210
|
| `settingsKey` | `columnVisibility`, `columnSizing`, `columnOrder`, `columnPinning`, `grouping` |
|
|
207
211
|
|
|
208
212
|
`grouping` is a settings slice because it names columns rather than values, so it
|
|
@@ -227,6 +231,73 @@ dropped.
|
|
|
227
231
|
|
|
228
232
|
Source: `packages/tmdatagrid/docs/persistence.md` (Behaviour).
|
|
229
233
|
|
|
234
|
+
### Deep links
|
|
235
|
+
|
|
236
|
+
`urlKey` keeps data slices in one URL search param, so a link to the page opens
|
|
237
|
+
the grid on the same filters. The string is the param name; a bare key takes
|
|
238
|
+
every data slice, a tuple a subset, as with `dataKey`.
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
const persist = {
|
|
242
|
+
settingsKey: "employees.settings",
|
|
243
|
+
// Sorting is remembered per browser; the filters travel in the link.
|
|
244
|
+
dataKey: ["employees.data", ["sorting"]],
|
|
245
|
+
urlKey: ["employees", ["columnFilters", "globalFilter"]],
|
|
246
|
+
} satisfies TMDataGridPersistence;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
- A slice lives in one group. A slice listed under `urlKey` is taken out of
|
|
250
|
+
`dataKey`: a bare `dataKey` hands it over silently, while a `dataKey` tuple
|
|
251
|
+
that names the slice explicitly is reported with `console.error` on mount.
|
|
252
|
+
- The param carries only the slices whose value differs from the initial state
|
|
253
|
+
(`initialState` merged over the grid defaults), and only the column filters
|
|
254
|
+
that are active. When nothing differs, the param is removed. A link without the param, or without a slice, opens on the
|
|
255
|
+
initial state; a URL slice never falls back to storage.
|
|
256
|
+
- Writes use `history.replaceState`, never `pushState`. Only the grid's own
|
|
257
|
+
param changes; the path, the hash, other params and `history.state` are kept.
|
|
258
|
+
Two grids on one page use two keys.
|
|
259
|
+
- The URL payload has no version stamp, so a bookmarked link survives a
|
|
260
|
+
release. The shape guards and the realignment against existing columns apply
|
|
261
|
+
as for storage, and `serialize` / `deserialize` apply to the URL payload too.
|
|
262
|
+
- `meta.filter.url: false` on a column keeps its filter out of the param, on
|
|
263
|
+
read and on write. The column's filter is then not persisted anywhere, and a
|
|
264
|
+
filter on it in `initialState` still applies when a link is opened. The
|
|
265
|
+
flag has no effect unless `urlKey` carries `columnFilters`.
|
|
266
|
+
- `urlStorage` replaces the default read and write of the param, for a router
|
|
267
|
+
that owns the URL. `get` returns the param's string or `null`; `set` receives
|
|
268
|
+
the string, or `null` to remove the param. `set` is only called when the
|
|
269
|
+
value changed. Keep `persist` referentially stable here too: react-router
|
|
270
|
+
rebuilds `setSearchParams` on every URL change, so read it through a ref.
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
// react-router: let the router do the replace.
|
|
274
|
+
const [, setSearchParams] = useSearchParams();
|
|
275
|
+
const setSearchParamsRef = useRef(setSearchParams);
|
|
276
|
+
setSearchParamsRef.current = setSearchParams;
|
|
277
|
+
|
|
278
|
+
const persist = useMemo(
|
|
279
|
+
() =>
|
|
280
|
+
({
|
|
281
|
+
urlKey: ["employees", ["columnFilters"]],
|
|
282
|
+
urlStorage: {
|
|
283
|
+
get: (name) => new URLSearchParams(window.location.search).get(name),
|
|
284
|
+
set: (name, value) =>
|
|
285
|
+
setSearchParamsRef.current(
|
|
286
|
+
(prev) => {
|
|
287
|
+
if (value === null) prev.delete(name);
|
|
288
|
+
else prev.set(name, value);
|
|
289
|
+
return prev;
|
|
290
|
+
},
|
|
291
|
+
{ replace: true },
|
|
292
|
+
),
|
|
293
|
+
},
|
|
294
|
+
}) satisfies TMDataGridPersistence,
|
|
295
|
+
[],
|
|
296
|
+
);
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Source: `packages/tmdatagrid/docs/persistence.md` (Deep links).
|
|
300
|
+
|
|
230
301
|
## Return value
|
|
231
302
|
|
|
232
303
|
| Field | Type | Description |
|
package/skills/rows/SKILL.md
CHANGED
|
@@ -8,16 +8,16 @@ description: >
|
|
|
8
8
|
reading a selection through the table store, onRowClick / onCellClick /
|
|
9
9
|
onCellDoubleClick / onCellContextMenu, the renderRowContextMenu slot with its
|
|
10
10
|
internalItems handback, renderColumnMenuItems and rowContextMenuProps, per-row
|
|
11
|
-
styling with rowStyle, rowClassName, striped and the
|
|
12
|
-
details panel through renderDetails,
|
|
13
|
-
DETAILS_COLUMN_ID, row pinning with enableRowPinning
|
|
14
|
-
row-number gutter through enableRowNumbers. Load when
|
|
15
|
-
to a click, opening a detail panel, colouring rows by
|
|
16
|
-
to an edge, or numbering them.
|
|
11
|
+
styling with rowStyle, rowClassName, striped, highlightOnHover and the
|
|
12
|
+
--row-bg rule, the row details panel through renderDetails,
|
|
13
|
+
detailsColumnPosition and DETAILS_COLUMN_ID, row pinning with enableRowPinning
|
|
14
|
+
and row.pin, and the row-number gutter through enableRowNumbers. Load when
|
|
15
|
+
selecting rows, reacting to a click, opening a detail panel, colouring rows by
|
|
16
|
+
their data, pinning rows to an edge, or numbering them.
|
|
17
17
|
metadata:
|
|
18
18
|
type: core
|
|
19
19
|
library: '@jielga/tmdatagrid'
|
|
20
|
-
library_version: '2.
|
|
20
|
+
library_version: '2.3.0'
|
|
21
21
|
sources:
|
|
22
22
|
- 'Jielga/react:packages/tmdatagrid/docs/row-selection.md'
|
|
23
23
|
- 'Jielga/react:packages/tmdatagrid/docs/row-interaction.md'
|
|
@@ -213,8 +213,15 @@ them and they stop showing. `striped` follows position in the view, so it
|
|
|
213
213
|
survives sorting and filtering rather than sticking to records, and pinned rows
|
|
214
214
|
are not striped.
|
|
215
215
|
|
|
216
|
+
The hover tint follows the gestures a row answers: a row takes it under
|
|
217
|
+
`selectionMode: "row"` or a highlight mode, `onRowClick` or
|
|
218
|
+
`renderRowContextMenu`, and a group row never does. A grid with none of those
|
|
219
|
+
shows no hover tint. `highlightOnHover` on the Table overrides that: `true`
|
|
220
|
+
tints every row, `false` none.
|
|
221
|
+
|
|
216
222
|
Rows carry `data-selected`, `data-selected-bg`, `data-highlighted`,
|
|
217
|
-
`data-grouped`, `data-depth`, `data-context-menu
|
|
223
|
+
`data-grouped`, `data-depth`, `data-context-menu`, `data-highlight-on-hover`
|
|
224
|
+
and `data-row-id`, so a
|
|
218
225
|
stylesheet can target any of it without a callback. The boolean attributes are
|
|
219
226
|
present, with the value `"true"`, only while they apply - `data-grouped` only
|
|
220
227
|
on group rows - so `[data-grouped]` and `[data-grouped="true"]` are
|
|
@@ -247,7 +254,9 @@ Which rows are open is TanStack's own `expanded` state, so anything can open
|
|
|
247
254
|
one - `row.toggleExpanded()` from a menu item, `initialState.expanded`,
|
|
248
255
|
`table.toggleAllRowsExpanded()` - and it persists as a `data` slice. The panel
|
|
249
256
|
is a cell spanning the row, not a row: `aria-rowcount` still counts records, and
|
|
250
|
-
a click inside it does not select the row underneath.
|
|
257
|
+
a click inside it does not select the row underneath. It has no padding: content
|
|
258
|
+
fills the row edge to edge, and content that should line up with the cell text
|
|
259
|
+
pads itself with `padding: var(--dg-padding)`. Group rows have no panel;
|
|
251
260
|
expanding one opens its children.
|
|
252
261
|
|
|
253
262
|
Rows are virtualized. A row that leaves the viewport and the `overscan`
|
|
@@ -15,7 +15,7 @@ description: >
|
|
|
15
15
|
metadata:
|
|
16
16
|
type: core
|
|
17
17
|
library: '@jielga/tmdatagrid'
|
|
18
|
-
library_version: '2.
|
|
18
|
+
library_version: '2.3.0'
|
|
19
19
|
sources:
|
|
20
20
|
- 'Jielga/react:packages/tmdatagrid/docs/server-side.md'
|
|
21
21
|
- 'Jielga/react:packages/tmdatagrid/docs/server-query.md'
|
package/skills/testing/SKILL.md
CHANGED
|
@@ -12,7 +12,7 @@ description: >
|
|
|
12
12
|
metadata:
|
|
13
13
|
type: core
|
|
14
14
|
library: '@jielga/tmdatagrid'
|
|
15
|
-
library_version: '2.
|
|
15
|
+
library_version: '2.3.0'
|
|
16
16
|
sources:
|
|
17
17
|
- 'Jielga/react:packages/tmdatagrid/docs/testing.md'
|
|
18
18
|
- 'Jielga/react:packages/tmdatagrid/test/gallery/main.tsx'
|
|
@@ -13,13 +13,15 @@
|
|
|
13
13
|
shape readable against any surface. Scoped through `.filterPills` for the
|
|
14
14
|
specificity to beat Mantine's own rule whichever stylesheet loads last. */
|
|
15
15
|
.filterPills .pill {
|
|
16
|
-
background-color:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
background-color: var(--mantine-color-gray-1);
|
|
17
|
+
color: var(--mantine-color-black);
|
|
18
|
+
border: 1px solid var(--mantine-color-gray-3);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:where([data-mantine-color-scheme="dark"]) .filterPills .pill {
|
|
22
|
+
background-color: var(--mantine-color-dark-5);
|
|
23
|
+
color: var(--mantine-color-dark-0);
|
|
24
|
+
border-color: var(--mantine-color-dark-3);
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
/* The label is a button so a pill can be clicked back open, but it must read as
|
|
@@ -84,7 +84,13 @@
|
|
|
84
84
|
--row-bg: var(--dg-row-new-bg, var(--mantine-color-body));
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
/* The hover tint, on the rows that carry `data-highlight-on-hover` - by default
|
|
88
|
+
the rows that answer a click or a right-click, see the Table's
|
|
89
|
+
`highlightOnHover`. `:where()` adds no specificity, so the rule stays at the
|
|
90
|
+
weight of the state rules around it: declared after the stripe and the entry
|
|
91
|
+
tint, which it wins, and before the selection and highlight rules, which win
|
|
92
|
+
over it. */
|
|
93
|
+
.bodyRow:where([data-highlight-on-hover="true"]):hover {
|
|
88
94
|
--row-bg: var(--mantine-color-default-hover);
|
|
89
95
|
}
|
|
90
96
|
|
|
@@ -320,7 +326,9 @@
|
|
|
320
326
|
/* Base and tint, exactly as .bodyCell paints them. */
|
|
321
327
|
background-color: var(--mantine-color-body);
|
|
322
328
|
background-image: linear-gradient(var(--row-bg), var(--row-bg));
|
|
323
|
-
padding:
|
|
329
|
+
/* No padding: the panel is the user's content, and a nested grid or a tab
|
|
330
|
+
strip wants the full width. Content that should line up with the cell
|
|
331
|
+
text pads itself with var(--dg-padding). */
|
|
324
332
|
/* The row above may be the selection control, which turns text selection off
|
|
325
333
|
for everything inside it. A panel is content, so it takes both back. */
|
|
326
334
|
user-select: text;
|
|
@@ -477,14 +485,15 @@
|
|
|
477
485
|
the browser's default so the colour is the grid's to state - override with
|
|
478
486
|
`--dg-match-highlight-bg` on the grid. */
|
|
479
487
|
.matchHighlight {
|
|
480
|
-
background-color: var(
|
|
481
|
-
--dg-match-highlight-bg,
|
|
482
|
-
light-dark(var(--mantine-color-yellow-2), rgba(250, 176, 5, 0.35))
|
|
483
|
-
);
|
|
488
|
+
background-color: var(--dg-match-highlight-bg, var(--mantine-color-yellow-2));
|
|
484
489
|
color: inherit;
|
|
485
490
|
border-radius: 2px;
|
|
486
491
|
}
|
|
487
492
|
|
|
493
|
+
:where([data-mantine-color-scheme="dark"]) .matchHighlight {
|
|
494
|
+
background-color: var(--dg-match-highlight-bg, rgba(250, 176, 5, 0.35));
|
|
495
|
+
}
|
|
496
|
+
|
|
488
497
|
/* The summary row - one sticky row of column footers along the bottom edge,
|
|
489
498
|
rendered only while at least one column defines `footer`. Same subgrid
|
|
490
499
|
placement as the header, so its cells sit exactly on the body's tracks.
|
|
@@ -90,7 +90,7 @@ import {
|
|
|
90
90
|
resolveRowSelectionClick,
|
|
91
91
|
} from "../core/rowSelection";
|
|
92
92
|
import { readPinnedRows } from "../core/rowPinning";
|
|
93
|
-
import {
|
|
93
|
+
import { filterNarrowsRows } from "../core/filterOperators";
|
|
94
94
|
import { buildMatchNeedles, findMatchRanges } from "../core/matchHighlight";
|
|
95
95
|
import { ROW_NUMBER_COLUMN_ID } from "./TMDataGridRowNumberColumn";
|
|
96
96
|
import { SearchIcon } from "./icons";
|
|
@@ -631,6 +631,14 @@ export type TMDataGridTableProps<TData extends RowData> = {
|
|
|
631
631
|
* stay put while the virtualizer mounts and unmounts rows.
|
|
632
632
|
*/
|
|
633
633
|
striped?: boolean;
|
|
634
|
+
/**
|
|
635
|
+
* Whether a body row takes the hover tint under the pointer. Unset, a row
|
|
636
|
+
* takes it when the row itself answers a gesture: `selectionMode: "row"`,
|
|
637
|
+
* a highlight mode, `onRowClick` or `renderRowContextMenu`. Group rows sit
|
|
638
|
+
* out those gestures and so sit out the tint too. `true` tints every row,
|
|
639
|
+
* `false` none. The row carries `data-highlight-on-hover` while it applies.
|
|
640
|
+
*/
|
|
641
|
+
highlightOnHover?: boolean;
|
|
634
642
|
/**
|
|
635
643
|
* Called when the scroll *arrives* at an edge - once per arrival, not per
|
|
636
644
|
* scroll event, and not on mount (the grid starts at the top-left edge).
|
|
@@ -751,6 +759,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
751
759
|
rowClassName,
|
|
752
760
|
rowStyle,
|
|
753
761
|
striped = false,
|
|
762
|
+
highlightOnHover,
|
|
754
763
|
onScrollToTop,
|
|
755
764
|
onScrollToBottom,
|
|
756
765
|
onScrollToLeft,
|
|
@@ -1480,18 +1489,12 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
1480
1489
|
const isEmpty = rows.length === 0 && pinnedRowCount === 0;
|
|
1481
1490
|
// Which emptiness this is. A column filter counts by the rule the pills, the
|
|
1482
1491
|
// header indicator and the page reset use, so the grid has one definition
|
|
1483
|
-
// of "active"
|
|
1484
|
-
//
|
|
1485
|
-
//
|
|
1486
|
-
// value written by consumer code narrows the rows as far as the grid can
|
|
1487
|
-
// tell. The body already subscribes to the whole table store, so these
|
|
1488
|
-
// reads are reactive.
|
|
1492
|
+
// of "active" - see `filterNarrowsRows`. The half-typed
|
|
1493
|
+
// `{ operator, value: "" }` the filter panel seeds filters nothing. The body
|
|
1494
|
+
// already subscribes to the whole table store, so these reads are reactive.
|
|
1489
1495
|
const emptyGlobalFilter = table.store.state.globalFilter;
|
|
1490
1496
|
const hasActiveFilters =
|
|
1491
|
-
table.store.state.columnFilters.some(
|
|
1492
|
-
(entry) =>
|
|
1493
|
-
!isTMDataGridFilterValue(entry.value) || isFilterActive(entry.value),
|
|
1494
|
-
) ||
|
|
1497
|
+
table.store.state.columnFilters.some(filterNarrowsRows) ||
|
|
1495
1498
|
(typeof emptyGlobalFilter === "string"
|
|
1496
1499
|
? emptyGlobalFilter.trim() !== ""
|
|
1497
1500
|
: emptyGlobalFilter != null);
|
|
@@ -2833,6 +2836,14 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
2833
2836
|
) => {
|
|
2834
2837
|
const isGroupRow = row.getIsGrouped();
|
|
2835
2838
|
const isInteractive = rowGesturesFor(row);
|
|
2839
|
+
// The hover tint promises that the row answers the pointer, so
|
|
2840
|
+
// by default it follows the gestures the row takes: the ones
|
|
2841
|
+
// behind `isInteractive`, and the context menu - which a group
|
|
2842
|
+
// row sits out as well, see the row's onContextMenu below.
|
|
2843
|
+
const highlightsOnHover =
|
|
2844
|
+
highlightOnHover ??
|
|
2845
|
+
(isInteractive ||
|
|
2846
|
+
(renderRowContextMenu !== undefined && !isGroupRow));
|
|
2836
2847
|
const rowCells = [
|
|
2837
2848
|
...row.getStartVisibleCells(),
|
|
2838
2849
|
...row.getCenterVisibleCells(),
|
|
@@ -2940,6 +2951,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
|
|
|
2940
2951
|
data-selects-on-click={
|
|
2941
2952
|
(selectsOnRowClick && !isGroupRow) || undefined
|
|
2942
2953
|
}
|
|
2954
|
+
data-highlight-on-hover={highlightsOnHover || undefined}
|
|
2943
2955
|
aria-selected={
|
|
2944
2956
|
features.rowSelection ? row.getIsSelected() : undefined
|
|
2945
2957
|
}
|
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
A box-shadow is drawn per cell, and its blur fades in at each cell's own top
|
|
6
6
|
and bottom edge - stacked down a column that reads as banding at every row
|
|
7
7
|
seam. Instead: a gradient pseudo element pinned to `top: 0; bottom: 0` so
|
|
8
|
-
consecutive cells butt together into one unbroken band.
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
consecutive cells butt together into one unbroken band.
|
|
9
|
+
|
|
10
|
+
The dark scheme is a second rule under Mantine's `data-mantine-color-scheme`
|
|
11
|
+
attribute, not the `light-dark` function: scripts/package-stylesheets.test.mjs
|
|
12
|
+
says why.
|
|
11
13
|
|
|
12
14
|
No border. A 1px line the colour of the grid's own borders drew a hard rule
|
|
13
15
|
between the pinned lanes and the data, so the pinned columns read as a
|
|
@@ -31,8 +33,8 @@
|
|
|
31
33
|
left: 100%;
|
|
32
34
|
background: linear-gradient(
|
|
33
35
|
to right,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
rgba(0, 0, 0, 0.07),
|
|
37
|
+
rgba(0, 0, 0, 0.025) 45%,
|
|
36
38
|
transparent
|
|
37
39
|
);
|
|
38
40
|
}
|
|
@@ -41,8 +43,26 @@
|
|
|
41
43
|
right: 100%;
|
|
42
44
|
background: linear-gradient(
|
|
43
45
|
to left,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
rgba(0, 0, 0, 0.07),
|
|
47
|
+
rgba(0, 0, 0, 0.025) 45%,
|
|
48
|
+
transparent
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
:where([data-mantine-color-scheme="dark"]) .stickyLeft::after {
|
|
53
|
+
background: linear-gradient(
|
|
54
|
+
to right,
|
|
55
|
+
rgba(0, 0, 0, 0.26),
|
|
56
|
+
rgba(0, 0, 0, 0.09) 45%,
|
|
57
|
+
transparent
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
:where([data-mantine-color-scheme="dark"]) .stickyRight::after {
|
|
62
|
+
background: linear-gradient(
|
|
63
|
+
to left,
|
|
64
|
+
rgba(0, 0, 0, 0.26),
|
|
65
|
+
rgba(0, 0, 0, 0.09) 45%,
|
|
46
66
|
transparent
|
|
47
67
|
);
|
|
48
68
|
}
|
|
@@ -106,4 +106,12 @@ export type TMDataGridColumnFilterOptions = {
|
|
|
106
106
|
* See {@link TMDataGridFilterControlComponent}.
|
|
107
107
|
*/
|
|
108
108
|
control?: TMDataGridFilterControlComponent;
|
|
109
|
+
/**
|
|
110
|
+
* Whether this column's filter goes into the `persist.urlKey` search param.
|
|
111
|
+
* Defaults to `true`. `false` keeps it out of the param, on read and on
|
|
112
|
+
* write. Only has an effect when `urlKey` carries `columnFilters`, and since such
|
|
113
|
+
* a slice is not stored under `dataKey` either, the filter is then not
|
|
114
|
+
* persisted anywhere.
|
|
115
|
+
*/
|
|
116
|
+
url?: boolean;
|
|
109
117
|
};
|
|
@@ -251,6 +251,19 @@ export function isFilterActive(value: unknown): boolean {
|
|
|
251
251
|
: typeof value.value === "string" && value.value.trim() !== "";
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Whether one `columnFilters` entry narrows the rows, by the one rule the grid
|
|
256
|
+
* uses for "active": an envelope counts once {@link isFilterActive} says so,
|
|
257
|
+
* and a value that is not an envelope always counts, since a raw value written
|
|
258
|
+
* by consumer code narrows the rows as far as the grid can tell.
|
|
259
|
+
*
|
|
260
|
+
* @internal Shared by the empty state and the `urlKey` param; not exported
|
|
261
|
+
* from the package.
|
|
262
|
+
*/
|
|
263
|
+
export function filterNarrowsRows(entry: { value: unknown }): boolean {
|
|
264
|
+
return !isTMDataGridFilterValue(entry.value) || isFilterActive(entry.value);
|
|
265
|
+
}
|
|
266
|
+
|
|
254
267
|
/** One column's filter, typed - what `columnFilters` holds per entry. */
|
|
255
268
|
export type TMDataGridColumnFilter = {
|
|
256
269
|
id: string;
|