@ai-matrx/design-system 0.15.2 → 0.17.0
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 +36 -0
- package/README.md +6 -0
- package/dist/data-table/copy-helpers.d.cts +1 -1
- package/dist/data-table/copy-helpers.d.ts +1 -1
- package/dist/data-table/filter-engine.d.cts +1 -1
- package/dist/data-table/filter-engine.d.ts +1 -1
- package/dist/data-table/index.cjs +303 -68
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +2 -2
- package/dist/data-table/index.d.ts +2 -2
- package/dist/data-table/index.js +299 -64
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +1 -1
- package/dist/data-table/infer-filter.d.ts +1 -1
- package/dist/data-table/layered-filters.d.cts +1 -1
- package/dist/data-table/layered-filters.d.ts +1 -1
- package/dist/data-table/query-control.d.cts +1 -1
- package/dist/data-table/query-control.d.ts +1 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +1 -1
- package/dist/data-table/types.d.ts +1 -1
- package/dist/data-table/url-state.d.cts +1 -1
- package/dist/data-table/url-state.d.ts +1 -1
- package/dist/data-table/xlsx.d.cts +1 -1
- package/dist/data-table/xlsx.d.ts +1 -1
- package/dist/index.cjs +12 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -67
- package/dist/index.js.map +1 -1
- package/dist/{types-XXbVB1sh.d.cts → types-4fmLG5AN.d.cts} +16 -1
- package/dist/{types-ClaxTaXq.d.ts → types-pZ95iFk5.d.ts} +16 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.0 — 2026-09-12
|
|
4
|
+
|
|
5
|
+
- `MatrxDataTable` accepts opt-in controlled `columnState` and `reorderableColumns`, allowing URL-backed order/visibility and package-owned header drag without a host renderer fork. Header grips and the column manager use the existing pointer sensor for mouse/touch ordering; the manager retains arrow controls and protected visibility. Headers show insertion feedback and cancel edge scrolling when the drag ends or leaves a valid target.
|
|
6
|
+
- `onViewChange` notifies when a subscriber attaches or row references/order change, while callback identity changes alone do not trigger a feedback loop.
|
|
7
|
+
|
|
8
|
+
### Consumer action
|
|
9
|
+
|
|
10
|
+
Update to 0.17.0 before using `columnState`, `reorderableColumns`, or the
|
|
11
|
+
controlled `columnManager` open state. These column ports are opt-in: existing
|
|
12
|
+
column-order and visibility behavior is unchanged until a consumer supplies
|
|
13
|
+
them. `onViewChange` subscribers receive the corrected attach and identity
|
|
14
|
+
semantics described above.
|
|
15
|
+
|
|
16
|
+
## 0.16.0 — 2026-09-11
|
|
17
|
+
|
|
18
|
+
`ConfirmDialogHost` now rides the shared opener primitive instead of its own
|
|
19
|
+
copy of the machinery: `useOpenerHost` from `@ai-matrx/kit/opener-react`
|
|
20
|
+
(kit 0.10.0) supplies the host registration, the ref-backed request queue, the
|
|
21
|
+
drain effect and the settle-once callback, and this package keeps only what was
|
|
22
|
+
ever its own — the dialog body, its motion layer and the themed scrim.
|
|
23
|
+
|
|
24
|
+
The same twenty lines lived here AND in three matrx-frontend dialog hosts;
|
|
25
|
+
package logic is never duplicated outside the package, and a host registry in
|
|
26
|
+
particular must never be re-implemented, because module-level host state
|
|
27
|
+
silently splits across ESM/CJS loader graphs.
|
|
28
|
+
|
|
29
|
+
Behaviour is unchanged and proven unchanged: all 17 confirm-surface tests —
|
|
30
|
+
imperative queueing, pre-mount calls, sequential presentation, the
|
|
31
|
+
never-resolve-silently rule, the destructive variant and the consequence-first
|
|
32
|
+
copy contract — pass untouched against the new host.
|
|
33
|
+
|
|
34
|
+
### Consumer action
|
|
35
|
+
|
|
36
|
+
None. `<ConfirmDialogHost />` mounts and behaves exactly as before. Requires
|
|
37
|
+
`@ai-matrx/kit` 0.10.0 or later.
|
|
38
|
+
|
|
3
39
|
## 0.15.2 — 2026-09-11
|
|
4
40
|
|
|
5
41
|
Editable append tables retain unsaved drafts by source identity. Returning to the
|
package/README.md
CHANGED
|
@@ -150,6 +150,12 @@ const pagination = usePaginatedData({ queryKey, initialCursor: 0, loadPage, getR
|
|
|
150
150
|
scroll: { mode: "scroll", thresholdPx: 96, intentTimeoutMs: 1200 } }} />;
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
+
URL/source owners can control columns without rebuilding the table: pass
|
|
154
|
+
`columnState={{ order, hidden, onChange }}` and `reorderableColumns`. The
|
|
155
|
+
package then commits both the Columns dialog and header drag through `onChange`.
|
|
156
|
+
The dialog provides drag ordering and labelled arrow controls; columns marked
|
|
157
|
+
`hideable: false` remain visible.
|
|
158
|
+
|
|
153
159
|
Use application-resolved preferences for `scroll`; `manual` always retains Load
|
|
154
160
|
more. Numbered exact-page sources use `controlled` with `totalItems`; fully loaded
|
|
155
161
|
client arrays use local mode or `controlled-local`. Partial server results must
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentPayloadInput } from './copy-types.cjs';
|
|
2
|
-
import { f as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-
|
|
2
|
+
import { f as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-4fmLG5AN.cjs';
|
|
3
3
|
import 'react';
|
|
4
4
|
|
|
5
5
|
/** Human markdown table of the current view (visible columns × rows). */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentPayloadInput } from './copy-types.js';
|
|
2
|
-
import { f as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-
|
|
2
|
+
import { f as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-pZ95iFk5.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
|
|
5
5
|
/** Human markdown table of the current view (visible columns × rows). */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-
|
|
1
|
+
import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-4fmLG5AN.cjs';
|
|
2
2
|
import 'react';
|
|
3
3
|
import './copy-types.cjs';
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-
|
|
1
|
+
import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-pZ95iFk5.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
import './copy-types.js';
|
|
4
4
|
|
|
@@ -460,7 +460,7 @@ module.exports = __toCommonJS(data_table_exports);
|
|
|
460
460
|
|
|
461
461
|
// src/data-table/MatrxDataTable.tsx
|
|
462
462
|
var import_react14 = require("react");
|
|
463
|
-
var
|
|
463
|
+
var import_core2 = require("@dnd-kit/core");
|
|
464
464
|
|
|
465
465
|
// src/data-table/icons.tsx
|
|
466
466
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -3416,6 +3416,7 @@ function parseOptionalNumber(raw) {
|
|
|
3416
3416
|
|
|
3417
3417
|
// src/data-table/ColumnManager.tsx
|
|
3418
3418
|
var import_react9 = require("react");
|
|
3419
|
+
var import_core = require("@dnd-kit/core");
|
|
3419
3420
|
init_filter_engine();
|
|
3420
3421
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3421
3422
|
function ColumnManager({
|
|
@@ -3432,6 +3433,8 @@ function ColumnManager({
|
|
|
3432
3433
|
);
|
|
3433
3434
|
const [draftOrder, setDraftOrder] = (0, import_react9.useState)(order);
|
|
3434
3435
|
const [draftHidden, setDraftHidden] = (0, import_react9.useState)(() => new Set(hidden));
|
|
3436
|
+
const [draggedColumnId, setDraggedColumnId] = (0, import_react9.useState)(null);
|
|
3437
|
+
const [dropTarget, setDropTarget] = (0, import_react9.useState)(null);
|
|
3435
3438
|
(0, import_react9.useEffect)(() => {
|
|
3436
3439
|
if (!open) return;
|
|
3437
3440
|
setDraftOrder(order);
|
|
@@ -3450,6 +3453,45 @@ function ColumnManager({
|
|
|
3450
3453
|
return next;
|
|
3451
3454
|
});
|
|
3452
3455
|
};
|
|
3456
|
+
const moveTo = (id, targetId) => {
|
|
3457
|
+
if (id === targetId) return;
|
|
3458
|
+
setDraftOrder((current) => {
|
|
3459
|
+
const from = current.indexOf(id);
|
|
3460
|
+
const target = current.indexOf(targetId);
|
|
3461
|
+
if (from < 0 || target < 0) return current;
|
|
3462
|
+
const next = [...current];
|
|
3463
|
+
next.splice(from, 1);
|
|
3464
|
+
const targetAfterRemoval = next.indexOf(targetId);
|
|
3465
|
+
next.splice(targetAfterRemoval, 0, id);
|
|
3466
|
+
return next;
|
|
3467
|
+
});
|
|
3468
|
+
};
|
|
3469
|
+
(0, import_core.useDndMonitor)({
|
|
3470
|
+
onDragStart(event) {
|
|
3471
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3472
|
+
setDraggedColumnId(String(event.active.data.current.columnId));
|
|
3473
|
+
},
|
|
3474
|
+
onDragOver(event) {
|
|
3475
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3476
|
+
const overData = event.over?.data.current;
|
|
3477
|
+
const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
|
|
3478
|
+
setDropTarget(target ? String(target) : null);
|
|
3479
|
+
},
|
|
3480
|
+
onDragCancel(event) {
|
|
3481
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3482
|
+
setDraggedColumnId(null);
|
|
3483
|
+
setDropTarget(null);
|
|
3484
|
+
},
|
|
3485
|
+
onDragEnd(event) {
|
|
3486
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3487
|
+
const dragged = String(event.active.data.current.columnId);
|
|
3488
|
+
const overData = event.over?.data.current;
|
|
3489
|
+
const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
|
|
3490
|
+
setDraggedColumnId(null);
|
|
3491
|
+
setDropTarget(null);
|
|
3492
|
+
if (target) moveTo(dragged, String(target));
|
|
3493
|
+
}
|
|
3494
|
+
});
|
|
3453
3495
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogContent, { className: "max-w-md", children: [
|
|
3454
3496
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogHeader, { children: [
|
|
3455
3497
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DialogTitle, { children: "Columns" }),
|
|
@@ -3462,14 +3504,16 @@ function ColumnManager({
|
|
|
3462
3504
|
const hideable = column.hideable !== false;
|
|
3463
3505
|
const visible = !draftHidden.has(id);
|
|
3464
3506
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3465
|
-
|
|
3507
|
+
ColumnManagerDropTarget,
|
|
3466
3508
|
{
|
|
3509
|
+
id,
|
|
3467
3510
|
className: cn(
|
|
3468
3511
|
"flex items-center gap-2 px-2 py-2",
|
|
3469
|
-
!visible && "bg-muted/30 text-muted-foreground"
|
|
3512
|
+
!visible && "bg-muted/30 text-muted-foreground",
|
|
3513
|
+
dropTarget === id && draggedColumnId !== id && "border-t-2 border-primary"
|
|
3470
3514
|
),
|
|
3471
3515
|
children: [
|
|
3472
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3516
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColumnManagerDragHandle, { id, label }),
|
|
3473
3517
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3474
3518
|
Checkbox,
|
|
3475
3519
|
{
|
|
@@ -3535,6 +3579,36 @@ function ColumnManager({
|
|
|
3535
3579
|
] })
|
|
3536
3580
|
] }) });
|
|
3537
3581
|
}
|
|
3582
|
+
function ColumnManagerDropTarget({
|
|
3583
|
+
id,
|
|
3584
|
+
className,
|
|
3585
|
+
children
|
|
3586
|
+
}) {
|
|
3587
|
+
const { setNodeRef } = (0, import_core.useDroppable)({
|
|
3588
|
+
id: `matrx-column-manager:${id}`,
|
|
3589
|
+
data: { matrxDragKind: "column-manager", columnId: id }
|
|
3590
|
+
});
|
|
3591
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: setNodeRef, "data-matrx-column-manager-drop-target": id, className, children });
|
|
3592
|
+
}
|
|
3593
|
+
function ColumnManagerDragHandle({ id, label }) {
|
|
3594
|
+
const { attributes, listeners, setNodeRef } = (0, import_core.useDraggable)({
|
|
3595
|
+
id: `matrx-column-manager:${id}`,
|
|
3596
|
+
data: { matrxDragKind: "column-manager", columnId: id }
|
|
3597
|
+
});
|
|
3598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3599
|
+
"button",
|
|
3600
|
+
{
|
|
3601
|
+
ref: setNodeRef,
|
|
3602
|
+
type: "button",
|
|
3603
|
+
className: "flex h-10 w-10 shrink-0 touch-none cursor-grab items-center justify-center text-muted-foreground hover:text-foreground active:cursor-grabbing",
|
|
3604
|
+
"aria-label": `Reorder ${label}`,
|
|
3605
|
+
title: `Drag to reorder ${label}`,
|
|
3606
|
+
...attributes,
|
|
3607
|
+
...listeners,
|
|
3608
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GripVertical, { className: "h-4 w-4" })
|
|
3609
|
+
}
|
|
3610
|
+
);
|
|
3611
|
+
}
|
|
3538
3612
|
|
|
3539
3613
|
// src/data-table/MatrxUuidCell.tsx
|
|
3540
3614
|
var import_react10 = require("react");
|
|
@@ -5004,6 +5078,9 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
|
|
|
5004
5078
|
|
|
5005
5079
|
// src/data-table/MatrxDataTable.tsx
|
|
5006
5080
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5081
|
+
function hasSameRowReferences(previous, next) {
|
|
5082
|
+
return previous.length === next.length && previous.every((row, index) => row === next[index]);
|
|
5083
|
+
}
|
|
5007
5084
|
function TableRowCopyControl({
|
|
5008
5085
|
copy,
|
|
5009
5086
|
row,
|
|
@@ -5121,6 +5198,9 @@ function MatrxDataTableWithUrlState({
|
|
|
5121
5198
|
function MatrxDataTableCore({
|
|
5122
5199
|
data: suppliedData,
|
|
5123
5200
|
columns,
|
|
5201
|
+
columnState,
|
|
5202
|
+
reorderableColumns = false,
|
|
5203
|
+
columnManager: controlledColumnManager,
|
|
5124
5204
|
getRowId,
|
|
5125
5205
|
searchText,
|
|
5126
5206
|
processLocalRows,
|
|
@@ -5186,8 +5266,8 @@ function MatrxDataTableCore({
|
|
|
5186
5266
|
);
|
|
5187
5267
|
const [internalSearch, setInternalSearch] = (0, import_react14.useState)("");
|
|
5188
5268
|
const [draggedRowId, setDraggedRowId] = (0, import_react14.useState)(null);
|
|
5189
|
-
const hierarchySensors = (0,
|
|
5190
|
-
(0,
|
|
5269
|
+
const hierarchySensors = (0, import_core2.useSensors)(
|
|
5270
|
+
(0, import_core2.useSensor)(import_core2.PointerSensor, { activationConstraint: { distance: 6 } })
|
|
5191
5271
|
);
|
|
5192
5272
|
const toolbarSearchControlled = toolbar?.searchValue !== void 0;
|
|
5193
5273
|
const searchValue = controlledQuery ? controlledQuery.state.search : toolbarSearchControlled ? toolbar?.searchValue ?? "" : internalSearch;
|
|
@@ -5424,13 +5504,67 @@ function MatrxDataTableCore({
|
|
|
5424
5504
|
observer?.disconnect();
|
|
5425
5505
|
};
|
|
5426
5506
|
}, [updateScrollHint, data, columns]);
|
|
5427
|
-
const [columnOrder, setColumnOrder] = (0, import_react14.useState)(() => columns.map(columnId));
|
|
5507
|
+
const [columnOrder, setColumnOrder] = (0, import_react14.useState)(() => columnState?.order ?? columns.map(columnId));
|
|
5428
5508
|
const [hiddenColumnIds, setHiddenColumnIds] = (0, import_react14.useState)(
|
|
5429
|
-
() => new Set(columns.filter((column) => column.hidden).map(columnId))
|
|
5509
|
+
() => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
|
|
5430
5510
|
);
|
|
5431
|
-
const
|
|
5511
|
+
const draggedColumnId = (0, import_react14.useRef)(null);
|
|
5512
|
+
const columnDragActive = (0, import_react14.useRef)(false);
|
|
5513
|
+
const columnDragRaf = (0, import_react14.useRef)(null);
|
|
5514
|
+
const columnDragScrollDirection = (0, import_react14.useRef)(0);
|
|
5515
|
+
const [columnDropTarget, setColumnDropTarget] = (0, import_react14.useState)(null);
|
|
5516
|
+
const stopColumnDragScroll = (0, import_react14.useCallback)(() => {
|
|
5517
|
+
if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
|
|
5518
|
+
columnDragRaf.current = null;
|
|
5519
|
+
columnDragScrollDirection.current = 0;
|
|
5520
|
+
}, []);
|
|
5521
|
+
(0, import_react14.useEffect)(() => () => {
|
|
5522
|
+
columnDragActive.current = false;
|
|
5523
|
+
stopColumnDragScroll();
|
|
5524
|
+
}, [stopColumnDragScroll]);
|
|
5525
|
+
const startColumnDragScroll = (0, import_react14.useCallback)(() => {
|
|
5526
|
+
if (!columnDragActive.current || columnDragRaf.current !== null) return;
|
|
5527
|
+
const scrollStep = () => {
|
|
5528
|
+
const scroll = scrollRef.current;
|
|
5529
|
+
const direction = columnDragScrollDirection.current;
|
|
5530
|
+
if (!columnDragActive.current || !scroll || direction === 0) {
|
|
5531
|
+
columnDragRaf.current = null;
|
|
5532
|
+
return;
|
|
5533
|
+
}
|
|
5534
|
+
const nextScrollLeft = Math.max(
|
|
5535
|
+
0,
|
|
5536
|
+
Math.min(scroll.scrollLeft + direction * 18, scroll.scrollWidth - scroll.clientWidth)
|
|
5537
|
+
);
|
|
5538
|
+
if (nextScrollLeft === scroll.scrollLeft) {
|
|
5539
|
+
columnDragRaf.current = null;
|
|
5540
|
+
columnDragScrollDirection.current = 0;
|
|
5541
|
+
return;
|
|
5542
|
+
}
|
|
5543
|
+
scroll.scrollLeft = nextScrollLeft;
|
|
5544
|
+
if (!columnDragActive.current || columnDragScrollDirection.current === 0) {
|
|
5545
|
+
columnDragRaf.current = null;
|
|
5546
|
+
return;
|
|
5547
|
+
}
|
|
5548
|
+
columnDragRaf.current = requestAnimationFrame(scrollStep);
|
|
5549
|
+
};
|
|
5550
|
+
columnDragRaf.current = requestAnimationFrame(scrollStep);
|
|
5551
|
+
}, []);
|
|
5552
|
+
const commitColumnState = (0, import_react14.useCallback)((order, hidden) => {
|
|
5553
|
+
if (columnState) columnState.onChange({ order, hidden: [...hidden] });
|
|
5554
|
+
else {
|
|
5555
|
+
setColumnOrder(order);
|
|
5556
|
+
setHiddenColumnIds(hidden);
|
|
5557
|
+
}
|
|
5558
|
+
}, [columnState]);
|
|
5559
|
+
const [internalColumnManagerOpen, setInternalColumnManagerOpen] = (0, import_react14.useState)(false);
|
|
5560
|
+
const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
|
|
5561
|
+
const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
|
|
5562
|
+
const columnIds = (0, import_react14.useMemo)(() => columns.map(columnId), [columns]);
|
|
5563
|
+
const effectiveColumnOrder = (0, import_react14.useMemo)(() => columnState ? [...columnState.order.filter((id, index, values) => columnIds.includes(id) && values.indexOf(id) === index), ...columnIds.filter((id) => !columnState.order.includes(id))] : columnOrder, [columnIds, columnOrder, columnState]);
|
|
5564
|
+
const effectiveHiddenColumnIds = (0, import_react14.useMemo)(() => columnState ? new Set(columnState.hidden.filter((id) => columnIds.includes(id))) : hiddenColumnIds, [columnIds, columnState, hiddenColumnIds]);
|
|
5432
5565
|
(0, import_react14.useEffect)(() => {
|
|
5433
5566
|
const ids = columns.map(columnId);
|
|
5567
|
+
if (columnState) return;
|
|
5434
5568
|
setColumnOrder((current) => [
|
|
5435
5569
|
...current.filter((id) => ids.includes(id)),
|
|
5436
5570
|
...ids.filter((id) => !current.includes(id))
|
|
@@ -5442,13 +5576,13 @@ function MatrxDataTableCore({
|
|
|
5442
5576
|
}
|
|
5443
5577
|
return next;
|
|
5444
5578
|
});
|
|
5445
|
-
}, [columns]);
|
|
5579
|
+
}, [columns, columnState]);
|
|
5446
5580
|
const visibleColumns = (0, import_react14.useMemo)(() => {
|
|
5447
5581
|
const byId = new Map(columns.map((column) => [columnId(column), column]));
|
|
5448
|
-
return
|
|
5449
|
-
(column) => column !== void 0 && !
|
|
5582
|
+
return effectiveColumnOrder.map((id) => byId.get(id)).filter(
|
|
5583
|
+
(column) => column !== void 0 && !effectiveHiddenColumnIds.has(columnId(column))
|
|
5450
5584
|
);
|
|
5451
|
-
}, [columns,
|
|
5585
|
+
}, [columns, effectiveColumnOrder, effectiveHiddenColumnIds]);
|
|
5452
5586
|
const copySubsetVariant = useCopySubsetVariant();
|
|
5453
5587
|
const copySubsetColumns = () => visibleColumns.filter((c) => c.filter !== false || c.accessorKey || c.accessorFn).map((c) => ({
|
|
5454
5588
|
id: columnId(c),
|
|
@@ -5522,8 +5656,15 @@ function MatrxDataTableCore({
|
|
|
5522
5656
|
sourceOwnsColumnFilters,
|
|
5523
5657
|
sourceOwnsSort
|
|
5524
5658
|
]);
|
|
5659
|
+
const lastNotifiedViewRows = (0, import_react14.useRef)(null);
|
|
5525
5660
|
(0, import_react14.useEffect)(() => {
|
|
5526
|
-
onViewChange
|
|
5661
|
+
if (!onViewChange) {
|
|
5662
|
+
lastNotifiedViewRows.current = null;
|
|
5663
|
+
return;
|
|
5664
|
+
}
|
|
5665
|
+
const changed = lastNotifiedViewRows.current === null || !hasSameRowReferences(lastNotifiedViewRows.current, processed);
|
|
5666
|
+
lastNotifiedViewRows.current = processed;
|
|
5667
|
+
if (changed) onViewChange(processed);
|
|
5527
5668
|
}, [processed, onViewChange]);
|
|
5528
5669
|
(0, import_react14.useEffect)(() => {
|
|
5529
5670
|
if (controlledQuery) return;
|
|
@@ -5953,16 +6094,77 @@ function MatrxDataTableCore({
|
|
|
5953
6094
|
} : facet
|
|
5954
6095
|
) : toolbar?.facets;
|
|
5955
6096
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5956
|
-
|
|
6097
|
+
import_core2.DndContext,
|
|
5957
6098
|
{
|
|
5958
6099
|
sensors: hierarchySensors,
|
|
5959
|
-
collisionDetection:
|
|
5960
|
-
measuring: { droppable: { strategy:
|
|
6100
|
+
collisionDetection: import_core2.pointerWithin,
|
|
6101
|
+
measuring: { droppable: { strategy: import_core2.MeasuringStrategy.Always } },
|
|
5961
6102
|
onDragStart: (event) => {
|
|
6103
|
+
const kind = event.active.data.current?.matrxDragKind;
|
|
6104
|
+
if (kind === "column-header") {
|
|
6105
|
+
draggedColumnId.current = String(event.active.data.current?.columnId);
|
|
6106
|
+
columnDragActive.current = true;
|
|
6107
|
+
return;
|
|
6108
|
+
}
|
|
6109
|
+
if (kind === "column-manager") return;
|
|
5962
6110
|
setDraggedRowId(String(event.active.id));
|
|
5963
6111
|
},
|
|
5964
|
-
|
|
5965
|
-
|
|
6112
|
+
onDragMove: (event) => {
|
|
6113
|
+
if (!columnDragActive.current || event.active.data.current?.matrxDragKind !== "column-header") return;
|
|
6114
|
+
const overData = event.over?.data.current;
|
|
6115
|
+
const overId = overData?.matrxDragKind === "column-header" ? overData.columnId : null;
|
|
6116
|
+
const activeRect = event.active.rect.current.translated;
|
|
6117
|
+
const overRect = event.over?.rect;
|
|
6118
|
+
if (!overId || !activeRect || !overRect) {
|
|
6119
|
+
setColumnDropTarget(null);
|
|
6120
|
+
columnDragScrollDirection.current = 0;
|
|
6121
|
+
stopColumnDragScroll();
|
|
6122
|
+
return;
|
|
6123
|
+
}
|
|
6124
|
+
const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
|
|
6125
|
+
setColumnDropTarget({ id: String(overId), after });
|
|
6126
|
+
const scroll = scrollRef.current;
|
|
6127
|
+
if (!scroll) return;
|
|
6128
|
+
const bounds = scroll.getBoundingClientRect();
|
|
6129
|
+
const center = activeRect.left + activeRect.width / 2;
|
|
6130
|
+
columnDragScrollDirection.current = center - bounds.left < 80 ? -1 : bounds.right - center < 80 ? 1 : 0;
|
|
6131
|
+
if (columnDragScrollDirection.current === 0) stopColumnDragScroll();
|
|
6132
|
+
else startColumnDragScroll();
|
|
6133
|
+
},
|
|
6134
|
+
onDragCancel: () => {
|
|
6135
|
+
columnDragActive.current = false;
|
|
6136
|
+
draggedColumnId.current = null;
|
|
6137
|
+
setColumnDropTarget(null);
|
|
6138
|
+
stopColumnDragScroll();
|
|
6139
|
+
setDraggedRowId(null);
|
|
6140
|
+
},
|
|
6141
|
+
onDragEnd: (event) => {
|
|
6142
|
+
const kind = event.active.data.current?.matrxDragKind;
|
|
6143
|
+
if (kind === "column-manager") return;
|
|
6144
|
+
if (kind !== "column-header") {
|
|
6145
|
+
endHierarchyDrag(event);
|
|
6146
|
+
return;
|
|
6147
|
+
}
|
|
6148
|
+
const from = String(event.active.data.current?.columnId);
|
|
6149
|
+
const targetData = event.over?.data.current;
|
|
6150
|
+
const target = targetData?.matrxDragKind === "column-header" ? targetData.columnId : null;
|
|
6151
|
+
const activeRect = event.active.rect.current.translated;
|
|
6152
|
+
const overRect = event.over?.rect;
|
|
6153
|
+
columnDragActive.current = false;
|
|
6154
|
+
draggedColumnId.current = null;
|
|
6155
|
+
setColumnDropTarget(null);
|
|
6156
|
+
stopColumnDragScroll();
|
|
6157
|
+
if (!target || from === target || !activeRect || !overRect) return;
|
|
6158
|
+
const order = [...effectiveColumnOrder];
|
|
6159
|
+
const fromIndex = order.indexOf(from);
|
|
6160
|
+
const targetIndex = order.indexOf(String(target));
|
|
6161
|
+
if (fromIndex < 0 || targetIndex < 0) return;
|
|
6162
|
+
order.splice(fromIndex, 1);
|
|
6163
|
+
const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
|
|
6164
|
+
const insertion = order.indexOf(String(target)) + (after ? 1 : 0);
|
|
6165
|
+
order.splice(insertion, 0, from);
|
|
6166
|
+
commitColumnState(order, effectiveHiddenColumnIds);
|
|
6167
|
+
},
|
|
5966
6168
|
children: [
|
|
5967
6169
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5968
6170
|
"div",
|
|
@@ -6184,8 +6386,8 @@ function MatrxDataTableCore({
|
|
|
6184
6386
|
onClick: () => setColumnManagerOpen(true),
|
|
6185
6387
|
children: [
|
|
6186
6388
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SlidersHorizontal, { className: "h-4 w-4" }),
|
|
6187
|
-
|
|
6188
|
-
|
|
6389
|
+
effectiveHiddenColumnIds.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "sr-only", children: [
|
|
6390
|
+
effectiveHiddenColumnIds.size,
|
|
6189
6391
|
" hidden"
|
|
6190
6392
|
] }) : null
|
|
6191
6393
|
]
|
|
@@ -6439,46 +6641,50 @@ function MatrxDataTableCore({
|
|
|
6439
6641
|
// horizontal-scroll surface.
|
|
6440
6642
|
col.width !== void 0 && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
|
|
6441
6643
|
col.headerClassName,
|
|
6644
|
+
columnDropTarget?.id === id && (columnDropTarget.after ? "border-r-2 border-primary" : "border-l-2 border-primary"),
|
|
6442
6645
|
col.align === "center" && "text-center",
|
|
6443
6646
|
col.align === "right" && "text-right"
|
|
6444
6647
|
),
|
|
6445
6648
|
style: columnWidthVar(col.width),
|
|
6446
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime32.
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6649
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: [
|
|
6650
|
+
reorderableColumns ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ColumnReorderHandle, { id, label: headerLabel }) : null,
|
|
6651
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6652
|
+
ColumnHeaderCell,
|
|
6653
|
+
{
|
|
6654
|
+
label: col.header,
|
|
6655
|
+
labelText: headerLabel,
|
|
6656
|
+
sortable: col.sortable !== false,
|
|
6657
|
+
isSorted: Boolean(isSorted),
|
|
6658
|
+
sortDirection: sort?.direction ?? defaultSortDirection,
|
|
6659
|
+
onSortAsc: () => setSort({ id, direction: "asc" }),
|
|
6660
|
+
onSortDesc: () => setSort({ id, direction: "desc" }),
|
|
6661
|
+
onClearSort: () => setSort(null),
|
|
6662
|
+
onHeaderSortClick: () => {
|
|
6663
|
+
if (!isSorted) {
|
|
6664
|
+
setSort({ id, direction: defaultSortDirection });
|
|
6665
|
+
return;
|
|
6666
|
+
}
|
|
6667
|
+
if (sort?.direction === "asc") {
|
|
6668
|
+
setSort({ id, direction: "desc" });
|
|
6669
|
+
return;
|
|
6670
|
+
}
|
|
6671
|
+
setSort(null);
|
|
6672
|
+
},
|
|
6673
|
+
filterKind: meta?.kind ?? null,
|
|
6674
|
+
filterValue: columnFilters[id],
|
|
6675
|
+
onFilterChange: (next) => setColumnFilter(id, next),
|
|
6676
|
+
selectOptions: meta?.options,
|
|
6677
|
+
selectSingle: col.filterSingle,
|
|
6678
|
+
filterApplyLabel: filterUi?.applyLabel,
|
|
6679
|
+
filterShowCancel: filterUi?.showCancel,
|
|
6680
|
+
filterFooterHint: filterUi?.footerHint,
|
|
6681
|
+
allowNegation: filterUi?.allowNegation,
|
|
6682
|
+
allowNullModes: filterUi?.allowNullModes,
|
|
6683
|
+
align: col.align,
|
|
6684
|
+
compact: col.compact
|
|
6685
|
+
}
|
|
6686
|
+
)
|
|
6687
|
+
] })
|
|
6482
6688
|
},
|
|
6483
6689
|
id
|
|
6484
6690
|
);
|
|
@@ -6777,12 +6983,9 @@ function MatrxDataTableCore({
|
|
|
6777
6983
|
open: columnManagerOpen,
|
|
6778
6984
|
onOpenChange: setColumnManagerOpen,
|
|
6779
6985
|
columns,
|
|
6780
|
-
order:
|
|
6781
|
-
hidden:
|
|
6782
|
-
onApply:
|
|
6783
|
-
setColumnOrder(order);
|
|
6784
|
-
setHiddenColumnIds(hidden);
|
|
6785
|
-
}
|
|
6986
|
+
order: effectiveColumnOrder,
|
|
6987
|
+
hidden: effectiveHiddenColumnIds,
|
|
6988
|
+
onApply: commitColumnState
|
|
6786
6989
|
}
|
|
6787
6990
|
),
|
|
6788
6991
|
detailEnabled && selectedRow ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
@@ -6981,7 +7184,7 @@ function MatrxDataTableCore({
|
|
|
6981
7184
|
]
|
|
6982
7185
|
}
|
|
6983
7186
|
),
|
|
6984
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7187
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core2.DragOverlay, { children: draggedRow ? (
|
|
6985
7188
|
// w-max: the overlay inherits the ACTIVE node's size, and the active
|
|
6986
7189
|
// node is the 16px grip handle — without it the label wraps to one
|
|
6987
7190
|
// character per line.
|
|
@@ -6996,7 +7199,7 @@ function HierarchyDragHandle({
|
|
|
6996
7199
|
label,
|
|
6997
7200
|
disabled
|
|
6998
7201
|
}) {
|
|
6999
|
-
const { attributes, listeners, setNodeRef } = (0,
|
|
7202
|
+
const { attributes, listeners, setNodeRef } = (0, import_core2.useDraggable)({
|
|
7000
7203
|
id,
|
|
7001
7204
|
disabled
|
|
7002
7205
|
});
|
|
@@ -7020,7 +7223,7 @@ function HierarchyRootDropTarget({
|
|
|
7020
7223
|
label,
|
|
7021
7224
|
draggedLabel
|
|
7022
7225
|
}) {
|
|
7023
|
-
const { isOver, setNodeRef } = (0,
|
|
7226
|
+
const { isOver, setNodeRef } = (0, import_core2.useDroppable)({ id: "__root__" });
|
|
7024
7227
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7025
7228
|
"div",
|
|
7026
7229
|
{
|
|
@@ -7044,7 +7247,7 @@ function HierarchyDragIndicatorLayer({
|
|
|
7044
7247
|
const [indicator, setIndicator] = (0, import_react14.useState)(
|
|
7045
7248
|
null
|
|
7046
7249
|
);
|
|
7047
|
-
(0,
|
|
7250
|
+
(0, import_core2.useDndMonitor)({
|
|
7048
7251
|
onDragMove(event) {
|
|
7049
7252
|
const container = scrollRef.current;
|
|
7050
7253
|
const overId = event.over ? String(event.over.id) : null;
|
|
@@ -7144,7 +7347,7 @@ function HierarchyDroppableRow({
|
|
|
7144
7347
|
disabled,
|
|
7145
7348
|
children
|
|
7146
7349
|
}) {
|
|
7147
|
-
const { setNodeRef } = (0,
|
|
7350
|
+
const { setNodeRef } = (0, import_core2.useDroppable)({ id, disabled });
|
|
7148
7351
|
if (!(0, import_react14.isValidElement)(children) || children.type !== "tr") return children;
|
|
7149
7352
|
const row = children;
|
|
7150
7353
|
return (0, import_react14.cloneElement)(row, {
|
|
@@ -7152,6 +7355,38 @@ function HierarchyDroppableRow({
|
|
|
7152
7355
|
className: row.props.className
|
|
7153
7356
|
});
|
|
7154
7357
|
}
|
|
7358
|
+
function ColumnHeaderDropZone({
|
|
7359
|
+
id,
|
|
7360
|
+
enabled,
|
|
7361
|
+
children
|
|
7362
|
+
}) {
|
|
7363
|
+
const { setNodeRef } = (0, import_core2.useDroppable)({
|
|
7364
|
+
id: `matrx-column-header:${id}`,
|
|
7365
|
+
disabled: !enabled,
|
|
7366
|
+
data: { matrxDragKind: "column-header", columnId: id }
|
|
7367
|
+
});
|
|
7368
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
|
|
7369
|
+
}
|
|
7370
|
+
function ColumnReorderHandle({ id, label }) {
|
|
7371
|
+
const { attributes, listeners, setNodeRef } = (0, import_core2.useDraggable)({
|
|
7372
|
+
id: `matrx-column-header:${id}`,
|
|
7373
|
+
data: { matrxDragKind: "column-header", columnId: id }
|
|
7374
|
+
});
|
|
7375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7376
|
+
"button",
|
|
7377
|
+
{
|
|
7378
|
+
ref: setNodeRef,
|
|
7379
|
+
type: "button",
|
|
7380
|
+
className: "mr-1 flex h-7 w-5 shrink-0 touch-none cursor-grab items-center justify-center text-muted-foreground hover:text-foreground active:cursor-grabbing",
|
|
7381
|
+
"aria-label": `Reorder ${label}`,
|
|
7382
|
+
title: `Drag to reorder ${label}`,
|
|
7383
|
+
onClick: (event) => event.stopPropagation(),
|
|
7384
|
+
...attributes,
|
|
7385
|
+
...listeners,
|
|
7386
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(GripVertical, { className: "h-3.5 w-3.5" })
|
|
7387
|
+
}
|
|
7388
|
+
);
|
|
7389
|
+
}
|
|
7155
7390
|
function columnWidthVar(width) {
|
|
7156
7391
|
if (width === void 0) return void 0;
|
|
7157
7392
|
return {
|