@jielga/tmdatagrid 2.0.0-beta.21 → 2.0.0-beta.22

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/docs/grouping.md CHANGED
@@ -56,7 +56,7 @@ grouped columns to the front. Note that the kept column's data cells render as
56
56
  TanStack's grouped-cell placeholder - blank - with the value only on group
57
57
  rows, so it repeats what the tree lane already shows and cannot be typed into.
58
58
  To set the grouped field on a new row, seed it through `edit.addRow(values)` -
59
- see [Editing](/docs/editing#adding-and-deleting-rows).
59
+ see [Editing](/docs/editing#adding-rows).
60
60
 
61
61
  ## Aggregation
62
62
 
package/docs/styling.md CHANGED
@@ -50,7 +50,7 @@ The wrapper components - `Toolbar`, `Spacer`, `Footer`, `FilterPanel`, `FilterPi
50
50
  | `--dg-row-height` | From `size` | Row height. Prefer `meta.rowHeight` - the virtualizer needs the number. |
51
51
  | `--dg-header-height` | From `size` | Header row height |
52
52
  | `--dg-summary-height` | From `size` | [Summary row](/docs/summary-row) height |
53
- | `--dg-entry-height` | From `size` | The sticky [entry block](/docs/editing#adding-and-deleting-rows) |
53
+ | `--dg-entry-height` | From `size` | The sticky [entry block](/docs/editing#adding-rows) |
54
54
  | `--dg-font-size` | From `size` | Cell and header font size |
55
55
  | `--dg-padding` | From `size` | Horizontal cell padding. The generated lanes are excluded: they are fixed 36px tracks that centre their control. |
56
56
  | `--dg-radius` | `--mantine-radius-md` | The frame's corner radius. `0` squares the grid off. The root clips its overflow, so the header and the last row follow it. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jielga/tmdatagrid",
3
- "version": "2.0.0-beta.21",
3
+ "version": "2.0.0-beta.22",
4
4
  "description": "A React data grid built on TanStack Table v9 and Mantine - always virtualized, with resizable, reorderable, sortable, filterable, hideable and pinnable columns.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.0.0-beta.21'
21
+ library_version: '2.0.0-beta.22'
22
22
  sources:
23
23
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/styling.md'
24
24
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/toolbar.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.21'
17
+ library_version: '2.0.0-beta.22'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/cell-selection.md'
20
20
  - 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/cellNavigation.ts'
@@ -16,7 +16,7 @@ description: >
16
16
  metadata:
17
17
  type: core
18
18
  library: '@jielga/tmdatagrid'
19
- library_version: '2.0.0-beta.21'
19
+ library_version: '2.0.0-beta.22'
20
20
  sources:
21
21
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/columns.md'
22
22
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/column-layout.md'
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.0.0-beta.21'
21
+ library_version: '2.0.0-beta.22'
22
22
  sources:
23
23
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/pagination.md'
24
24
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/scrolling.md'
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.0.0-beta.21'
21
+ library_version: '2.0.0-beta.22'
22
22
  sources:
23
23
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/editing.md'
24
24
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/query-builder.md'
@@ -385,8 +385,9 @@ row it reaches.
385
385
  `deleteRow`, `getForm`, and `store` for `useSelector` (an example is under
386
386
  [Submitting an outer form](#high-submitting-an-outer-form-while-the-grid-holds-a-draft)).
387
387
  `edit.store` publishes each open or committed row's drafted values as
388
- `rows[rowId].values`, which is what a computed cell or a cross-row check reads
389
- - `useTMDataGridContext()` reaches the engine from inside a cell renderer.
388
+ `rows[rowId].values`, which is what a cross-row check reads. A `cell`
389
+ renderer needs no lookup: its `row.original` is already the row as shown, and
390
+ `getRowValues(rowId)` is the same row for a handler with no cell context.
390
391
  Every member with its signature, the gates, `isColumnEditable`, `deactivate`,
391
392
  and the `edit.store` shape are in
392
393
  [references/editing-api.md](references/editing-api.md#the-edit-engine).
@@ -187,24 +187,23 @@ A refused value leaves the row open carrying its errors and the call resolves `f
187
187
 
188
188
  Source: `packages/tmdatagrid/src/core/editEngine.ts` (`begin`, `writeFields`).
189
189
 
190
- ## MEDIUM A computed column frozen while a row is edited
190
+ ## MEDIUM Reading an open row's values off `row.original` outside a cell
191
191
 
192
- A held draft is displayed by the column that owns the field. A column computed
193
- from other fields - `accessorFn` or `display` - reads `row.original`, which is
194
- `data`, so it keeps showing the saved record while the values it derives from
195
- are being typed.
192
+ Inside a `cell` renderer, `row.original` and `getValue()` are the row as
193
+ shown: the open form's values while the row is edited, the committed draft
194
+ after ✓, and `data` otherwise - a computed column follows the draft as it is
195
+ typed, and a button in a cell sends the draft the user sees. Outside it, the
196
+ row callbacks (`onRowClick`, `renderRowContextMenu`, `rowClassName`) and any
197
+ code holding a row id see `data`, or the committed draft, and never an open
198
+ form's values.
196
199
 
197
- Correct: read the drafted row from `edit.store` inside the cell renderer:
200
+ Correct: reach the row as shown by id:
198
201
 
199
202
  ```tsx
200
- function useDraftedRow(rowId: string, original: Product): Product {
201
- const { edit } = useTMDataGridContext();
202
- const values = useSelector(edit.store, (state) => state.rows[rowId]?.values);
203
- return (values as Product | undefined) ?? original;
204
- }
203
+ const shown = grid.edit.getRowValues(row.id) ?? row.original;
205
204
  ```
206
205
 
207
- Source: `packages/tmdatagrid/docs/editing.md` (Draft lifetime).
206
+ Source: `packages/tmdatagrid/docs/editing.md` (How a draft renders).
208
207
 
209
208
  ## MEDIUM Reading a commit's result as the saved value
210
209
 
@@ -72,6 +72,8 @@ path, which may be dotted.
72
72
  | `isColumnEditable` | `(column) => boolean` | The column's half alone, with no row in hand: it maps to a field, `editing.columns` lists it when that is set, and `meta.edit.enabled` is not `false`. |
73
73
  | `canDeleteRows` | `() => boolean` | Whether the delete control should be shown. |
74
74
  | `getForm` | `(rowId) => TMDataGridRowEditForm \| undefined` | The open row's live `FormApi`; `undefined` for a committed row. |
75
+ | `getRowValues` | `(rowId) => TData \| undefined` | The row as shown: the open form's values, else the committed draft, else the `data` value. `undefined` for an unknown row. |
76
+ | `getRows` | `() => ReadonlyArray<TMDataGridEditRowSnapshot>` | Every row as shown, from the core row model: drafts overlaid, entry rows appended, deletion-marked rows included and flagged `deleted`. |
75
77
  | `state` | `TMDataGridEditState` | Snapshot, for reads outside React. |
76
78
  | `store` | `Store<TMDataGridEditState>` | For `useSelector`. |
77
79
 
@@ -18,7 +18,7 @@ description: >
18
18
  metadata:
19
19
  type: core
20
20
  library: '@jielga/tmdatagrid'
21
- library_version: '2.0.0-beta.21'
21
+ library_version: '2.0.0-beta.22'
22
22
  sources:
23
23
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/filtering.md'
24
24
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/quick-search.md'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.21'
14
+ library_version: '2.0.0-beta.22'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/getting-started.md'
17
17
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/anatomy.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.21'
17
+ library_version: '2.0.0-beta.22'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/grouping.md'
20
20
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/summary-row.md'
@@ -14,7 +14,7 @@ description: >
14
14
  metadata:
15
15
  type: core
16
16
  library: '@jielga/tmdatagrid'
17
- library_version: '2.0.0-beta.21'
17
+ library_version: '2.0.0-beta.22'
18
18
  sources:
19
19
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/use-tm-data-grid.md'
20
20
  - 'Jielga/TMDataGrid:packages/tmdatagrid/src/useTMDataGrid.tsx'
@@ -17,7 +17,7 @@ description: >
17
17
  metadata:
18
18
  type: core
19
19
  library: '@jielga/tmdatagrid'
20
- library_version: '2.0.0-beta.21'
20
+ library_version: '2.0.0-beta.22'
21
21
  sources:
22
22
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/row-selection.md'
23
23
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/row-interaction.md'
@@ -15,7 +15,7 @@ description: >
15
15
  metadata:
16
16
  type: core
17
17
  library: '@jielga/tmdatagrid'
18
- library_version: '2.0.0-beta.21'
18
+ library_version: '2.0.0-beta.22'
19
19
  sources:
20
20
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/server-side.md'
21
21
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/server-query.md'
@@ -11,7 +11,7 @@ description: >
11
11
  metadata:
12
12
  type: core
13
13
  library: '@jielga/tmdatagrid'
14
- library_version: '2.0.0-beta.21'
14
+ library_version: '2.0.0-beta.22'
15
15
  sources:
16
16
  - 'Jielga/TMDataGrid:packages/tmdatagrid/docs/testing.md'
17
17
  - 'Jielga/TMDataGrid:packages/tmdatagrid/src/components/TMDataGrid.tsx'
@@ -16,6 +16,7 @@ import {
16
16
  isColumnEditableForRow,
17
17
  isControlColumn,
18
18
  } from "../core/columnUtils";
19
+ import { draftCellContext } from "../core/draftCellContext";
19
20
  import { getEditFieldName, type TMDataGridEditApi } from "../core/editEngine";
20
21
  import { focusEditorContent } from "../core/editorFocus";
21
22
  import {
@@ -45,10 +46,11 @@ function isEntryCellEditable(
45
46
  }
46
47
 
47
48
  /**
48
- * One cell of an entry row: the lane's controls, a value once the row is
49
- * committed, or an editor. The invalid marker subscribes here, per cell, as
50
- * a body cell's does - a refused ✓ paints the cells its issues name and
51
- * nothing else. No dirty marker: everything in an entry row is new.
49
+ * One cell of an entry row: the lane's controls, an editor for a cell the
50
+ * open row edits, or a value through the column's own renderer. The invalid
51
+ * marker subscribes here, per cell, as a body cell's does - a refused ✓
52
+ * paints the cells its issues name and nothing else. No dirty marker:
53
+ * everything in an entry row is new.
52
54
  */
53
55
  function EntryCell({
54
56
  entryRow,
@@ -76,6 +78,16 @@ function EntryCell({
76
78
  });
77
79
  const editable =
78
80
  cell !== undefined && isEntryCellEditable(entryRow, column, edit);
81
+ // An open row's cells outside the editors follow the form as it is typed,
82
+ // as a body row's do: the column's renderer over a context reading the
83
+ // form's values - the whole row, so a computed cell repaints with any
84
+ // field. `undefined` for a committed row, whose values the entry table
85
+ // already holds as data, and for the lanes.
86
+ const draftValues = useSelector(edit.store, (state) =>
87
+ committed || isControlColumn(column.id)
88
+ ? undefined
89
+ : state.rows[entryRow.id]?.values,
90
+ );
79
91
  return (
80
92
  <div
81
93
  role="cell"
@@ -108,16 +120,10 @@ function EntryCell({
108
120
  zIndex: layout.pinnedAt ? pinnedZ : undefined,
109
121
  }}
110
122
  >
111
- {cell !== undefined && column.id === EDIT_COLUMN_ID ? (
123
+ {cell === undefined ? null : column.id === EDIT_COLUMN_ID ? (
112
124
  // The lane's cell - the entry row's controls.
113
125
  flexRender(cell.column.columnDef.cell, cell.getContext())
114
- ) : committed && cell !== undefined ? (
115
- // Entered, awaiting Save all: a value row through the columns' own
116
- // renderers, over the draft the entry table was fed.
117
- <span className={classes.cellContent}>
118
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
119
- </span>
120
- ) : editable && cell !== undefined ? (
126
+ ) : !committed && editable ? (
121
127
  <TMDataGridCellEditor
122
128
  cell={cell}
123
129
  row={entryRow}
@@ -125,6 +131,24 @@ function EntryCell({
125
131
  onClose={() => {}}
126
132
  inEntryBlock
127
133
  />
134
+ ) : committed || !isControlColumn(column.id) ? (
135
+ // A value through the column's own renderer. Every cell of a row
136
+ // entered and awaiting Save all, over the draft the entry table was
137
+ // fed - and, while the row is open, every cell it does not open (a
138
+ // display column, `meta.edit.enabled` off), over the form as it is
139
+ // typed, as a body row in row mode shows them. Blank was how a
140
+ // calculated column or a button cell vanished the moment a
141
+ // committed row was reopened. The generated lanes stay blank while
142
+ // the row is open: a checkbox or a chevron there would act on the
143
+ // entry table's own state, which reaches nothing.
144
+ <span className={classes.cellContent}>
145
+ {flexRender(
146
+ cell.column.columnDef.cell,
147
+ draftValues !== undefined
148
+ ? draftCellContext(cell, draftValues)
149
+ : cell.getContext(),
150
+ )}
151
+ </span>
128
152
  ) : null}
129
153
  </div>
130
154
  );
@@ -245,18 +269,19 @@ export function TMDataGridEntryRows({
245
269
  focusEditorContent(editor);
246
270
  });
247
271
 
248
- // Open (uncommitted) rows keep the seed values frozen at addRow - the live values
249
- // belong to the forms, which the editors read directly, and this table only
250
- // provides row and cell identity. A committed row's cells render values, and
251
- // a committed row is data: its values come from the draft store, which is
252
- // also what the row keeps while a reopen is undecided.
272
+ // What the rows render over. A committed row is data: its values are the
273
+ // draft store's, which stand through a reopen. An open row's cells read
274
+ // the form itself - the editors directly, the rest through EntryCell's
275
+ // draft overlay - so its entry here gives the row an identity and a
276
+ // fallback: the committed values it was reopened from, else the seed
277
+ // frozen at addRow (the form's `defaultValues`, which a reopen keeps at
278
+ // the seed and writes the committed values over).
253
279
  const data = useMemo(
254
280
  () =>
255
281
  newRows.map(
256
- ({ tempId, committed }) =>
257
- ((committed
258
- ? committedValues[tempId]
259
- : edit.getForm(tempId)?.options.defaultValues) ??
282
+ ({ tempId }) =>
283
+ (committedValues[tempId] ??
284
+ edit.getForm(tempId)?.options.defaultValues ??
260
285
  {}) as TMDataGridRowData,
261
286
  ),
262
287
  [newRows, committedValues, edit],