@jielga/tmdatagrid 1.0.0 → 1.0.1

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.
Files changed (68) hide show
  1. package/README.md +8 -8
  2. package/dist/index.d.ts +225 -225
  3. package/dist/index.js +58 -50
  4. package/dist/index.js.map +1 -1
  5. package/dist/styles.css +1 -1
  6. package/package.json +3 -2
  7. package/skills/columns/SKILL.md +4 -4
  8. package/skills/features/SKILL.md +30 -30
  9. package/skills/getting-started/SKILL.md +16 -16
  10. package/skills/options/SKILL.md +8 -8
  11. package/skills/server-side/SKILL.md +7 -7
  12. package/skills/testing/SKILL.md +12 -12
  13. package/src/tmdatagrid/TMDataGridContext.ts +2 -2
  14. package/src/tmdatagrid/components/TMDataGrid.module.css +2 -2
  15. package/src/tmdatagrid/components/TMDataGrid.tsx +5 -5
  16. package/src/tmdatagrid/components/TMDataGridCellEditor.tsx +4 -4
  17. package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +2 -2
  18. package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +6 -6
  19. package/src/tmdatagrid/components/TMDataGridEditActions.tsx +2 -2
  20. package/src/tmdatagrid/components/TMDataGridEditColumn.tsx +4 -4
  21. package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +6 -6
  22. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +6 -6
  23. package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +2 -2
  24. package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +1 -1
  25. package/src/tmdatagrid/components/TMDataGridFooter.module.css +1 -1
  26. package/src/tmdatagrid/components/TMDataGridFooter.tsx +12 -6
  27. package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +1 -1
  28. package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +5 -5
  29. package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +8 -8
  30. package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +12 -12
  31. package/src/tmdatagrid/components/TMDataGridRowNumberColumn.tsx +4 -4
  32. package/src/tmdatagrid/components/TMDataGridSearch.tsx +5 -5
  33. package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +8 -8
  34. package/src/tmdatagrid/components/TMDataGridTable.module.css +18 -18
  35. package/src/tmdatagrid/components/TMDataGridTable.tsx +116 -116
  36. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +5 -5
  37. package/src/tmdatagrid/components/editors/TMDataGridBooleanEditor.tsx +1 -1
  38. package/src/tmdatagrid/components/editors/TMDataGridDateEditor.tsx +2 -2
  39. package/src/tmdatagrid/components/editors/TMDataGridMultiSelectEditor.tsx +1 -1
  40. package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +1 -1
  41. package/src/tmdatagrid/components/editors/TMDataGridSelectEditor.tsx +2 -2
  42. package/src/tmdatagrid/components/editors/editorShared.ts +3 -3
  43. package/src/tmdatagrid/components/filters/DgDateRangeFilter.tsx +1 -1
  44. package/src/tmdatagrid/components/filters/DgRangeSliderFilter.tsx +1 -1
  45. package/src/tmdatagrid/components/filters/DgTriStateFilter.tsx +1 -1
  46. package/src/tmdatagrid/components/filters/TMDataGridFilterValueInput.tsx +2 -2
  47. package/src/tmdatagrid/components/sticky.module.css +8 -8
  48. package/src/tmdatagrid/core/autosize.ts +4 -4
  49. package/src/tmdatagrid/core/capabilities.ts +17 -17
  50. package/src/tmdatagrid/core/cellExport.ts +13 -13
  51. package/src/tmdatagrid/core/cellNavigation.ts +6 -6
  52. package/src/tmdatagrid/core/cellRange.ts +4 -4
  53. package/src/tmdatagrid/core/columnOptions.ts +2 -2
  54. package/src/tmdatagrid/core/columnOrdering.ts +2 -2
  55. package/src/tmdatagrid/core/columnUtils.ts +3 -3
  56. package/src/tmdatagrid/core/editEngine.ts +49 -49
  57. package/src/tmdatagrid/core/expanding.ts +5 -5
  58. package/src/tmdatagrid/core/filterControls.ts +5 -5
  59. package/src/tmdatagrid/core/filterOperators.ts +14 -14
  60. package/src/tmdatagrid/core/labels.ts +8 -8
  61. package/src/tmdatagrid/core/matchHighlight.ts +4 -4
  62. package/src/tmdatagrid/core/persistence.ts +8 -8
  63. package/src/tmdatagrid/core/quickSearch.ts +8 -8
  64. package/src/tmdatagrid/core/rowPinning.ts +3 -3
  65. package/src/tmdatagrid/core/rowSelection.ts +12 -12
  66. package/src/tmdatagrid/core/sizes.ts +1 -1
  67. package/src/tmdatagrid/core/summary.ts +3 -3
  68. package/src/tmdatagrid/useTMDataGrid.tsx +79 -79
@@ -70,7 +70,7 @@ export type TMDataGridColumnLayout = {
70
70
  pinnedAt: "left" | "right" | false;
71
71
  /** Distance in px from the grid's left or right edge. */
72
72
  offset: number;
73
- /** Last left-pinned / first right-pinned column — the one that casts the edge. */
73
+ /** Last left-pinned / first right-pinned column - the one that casts the edge. */
74
74
  isBoundary: boolean;
75
75
  };
76
76
 
@@ -96,7 +96,7 @@ const FOCUSABLE_IN_CELL = [
96
96
 
97
97
  /**
98
98
  * The mounted element for a cell position, or `null` when its row is scrolled
99
- * out — the normal case for a move that has to scroll before it can focus.
99
+ * out - the normal case for a move that has to scroll before it can focus.
100
100
  */
101
101
  function findCellElement(
102
102
  container: HTMLElement,
@@ -115,7 +115,7 @@ function findCellElement(
115
115
  * so as far as the browser is concerned a cell sliding underneath them is
116
116
  * still perfectly visible, and it stops scrolling the moment the cell's edge
117
117
  * reaches the container's. The visible edge is the inside of the pinned lane,
118
- * which only this component knows — it laid the lanes out.
118
+ * which only this component knows - it laid the lanes out.
119
119
  */
120
120
  function keepColumnInView({
121
121
  container,
@@ -149,14 +149,14 @@ function keepColumnInView({
149
149
  * | Cell | Renders |
150
150
  * | ---- | ------- |
151
151
  * | On a data row | the column's `cell`, as always |
152
- * | Placeholder — a grouped column other than this row's own | nothing |
152
+ * | Placeholder - a grouped column other than this row's own | nothing |
153
153
  * | Aggregated, column declares `aggregatedCell` | that |
154
154
  * | Aggregated, column declares an `aggregationFn` | the column's `cell`, over the aggregate |
155
155
  * | Aggregated, column declares neither | nothing |
156
156
  *
157
157
  * That last row is the one worth spelling out. Without an aggregation function
158
158
  * `getValue()` is `undefined` on a group row, so the column's own renderer
159
- * would be handed nothing — and a renderer that formats what it gets
159
+ * would be handed nothing - and a renderer that formats what it gets
160
160
  * (`value.toFixed(2)`) would throw. Blank is both the safe answer and the right
161
161
  * one: a plain "group by" is a tree, not a summary, and a column only joins in
162
162
  * once it has been told how.
@@ -178,7 +178,7 @@ function renderCellContent(
178
178
 
179
179
  /**
180
180
  * What a cell needs to take part in cell selection, or `undefined` while the
181
- * feature is off — which is what keeps a plain grid's cells exactly as they
181
+ * feature is off - which is what keeps a plain grid's cells exactly as they
182
182
  * were: no tab stop, no `gridcell` role, no coordinates in the DOM.
183
183
  *
184
184
  * The coordinates are there for the delegated key handler, which reads them off
@@ -196,13 +196,13 @@ export type TMDataGridCellNav = {
196
196
  selected: boolean;
197
197
  /**
198
198
  * Which sides of the rectangle this cell is on, or `null` when it is not in
199
- * one. The outline is drawn per cell — see {@link boundsEdges}.
199
+ * one. The outline is drawn per cell - see {@link boundsEdges}.
200
200
  */
201
201
  edges: { top: boolean; bottom: boolean; left: boolean; right: boolean } | null;
202
202
  };
203
203
 
204
204
  /**
205
- * The text with its matched slices wrapped in `<mark>` — or handed back
205
+ * The text with its matched slices wrapped in `<mark>` - or handed back
206
206
  * whole when nothing matches. Only ever called on string output; a renderer
207
207
  * returning its own elements never reaches this.
208
208
  */
@@ -249,12 +249,12 @@ function TMDataGridBodyCell({
249
249
  /** The mounted editor, when this is the cell being edited. */
250
250
  editor?: ReactNode;
251
251
  /**
252
- * Replaces the column renderer's output — the row-number gutter, whose
252
+ * Replaces the column renderer's output - the row-number gutter, whose
253
253
  * value only the body knows. `undefined` means "render normally".
254
254
  */
255
255
  contentOverride?: ReactNode;
256
256
  /**
257
- * Needles to highlight in string output — see `enableMatchHighlighting`.
257
+ * Needles to highlight in string output - see `enableMatchHighlighting`.
258
258
  * `undefined` almost always: only set while a highlightable filter is
259
259
  * active for this column.
260
260
  */
@@ -267,7 +267,7 @@ function TMDataGridBodyCell({
267
267
  onContextMenu?: (event: MouseEvent<HTMLDivElement>) => void;
268
268
  }) {
269
269
  // The edit markers subscribe here, per cell, all to the one projection
270
- // store — so typing in an editor repaints the edited row's cells and
270
+ // store - so typing in an editor repaints the edited row's cells and
271
271
  // nothing else. Constant `false` everywhere while editing is off.
272
272
  const { table, edit } = useTMDataGridContext();
273
273
  const fieldName = getEditFieldName(cell.column);
@@ -296,7 +296,7 @@ function TMDataGridBodyCell({
296
296
  data-cell={nav ? true : undefined}
297
297
  // Both coordinates are always present, not only under cell selection:
298
298
  // autosize finds a column's mounted cells by the column id, and the pair
299
- // is how a test addresses one cell —
299
+ // is how a test addresses one cell -
300
300
  // `[data-row-id="42"][data-column-id="name"]`. The cell-navigation
301
301
  // selectors also require `data-cell`, so they are unaffected.
302
302
  data-row-id={cell.row.id}
@@ -312,7 +312,7 @@ function TMDataGridBodyCell({
312
312
  data-edge-left={nav?.edges?.left}
313
313
  data-edge-right={nav?.edges?.right}
314
314
  // Bubbles, so focus landing on a control inside the cell counts as
315
- // landing on the cell — the ring follows the user into the checkbox
315
+ // landing on the cell - the ring follows the user into the checkbox
316
316
  // rather than being left behind on whichever cell they came from.
317
317
  onFocus={onFocus}
318
318
  onClick={onClick}
@@ -341,7 +341,7 @@ function TMDataGridBodyCell({
341
341
  left: layout.pinnedAt === "left" ? layout.offset : undefined,
342
342
  right: layout.pinnedAt === "right" ? layout.offset : undefined,
343
343
  // The focus ring is drawn inside the cell's own box, so the cell has to
344
- // be able to stack above its neighbours — a plain one to lift the ring
344
+ // be able to stack above its neighbours - a plain one to lift the ring
345
345
  // over the pinned lane it sits beside, a pinned one to keep the ring
346
346
  // whole while the rest of the row slides under it. Values from the
347
347
  // stacking ladder in TMDataGrid.module.css.
@@ -360,8 +360,8 @@ function TMDataGridBodyCell({
360
360
  {editor ?? (
361
361
  <span className={classes.cellContent}>
362
362
  {(() => {
363
- // Highlighting replicates the *default* renderer — value, then
364
- // `toString` — with the matched slices marked. A column with its
363
+ // Highlighting replicates the *default* renderer - value, then
364
+ // `toString` - with the matched slices marked. A column with its
365
365
  // own `cell` opts out by existing: its renderer's identity is not
366
366
  // the default's, and the grid will not rummage inside its output.
367
367
  if (
@@ -389,7 +389,7 @@ function TMDataGridBodyCell({
389
389
  * when `rowContextMenu` is set.
390
390
  *
391
391
  * One instance for the whole body rather than one per row. A Mantine `Menu` is
392
- * a `Popover`, and a closed Popover still runs its hooks on every render — and
392
+ * a `Popover`, and a closed Popover still runs its hooks on every render - and
393
393
  * the body re-renders on every scroll frame, because that is how virtualization
394
394
  * works. Wrapping each of ~20 mounted rows measured a fifth onto a body render;
395
395
  * wrapping the group is the same behaviour for one instance.
@@ -418,7 +418,7 @@ function TMDataGridBodyRowGroup({
418
418
  role="rowgroup"
419
419
  style={{ display: "contents" }}
420
420
  // Runs before Mantine's own handler, which `Menu.ContextMenu` composes on
421
- // top of this one — so the row and cell are known by the time the
421
+ // top of this one - so the row and cell are known by the time the
422
422
  // dropdown is built and opened at the pointer.
423
423
  onContextMenu={enabled ? onContextMenu : undefined}
424
424
  >
@@ -453,7 +453,7 @@ export type TMDataGridRowContextMenuArgs<TData extends RowData> = {
453
453
  row: Row<TMDataGridFeatures, TData>;
454
454
  /**
455
455
  * The cell under the pointer. `null` only when the right-click landed on the
456
- * row but on no cell — which a custom cell renderer that stops propagation
456
+ * row but on no cell - which a custom cell renderer that stops propagation
457
457
  * can cause.
458
458
  */
459
459
  cell: Cell<TMDataGridFeatures, TData, unknown> | null;
@@ -465,7 +465,7 @@ export type TMDataGridRowContextMenuArgs<TData extends RowData> = {
465
465
  };
466
466
 
467
467
  /**
468
- * Builds the contents of a row's context menu — `Menu.Item`, `Menu.Label`,
468
+ * Builds the contents of a row's context menu - `Menu.Item`, `Menu.Label`,
469
469
  * `Menu.Divider`, `Menu.Sub`, or any other node. The grid owns the `Menu` and
470
470
  * its `Menu.Dropdown`; this fills the dropdown.
471
471
  */
@@ -474,7 +474,7 @@ export type TMDataGridRowContextMenu<TData extends RowData> = (
474
474
  ) => ReactNode;
475
475
 
476
476
  /**
477
- * What the `onCellClick` family receives — the cell with its row and column,
477
+ * What the `onCellClick` family receives - the cell with its row and column,
478
478
  * in the consumer's own row type, plus the pointer event.
479
479
  */
480
480
  export type TMDataGridCellEventArgs<TData extends RowData> = {
@@ -486,7 +486,7 @@ export type TMDataGridCellEventArgs<TData extends RowData> = {
486
486
 
487
487
  /**
488
488
  * Inline styles for a row. Widened to accept CSS variables, because setting
489
- * `--row-bg` is the supported way to colour a row — see {@link
489
+ * `--row-bg` is the supported way to colour a row - see {@link
490
490
  * TMDataGridTableProps.rowStyle}.
491
491
  */
492
492
  export type TMDataGridRowStyle =
@@ -501,8 +501,8 @@ export type TMDataGridTableProps<TData extends RowData> = {
501
501
  onRowClick?: (row: Row<TMDataGridFeatures, TData>) => void;
502
502
  /**
503
503
  * Called when a body cell is clicked. Composes, never suppresses: whatever
504
- * the click already does — selecting, highlighting, moving the cell cursor
505
- * — still happens. Group rows sit out the cell handlers the way they sit
504
+ * the click already does - selecting, highlighting, moving the cell cursor
505
+ * - still happens. Group rows sit out the cell handlers the way they sit
506
506
  * out `onRowClick`, and for the same reason.
507
507
  */
508
508
  onCellClick?: (args: TMDataGridCellEventArgs<TData>) => void;
@@ -515,7 +515,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
515
515
  */
516
516
  onCellContextMenu?: (args: TMDataGridCellEventArgs<TData>) => void;
517
517
  /**
518
- * Class for a body row — a string, or a function of the row (group rows
518
+ * Class for a body row - a string, or a function of the row (group rows
519
519
  * included; test `row.getIsGrouped()` to skip them). Added after the grid's
520
520
  * own row class.
521
521
  */
@@ -526,7 +526,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
526
526
  * Inline style for a body row. To colour a row, set `--row-bg` rather than
527
527
  * `background`: the row's own background, its sticky pinned cells and the
528
528
  * cell-range tint all read that variable, and hover/selection/highlight
529
- * keep working on top of it — a raw `background` bypasses all of them.
529
+ * keep working on top of it - a raw `background` bypasses all of them.
530
530
  *
531
531
  * ```tsx
532
532
  * rowStyle={(row) =>
@@ -539,12 +539,12 @@ export type TMDataGridTableProps<TData extends RowData> = {
539
539
  | ((row: Row<TMDataGridFeatures, TData>) => TMDataGridRowStyle | undefined);
540
540
  /**
541
541
  * Every second row takes `--dg-row-striped-bg`. Computed from the row's
542
- * position in the view — sorting and filtering restripe, and the stripes
542
+ * position in the view - sorting and filtering restripe, and the stripes
543
543
  * stay put while the virtualizer mounts and unmounts rows.
544
544
  */
545
545
  striped?: boolean;
546
546
  /**
547
- * Called when the scroll *arrives* at an edge — once per arrival, not per
547
+ * Called when the scroll *arrives* at an edge - once per arrival, not per
548
548
  * scroll event, and not on mount (the grid starts at the top-left edge).
549
549
  * For loading more rows as the end approaches, `onReachEnd` is the better
550
550
  * hook: it fires rows-early and latches per row count.
@@ -557,10 +557,10 @@ export type TMDataGridTableProps<TData extends RowData> = {
557
557
  /** As {@link onScrollToTop}, for the right edge. */
558
558
  onScrollToRight?: () => void;
559
559
  /**
560
- * Rendered centred in the body when the view is empty — the branded blank
560
+ * Rendered centred in the body when the view is empty - the branded blank
561
561
  * slate. It takes over states 3 and 4 of the empty matrix (see the docs):
562
562
  * loading still shows the loader, and open entry rows still show only
563
- * themselves. `hasActiveFilters` says which emptiness this is — a filter
563
+ * themselves. `hasActiveFilters` says which emptiness this is - a filter
564
564
  * that matched nothing wants a "clear filters" invitation, a grid with no
565
565
  * data wants a "create the first one".
566
566
  */
@@ -570,7 +570,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
570
570
  }) => ReactNode;
571
571
  /**
572
572
  * Contents of the menu a right-click on a row opens, at the pointer. Return
573
- * `null` to leave a row without one — the browser's own menu stays suppressed
573
+ * `null` to leave a row without one - the browser's own menu stays suppressed
574
574
  * either way.
575
575
  *
576
576
  * ```tsx
@@ -588,23 +588,23 @@ export type TMDataGridTableProps<TData extends RowData> = {
588
588
  * />
589
589
  * ```
590
590
  *
591
- * Called during render, and only for the row whose menu is open — so it stays
591
+ * Called during render, and only for the row whose menu is open - so it stays
592
592
  * a pure function of the row, and cost per row does not matter.
593
593
  */
594
594
  rowContextMenu?: TMDataGridRowContextMenu<TData>;
595
595
  /**
596
- * Passed to the Mantine `Menu` the grid wraps the row in — `width`, `shadow`,
596
+ * Passed to the Mantine `Menu` the grid wraps the row in - `width`, `shadow`,
597
597
  * `position`, `transitionProps` and the rest. Its open state is the grid's.
598
598
  */
599
599
  rowContextMenuProps?: Omit<MenuProps, "opened" | "onChange" | "children">;
600
600
  /**
601
601
  * How Ctrl+C and the export item write values, under
602
- * `cellSelection: "range"`. Defaults to the Nordic Excel conventions — see
602
+ * `cellSelection: "range"`. Defaults to the Nordic Excel conventions - see
603
603
  * {@link TMDataGridCellExportOptions}.
604
604
  */
605
605
  cellExport?: TMDataGridCellExportOptions;
606
606
  /**
607
- * Called when the scroll approaches the last row — the infinite-scroll
607
+ * Called when the scroll approaches the last row - the infinite-scroll
608
608
  * hook-in. Append the next page to `data` and the virtualizer keeps its
609
609
  * position; fires once per row count, so a pending fetch is not asked
610
610
  * again until it lands.
@@ -614,7 +614,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
614
614
  * ```
615
615
  *
616
616
  * Sorting and filtering must be server-side (`manual*`) on a grid that
617
- * loads this way — the client only ever holds a prefix of the data. Not
617
+ * loads this way - the client only ever holds a prefix of the data. Not
618
618
  * compatible with `enablePagination`, which slices the same scroll.
619
619
  */
620
620
  onReachEnd?: () => void;
@@ -623,7 +623,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
623
623
  */
624
624
  reachEndThreshold?: number;
625
625
  /**
626
- * Accessible name for the grid — what a screen reader announces on entry,
626
+ * Accessible name for the grid - what a screen reader announces on entry,
627
627
  * and what `getByRole("grid", { name })` matches. Worth setting on any page
628
628
  * holding more than one grid; without it they are all just "grid".
629
629
  */
@@ -634,7 +634,7 @@ export type TMDataGridTableProps<TData extends RowData> = {
634
634
 
635
635
  /**
636
636
  * The scrollable grid surface. Always virtualized: only the rows inside the
637
- * viewport (plus overscan) are mounted — which is what makes the default
637
+ * viewport (plus overscan) are mounted - which is what makes the default
638
638
  * no-pagination mode viable at any row count. Pagination is opt-in via
639
639
  * `enablePagination` (or implied by `manualPagination`).
640
640
  */
@@ -683,7 +683,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
683
683
  const focusedCell = useSelector(ui, (state) => state.focusedCell);
684
684
  const cellRange = useSelector(ui, (state) => state.cellRange);
685
685
  // Which cell has an editor open. The projection (dirty/error markers) is
686
- // subscribed per cell instead — see TMDataGridBodyCell.
686
+ // subscribed per cell instead - see TMDataGridBodyCell.
687
687
  const editActive = useSelector(edit.store, (state) => state.active);
688
688
  const newRowCount = useSelector(edit.store, (state) => state.newRows.length);
689
689
  const deletedRowIds = useSelector(edit.store, (state) => state.deletedRowIds);
@@ -697,14 +697,14 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
697
697
  // the rows as delivered, so the same branch serves server paging.
698
698
  const rows = getDisplayedRows(table, features);
699
699
 
700
- // Per-column highlight needles, or `null` while off or nothing is active —
700
+ // Per-column highlight needles, or `null` while off or nothing is active -
701
701
  // the common case, costing one flag check per render.
702
702
  const matchNeedles = features.matchHighlighting
703
703
  ? buildMatchNeedles(table)
704
704
  : null;
705
705
 
706
706
  // The edge blocks. `getDisplayedRows` above has already taken these out of
707
- // the scrolling order; stale ids resolve to nothing — see readPinnedRows.
707
+ // the scrolling order; stale ids resolve to nothing - see readPinnedRows.
708
708
  const pinnedTopRows = features.rowPinning ? readPinnedRows(table, "top") : [];
709
709
  const pinnedBottomRows = features.rowPinning
710
710
  ? readPinnedRows(table, "bottom")
@@ -713,7 +713,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
713
713
 
714
714
  // The row-number gutter's numbers: one pass over the view per render, only
715
715
  // while the lane exists. A cell cannot know its display position, so the
716
- // body hands each row its number — group rows get none (they are headings
716
+ // body hands each row its number - group rows get none (they are headings
717
717
  // over the rows being counted), and paging continues the count across
718
718
  // pages rather than restarting every page at 1.
719
719
  let rowNumberById: Map<string, number> | null = null;
@@ -732,7 +732,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
732
732
  * Whether this row opens a detail panel underneath it.
733
733
  *
734
734
  * Group rows are out: expanding one opens its children, and they share the
735
- * `expanded` state with details — so a grouped grid with `renderDetails` set
735
+ * `expanded` state with details - so a grouped grid with `renderDetails` set
736
736
  * would otherwise render a panel about the group's first record.
737
737
  */
738
738
  const showsDetails = (row: Row<TMDataGridFeatures, TMDataGridRowData>) =>
@@ -741,7 +741,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
741
741
  /**
742
742
  * `meta.autoSize` columns, sized once after the first rows are in the DOM.
743
743
  * A ref rather than an effect dependency: this must run exactly once per
744
- * mount, and only for columns no persisted or user width already covers —
744
+ * mount, and only for columns no persisted or user width already covers -
745
745
  * autosizing again on data changes would fight a width the user has since
746
746
  * dragged.
747
747
  */
@@ -760,7 +760,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
760
760
 
761
761
  /**
762
762
  * The header's height, published as `--dg-header-height` for the entry
763
- * block to stick under — never measured otherwise (`top: 0` needs no
763
+ * block to stick under - never measured otherwise (`top: 0` needs no
764
764
  * number). A ResizeObserver, mounted only while the block is in use: the
765
765
  * same discipline `renderDetails` applies to `measureElement`.
766
766
  */
@@ -785,7 +785,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
785
785
 
786
786
  /**
787
787
  * The entry block's height, published as `--dg-entry-height` so the pinned
788
- * top block can stack under it — measured only while both blocks exist,
788
+ * top block can stack under it - measured only while both blocks exist,
789
789
  * which is the only time the offset is anything but 0.
790
790
  */
791
791
  useEffect(() => {
@@ -847,14 +847,14 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
847
847
  getScrollElement: () => scrollContainerRef.current,
848
848
  /**
849
849
  * Exact for a plain row, which is fixed at `rowHeight`, and a guess for a
850
- * row showing a detail panel — the panel is as tall as whatever the
850
+ * row showing a detail panel - the panel is as tall as whatever the
851
851
  * consumer renders. Rows are measured whenever details are on (see
852
852
  * `measureElement` below), so this only has to hold until the row has been
853
853
  * on screen once.
854
854
  *
855
855
  * Not a `useCallback`, unlike `getItemKey` below it: the virtualizer's
856
856
  * measurement cache lists `getItemKey` among its dependencies and not this,
857
- * so a stable identity here would buy nothing — and the closure has to see
857
+ * so a stable identity here would buy nothing - and the closure has to see
858
858
  * the current expansion to answer at all.
859
859
  */
860
860
  estimateSize: (index: number) => {
@@ -864,8 +864,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
864
864
  },
865
865
  /**
866
866
  * Zero is never a row: every one carries `minHeight: rowHeight`. An element
867
- * reports it before layout has run — and always under jsdom, which has no
868
- * layout at all — and a row cached at zero height stays that way until
867
+ * reports it before layout has run - and always under jsdom, which has no
868
+ * layout at all - and a row cached at zero height stays that way until
869
869
  * something resizes it. The estimate stands in until there is a real
870
870
  * measurement.
871
871
  */
@@ -892,7 +892,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
892
892
  */
893
893
  useEffect(() => {
894
894
  scrollerRef.current = ({ rowId, align = "auto" }) => {
895
- // Already parked at an edge, and outside the scrolling order — see
895
+ // Already parked at an edge, and outside the scrolling order - see
896
896
  // `getDisplayedRows`. Nothing to scroll, but the row *is* on screen, so
897
897
  // reporting failure would be the wrong answer.
898
898
  if (
@@ -915,7 +915,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
915
915
  * Infinite scroll. Latched on the row count rather than debounced: one call
916
916
  * per count means a pending fetch is never asked twice, and the append that
917
917
  * resolves it changes the count, which re-arms the latch. A failed fetch
918
- * stays quiet until something changes the rows — retrying is the
918
+ * stays quiet until something changes the rows - retrying is the
919
919
  * consumer's call, not a scroll side effect.
920
920
  *
921
921
  * Effect (not render): `onReachEnd` sets consumer state.
@@ -928,7 +928,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
928
928
  if (features.pagination && !warnedReachEndPaginationRef.current) {
929
929
  warnedReachEndPaginationRef.current = true;
930
930
  console.warn(
931
- "TMDataGrid: onReachEnd and pagination slice the same scroll — the pager caps the rows, so the end it reaches is the page's. Use one or the other.",
931
+ "TMDataGrid: onReachEnd and pagination slice the same scroll - the pager caps the rows, so the end it reaches is the page's. Use one or the other.",
932
932
  );
933
933
  }
934
934
  if (lastMountedIndex < rows.length - 1 - reachEndThreshold) return;
@@ -968,7 +968,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
968
968
  }));
969
969
  // Unresized columns stay fluid (`minmax(min, flex fr)`) so the grid fills the
970
970
  // viewport; dragging a resize handle pins that column to an exact pixel width.
971
- // minWidth is the sum of those floors — anything wider and the grid would
971
+ // minWidth is the sum of those floors - anything wider and the grid would
972
972
  // force a horizontal scrollbar it doesn't need.
973
973
  //
974
974
  // Pinned columns are always exact: their sticky offsets come from
@@ -1050,7 +1050,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1050
1050
  * The summary row exists by declaration, not by flag: it renders exactly
1051
1051
  * when at least one visible leaf column defines a `footer`. Its cells come
1052
1052
  * from the leaf header group, whose headers sit in the same left → centre →
1053
- * right order as `orderedColumns` — so `layoutFor` and the grid tracks
1053
+ * right order as `orderedColumns` - so `layoutFor` and the grid tracks
1054
1054
  * apply unchanged.
1055
1055
  */
1056
1056
  const leafHeaders = headerGroups.at(-1)?.headers ?? [];
@@ -1059,7 +1059,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1059
1059
  );
1060
1060
 
1061
1061
  // "row" mode: the row itself is the selection control, with the modifier
1062
- // conventions of any desktop list — see resolveRowSelectionClick.
1062
+ // conventions of any desktop list - see resolveRowSelectionClick.
1063
1063
  const selectsOnRowClick = features.rowClickSelects;
1064
1064
  const rowIsInteractive =
1065
1065
  selectsOnRowClick || features.highlightRow || onRowClick !== undefined;
@@ -1070,7 +1070,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1070
1070
  * Not squeamishness: TanStack builds a group row on top of its first leaf's
1071
1071
  * record (`constructRow(table, id, leafRows[0].original, …)`), so an
1072
1072
  * `onRowClick` firing here would hand a consumer a real-looking row that is
1073
- * the wrong one — a detail panel would open on an arbitrary child. The same
1073
+ * the wrong one - a detail panel would open on an arbitrary child. The same
1074
1074
  * goes for the highlight, which is what a detail panel follows.
1075
1075
  *
1076
1076
  * Selecting a group is still possible, through its checkbox, which resolves
@@ -1138,8 +1138,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1138
1138
  // Three pieces: the tab stop (which cell the browser can reach), the key
1139
1139
  // handler (which cell the state points at), and the effect (which cell the
1140
1140
  // DOM actually focuses). They are separate because under virtualization the
1141
- // three can disagree for a frame — a move to row 4000 names a cell that has
1142
- // no element yet — and the state is the one that is always right.
1141
+ // three can disagree for a frame - a move to row 4000 names a cell that has
1142
+ // no element yet - and the state is the one that is always right.
1143
1143
  // ---------------------------------------------------------------------------
1144
1144
  const cellSelection = features.cellSelection;
1145
1145
  const cellRangeSelection = features.cellRangeSelection;
@@ -1150,7 +1150,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1150
1150
  *
1151
1151
  * A ref rather than "is the focus in the grid?" asked at the time, because by
1152
1152
  * the time the effect runs the cell the key was pressed on may have unmounted
1153
- * — a PageDown scrolls it away — and the focus with it. The intent survives
1153
+ * (a PageDown scrolls it away) and the focus with it. The intent survives
1154
1154
  * where the evidence does not.
1155
1155
  */
1156
1156
  const wantsCellFocusRef = useRef(false);
@@ -1158,8 +1158,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1158
1158
  const appliedCellRef = useRef<TMDataGridCellPosition | null>(null);
1159
1159
 
1160
1160
  // O(n) per keystroke and per render while a cell is focused. Fine at any row
1161
- // count a grid actually holds, and the alternative — an id→index map rebuilt
1162
- // whenever sorting, filtering or grouping changes — costs more than it saves.
1161
+ // count a grid actually holds, and the alternative - an id→index map rebuilt
1162
+ // whenever sorting, filtering or grouping changes - costs more than it saves.
1163
1163
  const focusedRowIndex =
1164
1164
  cellSelection && focusedCell !== null
1165
1165
  ? rows.findIndex((row) => row.id === focusedCell.rowId)
@@ -1175,8 +1175,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1175
1175
  /**
1176
1176
  * The one cell in the body that Tab can reach.
1177
1177
  *
1178
- * The focused cell when it is on screen. When it is not — the grid has never
1179
- * been entered, or the user scrolled the focus away with the wheel — the
1178
+ * The focused cell when it is on screen. When it is not - the grid has never
1179
+ * been entered, or the user scrolled the focus away with the wheel - the
1180
1180
  * first mounted cell stands in, so the body always has exactly one tab stop.
1181
1181
  * Without the fallback, scrolling the focused row out of the DOM would take
1182
1182
  * the grid out of the tab order entirely.
@@ -1197,7 +1197,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1197
1197
  ) => position !== null && position.rowId === rowId && position.columnId === columnId;
1198
1198
 
1199
1199
  // The rectangle, resolved from ids to the indices the cells are rendered at.
1200
- // `null` whenever a corner has been filtered or hidden away — the range keeps
1200
+ // `null` whenever a corner has been filtered or hidden away - the range keeps
1201
1201
  // its ids, so lifting the filter brings the selection back.
1202
1202
  const rangeBounds = resolveRangeBounds({
1203
1203
  range: cellRangeSelection ? cellRange : null,
@@ -1226,7 +1226,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1226
1226
  * What a copy or an export would take.
1227
1227
  *
1228
1228
  * The rectangle when there is one, and the focused cell on its own when there
1229
- * is not — under `"single"` there never is one, and under `"range"` there is
1229
+ * is not - under `"single"` there never is one, and under `"range"` there is
1230
1230
  * none until the first gesture. Copying the one cell the user is on is what
1231
1231
  * every spreadsheet does, so the two cases collapse into the same block here
1232
1232
  * rather than into two paths through the export code.
@@ -1245,9 +1245,9 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1245
1245
  /**
1246
1246
  * How many of the selected columns have anything to export.
1247
1247
  *
1248
- * The generated lanes are part of the selection — they take the tint and the
1248
+ * The generated lanes are part of the selection - they take the tint and the
1249
1249
  * outline, so the block stays a rectangle and the keyboard still reaches the
1250
- * checkbox — but they hold controls rather than values. A rectangle covering
1250
+ * checkbox - but they hold controls rather than values. A rectangle covering
1251
1251
  * only those has nothing to copy, and the items that would say otherwise are
1252
1252
  * disabled rather than quietly doing nothing.
1253
1253
  */
@@ -1276,7 +1276,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1276
1276
  });
1277
1277
 
1278
1278
  /**
1279
- * Ctrl+C. Values only, no header row — Excel's own copy does not include one
1279
+ * Ctrl+C. Values only, no header row - Excel's own copy does not include one
1280
1280
  * either, and a header pasted into the middle of a sheet is a row of text
1281
1281
  * where numbers were expected. The export menu is where headers are offered,
1282
1282
  * because a file is a document and a clipboard is a fragment.
@@ -1291,13 +1291,13 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1291
1291
  * Whether a drag is laying down a rectangle right now.
1292
1292
  *
1293
1293
  * State rather than a ref, because the cells only listen for `mouseenter`
1294
- * while it is true — one re-render at each end of the gesture buys a body
1294
+ * while it is true - one re-render at each end of the gesture buys a body
1295
1295
  * that is not running a handler per cell the rest of the time.
1296
1296
  */
1297
1297
  const [isDraggingRange, setIsDraggingRange] = useState(false);
1298
1298
 
1299
1299
  // The drag ends wherever the button comes up, which is routinely outside the
1300
- // grid — over the scrollbar, or past the window edge. Only the window hears
1300
+ // grid - over the scrollbar, or past the window edge. Only the window hears
1301
1301
  // that, so only the window can end it.
1302
1302
  useEffect(() => {
1303
1303
  if (!isDraggingRange) return;
@@ -1312,7 +1312,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1312
1312
  ) => {
1313
1313
  ui.actions.setFocusedCell(position);
1314
1314
  setRangeTo(position, { extend });
1315
- // A Shift+click is a single act, not the start of one — there is nothing
1315
+ // A Shift+click is a single act, not the start of one - there is nothing
1316
1316
  // left to drag once the far corner has been named.
1317
1317
  if (!extend) setIsDraggingRange(true);
1318
1318
  };
@@ -1331,7 +1331,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1331
1331
  *
1332
1332
  * `extend` is the Shift key: held, the rectangle grows from wherever it was
1333
1333
  * anchored; released, it collapses onto the cell just moved to. Collapsing
1334
- * rather than clearing keeps the invariant the copy path relies on — the
1334
+ * rather than clearing keeps the invariant the copy path relies on - the
1335
1335
  * selection is always the block Ctrl+C would take, even when that block is
1336
1336
  * one cell.
1337
1337
  */
@@ -1351,7 +1351,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1351
1351
  };
1352
1352
 
1353
1353
  // ---------------------------------------------------------------------------
1354
- // Cell editing — the gestures. The engine owns the forms; this component
1354
+ // Cell editing - the gestures. The engine owns the forms; this component
1355
1355
  // owns where the editor opens from (keys, double-click) and where the
1356
1356
  // focus lands when it closes.
1357
1357
  // ---------------------------------------------------------------------------
@@ -1364,7 +1364,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1364
1364
  return seed;
1365
1365
  };
1366
1366
 
1367
- /** DOM focus back onto a cell — after Escape, or a commit with nowhere to go. */
1367
+ /** DOM focus back onto a cell - after Escape, or a commit with nowhere to go. */
1368
1368
  const refocusCell = (position: TMDataGridCellPosition) => {
1369
1369
  const container = scrollContainerRef.current;
1370
1370
  if (container === null) return;
@@ -1387,7 +1387,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1387
1387
  close: TMDataGridCellEditorClose,
1388
1388
  ) => {
1389
1389
  // Where the keyboard goes: Enter moves down, Tab to the next editable
1390
- // cell (the deferring batch variants move the same way, draft in tow) —
1390
+ // cell (the deferring batch variants move the same way, draft in tow) -
1391
1391
  // everything else, and a saved row, goes back to where the edit was.
1392
1392
  const move =
1393
1393
  close.via === "enter"
@@ -1439,7 +1439,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1439
1439
  /**
1440
1440
  * Space, from a cell. Checkbox semantics rather than click semantics: it adds
1441
1441
  * to the selection instead of replacing it, so a keyboard user builds one the
1442
- * way they would by ticking boxes — which is what the key has taken over from.
1442
+ * way they would by ticking boxes - which is what the key has taken over from.
1443
1443
  *
1444
1444
  * Group rows work because the resolver expands a tick to the descendants they
1445
1445
  * stand for. A grid with no selection at all falls back to the highlight,
@@ -1470,7 +1470,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1470
1470
  /**
1471
1471
  * One handler on the grid rather than one per cell: the body mounts a few
1472
1472
  * hundred cells and remounts them on every scroll frame, and this closes over
1473
- * `rows` and `orderedColumns` — which every cell would otherwise have to be
1473
+ * `rows` and `orderedColumns` - which every cell would otherwise have to be
1474
1474
  * handed just in case it is the one that gets a key.
1475
1475
  *
1476
1476
  * The cell it is about comes off `event.target`, which is where the
@@ -1479,7 +1479,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1479
1479
  const handleGridKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
1480
1480
  const target = event.target as HTMLElement;
1481
1481
 
1482
- // Focus is on something inside a cell — a checkbox, a link, an editor. Its
1482
+ // Focus is on something inside a cell - a checkbox, a link, an editor. Its
1483
1483
  // keys are its own; the one the grid still answers is the way back out.
1484
1484
  if (target.dataset.cell !== "true") {
1485
1485
  if (event.key !== "Escape") return;
@@ -1511,7 +1511,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1511
1511
  return;
1512
1512
  }
1513
1513
 
1514
- // Editing keys, ahead of the step-into pair — an editable cell's Enter
1514
+ // Editing keys, ahead of the step-into pair - an editable cell's Enter
1515
1515
  // opens its editor, and only a non-editable cell's falls through to the
1516
1516
  // control it holds.
1517
1517
  const keyRow = rows[rowIndex];
@@ -1527,11 +1527,11 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1527
1527
  openEditor({ rowId, columnId });
1528
1528
  return;
1529
1529
  }
1530
- // The quick single-cell gestures — Delete-to-clear and type-to-edit —
1530
+ // The quick single-cell gestures - Delete-to-clear and type-to-edit -
1531
1531
  // sit out row mode, whose whole point is that nothing commits until
1532
1532
  // the row's explicit save.
1533
1533
  if (features.editMode !== "row") {
1534
- // Clear-and-commit, without opening anything — the spreadsheet Delete.
1534
+ // Clear-and-commit, without opening anything - the spreadsheet Delete.
1535
1535
  if (event.key === "Delete" || event.key === "Backspace") {
1536
1536
  event.preventDefault();
1537
1537
  void edit
@@ -1569,7 +1569,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1569
1569
  }
1570
1570
 
1571
1571
  // Escape drops the rectangle back to the one cell, as it drops the marching
1572
- // ants in a spreadsheet. The focus stays where it is — Escape is about the
1572
+ // ants in a spreadsheet. The focus stays where it is - Escape is about the
1573
1573
  // selection, not about leaving the grid.
1574
1574
  if (event.key === "Escape") {
1575
1575
  if (cellRange === null) return;
@@ -1583,7 +1583,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1583
1583
  // Not routed through `handleRowActivate`, which is the *click* path and only
1584
1584
  // selects in `"row"` mode: with the cell cursor on, the checkbox is no
1585
1585
  // longer a tab stop (see useCellControlTabIndex), so this is the keyboard's
1586
- // way to a selection under every mode that has one — checkbox included.
1586
+ // way to a selection under every mode that has one - checkbox included.
1587
1587
  if (event.key === " ") {
1588
1588
  event.preventDefault();
1589
1589
  const row = rows[rowIndex];
@@ -1609,7 +1609,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1609
1609
  // did not move.
1610
1610
  event.preventDefault();
1611
1611
  if (next.rowIndex === rowIndex && next.columnIndex === columnIndex) return;
1612
- // Shift extends the rectangle instead of collapsing it — the same key that
1612
+ // Shift extends the rectangle instead of collapsing it - the same key that
1613
1613
  // extends a text selection, a file list and a spreadsheet range.
1614
1614
  moveFocusedCell(next, { extend: event.shiftKey && cellRangeSelection });
1615
1615
  };
@@ -1630,7 +1630,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1630
1630
 
1631
1631
  if (focusedCell !== appliedCellRef.current) {
1632
1632
  appliedCellRef.current = focusedCell;
1633
- // Bring the row on screen first — this is what makes a cell that is not
1633
+ // Bring the row on screen first - this is what makes a cell that is not
1634
1634
  // mounted focusable at all, one frame later.
1635
1635
  if (focusedRowIndex >= 0) {
1636
1636
  virtualizer.scrollToIndex(focusedRowIndex, { align: "auto" });
@@ -1643,7 +1643,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1643
1643
 
1644
1644
  // Never take the focus from elsewhere on the page. A consumer moving the
1645
1645
  // cell while the user is typing in a form somewhere means "move the ring",
1646
- // not "move the caret" — the scroll above already did the visible part.
1646
+ // not "move the caret" - the scroll above already did the visible part.
1647
1647
  if (
1648
1648
  !wantsCellFocusRef.current &&
1649
1649
  !container.contains(document.activeElement)
@@ -1655,7 +1655,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1655
1655
  // Still scrolling. The intent stays up, and the next render tries again.
1656
1656
  if (cellElement === null) return;
1657
1657
  wantsCellFocusRef.current = false;
1658
- // Focus is already inside — on the control Enter stepped into. The cell is
1658
+ // Focus is already inside - on the control Enter stepped into. The cell is
1659
1659
  // where the ring belongs, so there is nothing to move.
1660
1660
  if (cellElement.contains(document.activeElement)) return;
1661
1661
 
@@ -1693,8 +1693,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1693
1693
  // A right-click inside the selection is about the selection and leaves it
1694
1694
  // alone; one outside moves it first, so the menu never offers to copy a
1695
1695
  // block somewhere else on the screen. Spreadsheets and file managers both
1696
- // behave this way, and the alternative — exporting cells the user cannot
1697
- // see the outline of — is the kind of surprise that ends in a support call.
1696
+ // behave this way, and the alternative - exporting cells the user cannot
1697
+ // see the outline of - is the kind of surprise that ends in a support call.
1698
1698
  if (cellSelection && rowId !== null && columnId !== null) {
1699
1699
  const rowIndex = rows.findIndex((row) => row.id === rowId);
1700
1700
  const columnIndex = orderedColumns.findIndex(
@@ -1719,7 +1719,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1719
1719
  * opened menu rather than once per mounted row. `null` back from it means
1720
1720
  * this row has no menu, which is also how the menu stays shut.
1721
1721
  *
1722
- * The casts put back the concrete row type the context boundary erased — the
1722
+ * The casts put back the concrete row type the context boundary erased - the
1723
1723
  * same crossing `onRowClick` makes.
1724
1724
  */
1725
1725
  const rowMenuContent =
@@ -1743,7 +1743,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1743
1743
  *
1744
1744
  * Offered under `"range"` only. Under `"single"` the selection is always the
1745
1745
  * one cell the user is standing on, and a menu whose every item acts on it
1746
- * would be a menu about nothing much — Ctrl+C still copies it.
1746
+ * would be a menu about nothing much - Ctrl+C still copies it.
1747
1747
  */
1748
1748
  const cellMenuContent =
1749
1749
  cellRangeSelection && contextMenuTarget !== null && selectionBounds !== null ? (
@@ -1795,7 +1795,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1795
1795
 
1796
1796
  /**
1797
1797
  * Which edges the scroll position is currently at. Seeded "at top-left",
1798
- * which is where a grid mounts — so the callbacks report *arrivals*, and
1798
+ * which is where a grid mounts - so the callbacks report *arrivals*, and
1799
1799
  * mounting fires nothing.
1800
1800
  */
1801
1801
  const scrollEdgesRef = useRef({
@@ -1812,7 +1812,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1812
1812
 
1813
1813
  /**
1814
1814
  * The context menu's dropdown is anchored to a fixed viewport point, so it
1815
- * does not travel with the row when the body scrolls — and under
1815
+ * does not travel with the row when the body scrolls - and under
1816
1816
  * virtualization the row it belongs to may unmount entirely. Closing is
1817
1817
  * the honest answer, and matches what every desktop context menu does.
1818
1818
  *
@@ -1860,7 +1860,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1860
1860
  aria-label={ariaLabel}
1861
1861
  aria-labelledby={ariaLabelledBy}
1862
1862
  // Set while `meta.loading` is, whether or not the body has rows to
1863
- // show — a refetch over existing rows is still a fetch, and a test
1863
+ // show - a refetch over existing rows is still a fetch, and a test
1864
1864
  // waiting for the grid to settle has nothing else to wait on.
1865
1865
  aria-busy={loading === true ? true : undefined}
1866
1866
  aria-multiselectable={
@@ -1884,7 +1884,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1884
1884
  (hasSummaryRow ? 1 : 0)
1885
1885
  }
1886
1886
  aria-colcount={orderedColumns.length}
1887
- // Body rows the grid is currently showing — the page under
1887
+ // Body rows the grid is currently showing - the page under
1888
1888
  // pagination, everything the filters left otherwise, edge blocks
1889
1889
  // included. Most of them are not in the DOM, so this is what a test
1890
1890
  // waits on rather than counting nodes.
@@ -1899,7 +1899,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1899
1899
  aria-rowindex={groupIndex + 1}
1900
1900
  data-dg-header-row
1901
1901
  // The scrolled-under shadow belongs to the boundary between
1902
- // header and body — the last header row, not every stacked
1902
+ // header and body - the last header row, not every stacked
1903
1903
  // group row above it. See the stylesheet.
1904
1904
  data-dg-header-last={
1905
1905
  groupIndex === headerGroups.length - 1 || undefined
@@ -1917,7 +1917,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1917
1917
  ))}
1918
1918
  </div>
1919
1919
 
1920
- {/* The entry block — new rows being typed, stuck under the header.
1920
+ {/* The entry block - new rows being typed, stuck under the header.
1921
1921
  Present only while `edit.addRow()` has open entries. */}
1922
1922
  {features.editing && newRowCount > 0 && (
1923
1923
  <TMDataGridEntryRows
@@ -1940,7 +1940,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1940
1940
  /**
1941
1941
  * One renderer for every body row, wherever it sits: the
1942
1942
  * virtualized centre, or a pinned edge block. `viewIndex` is the
1943
- * row's index in the scrolling view — `-1` for a pinned row,
1943
+ * row's index in the scrolling view - `-1` for a pinned row,
1944
1944
  * which takes it out of striping, row measurement and the cell
1945
1945
  * range, all of which are statements about the scrolling order.
1946
1946
  * Scoped here rather than a component so the row keeps closing
@@ -1971,7 +1971,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1971
1971
  )?.column.id ?? null)
1972
1972
  : null;
1973
1973
  // Cell selection takes the body's tab stop off the row and puts
1974
- // it on a cell — two stops per row would make Tab a way of
1974
+ // it on a cell - two stops per row would make Tab a way of
1975
1975
  // walking the grid, which is what the arrow keys are for. Space
1976
1976
  // on a cell keeps the selection reachable; see handleGridKeyDown.
1977
1977
  const takesKeyboard =
@@ -1987,13 +1987,13 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
1987
1987
  data-row-id={row.id}
1988
1988
  // Only measured when details are on: without them every row
1989
1989
  // is exactly `rowHeight`, and the estimate above is already
1990
- // the answer — so a plain grid keeps its ResizeObserver-free
1990
+ // the answer - so a plain grid keeps its ResizeObserver-free
1991
1991
  // body. `measureElement` is a stable instance method and
1992
1992
  // returns nothing, so it can be the ref itself.
1993
1993
  //
1994
1994
  // `data-index` is how the virtualizer maps the observed
1995
1995
  // element back to its item. The panel is inside this element,
1996
- // so what gets measured is the row *and* its detail — which
1996
+ // so what gets measured is the row *and* its detail - which
1997
1997
  // is the whole reason no second virtual item is needed.
1998
1998
  data-index={
1999
1999
  renderDetails && viewIndex >= 0 ? viewIndex : undefined
@@ -2004,7 +2004,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2004
2004
  : undefined
2005
2005
  }
2006
2006
  // The tree's own rows. `data-grouped` rather than a class, to
2007
- // match how the rest of the row's state is published — and so
2007
+ // match how the rest of the row's state is published - and so
2008
2008
  // a consumer can restyle them without reaching into modules.
2009
2009
  data-grouped={isGroupRow}
2010
2010
  data-depth={row.depth}
@@ -2012,8 +2012,8 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2012
2012
  data-pinned={pinnedAt}
2013
2013
  // Gated on the flag, not just on `getIsSelected()`: under
2014
2014
  // `"highlight"` there is no selection, but `rowSelection` may
2015
- // still hold ids from before the mode changed — TanStack never
2016
- // prunes it — and a row must not report itself selected in a
2015
+ // still hold ids from before the mode changed - TanStack never
2016
+ // prunes it - and a row must not report itself selected in a
2017
2017
  // mode where selecting is not a thing.
2018
2018
  data-selected={features.rowSelection && row.getIsSelected()}
2019
2019
  // Being selected is state; painting it is a display choice, so
@@ -2024,7 +2024,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2024
2024
  row.getIsSelected()
2025
2025
  }
2026
2026
  // The highlighted row is its own concept, so its own attribute
2027
- // pair — `data-highlighted` / `aria-current` against
2027
+ // pair - `data-highlighted` / `aria-current` against
2028
2028
  // `data-selected` / `aria-selected` for selection. Under
2029
2029
  // `"checkboxAndHighlight"` a row can carry both.
2030
2030
  //
@@ -2057,7 +2057,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2057
2057
  : undefined
2058
2058
  }
2059
2059
  // From the row's position in the whole view, so the stripes
2060
- // survive the virtualizer's moving window — see the prop.
2060
+ // survive the virtualizer's moving window - see the prop.
2061
2061
  data-striped={
2062
2062
  striped && viewIndex >= 0 ? viewIndex % 2 === 1 : undefined
2063
2063
  }
@@ -2106,7 +2106,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2106
2106
  }
2107
2107
  : undefined
2108
2108
  }
2109
- // Bubbles to the rowgroup, where the menu opens — so the row
2109
+ // Bubbles to the rowgroup, where the menu opens - so the row
2110
2110
  // is recorded before the dropdown is built.
2111
2111
  //
2112
2112
  // A group row records itself only for the cell menu, which is
@@ -2114,7 +2114,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2114
2114
  // called for one: TanStack builds a group row on its first
2115
2115
  // child's record, so a render prop reaching for `row.original`
2116
2116
  // would be handed a real employee that has nothing to do with
2117
- // the group — see where the content is built. The browser menu
2117
+ // the group - see where the content is built. The browser menu
2118
2118
  // stays suppressed over them either way.
2119
2119
  onContextMenu={
2120
2120
  (rowContextMenu && !isGroupRow) || cellRangeSelection
@@ -2204,7 +2204,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2204
2204
  ? 0
2205
2205
  : -1,
2206
2206
  // "Selected" means "in the block Ctrl+C would
2207
- // take" — which under `"single"` is the one cell
2207
+ // take" - which under `"single"` is the one cell
2208
2208
  // the user is standing on.
2209
2209
  selected: cellRangeSelection
2210
2210
  ? isWithinBounds(rangeBounds, viewIndex, cellIndex)
@@ -2267,7 +2267,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2267
2267
  })}
2268
2268
 
2269
2269
  {/* A second grid row inside the row element, on the same
2270
- subgrid tracks — which is what lets one measurement cover
2270
+ subgrid tracks - which is what lets one measurement cover
2271
2271
  both. A cell spanning every column rather than a row of
2272
2272
  its own, so the row keeps holding exactly one row's worth
2273
2273
  of content and `aria-rowcount` still counts records. */}
@@ -2280,7 +2280,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2280
2280
  className={classes.detailsCell}
2281
2281
  // The row underneath may select, highlight or open a
2282
2282
  // context menu. A panel is content, not part of that
2283
- // gesture surface — and stopping the right-click here is
2283
+ // gesture surface - and stopping the right-click here is
2284
2284
  // what leaves the browser's own menu working for a link
2285
2285
  // or an input inside it.
2286
2286
  onClick={(event) => event.stopPropagation()}
@@ -2300,7 +2300,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2300
2300
  return (
2301
2301
  <>
2302
2302
  {/* The pinned edge blocks. Same sticky mechanics as the
2303
- entry block — the *block* is the sticky element, its rows
2303
+ entry block - the *block* is the sticky element, its rows
2304
2304
  flow normally inside it. `role="presentation"` keeps the
2305
2305
  wrapper out of the accessibility tree, so the rows stay
2306
2306
  direct children of the rowgroup. Inside the rowgroup so
@@ -2378,7 +2378,7 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2378
2378
  its way, "empty" would be a lie), open entry rows show only
2379
2379
  themselves (a "no rows" under the row being typed reads as a
2380
2380
  contradiction), then the consumer's blank slate, then the two
2381
- defaults — filtered-empty with its search icon, truly-empty as
2381
+ defaults - filtered-empty with its search icon, truly-empty as
2382
2382
  plain text, because only one of them is the user's own doing. */}
2383
2383
  {isEmpty && loading === true && (
2384
2384
  <div role="row" className={classes.messageRow}>
@@ -2396,12 +2396,12 @@ export function TMDataGridTable<TData extends RowData = TMDataGridRowData>({
2396
2396
  ) : hasActiveFilters ? (
2397
2397
  <>
2398
2398
  <SearchIcon size={40} stroke={1.4} opacity={0.4} />
2399
- <Text size={controlSize} c="dimmed">
2399
+ <Text span size={controlSize} c="dimmed">
2400
2400
  {noResultsLabel}
2401
2401
  </Text>
2402
2402
  </>
2403
2403
  ) : (
2404
- <Text size={controlSize} c="dimmed">
2404
+ <Text span size={controlSize} c="dimmed">
2405
2405
  {labels.noRows}
2406
2406
  </Text>
2407
2407
  )}