You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: skills/lytenyte-grid/refs/cell-editing.md
+19-13Lines changed: 19 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,14 +23,17 @@ Make individual columns editable with `editable` and `editRenderer`:
23
23
24
24
## Edit Renderers
25
25
26
-
An edit renderer is a **standard React component** — LyteNyte Grid provides the editing state and wiring props (`editValue`, `changeValue`, `commit`, `cancel`), and you bring whatever input or UI element you need. This means you can use:
26
+
An edit renderer is a **standard React component** — LyteNyte Grid provides the editing state and wiring props
27
+
(`editValue`, `changeValue`, `commit`, `cancel`), and you bring whatever input or
- Existing form components already in the project (e.g. a `NumberInput` or `DatePicker` the user already has)
30
32
- Third-party libraries: React Select, Radix UI, shadcn/ui inputs, etc.
31
33
- Custom components built from scratch
32
34
33
-
**The pattern is always the same:** read `editValue` for the initial value, call `changeValue(newVal)` when the value changes. LyteNyte Grid handles the rest.
35
+
**The pattern is always the same:** read `editValue` for the initial value, call `changeValue(newVal)` when the value changes.
-**`editMutateCommit` fires for every column when any cell is committed** — a common mistake is writing `editMutateCommit` on a column that converts strings to numbers, but forgetting it fires even when a _different_ column is edited. The hook receives the full `editData`, so each column's `editMutateCommit` should only transform its own field and leave others untouched.
385
389
-**`editSetter` must return the full `editData` object** — returning only the changed field (e.g. `{ price: newValue }`) replaces the entire row data with a partial object. Always spread: `{ ...editData, price: newValue }`.
386
390
-**Controlled date inputs cause "jumping" bugs** — for date inputs, use `defaultValue` (uncontrolled) rather than `value` (controlled). A controlled date input can enter invalid intermediate states as the user types (e.g. `"2024-"` mid-entry), causing the input to jump. See the date editor example above.
387
-
-**Popover editors: set `editOnPrintable: false`** — if your editor component responds to keyboard input (e.g. opens a dropdown on keypress), the grid would otherwise open editing on every printable key typed while the cell is focused.
388
-
-**`editUpdate` runs through the full validation pipeline** — if validation fails, the update is rejected and the map is not partially applied. Check the return value.
391
+
-**Popover editors: set `editOnPrintable: false`** — if your editor component responds to keyboard input (e.g. opens a dropdown on keypress),
392
+
the grid would otherwise open editing on every printable key typed while the cell is focused.
393
+
-**`editUpdate` runs through the full validation pipeline** — if validation fails, the update is rejected and
394
+
the map is not partially applied. Check the return value.
Copy file name to clipboardExpand all lines: skills/lytenyte-grid/refs/cells.md
+41-24Lines changed: 41 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,8 @@
2
2
3
3
## Cell Renderers
4
4
5
-
A cell renderer is a standard React component assigned to a column's `cellRenderer` property. It receives `Grid.T.CellRendererParams<GridSpec>` as props:
5
+
A cell renderer is a standard React component assigned to a column's `cellRenderer` property.
6
+
It receives `Grid.T.CellRendererParams<GridSpec>` as props:
6
7
7
8
```tsx
8
9
function ProductCell({ api, row, column }:Grid.T.CellRendererParams<GridSpec>) {
LyteNyte Grid virtualizes rows — cells unmount/remount as they scroll in/out of view. **Do not use `useState` inside cell renderers for persistent state** — it resets on unmount.
60
+
LyteNyte Grid virtualizes rows — cells unmount/remount as they scroll in/out of view.
61
+
62
+
**Do not use `useState` inside cell renderers for persistent state** — it resets on unmount.
@@ -181,9 +185,12 @@ Display the direction and magnitude of the change alongside the value:
181
185
## Gotchas
182
186
183
187
-**`api.columnField(column, row)` is the safe way to read values** — it handles all row types (leaf, group, aggregated) uniformly. Direct `row.data[column.id]` fails for group rows (no `data`) and ignores custom `field` definitions.
184
-
-**Popover/tooltip libraries need portals to escape grid clipping** — the grid clips its cells. A tooltip anchored to a cell element will be clipped by the cell's overflow boundary unless it renders in a portal (e.g. `Tooltip.Portal` in Radix UI).
185
-
-**Cell renderers receive new props on every render** — do not use deep equality checks or memoize based on props inside renderers. The grid controls when renderers re-render; hook into that rather than trying to suppress it.
186
-
-**`useRef` for diff tracking, not `useState`** — for diff flashing, tracking the previous value with `useRef` works across virtualization remounts. `useState` would reset on unmount and produce false "new value" flashes for rows that just scrolled back into view.
188
+
-**Popover/tooltip libraries need portals to escape grid clipping** — the grid clips its cells. A tooltip anchored to a cell element will
189
+
be clipped by the cell's overflow boundary unless it renders in a portal (e.g. `Tooltip.Portal` in Radix UI).
190
+
-**Cell renderers receive new props on every render** — do not use deep equality checks or memoize based on props inside renderers.
191
+
The grid controls when renderers re-render; hook into that rather than trying to suppress it.
192
+
-**`useRef` for diff tracking, not `useState`** — for diff flashing, tracking the previous value with `useRef` works across
193
+
virtualization remounts. `useState` would reset on unmount and produce false "new value" flashes for rows that just scrolled back into view.
187
194
188
195
## Cell Range Selection
189
196
@@ -197,7 +204,8 @@ Set `cellSelectionMode` on the grid:
Listen for the keyboard shortcut in the `viewport.keyDown` event, read the selection rect, export the data, and write to the clipboard. The `viewport` parameter is the grid's DOM element — add/remove a CSS class on it for copy-flash visual feedback.
231
+
Listen for the keyboard shortcut in the `viewport.keyDown` event, read the selection rect, export the data,
232
+
and write to the clipboard. The `viewport` parameter is the grid's DOM element,
233
+
add/remove a CSS class on it for copy-flash visual feedback.
224
234
225
235
```tsx
226
236
<Grid
@@ -236,9 +246,7 @@ Listen for the keyboard shortcut in the `viewport.keyDown` event, read the selec
236
246
const exported =awaitapi.exportData({ rect });
237
247
238
248
// Tab-separated rows for spreadsheet paste (Excel, Google Sheets)
> **Warning:**`cellSelections` is both a grid **prop** (controlled state) and an **API method** (`api.cellSelections()`). In controlled mode, the API method returns the same value you passed in. In uncontrolled mode, the API method reads internal state.
290
306
@@ -346,7 +362,8 @@ LyteNyte Grid renders inert `div` overlays to visualize selections. They are uns
346
362
}
347
363
```
348
364
349
-
Header cells of columns containing selected cells get `data-ln-cell-selected="true"`. Rows containing selected cells also get this attribute:
365
+
Header cells of columns containing selected cells get `data-ln-cell-selected="true"`.
366
+
Rows containing selected cells also get this attribute:
0 commit comments