@rozie-ui/data-table-solid 0.7.4 → 0.8.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.
- package/CHANGELOG.md +18 -0
- package/README.md +5 -1
- package/dist/index.cjs +501 -16
- package/dist/index.d.cts +23 -2
- package/dist/index.d.mts +23 -2
- package/dist/index.mjs +501 -16
- package/dist/source/index.jsx +500 -15
- package/package.json +2 -2
- package/src/Column.tsx +36 -3
- package/src/DataTable.tsx +484 -32
- package/src/helpers/activeFollow.ts +42 -0
- package/src/helpers/columnRuleUtils.ts +105 -0
- package/src/helpers/heldView.ts +185 -0
- package/src/index.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @rozie-ui/data-table-solid
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3c4b293: README fixes: Angular examples use the `<rozie-data-table>`, `<rozie-column>` and other child-component selectors (the PascalCase tags they showed fail to compile with NG8001), and the grouping and faceting examples no longer nest backticks inside the template string.
|
|
8
|
+
|
|
9
|
+
## 0.8.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- a80d5aa: Custom column filter and sort rules, holding the view while editing, and an active cell that stays on its record.
|
|
14
|
+
- **`filterFn` / `sortingFn`** on `<Column>` and on `columns` config entries. Each takes a table-core built-in name (`'arrIncludesSome'`, `'equalsString'`, `'alphanumeric'`, …) or a function: `filterFn(value, filterValue, row) => boolean` and an ascending `sortingFn(a, b, rowA, rowB) => number`, called with cell values and the original data objects. An unknown name falls back to `'auto'` with one console warning; a filter function that throws counts as a match and a sort function that throws counts as equal. List- and id-valued columns can now be filtered inside the table, so filtering no longer replaces the `data` array or clears undo history. The table re-filters only when `data`, `columnFilters`, `globalFilter` or `sorting` change; call `refreshView()` after the outside state a rule reads changes.
|
|
15
|
+
- **`holdView`** (default `false`): the table's own writes (edits, paste, fill, cut, clear, the boolean toggle, undo, redo) keep the rows' membership and order, and new values render in place. The view is re-derived when `sorting`, `columnFilters` or `globalFilter` change, on `refreshView()`, on an external `data` swap, or when `holdView` is toggled. New `refreshView()` and `getViewState()` verbs and a `view-state-change` event report `{ held, filterMismatches, sortMismatches }`. Grouping, `manual` mode and tree data fall back to live behaviour with one console warning. `getRowId` is not required.
|
|
16
|
+
- **Fix: the active cell follows its record.** After a re-sort, a filter change, `refreshView()` or one of the table's own writes, the active cell (and any open cell or row editor) moves with its record and fires `activecell-change` with the new position. If the record left the view, the active cell parks on the column header (`{ rowIndex: null, isHeader: true }`) and an open editor closes without writing, so the next keystroke can no longer edit a record nobody was looking at. Paging, page-size changes, expand/collapse and external data swaps still clamp to the same position when the record is gone. A sort, filter or write that reorders the rows clears an active cell range; a page-size change still clamps it. This applies to every grid, with or without `holdView`.
|
|
17
|
+
- **Fix: a table write or `refreshView()` no longer turns the page.** Before, any edit, paste, fill, cut, clear, boolean toggle, undo, redo or `refreshView()` on a paginated table jumped back to the first page (table-core's automatic page reset), leaving the active cell on a different record. The page now stays put for those, with or without `holdView`. A sort, `columnFilters`, `globalFilter` or grouping change still returns to the first page (with `page-change` when the page was not already the first); an external `data` swap now keeps the page (clamped to the last page when the new data has fewer), and the active cell follows its record there or parks on its column header. An external swap on a table without `getRowId` keeps the active cell's position (clamped) instead of following row positions that no longer mean the same records.
|
|
18
|
+
- **Fix: an initial `sorting` or `columnFilters` now applies when the columns come from `<Column>` children.** On React, Solid and Lit the first row model was built before the `<Column>` children registered, so a sort or filter on those columns was skipped and stayed skipped until the next sort or filter change. The table now re-runs both whenever the set of columns changes.
|
|
19
|
+
- **Fix: an editor opened from outside the grid stays open.** An editor opened by the `editCell` verb from a toolbar button closed itself (committing its value) on Solid and Lit as soon as a re-sort moved its row.
|
|
20
|
+
|
|
3
21
|
## 0.7.4
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -464,7 +464,7 @@ import '@rozie-ui/data-table-solid/themes/shadcn.css'; // or material.css, bo
|
|
|
464
464
|
| Name | Type | Default | Two-way (model) | Required | Description |
|
|
465
465
|
| --- | --- | --- | :---: | :---: | --- |
|
|
466
466
|
| `data` | `Array` | `—` | ✓ | ✓ | The row data — `model: true`, so a committed cell/row edit writes a **fresh** array back through the two-way `data` binding (uncontrolled fallback `dataDefault`). A stable reference per Rozie's setup-once model — fed directly into table-core (never map/cloned in the watcher). |
|
|
467
|
-
| `columns` | `Array` | `[]` | | | Config-array column fallback (lower precedence than `<Column>` children). Each entry: `{ id?, field, header?, sortable?, filterable?, pinned?, width? }
|
|
467
|
+
| `columns` | `Array` | `[]` | | | Config-array column fallback (lower precedence than `<Column>` children). Each entry: `{ id?, field, header?, sortable?, filterable?, filterFn?, sortingFn?, pinned?, width? }` (`filterFn`/`sortingFn` take a table-core built-in name or a custom function). Columns may come from this array, from `<Column>` children, or both (id-keyed last-write-wins union). A `pinned` value of `'left'` or `'right'` is applied once as the table's initial `columnPinning` state — identical to `<Column pinned>` — which also REORDERS that column, since table-core orders visible cells `[left-pinned, center, right-pinned]`. A consumer who has already expressed a pin (an initial two-way `columnPinning` model value or an interactive pin) owns the slice and this declaration is ignored. |
|
|
468
468
|
| `selectionMode` | `String` | `"none"` | | | Row-selection mode: `'none'` \| `'single'` \| `'multiple'`. `'multiple'` auto-injects a leading checkbox column with a select-all header. |
|
|
469
469
|
| `sorting` | `Array` | `[]` | ✓ | | `SortingState` — `[{ id, desc }]`. Uncontrolled fallback when unbound. Two-way: writes funnel a fresh value through the `sort-change` event regardless of binding. |
|
|
470
470
|
| `globalFilter` | `String` | `''` | ✓ | | The global search string — narrows all columns. Feeds `getFilteredRowModel()`. Surfaces through `filter-change`. Two-way: fires `filter-change` regardless of binding. |
|
|
@@ -489,6 +489,7 @@ import '@rozie-ui/data-table-solid/themes/shadcn.css'; // or material.css, bo
|
|
|
489
489
|
| `singleClickEdit` | `Boolean` | `false` | | | Grid mode only. When `true`, a plain click on an **editable** cell opens its editor immediately (single-click-to-edit) instead of just activating the cell. Default `false` keeps click-to-activate (double-click opens the editor). Shift+click (range selection) and clicks on non-editable cells are unaffected. |
|
|
490
490
|
| `undoable` | `Boolean` | `false` | | | Grid mode. When `true`, every committed data mutation (cell/row edit, paste, fill, cut, clear) becomes one undo step: Ctrl/Cmd+Z undoes, Ctrl/Cmd+Y or Ctrl/Cmd+Shift+Z redoes. Default `false` records no history and Ctrl+Z/Y are inert. |
|
|
491
491
|
| `undoLimit` | `Number` | `100` | | | The maximum number of undo steps retained (oldest evicted past this depth). Only consulted when `undoable` is `true`. |
|
|
492
|
+
| `holdView` | `Boolean` | `false` | | | When `true`, the table holds its current view through its own writes (edit, paste, fill, cut, clear, the boolean toggle, undo and redo): rows keep the membership and order they had before the write and new values render in place, so an edited row does not jump or vanish under an active sort or filter. The view is re-derived (and both mismatch counts reset to 0) when `sorting`, `columnFilters` or `globalFilter` change, when `refreshView()` is called, when the dataset is swapped externally, or when `holdView` is toggled. Paging, page size, column visibility/order/pinning/sizing and expanding rows move through the held rows; a table write or `refreshView()` never changes the page (a sort, filter or grouping change returns to the first page). Falls back to live behaviour (with one console warning) while grouping is active, in `manual` mode, or with tree data (`getSubRows`). Passing a fresh `data` array that did not come from the table (for example reloading from the server after a save) is an external swap: it re-derives the view and clears undo history. Track mismatches with `view-state-change` / `getViewState()`. |
|
|
492
493
|
| `virtual` | `any` | `false` | | | Opt-in windowing grammar: `false` (default, off — byte-identical to a non-virtual table) \| `true` or `'rows'` (vertical row windowing; `true` is byte-behavior-identical to every existing consumer, zero churn) \| `'columns'` (horizontal column windowing) \| `'both'` (both axes windowed). Row windowing renders only the visible slice of rows inside a bounded `rdt-scroll` container (with leading/trailing spacer rows preserving total scroll height), windowing over the full filtered + sorted (pre-pagination) model and suppressing the client pagination chrome. Column windowing renders only the visible slice of leaf columns inside the same `rdt-scroll` container. An unrecognised string behaves as `false`. |
|
|
493
494
|
| `estimateRowHeight` | `Number` | `40` | | | Estimated row height (px) — the first-paint seed for the windowing engine before any row has been measured. Only consulted when rows are windowed. When `autoMeasure` is `true`, later renders progressively refine the estimate from measured content; when `autoMeasure` is `false` this remains the explicit override for every render. |
|
|
494
495
|
| `autoMeasure` | `Boolean` | `false` | | | Opt-in content-driven row-size estimation. When `true`, the windowing engine feeds `estimateSize()` a running mean of measured row heights instead of the fixed `estimateRowHeight` seed, so `getTotalSize()` converges to the true content total on a large table with variable-height rows. Falls back to `estimateRowHeight` before any row has been measured. Default `false` keeps the estimate fixed at `estimateRowHeight` for every render (today's behavior). |
|
|
@@ -514,6 +515,7 @@ import '@rozie-ui/data-table-solid/themes/shadcn.css'; // or material.css, bo
|
|
|
514
515
|
| `selection-change` | Fired when the row selection changes (a row/select-all checkbox toggle or a `toggleAllRows`/`clearSelection` call). Payload is the fresh `RowSelectionState` `{ [rowId]: true }` object. |
|
|
515
516
|
| `sort-change` | Fired when the sort state changes (header click / shift-click multi-sort / a `sortColumn`/`clearSorting` call). Payload is the fresh `SortingState` array `[{ id, desc }]`. |
|
|
516
517
|
| `visibility-change` | Fired when a column is shown/hidden (the column-toggle menu or a `toggleColumnVisibility` call). Payload is the fresh `VisibilityState` `{ [colId]: boolean }` object. |
|
|
518
|
+
| `view-state-change` | Fired when the held-view state changes (`holdView`) — EDGE-triggered (only when `held`, `filterMismatches` or `sortMismatches` changes). Payload `{ held, filterMismatches, sortMismatches }`: `held` is whether the view is held right now (`false` when `holdView` is off or the table fell back to live behaviour under grouping, `manual` or tree data — both counts are then 0); `filterMismatches` counts rows whose membership differs from the current filters in either direction; `sortMismatches` counts rows written since the last re-derive whose held position differs from the live sort. Call `refreshView()` to re-derive. |
|
|
517
519
|
| `visible-range-change` | Fired when the RENDERED row window changes under row windowing (`virtual`) — the window the table actually renders, overscan included — and once after mount. Payload `{ start, end }` over the full row space (`end` exclusive; with lazy rows that space is `rowCount` long). Deduped: a scroll that does not move the window emits nothing. Pair with `manual` + `rowCount` and sparse `data` to fetch the rows the viewport needs. |
|
|
518
520
|
|
|
519
521
|
## Imperative handle
|
|
@@ -558,6 +560,8 @@ Beyond props, the component exposes imperative methods (declared once in the Roz
|
|
|
558
560
|
| `canUndo` | Return whether an undo step is available — `canUndo()` → `boolean`. Reflects the undo stack depth; use alongside the `history-change` event to drive a toolbar button`s disabled state without polling. |
|
|
559
561
|
| `canRedo` | Return whether a redo step is available — `canRedo()` → `boolean`. Reflects the redo stack depth; cleared by any new edit after an undo (standard undo semantics). |
|
|
560
562
|
| `clearHistory` | Discard all undo/redo history — `clearHistory()`. Empties both stacks (`canUndo()`/`canRedo()` become `false`). Also called internally on an external data-reference swap (a dataset the component itself did not write), since undoing across a dataset boundary is incoherent. |
|
|
563
|
+
| `refreshView` | Re-derive the view from the current filters and sort — `refreshView()`. Releases a held view (`holdView`) and resets both mismatch counts to 0, so rows the held view kept on screen leave and re-sort. Works with `holdView` off too: it forces custom `filterFn`/`sortingFn` rules (for example a closure over outside state, or a rule whose logic changed) to re-run, since table-core does not re-filter or re-sort when only a column rule changes. |
|
|
564
|
+
| `getViewState` | Return the held-view state — `getViewState()` → `{ held, filterMismatches, sortMismatches }` (the `view-state-change` payload). `held` is `false` when `holdView` is off or the table fell back to live behaviour (grouping, `manual`, tree data); a non-zero count means `refreshView()` would change what is on screen. |
|
|
561
565
|
|
|
562
566
|
```tsx
|
|
563
567
|
import { DataTable, type DataTableHandle } from '@rozie-ui/data-table-solid';
|