@jielga/tmdatagrid 1.0.0 → 1.0.2

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 (78) 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/appearance/SKILL.md +322 -0
  8. package/skills/cell-selection/SKILL.md +240 -0
  9. package/skills/columns/SKILL.md +261 -86
  10. package/skills/data/SKILL.md +289 -0
  11. package/skills/editing/SKILL.md +492 -0
  12. package/skills/editing/references/editing-api.md +124 -0
  13. package/skills/editing/references/editors-and-validation.md +198 -0
  14. package/skills/filtering/SKILL.md +344 -0
  15. package/skills/getting-started/SKILL.md +48 -27
  16. package/skills/grouping/SKILL.md +264 -0
  17. package/skills/options/SKILL.md +31 -20
  18. package/skills/rows/SKILL.md +369 -0
  19. package/skills/rows/references/rows-api.md +117 -0
  20. package/skills/server-side/SKILL.md +7 -7
  21. package/skills/testing/SKILL.md +12 -12
  22. package/src/tmdatagrid/TMDataGridContext.ts +2 -2
  23. package/src/tmdatagrid/components/TMDataGrid.module.css +2 -2
  24. package/src/tmdatagrid/components/TMDataGrid.tsx +5 -5
  25. package/src/tmdatagrid/components/TMDataGridCellEditor.tsx +4 -4
  26. package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +2 -2
  27. package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +6 -6
  28. package/src/tmdatagrid/components/TMDataGridEditActions.tsx +2 -2
  29. package/src/tmdatagrid/components/TMDataGridEditColumn.tsx +4 -4
  30. package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +6 -6
  31. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +6 -6
  32. package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +2 -2
  33. package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +1 -1
  34. package/src/tmdatagrid/components/TMDataGridFooter.module.css +1 -1
  35. package/src/tmdatagrid/components/TMDataGridFooter.tsx +12 -6
  36. package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +1 -1
  37. package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +5 -5
  38. package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +8 -8
  39. package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +12 -12
  40. package/src/tmdatagrid/components/TMDataGridRowNumberColumn.tsx +4 -4
  41. package/src/tmdatagrid/components/TMDataGridSearch.tsx +5 -5
  42. package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +8 -8
  43. package/src/tmdatagrid/components/TMDataGridTable.module.css +18 -18
  44. package/src/tmdatagrid/components/TMDataGridTable.tsx +116 -116
  45. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +5 -5
  46. package/src/tmdatagrid/components/editors/TMDataGridBooleanEditor.tsx +1 -1
  47. package/src/tmdatagrid/components/editors/TMDataGridDateEditor.tsx +2 -2
  48. package/src/tmdatagrid/components/editors/TMDataGridMultiSelectEditor.tsx +1 -1
  49. package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +1 -1
  50. package/src/tmdatagrid/components/editors/TMDataGridSelectEditor.tsx +2 -2
  51. package/src/tmdatagrid/components/editors/editorShared.ts +3 -3
  52. package/src/tmdatagrid/components/filters/DgDateRangeFilter.tsx +1 -1
  53. package/src/tmdatagrid/components/filters/DgRangeSliderFilter.tsx +1 -1
  54. package/src/tmdatagrid/components/filters/DgTriStateFilter.tsx +1 -1
  55. package/src/tmdatagrid/components/filters/TMDataGridFilterValueInput.tsx +2 -2
  56. package/src/tmdatagrid/components/sticky.module.css +8 -8
  57. package/src/tmdatagrid/core/autosize.ts +4 -4
  58. package/src/tmdatagrid/core/capabilities.ts +17 -17
  59. package/src/tmdatagrid/core/cellExport.ts +13 -13
  60. package/src/tmdatagrid/core/cellNavigation.ts +6 -6
  61. package/src/tmdatagrid/core/cellRange.ts +4 -4
  62. package/src/tmdatagrid/core/columnOptions.ts +2 -2
  63. package/src/tmdatagrid/core/columnOrdering.ts +2 -2
  64. package/src/tmdatagrid/core/columnUtils.ts +3 -3
  65. package/src/tmdatagrid/core/editEngine.ts +49 -49
  66. package/src/tmdatagrid/core/expanding.ts +5 -5
  67. package/src/tmdatagrid/core/filterControls.ts +5 -5
  68. package/src/tmdatagrid/core/filterOperators.ts +14 -14
  69. package/src/tmdatagrid/core/labels.ts +8 -8
  70. package/src/tmdatagrid/core/matchHighlight.ts +4 -4
  71. package/src/tmdatagrid/core/persistence.ts +8 -8
  72. package/src/tmdatagrid/core/quickSearch.ts +8 -8
  73. package/src/tmdatagrid/core/rowPinning.ts +3 -3
  74. package/src/tmdatagrid/core/rowSelection.ts +12 -12
  75. package/src/tmdatagrid/core/sizes.ts +1 -1
  76. package/src/tmdatagrid/core/summary.ts +3 -3
  77. package/src/tmdatagrid/useTMDataGrid.tsx +79 -79
  78. package/skills/features/SKILL.md +0 -352
@@ -10,7 +10,7 @@ export type TMDataGridSearchProps = {
10
10
  placeholder?: string;
11
11
  /**
12
12
  * How long typing pauses before the filter is applied, in ms. Defaults to
13
- * 250. `0` writes on every keystroke — what the tests use, and fine for
13
+ * 250. `0` writes on every keystroke - what the tests use, and fine for
14
14
  * small client-side data sets.
15
15
  */
16
16
  debounce?: number;
@@ -19,7 +19,7 @@ export type TMDataGridSearchProps = {
19
19
  };
20
20
 
21
21
  /**
22
- * Quick search over every column — a debounced input writing the table's
22
+ * Quick search over every column - a debounced input writing the table's
23
23
  * `globalFilter` state through the `"includesString"` filter the grid
24
24
  * configures by default.
25
25
  *
@@ -32,12 +32,12 @@ export type TMDataGridSearchProps = {
32
32
  * ```
33
33
  *
34
34
  * Renders nothing under `enableGlobalFilter: false`. Columns opt out with
35
- * their own `enableGlobalFilter: false` — the generated lanes already do.
35
+ * their own `enableGlobalFilter: false` - the generated lanes already do.
36
36
  *
37
37
  * The state is TanStack's `globalFilter`, so everything around it comes free:
38
38
  * `manualFiltering` grids forward it to the server, and it is one of the
39
39
  * persisted `data` slices. A grid that wants its own input entirely writes
40
- * `table.setGlobalFilter` itself — this component is only the built-in one.
40
+ * `table.setGlobalFilter` itself - this component is only the built-in one.
41
41
  */
42
42
  export function TMDataGridSearch({
43
43
  placeholder,
@@ -60,7 +60,7 @@ export function TMDataGridSearch({
60
60
  // for an external change that should overwrite what is being typed.
61
61
  const lastWrittenRef = useRef(globalFilter);
62
62
 
63
- // External writes — a consumer's `setGlobalFilter`, a persistence restore —
63
+ // External writes - a consumer's `setGlobalFilter`, a persistence restore -
64
64
  // win over the draft; the input is a mirror, not an owner.
65
65
  useEffect(() => {
66
66
  if (globalFilter === lastWrittenRef.current) return;
@@ -19,7 +19,7 @@ export const SELECT_COLUMN_ID = "__select__";
19
19
  * the selection off the render they were handed.
20
20
  *
21
21
  * A cell is rendered by `flexRender`, which mounts the cell function as its own
22
- * component — but the body cell above it keeps the same props across a
22
+ * component - but the body cell above it keeps the same props across a
23
23
  * selection change (row, column and layout identities all survive it), so the
24
24
  * React Compiler reuses the memoized element and the subtree never re-renders.
25
25
  * The row highlight would update, from state `TMDataGridTable` subscribes to,
@@ -59,7 +59,7 @@ function SelectAllCheckbox<TData extends RowData>({
59
59
  * feature flags rather than `table.options.enableMultiRowSelection` directly:
60
60
  * the flags are re-derived from a fresh object every render, so the switch
61
61
  * cannot be cached along with a `table` identity that survives an options
62
- * change — the same reason the rest of the chrome reads them. See
62
+ * change - the same reason the rest of the chrome reads them. See
63
63
  * readFeatureFlags.
64
64
  */
65
65
  function SelectAllHeader<TData extends RowData>({
@@ -78,10 +78,10 @@ function SelectRowCheckbox<TData extends RowData>({
78
78
  row: Row<TMDataGridFeatures, TData>;
79
79
  }) {
80
80
  // Cells render inside the grid's provider, so the checkbox can reach the
81
- // chrome store — it needs the shift-click pivot, and the feature flags to know
81
+ // chrome store - it needs the shift-click pivot, and the feature flags to know
82
82
  // which row model a range is measured over.
83
83
  const { ui, features, labels } = useTMDataGridContext();
84
- // Out of the tab order once the grid has a cell cursor — see
84
+ // Out of the tab order once the grid has a cell cursor - see
85
85
  // useCellControlTabIndex. Enter on the lane still steps in, and Space on any
86
86
  // cell of the row ticks it.
87
87
  const tabIndex = useCellControlTabIndex();
@@ -90,7 +90,7 @@ function SelectRowCheckbox<TData extends RowData>({
90
90
  // A group row is never selected by id: `rowSelection` only ever holds the
91
91
  // leaves, and TanStack's `getIsSelected()` is a plain lookup in that map. So
92
92
  // a group asks about its descendants instead, which is also the honest
93
- // reading — the box means "all of these", and it goes indeterminate as soon
93
+ // reading - the box means "all of these", and it goes indeterminate as soon
94
94
  // as that stops being true.
95
95
  const selected = useSelector(row.table.store, () =>
96
96
  isGroupRow ? row.getIsAllSubRowsSelected() : row.getIsSelected(),
@@ -117,7 +117,7 @@ function SelectRowCheckbox<TData extends RowData>({
117
117
  checked={selected}
118
118
  disabled={selectableIds.length === 0}
119
119
  indeterminate={someSelected && !selected}
120
- // Every tick goes through the resolver, shift held or not — plain becomes
120
+ // Every tick goes through the resolver, shift held or not - plain becomes
121
121
  // a toggle that moves the pivot, so a later shift-click extends from the
122
122
  // box the user last touched.
123
123
  //
@@ -138,7 +138,7 @@ function SelectRowCheckbox<TData extends RowData>({
138
138
  extend: isMouse && native.shiftKey,
139
139
  },
140
140
  selection: row.table.store.state.rowSelection,
141
- // A checkbox is only ever additive — ticking one has never cleared
141
+ // A checkbox is only ever additive - ticking one has never cleared
142
142
  // the others, so `canReplaceSelection` stays false whatever is held.
143
143
  canReplaceSelection: false,
144
144
  });
@@ -168,7 +168,7 @@ export function createSelectColumn<TData extends RowData>(
168
168
  enableOrdering: false,
169
169
  },
170
170
  // A system lane: as wide as the control it holds and no wider. Fixed at
171
- // every scale — the control does not grow with the font size, so neither
171
+ // every scale - the control does not grow with the font size, so neither
172
172
  // should its track.
173
173
  size: 36,
174
174
  minSize: 36,
@@ -34,12 +34,12 @@
34
34
  }
35
35
 
36
36
  /* The scrolled-under shadow: a soft band under the header, only while body
37
- rows are actually beneath it. On the last header row — the header/body
38
- boundary — not on every stacked group row. A scroll-driven animation, like
37
+ rows are actually beneath it. On the last header row - the header/body
38
+ boundary - not on every stacked group row. A scroll-driven animation, like
39
39
  the pinned-lane gradients: the shadow tracks the scroll on the compositor
40
40
  with no listener and no render, and an inactive timeline (nothing to
41
41
  scroll) leaves `opacity: 0` standing, so a grid that fits shows nothing.
42
- Where unsupported there is simply no shadow — the header's border already
42
+ Where unsupported there is simply no shadow - the header's border already
43
43
  draws the boundary. */
44
44
  .headerRow[data-dg-header-last]::after {
45
45
  content: "";
@@ -97,7 +97,7 @@
97
97
  /* A group row takes no background of its own. Collapsed, every row on screen is
98
98
  a group row, so a tint would grey out the whole grid and read as if
99
99
  everything were selected. The bold label and the chevron carry the
100
- distinction instead — and `--dg-row-group-bg` is there for a consumer who
100
+ distinction instead - and `--dg-row-group-bg` is there for a consumer who
101
101
  wants the tint back. Declared before the selection rules, so a selected or
102
102
  highlighted group still reads as one. */
103
103
  .bodyRow[data-grouped="true"] {
@@ -114,7 +114,7 @@
114
114
 
115
115
  /* Being selected and being painted for it are separate: a row is always
116
116
  `data-selected`, but only takes the background when `showSelectedBackground`
117
- is on — the default under `"row"`, off with checkboxes. */
117
+ is on - the default under `"row"`, off with checkboxes. */
118
118
  .bodyRow[data-selected-bg="true"] {
119
119
  --row-bg: var(--dg-row-selected-bg);
120
120
  }
@@ -138,19 +138,19 @@
138
138
  outline-offset: -2px;
139
139
  }
140
140
 
141
- /* Clipping lives on .cellContent, not here — a pinned cell has to let its
141
+ /* Clipping lives on .cellContent, not here - a pinned cell has to let its
142
142
  boundary gradient escape past its own right/left edge. */
143
143
  .bodyCell {
144
144
  display: flex;
145
145
  align-items: center;
146
146
  padding: 0 var(--dg-padding);
147
147
  border-bottom: 1px solid var(--mantine-color-default-border);
148
- /* Inherited from .bodyRow — sticky cells need an opaque background. */
148
+ /* Inherited from .bodyRow - sticky cells need an opaque background. */
149
149
  background-color: var(--row-bg);
150
150
  font-size: var(--dg-font-size);
151
151
  }
152
152
 
153
- /* A control lane — the checkbox, the details chevron — is a fixed 36px track
153
+ /* A control lane - the checkbox, the details chevron - is a fixed 36px track
154
154
  holding a control of a known width, not text that can ellipsize. Cell padding
155
155
  is sized for text and grows with the scale, so at `xl` its 18px a side left
156
156
  12px for a 16px box and the checkbox was clipped. The lane centres its
@@ -185,8 +185,8 @@
185
185
  positioned against a scrolling grid with sticky lanes in it.
186
186
 
187
187
  Four shadows are always laid down and each is transparent until its edge
188
- says otherwise. `box-shadow` does not accumulate across rules — a second
189
- declaration replaces the first — so the alternative is one rule per corner
188
+ says otherwise. `box-shadow` does not accumulate across rules - a second
189
+ declaration replaces the first - so the alternative is one rule per corner
190
190
  combination, and a cell can be on any of fifteen of them. */
191
191
  .bodyCell[data-selected="true"] {
192
192
  --dg-edge-top: transparent;
@@ -219,7 +219,7 @@
219
219
  /* The cell the keyboard is on, under `cellSelection`.
220
220
 
221
221
  Painted from `data-focused` rather than `:focus-visible`, because the ring
222
- has to stay while the focus steps into a control inside the cell — that is
222
+ has to stay while the focus steps into a control inside the cell - that is
223
223
  still where the arrow keys resume from. The offset keeps it inside the
224
224
  cell's own box, so a pinned neighbour cannot clip it. */
225
225
  .bodyCell[data-focused="true"] {
@@ -275,7 +275,7 @@
275
275
  border-right-color: var(--mantine-primary-color-filled);
276
276
  }
277
277
 
278
- /* Invalid wins over dirty — a cell is usually both. */
278
+ /* Invalid wins over dirty - a cell is usually both. */
279
279
  .bodyCell[data-invalid]::after {
280
280
  border-top-color: var(--mantine-color-error);
281
281
  border-right-color: var(--mantine-color-error);
@@ -295,7 +295,7 @@
295
295
  }
296
296
 
297
297
  /* The panel an expanded row opens. Its own grid row inside .bodyRow, spanning
298
- every column track — so it is measured together with the row above it.
298
+ every column track - so it is measured together with the row above it.
299
299
 
300
300
  It takes `--row-bg` rather than a colour of its own: the panel belongs to its
301
301
  row, and a selected or highlighted row whose panel stayed white would read as
@@ -330,7 +330,7 @@
330
330
  }
331
331
 
332
332
  /* Marked deleted under batch: struck through and inert until submitAll
333
- reports it. Interaction off wholesale — a row about to go away must not
333
+ reports it. Interaction off wholesale - a row about to go away must not
334
334
  keep taking edits. */
335
335
  .bodyRow[data-deleted="true"] {
336
336
  text-decoration: line-through;
@@ -338,7 +338,7 @@
338
338
  pointer-events: none;
339
339
  }
340
340
 
341
- /* The entry block — one row per edit.addRow(), under the header on the same
341
+ /* The entry block - one row per edit.addRow(), under the header on the same
342
342
  subgrid tracks as everything else. The *block* is the sticky element, not
343
343
  the rows: sticky siblings would all compete for the same `top` and stack
344
344
  onto one spot, while a single sticky wrapper lets its rows flow normally
@@ -359,7 +359,7 @@
359
359
  grid-template-columns: subgrid;
360
360
  }
361
361
 
362
- /* The pinned edge blocks — user-pinned rows held at the top or bottom of the
362
+ /* The pinned edge blocks - user-pinned rows held at the top or bottom of the
363
363
  body, on the entry block's sticky mechanics: the block is the sticky
364
364
  element, its rows flow normally inside it. The top block stacks under the
365
365
  entry block when both exist; `--dg-entry-height` is measured only then, so
@@ -417,7 +417,7 @@
417
417
 
418
418
  /* The matched slice of a cell's text, while `enableMatchHighlighting` is on
419
419
  and a contains-family filter or the quick search is active. `mark` resets
420
- the browser's default so the colour is the grid's to state — override with
420
+ the browser's default so the colour is the grid's to state - override with
421
421
  `--dg-match-highlight-bg` on the grid. */
422
422
  .matchHighlight {
423
423
  background-color: var(
@@ -428,7 +428,7 @@
428
428
  border-radius: 2px;
429
429
  }
430
430
 
431
- /* The summary row — one sticky row of column footers along the bottom edge,
431
+ /* The summary row - one sticky row of column footers along the bottom edge,
432
432
  rendered only while at least one column defines `footer`. Same subgrid
433
433
  placement as the header, so its cells sit exactly on the body's tracks. */
434
434
  .summaryRow {