@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rozie-ui/data-table-solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@solid-primitives/keyed": "^1.5.3",
|
|
51
|
-
"@rozie/runtime-solid": "^0.10.
|
|
51
|
+
"@rozie/runtime-solid": "^0.10.1"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"solid-js": "^1.8",
|
package/src/Column.tsx
CHANGED
|
@@ -45,6 +45,14 @@ interface ColumnProps {
|
|
|
45
45
|
* The table-core aggregation for this column inside a group-header cell. Either a built-in name string — `'sum'` | `'min'` | `'max'` | `'extent'` | `'mean'` | `'median'` | `'unique'` | `'uniqueCount'` | `'count'` — or a custom function `(columnId, leafRows, childRows) => any` (defensively wrapped by the parent so a throw cannot crash grouping). Null → no aggregation (the group-header cell renders as a placeholder).
|
|
46
46
|
*/
|
|
47
47
|
aggregationFn?: (string | ((...args: any[]) => any)) | null;
|
|
48
|
+
/**
|
|
49
|
+
* The table-core filter rule for this column. Either a built-in name string (e.g. `'arrIncludesSome'`, `'equalsString'`) or a custom function `(value, filterValue, row) => boolean`, where `row` is the original data object. Null → table-core's auto rule for the column's value type.
|
|
50
|
+
*/
|
|
51
|
+
filterFn?: (string | ((...args: any[]) => any)) | null;
|
|
52
|
+
/**
|
|
53
|
+
* The table-core sort rule for this column. Either a built-in name string (e.g. `'alphanumeric'`, `'basic'`) or a custom ascending comparator `(a, b, rowA, rowB) => number` over the cell values, with the original data objects as `rowA` / `rowB`. Null → table-core's auto rule for the column's value type.
|
|
54
|
+
*/
|
|
55
|
+
sortingFn?: (string | ((...args: any[]) => any)) | null;
|
|
48
56
|
/**
|
|
49
57
|
* Whether this column's cells are editable (opt-in). Default `false` → the column is read-only and the display↔editor branch never mounts an editor. Bind `:editable="true"` (a bare attr only coerces on Vue+Lit).
|
|
50
58
|
*/
|
|
@@ -64,11 +72,13 @@ interface ColumnProps {
|
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
export default function Column(_props: ColumnProps): JSX.Element {
|
|
67
|
-
const _merged = mergeProps({ id: '', field: '', header: '', sortable: false, filterable: false, pinned: '', width: '', expandable: false, groupable: true, aggregationFn: null, editable: false, editor: 'text', editorOptions: (() => [])() as any[], validate: null }, _props);
|
|
68
|
-
const [local, attrs] = splitProps(_merged, ['id', 'field', 'header', 'sortable', 'filterable', 'pinned', 'width', 'expandable', 'groupable', 'aggregationFn', 'editable', 'editor', 'editorOptions', 'validate']);
|
|
75
|
+
const _merged = mergeProps({ id: '', field: '', header: '', sortable: false, filterable: false, pinned: '', width: '', expandable: false, groupable: true, aggregationFn: null, filterFn: null, sortingFn: null, editable: false, editor: 'text', editorOptions: (() => [])() as any[], validate: null }, _props);
|
|
76
|
+
const [local, attrs] = splitProps(_merged, ['id', 'field', 'header', 'sortable', 'filterable', 'pinned', 'width', 'expandable', 'groupable', 'aggregationFn', 'filterFn', 'sortingFn', 'editable', 'editor', 'editorOptions', 'validate']);
|
|
69
77
|
|
|
70
78
|
const registry = useContext(rozieContext("data-table:columns"));
|
|
71
|
-
createEffect(on(() => (() => [local.id, local.field, local.header, local.sortable, local.filterable, local.pinned, local.width, local.expandable, local.groupable, local.aggregationFn, local.editable, local.editor, local.editorOptions, local.validate])(), (v) => untrack(() => (() => {
|
|
79
|
+
createEffect(on(() => (() => [local.id, local.field, local.header, local.sortable, local.filterable, local.pinned, local.width, local.expandable, local.groupable, local.aggregationFn, local.filterFn, local.sortingFn, local.editable, local.editor, local.editorOptions, local.validate])(), (v) => untrack(() => (() => {
|
|
80
|
+
latestFilterFn = local.filterFn;
|
|
81
|
+
latestSortingFn = local.sortingFn;
|
|
72
82
|
if (reg) reg.registerColumn(colId(), buildSpec());
|
|
73
83
|
})()), { defer: true }));
|
|
74
84
|
onMount(() => {
|
|
@@ -109,6 +119,24 @@ export default function Column(_props: ColumnProps): JSX.Element {
|
|
|
109
119
|
// REQ-30) and the $onMount registration never double-register the column.
|
|
110
120
|
let registered = false;
|
|
111
121
|
|
|
122
|
+
// Stable trampolines for custom filterFn/sortingFn. An inline arrow is a new identity every
|
|
123
|
+
// consumer render; registering it directly would defeat the registerColumn equivalence guard
|
|
124
|
+
// (a function compares by source, but table-core would hold a stale closure). The spec holds
|
|
125
|
+
// ONE trampoline per column that always calls the latest function, refreshed in the re-register
|
|
126
|
+
// watch below BEFORE the equivalence check. A mutable top-level `let` (a ref on React).
|
|
127
|
+
// table-core reads `autoRemove` / `resolveFilterValue` OFF the filter function itself, so the
|
|
128
|
+
// filter trampoline carries stable forwarders that read the CURRENT latestFilterFn (absent on
|
|
129
|
+
// the consumer's fn => table-core's own defaults: never auto-remove, value passes through).
|
|
130
|
+
let latestFilterFn: any = null;
|
|
131
|
+
let latestSortingFn: any = null;
|
|
132
|
+
const filterTrampoline: any = Object.assign((...args: any[]) => typeof latestFilterFn === 'function' ? latestFilterFn(...args) : true, {
|
|
133
|
+
autoRemove: (value: any, column: any) => typeof latestFilterFn === 'function' && typeof latestFilterFn.autoRemove === 'function' ? latestFilterFn.autoRemove(value, column) : false,
|
|
134
|
+
resolveFilterValue: (value: any) => typeof latestFilterFn === 'function' && typeof latestFilterFn.resolveFilterValue === 'function' ? latestFilterFn.resolveFilterValue(value) : value
|
|
135
|
+
});
|
|
136
|
+
function sortingTrampoline(...args: any[]) {
|
|
137
|
+
return typeof latestSortingFn === 'function' ? latestSortingFn(...args) : 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
112
140
|
// the column SPEC builder — shared by the $onMount register and the late-context
|
|
113
141
|
// $onUpdate below. Carries METADATA ONLY (no cell/header render callbacks — D-A moved
|
|
114
142
|
// per-cell rendering to the parent's #cell/#header scoped slot, dispatched by columnId).
|
|
@@ -116,6 +144,9 @@ export default function Column(_props: ColumnProps): JSX.Element {
|
|
|
116
144
|
return local.id !== '' ? local.id : local.field;
|
|
117
145
|
}
|
|
118
146
|
function buildSpec() {
|
|
147
|
+
// Seed the trampolines' targets at first registration (Lit props may not exist earlier).
|
|
148
|
+
latestFilterFn = local.filterFn;
|
|
149
|
+
latestSortingFn = local.sortingFn;
|
|
119
150
|
return {
|
|
120
151
|
id: colId(),
|
|
121
152
|
field: local.field !== '' ? local.field : colId(),
|
|
@@ -131,6 +162,8 @@ export default function Column(_props: ColumnProps): JSX.Element {
|
|
|
131
162
|
// custom fn) and filters groupableColumns by `groupable`.
|
|
132
163
|
groupable: local.groupable,
|
|
133
164
|
aggregationFn: local.aggregationFn,
|
|
165
|
+
filterFn: typeof local.filterFn === 'function' ? filterTrampoline : local.filterFn,
|
|
166
|
+
sortingFn: typeof local.sortingFn === 'function' ? sortingTrampoline : local.sortingFn,
|
|
134
167
|
// Editable-cell config (Phase 51) — carried into ColumnDef.meta via the parent
|
|
135
168
|
// registry (the existing per-column metadata path; NO parallel registry).
|
|
136
169
|
editable: local.editable,
|