@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/dist/index.mjs
CHANGED
|
@@ -94,6 +94,74 @@ const columnSpecsEquivalent = (a, b, depth) => {
|
|
|
94
94
|
return true;
|
|
95
95
|
};
|
|
96
96
|
//#endregion
|
|
97
|
+
//#region src/helpers/columnRuleUtils.ts
|
|
98
|
+
const FILTER_FN_NAMES = [
|
|
99
|
+
"includesString",
|
|
100
|
+
"includesStringSensitive",
|
|
101
|
+
"equalsString",
|
|
102
|
+
"arrIncludes",
|
|
103
|
+
"arrIncludesAll",
|
|
104
|
+
"arrIncludesSome",
|
|
105
|
+
"equals",
|
|
106
|
+
"weakEquals",
|
|
107
|
+
"inNumberRange"
|
|
108
|
+
];
|
|
109
|
+
const SORTING_FN_NAMES = [
|
|
110
|
+
"alphanumeric",
|
|
111
|
+
"alphanumericCaseSensitive",
|
|
112
|
+
"text",
|
|
113
|
+
"textCaseSensitive",
|
|
114
|
+
"datetime",
|
|
115
|
+
"basic"
|
|
116
|
+
];
|
|
117
|
+
const warned = /* @__PURE__ */ new Set();
|
|
118
|
+
const resolveName = (value, names, kind, columnId, warn) => {
|
|
119
|
+
if (value === "auto" || names.includes(value)) return value;
|
|
120
|
+
const key = kind + "\0" + columnId + "\0" + value;
|
|
121
|
+
if (!warned.has(key)) {
|
|
122
|
+
warned.add(key);
|
|
123
|
+
warn(`[data-table] column "${columnId}": unknown ${kind} "${value}"; falling back to "auto".`);
|
|
124
|
+
}
|
|
125
|
+
return "auto";
|
|
126
|
+
};
|
|
127
|
+
const resolveFilterFn = (value, columnId, warn = console.warn) => {
|
|
128
|
+
if (value == null) return void 0;
|
|
129
|
+
if (typeof value === "string") return resolveName(value, FILTER_FN_NAMES, "filterFn", columnId, warn);
|
|
130
|
+
if (typeof value !== "function") return void 0;
|
|
131
|
+
const fn = value;
|
|
132
|
+
const adapter = (row, colId, filterValue) => {
|
|
133
|
+
try {
|
|
134
|
+
return fn(row.getValue(colId), filterValue, row.original);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
if (fn.autoRemove !== void 0) adapter.autoRemove = fn.autoRemove;
|
|
140
|
+
if (fn.resolveFilterValue !== void 0) adapter.resolveFilterValue = fn.resolveFilterValue;
|
|
141
|
+
return adapter;
|
|
142
|
+
};
|
|
143
|
+
const resolveSortingFn = (value, columnId, warn = console.warn) => {
|
|
144
|
+
if (value == null) return void 0;
|
|
145
|
+
if (typeof value === "string") return resolveName(value, SORTING_FN_NAMES, "sortingFn", columnId, warn);
|
|
146
|
+
if (typeof value !== "function") return void 0;
|
|
147
|
+
const fn = value;
|
|
148
|
+
return (rowA, rowB, colId) => {
|
|
149
|
+
try {
|
|
150
|
+
return fn(rowA.getValue(colId), rowB.getValue(colId), rowA.original, rowB.original);
|
|
151
|
+
} catch (err) {
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
const columnRuleKeys = (spec, columnId, warn) => {
|
|
157
|
+
const out = {};
|
|
158
|
+
const f = resolveFilterFn(spec?.filterFn, columnId, warn);
|
|
159
|
+
if (f !== void 0) out.filterFn = f;
|
|
160
|
+
const s = resolveSortingFn(spec?.sortingFn, columnId, warn);
|
|
161
|
+
if (s !== void 0) out.sortingFn = s;
|
|
162
|
+
return out;
|
|
163
|
+
};
|
|
164
|
+
//#endregion
|
|
97
165
|
//#region src/helpers/indexMath.ts
|
|
98
166
|
const clamp = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
|
|
99
167
|
const focusables = (cellEl) => {
|
|
@@ -102,6 +170,24 @@ const focusables = (cellEl) => {
|
|
|
102
170
|
};
|
|
103
171
|
const applyUpdater = (updater, current) => typeof updater === "function" ? updater(current) : updater;
|
|
104
172
|
//#endregion
|
|
173
|
+
//#region src/helpers/activeFollow.ts
|
|
174
|
+
function resolveFollow(prevIds, activeRow, nextIds, viewChangeOrWrite) {
|
|
175
|
+
if (!prevIds || !Number.isInteger(activeRow) || activeRow < 0 || activeRow >= prevIds.length) return { kind: "clamp" };
|
|
176
|
+
const id = prevIds[activeRow];
|
|
177
|
+
if (nextIds[activeRow] === id) return { kind: "stay" };
|
|
178
|
+
const index = nextIds.indexOf(id);
|
|
179
|
+
if (index >= 0) return {
|
|
180
|
+
kind: "move",
|
|
181
|
+
index
|
|
182
|
+
};
|
|
183
|
+
return viewChangeOrWrite ? { kind: "park" } : { kind: "clamp" };
|
|
184
|
+
}
|
|
185
|
+
function sameIdSequence(a, b) {
|
|
186
|
+
if (!a || a.length !== b.length) return false;
|
|
187
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
//#endregion
|
|
105
191
|
//#region src/helpers/tsvGrid.ts
|
|
106
192
|
const escapeTsvField = (s) => {
|
|
107
193
|
if (s.indexOf(" ") >= 0 || s.indexOf("\n") >= 0 || s.indexOf("\r") >= 0 || s.indexOf("\"") >= 0) return "\"" + s.replace(/"/g, "\"\"") + "\"";
|
|
@@ -237,9 +323,153 @@ const indexOfRowIn = (rows, rowOriginal, rowId) => {
|
|
|
237
323
|
return -1;
|
|
238
324
|
};
|
|
239
325
|
//#endregion
|
|
326
|
+
//#region src/helpers/heldView.ts
|
|
327
|
+
const CLEAN_VIEW_STATE = Object.freeze({
|
|
328
|
+
held: false,
|
|
329
|
+
filterMismatches: 0,
|
|
330
|
+
sortMismatches: 0
|
|
331
|
+
});
|
|
332
|
+
const viewStatesEqual = (a, b) => a.held === b.held && a.filterMismatches === b.filterMismatches && a.sortMismatches === b.sortMismatches;
|
|
333
|
+
const changedIndices = (prev, next) => {
|
|
334
|
+
const out = [];
|
|
335
|
+
if (prev.length !== next.length) {
|
|
336
|
+
const n = Math.max(prev.length, next.length);
|
|
337
|
+
for (let i = 0; i < n; i++) out.push(i);
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
for (let i = 0; i < next.length; i++) if (prev[i] !== next[i]) out.push(i);
|
|
341
|
+
return out;
|
|
342
|
+
};
|
|
343
|
+
const rowIds = (model) => (model?.rows ?? []).map((r) => r.id);
|
|
344
|
+
const createHoldController = () => {
|
|
345
|
+
let active = false;
|
|
346
|
+
let heldMembership = null;
|
|
347
|
+
let heldOrder = null;
|
|
348
|
+
const written = /* @__PURE__ */ new Set();
|
|
349
|
+
let version = 0;
|
|
350
|
+
let liveFilteredIds = /* @__PURE__ */ new Set();
|
|
351
|
+
let liveSortedIds = [];
|
|
352
|
+
const release = () => {
|
|
353
|
+
heldMembership = null;
|
|
354
|
+
heldOrder = null;
|
|
355
|
+
written.clear();
|
|
356
|
+
version++;
|
|
357
|
+
};
|
|
358
|
+
const wrapFiltered = (base) => (table) => {
|
|
359
|
+
const getBase = base(table);
|
|
360
|
+
let lastBase = void 0;
|
|
361
|
+
let lastVersion = -1;
|
|
362
|
+
let lastOut = void 0;
|
|
363
|
+
return () => {
|
|
364
|
+
const baseModel = getBase();
|
|
365
|
+
if (!heldMembership) return baseModel;
|
|
366
|
+
if (baseModel === lastBase && version === lastVersion) return lastOut;
|
|
367
|
+
liveFilteredIds = new Set(rowIds(baseModel));
|
|
368
|
+
const held = heldMembership;
|
|
369
|
+
const rows = table.getCoreRowModel().rows.filter((r) => held.has(r.id));
|
|
370
|
+
const rowsById = {};
|
|
371
|
+
for (const r of rows) rowsById[r.id] = r;
|
|
372
|
+
lastBase = baseModel;
|
|
373
|
+
lastVersion = version;
|
|
374
|
+
lastOut = {
|
|
375
|
+
rows,
|
|
376
|
+
flatRows: rows,
|
|
377
|
+
rowsById
|
|
378
|
+
};
|
|
379
|
+
return lastOut;
|
|
380
|
+
};
|
|
381
|
+
};
|
|
382
|
+
const wrapSorted = (base) => (table) => {
|
|
383
|
+
const getBase = base(table);
|
|
384
|
+
let lastBase = void 0;
|
|
385
|
+
let lastVersion = -1;
|
|
386
|
+
let lastOut = void 0;
|
|
387
|
+
return () => {
|
|
388
|
+
const baseModel = getBase();
|
|
389
|
+
if (!heldOrder) return baseModel;
|
|
390
|
+
if (baseModel === lastBase && version === lastVersion) return lastOut;
|
|
391
|
+
const baseRows = baseModel?.rows ?? [];
|
|
392
|
+
liveSortedIds = baseRows.map((r) => r.id);
|
|
393
|
+
const byId = /* @__PURE__ */ new Map();
|
|
394
|
+
for (const r of baseRows) byId.set(r.id, r);
|
|
395
|
+
const rows = [];
|
|
396
|
+
for (const id of heldOrder) {
|
|
397
|
+
const r = byId.get(id);
|
|
398
|
+
if (r) {
|
|
399
|
+
rows.push(r);
|
|
400
|
+
byId.delete(id);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
for (const r of baseRows) if (byId.has(r.id)) rows.push(r);
|
|
404
|
+
lastBase = baseModel;
|
|
405
|
+
lastVersion = version;
|
|
406
|
+
lastOut = {
|
|
407
|
+
rows,
|
|
408
|
+
flatRows: rows,
|
|
409
|
+
rowsById: baseModel?.rowsById ?? {}
|
|
410
|
+
};
|
|
411
|
+
return lastOut;
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
return {
|
|
415
|
+
setActive(next) {
|
|
416
|
+
const was = active;
|
|
417
|
+
active = !!next;
|
|
418
|
+
if (!active && was) release();
|
|
419
|
+
},
|
|
420
|
+
isActive: () => active,
|
|
421
|
+
isHolding: () => heldMembership !== null,
|
|
422
|
+
capture(table) {
|
|
423
|
+
if (!active || heldMembership) return;
|
|
424
|
+
const filtered = table.getFilteredRowModel();
|
|
425
|
+
const sorted = typeof table.getSortedRowModel === "function" ? table.getSortedRowModel() : filtered;
|
|
426
|
+
heldMembership = new Set(rowIds(filtered));
|
|
427
|
+
heldOrder = rowIds(sorted);
|
|
428
|
+
written.clear();
|
|
429
|
+
version++;
|
|
430
|
+
},
|
|
431
|
+
release,
|
|
432
|
+
noteWrite(prev, next) {
|
|
433
|
+
if (!heldMembership) return;
|
|
434
|
+
for (const i of changedIndices(prev, next)) written.add(i);
|
|
435
|
+
},
|
|
436
|
+
wrapFiltered,
|
|
437
|
+
wrapSorted,
|
|
438
|
+
viewState(table) {
|
|
439
|
+
if (!active) return CLEAN_VIEW_STATE;
|
|
440
|
+
if (!heldMembership || !heldOrder) return {
|
|
441
|
+
held: true,
|
|
442
|
+
filterMismatches: 0,
|
|
443
|
+
sortMismatches: 0
|
|
444
|
+
};
|
|
445
|
+
table.getSortedRowModel();
|
|
446
|
+
const held = heldMembership;
|
|
447
|
+
let filterMismatches = 0;
|
|
448
|
+
for (const id of held) if (!liveFilteredIds.has(id)) filterMismatches++;
|
|
449
|
+
const coreRows = table.getCoreRowModel().rows;
|
|
450
|
+
for (const r of coreRows) if (!held.has(r.id) && liveFilteredIds.has(r.id)) filterMismatches++;
|
|
451
|
+
const heldPos = /* @__PURE__ */ new Map();
|
|
452
|
+
heldOrder.forEach((id, i) => heldPos.set(id, i));
|
|
453
|
+
const livePos = /* @__PURE__ */ new Map();
|
|
454
|
+
liveSortedIds.forEach((id, i) => livePos.set(id, i));
|
|
455
|
+
let sortMismatches = 0;
|
|
456
|
+
for (const i of written) {
|
|
457
|
+
const id = coreRows[i]?.id;
|
|
458
|
+
if (id === void 0 || !heldPos.has(id)) continue;
|
|
459
|
+
if (heldPos.get(id) !== livePos.get(id)) sortMismatches++;
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
held: true,
|
|
463
|
+
filterMismatches,
|
|
464
|
+
sortMismatches
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
//#endregion
|
|
240
470
|
//#region src/DataTable.tsx
|
|
241
471
|
var _tmpl$$11 = /* @__PURE__ */ template(`<div class=rozie-data-table-wrap data-rozie-s-d5dcab4c=""><div class=rdt-column-defs aria-hidden=true data-rozie-s-d5dcab4c=""></div><div class=rdt-toolbar data-rozie-s-d5dcab4c=""><input type=text role=searchbox aria-label="Search table"class=rdt-global-filter data-rozie-s-d5dcab4c="">`), _tmpl$2$4 = /* @__PURE__ */ template(`<div class=rdt-sr-live role=status aria-live=polite aria-atomic=true data-rozie-s-d5dcab4c="">`), _tmpl$3$1 = /* @__PURE__ */ template(`<div class="rdt-sr-live rdt-sr-paste"data-testid=paste-announce role=status aria-live=polite aria-atomic=true data-rozie-s-d5dcab4c="">`), _tmpl$4$1 = /* @__PURE__ */ template(`<div class="rdt-sr-live rdt-sr-range"data-testid=range-announce role=status aria-live=polite aria-atomic=true data-rozie-s-d5dcab4c="">`), _tmpl$5$1 = /* @__PURE__ */ template(`<div class="rdt-sr-live rdt-sr-sortfilter"data-testid=sortfilter-announce role=status aria-live=polite aria-atomic=true data-rozie-s-d5dcab4c="">`), _tmpl$6 = /* @__PURE__ */ template(`<details class=rdt-colvis data-rozie-s-d5dcab4c=""><summary class=rdt-colvis-summary data-rozie-s-d5dcab4c="">Columns</summary><div class=rdt-colvis-menu role=group aria-label="Toggle columns"data-rozie-s-d5dcab4c="">`), _tmpl$7 = /* @__PURE__ */ template(`<label class=rdt-colvis-item data-rozie-s-d5dcab4c=""><input type=checkbox class=rdt-colvis-checkbox data-rozie-s-d5dcab4c=""><span class=rdt-colvis-label data-rozie-s-d5dcab4c="">`), _tmpl$8 = /* @__PURE__ */ template(`<div class=rdt-group-bar-host data-rozie-s-d5dcab4c="">`), _tmpl$9 = /* @__PURE__ */ template(`<span class=rdt-group-token data-group-token=""data-rozie-s-d5dcab4c="">`), _tmpl$0 = /* @__PURE__ */ template(`<div class=rdt-scroll data-rozie-s-d5dcab4c=""><table data-rozie-s-d5dcab4c=""><thead class=rdt-thead role=rowgroup data-rozie-s-d5dcab4c=""></thead><tbody class=rdt-tbody role=rowgroup data-rozie-s-d5dcab4c=""><tr class=rdt-spacer aria-hidden=true data-rozie-s-d5dcab4c=""><td data-rozie-s-d5dcab4c=""></td></tr><tr class=rdt-spacer aria-hidden=true data-rozie-s-d5dcab4c=""><td data-rozie-s-d5dcab4c="">`), _tmpl$1 = /* @__PURE__ */ template(`<table data-rozie-s-d5dcab4c=""><thead class=rdt-thead role=rowgroup data-rozie-s-d5dcab4c=""></thead><tbody class=rdt-tbody role=rowgroup data-rozie-s-d5dcab4c="">`), _tmpl$10 = /* @__PURE__ */ template(`<tr class=rdt-tr role=row data-rozie-s-d5dcab4c="">`), _tmpl$11 = /* @__PURE__ */ template(`<th role=columnheader data-grid-cell=""data-row=__header data-rozie-s-d5dcab4c="">`), _tmpl$12 = /* @__PURE__ */ template(`<span data-rozie-s-d5dcab4c="">`), _tmpl$13 = /* @__PURE__ */ template(`<div class=rdt-col-menu role=menu data-rozie-s-d5dcab4c=""><button type=button role=menuitem class=rdt-col-menu-item data-rozie-s-d5dcab4c="">Pin left</button><button type=button role=menuitem class=rdt-col-menu-item data-rozie-s-d5dcab4c="">Pin right</button><button type=button role=menuitem class=rdt-col-menu-item data-rozie-s-d5dcab4c="">Unpin</button><hr class=rdt-col-menu-sep data-rozie-s-d5dcab4c=""><button type=button role=menuitem class=rdt-col-menu-item data-rozie-s-d5dcab4c="">Hide column`), _tmpl$14 = /* @__PURE__ */ template(`<span data-rozie-s-d5dcab4c=""><button type=button class=rdt-resize-handle data-rozie-s-d5dcab4c=""><span class=rdt-resize-grip aria-hidden=true data-rozie-s-d5dcab4c="">`), _tmpl$15 = /* @__PURE__ */ template(`<button type=button class=rdt-sort-btn data-rozie-s-d5dcab4c=""><span class=rdt-header-label data-rozie-s-d5dcab4c=""></span><span class=rdt-sort-ind aria-hidden=true data-rozie-s-d5dcab4c="">`), _tmpl$16 = /* @__PURE__ */ template(`<span data-rozie-s-d5dcab4c=""><span class=rdt-header-label data-rozie-s-d5dcab4c="">`), _tmpl$17 = /* @__PURE__ */ template(`<button type=button class=rdt-col-menu-trigger data-rozie-s-d5dcab4c="">⋯`), _tmpl$18 = /* @__PURE__ */ template(`<input type=checkbox aria-label="Select all rows"class=rdt-select-all data-rozie-s-d5dcab4c="">`), _tmpl$19 = /* @__PURE__ */ template(`<tr class=rdt-filter-row data-rozie-s-d5dcab4c="">`), _tmpl$20 = /* @__PURE__ */ template(`<th role=presentation data-rozie-s-d5dcab4c="">`), _tmpl$21 = /* @__PURE__ */ template(`<input type=text class=rdt-col-filter data-rozie-s-d5dcab4c="">`), _tmpl$22 = /* @__PURE__ */ template(`<tr role=row data-rozie-s-d5dcab4c="">`), _tmpl$23 = /* @__PURE__ */ template(`<td data-grid-cell=""data-rozie-s-d5dcab4c="">`), _tmpl$24 = /* @__PURE__ */ template(`<span data-rozie-s-d5dcab4c=""><button type=button data-expander=""class="rdt-expander rdt-group-toggle"data-rozie-s-d5dcab4c=""></button><span class=rdt-group-value data-rozie-s-d5dcab4c=""></span><span class=rdt-group-count data-rozie-s-d5dcab4c="">`), _tmpl$25 = /* @__PURE__ */ template(`<span class=rdt-cell-value data-rozie-s-d5dcab4c="">`), _tmpl$26 = /* @__PURE__ */ template(`<input type=number data-editing-cell=""data-builtin-editor=""class=rdt-cell-editor data-rozie-s-d5dcab4c="">`), _tmpl$27 = /* @__PURE__ */ template(`<select data-editing-cell=""data-builtin-editor=""class=rdt-cell-editor data-rozie-s-d5dcab4c="">`), _tmpl$28 = /* @__PURE__ */ template(`<input type=checkbox data-editing-cell=""data-builtin-editor=""class=rdt-cell-editor data-rozie-s-d5dcab4c="">`), _tmpl$29 = /* @__PURE__ */ template(`<input type=text data-editing-cell=""data-builtin-editor=""class=rdt-cell-editor data-rozie-s-d5dcab4c="">`), _tmpl$30 = /* @__PURE__ */ template(`<option data-rozie-s-d5dcab4c="">`), _tmpl$31 = /* @__PURE__ */ template(`<input type=checkbox aria-label="Select row"class=rdt-select-row data-rozie-s-d5dcab4c="">`), _tmpl$32 = /* @__PURE__ */ template(`<button type=button data-expander=""class=rdt-expander data-rozie-s-d5dcab4c="">`), _tmpl$33 = /* @__PURE__ */ template(`<span data-fill-handle=""data-testid=fill-handle aria-hidden=true class=rdt-fill-handle data-rozie-s-d5dcab4c="">`), _tmpl$34 = /* @__PURE__ */ template(`<tr class=rdt-detail-row role=row data-rozie-s-d5dcab4c=""><td class=rdt-detail-cell data-rozie-s-d5dcab4c="">`), _tmpl$35 = /* @__PURE__ */ template(`<th class=rdt-col-spacer aria-hidden=true data-rozie-s-d5dcab4c="">`), _tmpl$36 = /* @__PURE__ */ template(`<td class=rdt-col-spacer aria-hidden=true data-rozie-s-d5dcab4c="">`), _tmpl$37 = /* @__PURE__ */ template(`<span data-rozie-s-d5dcab4c=""><input class=rdt-select-placeholder type=checkbox tabindex=-1 aria-hidden=true data-rozie-s-d5dcab4c="">`), _tmpl$38 = /* @__PURE__ */ template(`<span class=rdt-skeleton aria-hidden=true data-rozie-s-d5dcab4c="">​`), _tmpl$39 = /* @__PURE__ */ template(`<div class=rdt-pagination role=group aria-label=Pagination data-rozie-s-d5dcab4c=""><button type=button class="rdt-page-btn rdt-page-prev"data-rozie-s-d5dcab4c="">Prev</button><span class=rdt-page-status aria-live=polite data-rozie-s-d5dcab4c=""></span><button type=button class="rdt-page-btn rdt-page-next"data-rozie-s-d5dcab4c="">Next</button><select aria-label="Rows per page"class=rdt-page-size data-rozie-s-d5dcab4c=""><option value=10 data-rozie-s-d5dcab4c="">10</option><option value=25 data-rozie-s-d5dcab4c="">25</option><option value=50 data-rozie-s-d5dcab4c="">50</option><option value=100 data-rozie-s-d5dcab4c="">100`);
|
|
242
|
-
/** A cell position as integers over the visible (display-order) model. */ /** The active (roving-focus) cell. A header cell reports `rowIndex: null` and `isHeader: true`. */ /** The rectangular cell-range selection. Both corners are `null` when there is no range. */ /** One data column offered to the `#groupBar` slot. */ /** One changed cell inside a row edit commit. */ /** The `activecell-change` payload. `isHeader` is set when the move landed on or left a header cell. */ /** The `cell-edit-commit` payload: one committed cell. */ /** The `row-edit-commit` payload: the row and every cell the save changed. */ /** The `filter-change` payload: `globalFilter` for the search box, `columnFilters` for a per-column filter. Exactly one key is set. */ /** The `history-change` payload: undo/redo availability. */ /** The `range-change` payload: the new range corners (both `null` when the range cleared). */ /** The `row-activate` payload. `row` is the original data object and `index` its position in the rendered model. */ /** The `visible-range-change` payload: the rendered row window, `end` exclusive. */ __rozieInjectStyle("DataTable-d5dcab4c", `[data-rozie-s-d5dcab4c]:host {
|
|
472
|
+
/** A cell position as integers over the visible (display-order) model. */ /** The active (roving-focus) cell. A header cell reports `rowIndex: null` and `isHeader: true`. */ /** The rectangular cell-range selection. Both corners are `null` when there is no range. */ /** One data column offered to the `#groupBar` slot. */ /** One changed cell inside a row edit commit. */ /** The `activecell-change` payload. `isHeader` is set when the move landed on or left a header cell. */ /** The `cell-edit-commit` payload: one committed cell. */ /** The `row-edit-commit` payload: the row and every cell the save changed. */ /** The `filter-change` payload: `globalFilter` for the search box, `columnFilters` for a per-column filter. Exactly one key is set. */ /** The `history-change` payload: undo/redo availability. */ /** The held-view state (`holdView`): whether the view is held right now, and how many rows the held view disagrees with. */ /** The `range-change` payload: the new range corners (both `null` when the range cleared). */ /** The `row-activate` payload. `row` is the original data object and `index` its position in the rendered model. */ /** The `visible-range-change` payload: the rendered row window, `end` exclusive. */ __rozieInjectStyle("DataTable-d5dcab4c", `[data-rozie-s-d5dcab4c]:host {
|
|
243
473
|
--rdt-color: var(--rozie-data-table-fg, var(--rdt-ds-fg));
|
|
244
474
|
--rdt-select-accent: var(--rozie-data-table-select-accent, var(--rozie-data-table-accent, var(--rdt-ds-select-accent)));
|
|
245
475
|
--rdt-border: 1px solid var(--rozie-data-table-border-color, var(--rdt-ds-border-color));
|
|
@@ -655,6 +885,7 @@ function DataTable(_props) {
|
|
|
655
885
|
singleClickEdit: false,
|
|
656
886
|
undoable: false,
|
|
657
887
|
undoLimit: 100,
|
|
888
|
+
holdView: false,
|
|
658
889
|
virtual: false,
|
|
659
890
|
estimateRowHeight: 40,
|
|
660
891
|
autoMeasure: false,
|
|
@@ -686,6 +917,7 @@ function DataTable(_props) {
|
|
|
686
917
|
"singleClickEdit",
|
|
687
918
|
"undoable",
|
|
688
919
|
"undoLimit",
|
|
920
|
+
"holdView",
|
|
689
921
|
"virtual",
|
|
690
922
|
"estimateRowHeight",
|
|
691
923
|
"autoMeasure",
|
|
@@ -708,6 +940,7 @@ function DataTable(_props) {
|
|
|
708
940
|
"onSelectionChange",
|
|
709
941
|
"onSortChange",
|
|
710
942
|
"onVisibilityChange",
|
|
943
|
+
"onViewStateChange",
|
|
711
944
|
"onVisibleRangeChange",
|
|
712
945
|
"groupBarSlot",
|
|
713
946
|
"selectAllSlot",
|
|
@@ -758,7 +991,9 @@ function DataTable(_props) {
|
|
|
758
991
|
redo,
|
|
759
992
|
canUndo,
|
|
760
993
|
canRedo,
|
|
761
|
-
clearHistory
|
|
994
|
+
clearHistory,
|
|
995
|
+
refreshView,
|
|
996
|
+
getViewState
|
|
762
997
|
});
|
|
763
998
|
});
|
|
764
999
|
const __ctx_data_table_columns = rozieContext("data-table:columns");
|
|
@@ -847,6 +1082,7 @@ function DataTable(_props) {
|
|
|
847
1082
|
columnOrder(),
|
|
848
1083
|
columnPinning(),
|
|
849
1084
|
local.selectionMode,
|
|
1085
|
+
local.holdView,
|
|
850
1086
|
(data() || []).length,
|
|
851
1087
|
data(),
|
|
852
1088
|
dataDefault(),
|
|
@@ -871,13 +1107,15 @@ function DataTable(_props) {
|
|
|
871
1107
|
onMount(() => {
|
|
872
1108
|
setDataDefault(data() || []);
|
|
873
1109
|
seedColumnPinning();
|
|
1110
|
+
const cols0 = tableColumns();
|
|
1111
|
+
lastColumnSig = columnSetSignature(cols0);
|
|
874
1112
|
table = createTable({
|
|
875
1113
|
data: feedData(),
|
|
876
|
-
columns:
|
|
1114
|
+
columns: cols0,
|
|
877
1115
|
state: currentState(),
|
|
878
1116
|
getCoreRowModel: getCoreRowModel(),
|
|
879
|
-
getSortedRowModel:
|
|
880
|
-
getFilteredRowModel:
|
|
1117
|
+
getSortedRowModel: heldSortedRowModel,
|
|
1118
|
+
getFilteredRowModel: heldFilteredRowModel,
|
|
881
1119
|
getPaginationRowModel: getPaginationRowModel(),
|
|
882
1120
|
getExpandedRowModel: getExpandedRowModel(),
|
|
883
1121
|
getSubRows: local.getSubRows || void 0,
|
|
@@ -912,6 +1150,21 @@ function DataTable(_props) {
|
|
|
912
1150
|
renderFallbackValue: null,
|
|
913
1151
|
onStateChange: () => {}
|
|
914
1152
|
});
|
|
1153
|
+
table.resetPageIndex = () => {
|
|
1154
|
+
if (!table) return;
|
|
1155
|
+
const pg = table.getState().pagination;
|
|
1156
|
+
writePagination({
|
|
1157
|
+
pageIndex: pg.pageIndex,
|
|
1158
|
+
pageSize: pg.pageSize
|
|
1159
|
+
});
|
|
1160
|
+
};
|
|
1161
|
+
const st0 = currentState();
|
|
1162
|
+
lastHoldSorting = st0.sorting;
|
|
1163
|
+
lastHoldColumnFilters = st0.columnFilters;
|
|
1164
|
+
lastHoldGlobalFilter = st0.globalFilter;
|
|
1165
|
+
lastPageGrouping = st0.grouping;
|
|
1166
|
+
syncHoldActive(st0);
|
|
1167
|
+
lastPropsData = data();
|
|
915
1168
|
refreshRowModel = () => {
|
|
916
1169
|
if (!table) return;
|
|
917
1170
|
const nextRows = windowSource().slice();
|
|
@@ -926,7 +1179,17 @@ function DataTable(_props) {
|
|
|
926
1179
|
}
|
|
927
1180
|
remeasureColumnWindow();
|
|
928
1181
|
const nextRowCount = nextRows.length;
|
|
929
|
-
|
|
1182
|
+
const nextColCount = nextRows.length ? nextRows[0].getVisibleCells().length : nextGroups.length ? (nextGroups[nextGroups.length - 1].headers || []).length : 0;
|
|
1183
|
+
const nextIds = nextRows.map((r) => r.id);
|
|
1184
|
+
const fedData = table.options.data;
|
|
1185
|
+
const dataChanged = fedData !== lastFedData;
|
|
1186
|
+
lastFedData = fedData;
|
|
1187
|
+
const viewChangeOrWrite = pendingViewChange || pendingWrite && dataChanged;
|
|
1188
|
+
const swapWithoutIds = dataChanged && !pendingWrite && !pendingViewChange && table.options.getRowId == null;
|
|
1189
|
+
pendingViewChange = false;
|
|
1190
|
+
if (dataChanged) pendingWrite = false;
|
|
1191
|
+
followActiveCell(swapWithoutIds ? null : prevRowIds, nextIds, viewChangeOrWrite, nextRowCount, nextColCount, pendingEditFollow != null);
|
|
1192
|
+
prevRowIds = nextIds;
|
|
930
1193
|
const pgState = table.getState().pagination;
|
|
931
1194
|
const pc = table.getPageCount();
|
|
932
1195
|
if (pc > 0 && pgState.pageIndex > pc - 1) writePagination({
|
|
@@ -942,6 +1205,11 @@ function DataTable(_props) {
|
|
|
942
1205
|
syncIndeterminate();
|
|
943
1206
|
if (typeof queueMicrotask !== "undefined") queueMicrotask(syncIndeterminate);
|
|
944
1207
|
else Promise.resolve().then(syncIndeterminate);
|
|
1208
|
+
const vs = holdCtrl.viewState(table);
|
|
1209
|
+
if (!viewStatesEqual(vs, lastViewState)) {
|
|
1210
|
+
lastViewState = vs;
|
|
1211
|
+
_props.onViewStateChange?.(vs);
|
|
1212
|
+
}
|
|
945
1213
|
};
|
|
946
1214
|
refreshRowModel();
|
|
947
1215
|
gridRoot = __rozieRootRef ? __rozieRootRef.querySelector(".rozie-data-table") : null;
|
|
@@ -1033,6 +1301,48 @@ function DataTable(_props) {
|
|
|
1033
1301
|
let undoStack = [];
|
|
1034
1302
|
let redoStack = [];
|
|
1035
1303
|
let restoringHistory = false;
|
|
1304
|
+
const holdCtrl = createHoldController();
|
|
1305
|
+
const heldFilteredRowModel = holdCtrl.wrapFiltered(getFilteredRowModel());
|
|
1306
|
+
const heldSortedRowModel = holdCtrl.wrapSorted(getSortedRowModel());
|
|
1307
|
+
let pendingViewChange = false;
|
|
1308
|
+
let pendingWrite = false;
|
|
1309
|
+
let prevRowIds = null;
|
|
1310
|
+
let lastFedData = null;
|
|
1311
|
+
let lastViewState = CLEAN_VIEW_STATE;
|
|
1312
|
+
let lastHoldSorting = null;
|
|
1313
|
+
let lastHoldColumnFilters = null;
|
|
1314
|
+
let lastHoldGlobalFilter = null;
|
|
1315
|
+
let holdFallbackWarned = false;
|
|
1316
|
+
let lastPageGrouping = null;
|
|
1317
|
+
let lastColumnSig = "";
|
|
1318
|
+
function columnSetSignature(defs) {
|
|
1319
|
+
let sig = "";
|
|
1320
|
+
const stack = (defs || []).slice().reverse();
|
|
1321
|
+
while (stack.length) {
|
|
1322
|
+
const d = stack.pop();
|
|
1323
|
+
if (!d) continue;
|
|
1324
|
+
sig += String(d.id) + (d.enableSorting ? "+" : "") + (d.enableColumnFilter ? "*" : "") + "|";
|
|
1325
|
+
if (Array.isArray(d.columns)) for (let i = d.columns.length - 1; i >= 0; i--) stack.push(d.columns[i]);
|
|
1326
|
+
}
|
|
1327
|
+
return sig;
|
|
1328
|
+
}
|
|
1329
|
+
let lastPropsData = null;
|
|
1330
|
+
function isExternalSwap() {
|
|
1331
|
+
const pd = data();
|
|
1332
|
+
if (pd === lastPropsData) return false;
|
|
1333
|
+
return !(pd != null && pd[DATA_WRITE_TOKEN_KEY] != null);
|
|
1334
|
+
}
|
|
1335
|
+
function syncHoldActive(st) {
|
|
1336
|
+
const wanted = local.holdView === true;
|
|
1337
|
+
const active = wanted && local.manual !== true && local.getSubRows == null && !(st.grouping || []).length;
|
|
1338
|
+
const wasHolding = holdCtrl.isHolding();
|
|
1339
|
+
holdCtrl.setActive(active);
|
|
1340
|
+
if (wasHolding && !holdCtrl.isHolding()) pendingViewChange = true;
|
|
1341
|
+
if (wanted && !active && !holdFallbackWarned) {
|
|
1342
|
+
holdFallbackWarned = true;
|
|
1343
|
+
console.warn("[rozie-data-table] holdView falls back to live behaviour while grouping is active, in manual mode, or with tree data (getSubRows); the view is not held.");
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1036
1346
|
let expandedTouched = false;
|
|
1037
1347
|
function groupingActiveDefault() {
|
|
1038
1348
|
return ((grouping() != null ? grouping() : groupingDefault()) || []).length > 0;
|
|
@@ -1165,6 +1475,7 @@ function DataTable(_props) {
|
|
|
1165
1475
|
expandable: c.expandable === true,
|
|
1166
1476
|
groupable: c.groupable !== false,
|
|
1167
1477
|
aggregationFn: wrapAggregationFn(c.aggregationFn),
|
|
1478
|
+
...columnRuleKeys(c, id),
|
|
1168
1479
|
pinned: c.pinned != null ? c.pinned : "",
|
|
1169
1480
|
width: c.width != null ? c.width : "",
|
|
1170
1481
|
...parseWidthToSize(c.width) != null ? { size: parseWidthToSize(c.width) } : {},
|
|
@@ -1208,6 +1519,7 @@ function DataTable(_props) {
|
|
|
1208
1519
|
expandable: spec.expandable === true,
|
|
1209
1520
|
groupable: spec.groupable !== false,
|
|
1210
1521
|
aggregationFn: wrapAggregationFn(spec.aggregationFn),
|
|
1522
|
+
...columnRuleKeys(spec, id),
|
|
1211
1523
|
pinned: spec.pinned != null ? spec.pinned : "",
|
|
1212
1524
|
width: spec.width != null ? spec.width : "",
|
|
1213
1525
|
...parseWidthToSize(spec.width) != null ? { size: parseWidthToSize(spec.width) } : {},
|
|
@@ -1364,6 +1676,9 @@ function DataTable(_props) {
|
|
|
1364
1676
|
recordSnapshot(currentData());
|
|
1365
1677
|
emitHistoryChangeIfEdged(prevU, prevR);
|
|
1366
1678
|
}
|
|
1679
|
+
if (table) holdCtrl.capture(table);
|
|
1680
|
+
holdCtrl.noteWrite(currentData() || [], Array.isArray(next) ? next : []);
|
|
1681
|
+
pendingWrite = true;
|
|
1367
1682
|
const fresh = Array.isArray(next) ? next.slice() : next;
|
|
1368
1683
|
try {
|
|
1369
1684
|
Object.defineProperty(fresh, DATA_WRITE_TOKEN_KEY, {
|
|
@@ -1987,13 +2302,60 @@ function DataTable(_props) {
|
|
|
1987
2302
|
if (local.selectionMode === "none") return false;
|
|
1988
2303
|
return lazyRowsActive() ? (row) => !rowIsLazyPlaceholder(row) : true;
|
|
1989
2304
|
}
|
|
2305
|
+
function writePaginationSoon(next) {
|
|
2306
|
+
if (!programmatic) {
|
|
2307
|
+
writePagination(next);
|
|
2308
|
+
return;
|
|
2309
|
+
}
|
|
2310
|
+
const run = () => writePagination(next);
|
|
2311
|
+
if (typeof queueMicrotask !== "undefined") queueMicrotask(run);
|
|
2312
|
+
else Promise.resolve().then(run);
|
|
2313
|
+
}
|
|
1990
2314
|
function reFeed() {
|
|
1991
2315
|
if (!table) return;
|
|
2316
|
+
const st0 = currentState();
|
|
2317
|
+
syncHoldActive(st0);
|
|
2318
|
+
let st = st0;
|
|
2319
|
+
let pageReset = null;
|
|
2320
|
+
const groupingChanged = st0.grouping !== lastPageGrouping;
|
|
2321
|
+
lastPageGrouping = st0.grouping;
|
|
2322
|
+
const viewChanged = st0.sorting !== lastHoldSorting || st0.columnFilters !== lastHoldColumnFilters || st0.globalFilter !== lastHoldGlobalFilter;
|
|
2323
|
+
if (viewChanged) {
|
|
2324
|
+
lastHoldSorting = st0.sorting;
|
|
2325
|
+
lastHoldColumnFilters = st0.columnFilters;
|
|
2326
|
+
lastHoldGlobalFilter = st0.globalFilter;
|
|
2327
|
+
holdCtrl.release();
|
|
2328
|
+
pendingViewChange = true;
|
|
2329
|
+
}
|
|
2330
|
+
if ((viewChanged || groupingChanged) && local.manual !== true && st0.pagination && st0.pagination.pageIndex !== 0) {
|
|
2331
|
+
pageReset = {
|
|
2332
|
+
pageIndex: 0,
|
|
2333
|
+
pageSize: st0.pagination.pageSize
|
|
2334
|
+
};
|
|
2335
|
+
st = {
|
|
2336
|
+
...st0,
|
|
2337
|
+
pagination: pageReset
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
const cols = tableColumns();
|
|
2341
|
+
const colSig = columnSetSignature(cols);
|
|
2342
|
+
if (colSig !== lastColumnSig) {
|
|
2343
|
+
lastColumnSig = colSig;
|
|
2344
|
+
st = {
|
|
2345
|
+
...st,
|
|
2346
|
+
sorting: [...st.sorting || []],
|
|
2347
|
+
columnFilters: [...st.columnFilters || []]
|
|
2348
|
+
};
|
|
2349
|
+
}
|
|
2350
|
+
if (holdCtrl.isHolding() && isExternalSwap()) holdCtrl.release();
|
|
2351
|
+
if (pendingWrite && isExternalSwap()) pendingWrite = false;
|
|
1992
2352
|
table.setOptions((prev) => ({
|
|
1993
2353
|
...prev,
|
|
1994
2354
|
data: feedData(),
|
|
1995
|
-
columns:
|
|
1996
|
-
state:
|
|
2355
|
+
columns: cols,
|
|
2356
|
+
state: st,
|
|
2357
|
+
getFilteredRowModel: heldFilteredRowModel,
|
|
2358
|
+
getSortedRowModel: heldSortedRowModel,
|
|
1997
2359
|
enableRowSelection: rowSelectionOption(),
|
|
1998
2360
|
enableMultiRowSelection: local.selectionMode === "multiple",
|
|
1999
2361
|
rowCount: local.rowCount ?? void 0,
|
|
@@ -2021,15 +2383,19 @@ function DataTable(_props) {
|
|
|
2021
2383
|
onColumnSizingInfoChange: onColumnSizingInfoChangeCb
|
|
2022
2384
|
}));
|
|
2023
2385
|
if (refreshRowModel) refreshRowModel();
|
|
2386
|
+
if (pageReset) writePaginationSoon(pageReset);
|
|
2024
2387
|
}
|
|
2025
|
-
let lastPropsData = null;
|
|
2026
2388
|
function maybeClearHistoryOnExternalSwap() {
|
|
2027
2389
|
const pd = data();
|
|
2028
2390
|
if (pd === lastPropsData) return;
|
|
2029
2391
|
lastPropsData = pd;
|
|
2030
|
-
if (!local.undoable) return;
|
|
2031
2392
|
if (pd != null && pd[DATA_WRITE_TOKEN_KEY] != null) return;
|
|
2032
|
-
|
|
2393
|
+
pendingWrite = false;
|
|
2394
|
+
if (holdCtrl.isHolding()) {
|
|
2395
|
+
holdCtrl.release();
|
|
2396
|
+
if (refreshRowModel) refreshRowModel();
|
|
2397
|
+
}
|
|
2398
|
+
if (local.undoable) clearHistory();
|
|
2033
2399
|
}
|
|
2034
2400
|
let lastData = null;
|
|
2035
2401
|
let lastDataLen = -1;
|
|
@@ -2406,6 +2772,23 @@ function DataTable(_props) {
|
|
|
2406
2772
|
function cut() {
|
|
2407
2773
|
return cutRange();
|
|
2408
2774
|
}
|
|
2775
|
+
function refreshView() {
|
|
2776
|
+
holdCtrl.release();
|
|
2777
|
+
pendingViewChange = true;
|
|
2778
|
+
if (!table) return;
|
|
2779
|
+
table.setOptions((p) => ({
|
|
2780
|
+
...p,
|
|
2781
|
+
state: {
|
|
2782
|
+
...p.state,
|
|
2783
|
+
columnFilters: [...p.state.columnFilters || []],
|
|
2784
|
+
sorting: [...p.state.sorting || []]
|
|
2785
|
+
}
|
|
2786
|
+
}));
|
|
2787
|
+
if (refreshRowModel) refreshRowModel();
|
|
2788
|
+
}
|
|
2789
|
+
function getViewState() {
|
|
2790
|
+
return holdCtrl.viewState(table);
|
|
2791
|
+
}
|
|
2409
2792
|
function isGrid() {
|
|
2410
2793
|
return local.interactionMode === "grid";
|
|
2411
2794
|
}
|
|
@@ -2938,6 +3321,7 @@ function DataTable(_props) {
|
|
|
2938
3321
|
if (!tgt || !tgt.closest) return;
|
|
2939
3322
|
const cellEl = tgt.closest("[data-grid-cell]");
|
|
2940
3323
|
if (!cellEl) return;
|
|
3324
|
+
activeCellEngaged = true;
|
|
2941
3325
|
const rowAttr = cellEl.getAttribute("data-row");
|
|
2942
3326
|
const colAttr = cellEl.getAttribute("data-col-index");
|
|
2943
3327
|
if (rowAttr == null || colAttr == null) return;
|
|
@@ -3111,13 +3495,62 @@ function DataTable(_props) {
|
|
|
3111
3495
|
if (typeof requestAnimationFrame === "function") requestAnimationFrame(tryFocus);
|
|
3112
3496
|
else setTimeout(tryFocus, 0);
|
|
3113
3497
|
}
|
|
3114
|
-
function
|
|
3498
|
+
function followOpenEditors(prevIds, nextIds) {
|
|
3499
|
+
if (!prevIds || sameIdSequence(prevIds, nextIds)) return false;
|
|
3500
|
+
let owns = false;
|
|
3501
|
+
const er = editingRow();
|
|
3502
|
+
if (er >= 0) {
|
|
3503
|
+
const ef = resolveFollow(prevIds, er, nextIds, true);
|
|
3504
|
+
if (ef.kind === "move") {
|
|
3505
|
+
setEditingRow(ef.index);
|
|
3506
|
+
focusEditorWhenReady(ef.index, editingCol(), false);
|
|
3507
|
+
owns = true;
|
|
3508
|
+
} else if (ef.kind !== "stay") {
|
|
3509
|
+
committedThisSession = true;
|
|
3510
|
+
editTransition = true;
|
|
3511
|
+
endEdit();
|
|
3512
|
+
editTransition = false;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
const rr = editingRowIndex();
|
|
3516
|
+
if (rr != null && rr >= 0) {
|
|
3517
|
+
const rf = resolveFollow(prevIds, rr, nextIds, true);
|
|
3518
|
+
if (rf.kind === "move") {
|
|
3519
|
+
setEditingRowIndex(rf.index);
|
|
3520
|
+
owns = true;
|
|
3521
|
+
} else if (rf.kind !== "stay") {
|
|
3522
|
+
editTransition = true;
|
|
3523
|
+
endRowEdit();
|
|
3524
|
+
editTransition = false;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
return owns;
|
|
3528
|
+
}
|
|
3529
|
+
function rowIdInModel(index) {
|
|
3530
|
+
const row = windowSource()[index];
|
|
3531
|
+
return row ? row.id : null;
|
|
3532
|
+
}
|
|
3533
|
+
function modelIndexOfRowId(id) {
|
|
3534
|
+
const rows = windowSource();
|
|
3535
|
+
for (let i = 0; i < rows.length; i++) if (rows[i].id === id) return i;
|
|
3536
|
+
return -1;
|
|
3537
|
+
}
|
|
3538
|
+
function followActiveCell(prevIds, nextIds, viewChangeOrWrite, rowCount, colCount, editFollowPending = false) {
|
|
3539
|
+
const editorOwnsFocus = followOpenEditors(prevIds, nextIds);
|
|
3540
|
+
if (!isGrid()) return;
|
|
3541
|
+
let follow = null;
|
|
3542
|
+
if (activeCellEngaged && rowCount > 0 && !activeIsHeader() && !gridEmptyFallback) follow = resolveFollow(prevIds, activeRow(), nextIds, viewChangeOrWrite);
|
|
3543
|
+
clampActiveCell(rowCount, colCount, follow, editFollowPending || editorOwnsFocus, rowCount <= 0 && viewChangeOrWrite);
|
|
3544
|
+
if (viewChangeOrWrite && !sameIdSequence(prevIds, nextIds)) clearRange();
|
|
3545
|
+
}
|
|
3546
|
+
function clampActiveCell(rowCount, colCount, follow = null, editFollowPending = false, focusEmptyPark = false) {
|
|
3115
3547
|
if (!isGrid()) return;
|
|
3116
3548
|
const colN = colCount != null ? colCount : visibleColCount();
|
|
3117
3549
|
const rowN = rowCount != null ? rowCount : bodyRowCount();
|
|
3118
3550
|
let recoverFocus = false;
|
|
3119
3551
|
let doomedRow = -1;
|
|
3120
3552
|
let doomedCol = 0;
|
|
3553
|
+
let focusOnBody = false;
|
|
3121
3554
|
if (gridRoot) {
|
|
3122
3555
|
const rootNode = gridRoot.getRootNode ? gridRoot.getRootNode() : null;
|
|
3123
3556
|
const focusedEl = rootNode ? rootNode.activeElement : null;
|
|
@@ -3126,6 +3559,7 @@ function DataTable(_props) {
|
|
|
3126
3559
|
const fRowAttr = focusedCell.getAttribute("data-row");
|
|
3127
3560
|
const fColAttr = focusedCell.getAttribute("data-col-index");
|
|
3128
3561
|
if (fRowAttr != null && fRowAttr !== "__header") {
|
|
3562
|
+
focusOnBody = true;
|
|
3129
3563
|
const fr = parseInt(fRowAttr, 10);
|
|
3130
3564
|
const fc = parseInt(fColAttr, 10);
|
|
3131
3565
|
if (Number.isFinite(fr) && fr > rowN - 1) {
|
|
@@ -3145,6 +3579,7 @@ function DataTable(_props) {
|
|
|
3145
3579
|
setActiveColIndex(0);
|
|
3146
3580
|
gridEmptyFallback = true;
|
|
3147
3581
|
clampRange(rowN - 1, colN - 1);
|
|
3582
|
+
if (focusEmptyPark && (focusOnBody || editFollowPending)) recoverGridFocus("__header", 0, headerLeafLevel());
|
|
3148
3583
|
return;
|
|
3149
3584
|
}
|
|
3150
3585
|
if (gridEmptyFallback) {
|
|
@@ -3152,6 +3587,31 @@ function DataTable(_props) {
|
|
|
3152
3587
|
setActiveIsHeader(false);
|
|
3153
3588
|
setActiveRow(0);
|
|
3154
3589
|
}
|
|
3590
|
+
if (follow && follow.kind === "move") {
|
|
3591
|
+
const nextRow = follow.index;
|
|
3592
|
+
setActiveRow(nextRow);
|
|
3593
|
+
clampRange(rowN - 1, colN - 1);
|
|
3594
|
+
_props.onActivecellChange?.({
|
|
3595
|
+
rowIndex: toAbsRow(nextRow),
|
|
3596
|
+
colIndex: col,
|
|
3597
|
+
isHeader: false
|
|
3598
|
+
});
|
|
3599
|
+
if (focusOnBody && !editFollowPending) focusCellWhenReady(nextRow, col);
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3602
|
+
if (follow && follow.kind === "park") {
|
|
3603
|
+
const level = headerLeafLevel();
|
|
3604
|
+
setActiveIsHeader(true);
|
|
3605
|
+
setActiveHeaderLevel(level);
|
|
3606
|
+
clampRange(rowN - 1, colN - 1);
|
|
3607
|
+
_props.onActivecellChange?.({
|
|
3608
|
+
rowIndex: null,
|
|
3609
|
+
colIndex: col,
|
|
3610
|
+
isHeader: true
|
|
3611
|
+
});
|
|
3612
|
+
if (focusOnBody || editFollowPending) recoverGridFocus("__header", col, level);
|
|
3613
|
+
return;
|
|
3614
|
+
}
|
|
3155
3615
|
if (!activeIsHeader()) {
|
|
3156
3616
|
const lastRow = rowN - 1;
|
|
3157
3617
|
const maxRow = lastRow < 0 ? 0 : lastRow;
|
|
@@ -3217,6 +3677,7 @@ function DataTable(_props) {
|
|
|
3217
3677
|
colVirtualizer._willUpdate();
|
|
3218
3678
|
}
|
|
3219
3679
|
let gridEmptyFallback = false;
|
|
3680
|
+
let activeCellEngaged = false;
|
|
3220
3681
|
let rangeTransition = false;
|
|
3221
3682
|
let rangeClickPending = null;
|
|
3222
3683
|
let rangeActive = false;
|
|
@@ -3937,6 +4398,7 @@ function DataTable(_props) {
|
|
|
3937
4398
|
const colId = columnIdAt(rowIndex, colIndex);
|
|
3938
4399
|
if (colId == null || !columnEditable(colId)) return;
|
|
3939
4400
|
committedThisSession = false;
|
|
4401
|
+
outsidePointerDown = false;
|
|
3940
4402
|
setInvalid("");
|
|
3941
4403
|
setEditingRowIndex(null);
|
|
3942
4404
|
setRowDraft({});
|
|
@@ -4387,12 +4849,14 @@ function DataTable(_props) {
|
|
|
4387
4849
|
const fromRow = editingRow();
|
|
4388
4850
|
const fromCol = editingCol();
|
|
4389
4851
|
const target = e.shiftKey ? prevEditableCell(fromRow, fromCol) : nextEditableCell(fromRow, fromCol);
|
|
4852
|
+
const targetRowId = target ? rowIdInModel(target.row) : null;
|
|
4390
4853
|
const committed = commitEdit(void 0, true);
|
|
4391
|
-
|
|
4392
|
-
|
|
4854
|
+
const advanceRow = targetRowId != null ? modelIndexOfRowId(targetRowId) : -1;
|
|
4855
|
+
if (committed && target && advanceRow >= 0) {
|
|
4856
|
+
setActiveRow(advanceRow);
|
|
4393
4857
|
setActiveColIndex(target.col);
|
|
4394
|
-
beginEdit(
|
|
4395
|
-
} else if (committed) focusCellWhenReady(fromRow, fromCol);
|
|
4858
|
+
beginEdit(advanceRow, target.col, null);
|
|
4859
|
+
} else if (committed && target) {} else if (committed) focusCellWhenReady(fromRow, fromCol);
|
|
4396
4860
|
} else if (key === "Escape") {
|
|
4397
4861
|
e.preventDefault();
|
|
4398
4862
|
cancelEdit();
|
|
@@ -6594,6 +7058,8 @@ function Column(_props) {
|
|
|
6594
7058
|
expandable: false,
|
|
6595
7059
|
groupable: true,
|
|
6596
7060
|
aggregationFn: null,
|
|
7061
|
+
filterFn: null,
|
|
7062
|
+
sortingFn: null,
|
|
6597
7063
|
editable: false,
|
|
6598
7064
|
editor: "text",
|
|
6599
7065
|
editorOptions: [],
|
|
@@ -6609,6 +7075,8 @@ function Column(_props) {
|
|
|
6609
7075
|
"expandable",
|
|
6610
7076
|
"groupable",
|
|
6611
7077
|
"aggregationFn",
|
|
7078
|
+
"filterFn",
|
|
7079
|
+
"sortingFn",
|
|
6612
7080
|
"editable",
|
|
6613
7081
|
"editor",
|
|
6614
7082
|
"editorOptions",
|
|
@@ -6626,11 +7094,15 @@ function Column(_props) {
|
|
|
6626
7094
|
local.expandable,
|
|
6627
7095
|
local.groupable,
|
|
6628
7096
|
local.aggregationFn,
|
|
7097
|
+
local.filterFn,
|
|
7098
|
+
local.sortingFn,
|
|
6629
7099
|
local.editable,
|
|
6630
7100
|
local.editor,
|
|
6631
7101
|
local.editorOptions,
|
|
6632
7102
|
local.validate
|
|
6633
7103
|
], (v) => untrack(() => (() => {
|
|
7104
|
+
latestFilterFn = local.filterFn;
|
|
7105
|
+
latestSortingFn = local.sortingFn;
|
|
6634
7106
|
if (reg) reg.registerColumn(colId(), buildSpec());
|
|
6635
7107
|
})()), { defer: true }));
|
|
6636
7108
|
onMount(() => {
|
|
@@ -6656,10 +7128,21 @@ function Column(_props) {
|
|
|
6656
7128
|
let reg = null;
|
|
6657
7129
|
reg = registry;
|
|
6658
7130
|
let registered = false;
|
|
7131
|
+
let latestFilterFn = null;
|
|
7132
|
+
let latestSortingFn = null;
|
|
7133
|
+
const filterTrampoline = Object.assign((...args) => typeof latestFilterFn === "function" ? latestFilterFn(...args) : true, {
|
|
7134
|
+
autoRemove: (value, column) => typeof latestFilterFn === "function" && typeof latestFilterFn.autoRemove === "function" ? latestFilterFn.autoRemove(value, column) : false,
|
|
7135
|
+
resolveFilterValue: (value) => typeof latestFilterFn === "function" && typeof latestFilterFn.resolveFilterValue === "function" ? latestFilterFn.resolveFilterValue(value) : value
|
|
7136
|
+
});
|
|
7137
|
+
function sortingTrampoline(...args) {
|
|
7138
|
+
return typeof latestSortingFn === "function" ? latestSortingFn(...args) : 0;
|
|
7139
|
+
}
|
|
6659
7140
|
function colId() {
|
|
6660
7141
|
return local.id !== "" ? local.id : local.field;
|
|
6661
7142
|
}
|
|
6662
7143
|
function buildSpec() {
|
|
7144
|
+
latestFilterFn = local.filterFn;
|
|
7145
|
+
latestSortingFn = local.sortingFn;
|
|
6663
7146
|
return {
|
|
6664
7147
|
id: colId(),
|
|
6665
7148
|
field: local.field !== "" ? local.field : colId(),
|
|
@@ -6671,6 +7154,8 @@ function Column(_props) {
|
|
|
6671
7154
|
expandable: local.expandable,
|
|
6672
7155
|
groupable: local.groupable,
|
|
6673
7156
|
aggregationFn: local.aggregationFn,
|
|
7157
|
+
filterFn: typeof local.filterFn === "function" ? filterTrampoline : local.filterFn,
|
|
7158
|
+
sortingFn: typeof local.sortingFn === "function" ? sortingTrampoline : local.sortingFn,
|
|
6674
7159
|
editable: local.editable,
|
|
6675
7160
|
editor: local.editor,
|
|
6676
7161
|
editorOptions: local.editorOptions,
|