@ai-matrx/design-system 0.16.0 → 0.17.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 +26 -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 +321 -75
- 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 +317 -71
- 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/scroll-pagination.cjs +18 -7
- package/dist/data-table/scroll-pagination.cjs.map +1 -1
- package/dist/data-table/scroll-pagination.js +18 -7
- package/dist/data-table/scroll-pagination.js.map +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/{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
|
@@ -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");
|
|
@@ -1197,6 +1197,7 @@ function useScrollPagination({
|
|
|
1197
1197
|
const inFlightGenerationRef = (0, import_react.useRef)(null);
|
|
1198
1198
|
const requestErrorRef = (0, import_react.useRef)(null);
|
|
1199
1199
|
const mountedRef = (0, import_react.useRef)(false);
|
|
1200
|
+
const observedTopRef = (0, import_react.useRef)(/* @__PURE__ */ new WeakMap());
|
|
1200
1201
|
const effectiveError = error ?? requestError;
|
|
1201
1202
|
(0, import_react.useEffect)(() => {
|
|
1202
1203
|
mountedRef.current = true;
|
|
@@ -1230,6 +1231,7 @@ function useScrollPagination({
|
|
|
1230
1231
|
};
|
|
1231
1232
|
(0, import_react.useEffect)(() => {
|
|
1232
1233
|
intentRef.current = null;
|
|
1234
|
+
observedTopRef.current = /* @__PURE__ */ new WeakMap();
|
|
1233
1235
|
consumedSequenceRef.current = inputSequenceRef.current;
|
|
1234
1236
|
requestErrorRef.current = null;
|
|
1235
1237
|
setRequestError(null);
|
|
@@ -1239,14 +1241,18 @@ function useScrollPagination({
|
|
|
1239
1241
|
(0, import_react.useEffect)(() => {
|
|
1240
1242
|
if (mode !== "scroll" || !enabled || typeof window === "undefined") return;
|
|
1241
1243
|
const attachable = containers.map(resolveContainer).filter((container) => container !== null);
|
|
1242
|
-
const setIntent = (container) => {
|
|
1244
|
+
const setIntent = (container, startTop) => {
|
|
1243
1245
|
const current = latestRef.current;
|
|
1244
1246
|
if (!isVisibleContainer(container) || current.loading || current.isFetchingNextPage || inFlightGenerationRef.current !== null) return;
|
|
1245
1247
|
inputSequenceRef.current += 1;
|
|
1246
1248
|
intentRef.current = {
|
|
1247
1249
|
queryKey: latestRef.current.queryKey,
|
|
1248
1250
|
container,
|
|
1249
|
-
|
|
1251
|
+
// The compositor can advance downward before the passive input
|
|
1252
|
+
// listener, while DOM/test callers can move upward before its scroll
|
|
1253
|
+
// notification. Either way, the lower position is the only safe
|
|
1254
|
+
// baseline for proving that this downward intent caused movement.
|
|
1255
|
+
startTop: Math.min(startTop, container.scrollTop),
|
|
1250
1256
|
sequence: inputSequenceRef.current,
|
|
1251
1257
|
expiresAt: Date.now() + intentTimeoutMs
|
|
1252
1258
|
};
|
|
@@ -1261,9 +1267,11 @@ function useScrollPagination({
|
|
|
1261
1267
|
void requestNextPage();
|
|
1262
1268
|
};
|
|
1263
1269
|
const cleanups = attachable.map((container) => {
|
|
1270
|
+
if (!observedTopRef.current.has(container)) observedTopRef.current.set(container, container.scrollTop);
|
|
1271
|
+
const lastObservedTop = () => observedTopRef.current.get(container) ?? container.scrollTop;
|
|
1264
1272
|
const onWheel = (event) => {
|
|
1265
1273
|
if (event.deltaY > 0 && Math.abs(event.deltaY) > Math.abs(event.deltaX)) {
|
|
1266
|
-
setIntent(container);
|
|
1274
|
+
setIntent(container, lastObservedTop());
|
|
1267
1275
|
}
|
|
1268
1276
|
};
|
|
1269
1277
|
const onTouchStart = (event) => {
|
|
@@ -1274,19 +1282,22 @@ function useScrollPagination({
|
|
|
1274
1282
|
const touch = event.touches.item(0);
|
|
1275
1283
|
const startY = Number(container.dataset.matrxPaginationTouchY);
|
|
1276
1284
|
if (touch && Number.isFinite(startY) && startY - touch.clientY > 0) {
|
|
1277
|
-
setIntent(container);
|
|
1285
|
+
setIntent(container, lastObservedTop());
|
|
1278
1286
|
}
|
|
1279
1287
|
};
|
|
1280
1288
|
const onTouchEnd = () => {
|
|
1281
1289
|
delete container.dataset.matrxPaginationTouchY;
|
|
1282
1290
|
};
|
|
1283
1291
|
const onKeyDown = (event) => {
|
|
1284
|
-
if (isDownwardKeyboardInput(event)) setIntent(container);
|
|
1292
|
+
if (isDownwardKeyboardInput(event)) setIntent(container, lastObservedTop());
|
|
1285
1293
|
};
|
|
1286
1294
|
const onPointerDown = (event) => {
|
|
1287
|
-
if (isNativeScrollbarPointer(event, container)) setIntent(container);
|
|
1295
|
+
if (isNativeScrollbarPointer(event, container)) setIntent(container, lastObservedTop());
|
|
1296
|
+
};
|
|
1297
|
+
const onScroll = () => {
|
|
1298
|
+
handleScroll(container);
|
|
1299
|
+
observedTopRef.current.set(container, container.scrollTop);
|
|
1288
1300
|
};
|
|
1289
|
-
const onScroll = () => handleScroll(container);
|
|
1290
1301
|
container.addEventListener("wheel", onWheel, { passive: true });
|
|
1291
1302
|
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
1292
1303
|
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
@@ -3416,6 +3427,7 @@ function parseOptionalNumber(raw) {
|
|
|
3416
3427
|
|
|
3417
3428
|
// src/data-table/ColumnManager.tsx
|
|
3418
3429
|
var import_react9 = require("react");
|
|
3430
|
+
var import_core = require("@dnd-kit/core");
|
|
3419
3431
|
init_filter_engine();
|
|
3420
3432
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3421
3433
|
function ColumnManager({
|
|
@@ -3432,6 +3444,8 @@ function ColumnManager({
|
|
|
3432
3444
|
);
|
|
3433
3445
|
const [draftOrder, setDraftOrder] = (0, import_react9.useState)(order);
|
|
3434
3446
|
const [draftHidden, setDraftHidden] = (0, import_react9.useState)(() => new Set(hidden));
|
|
3447
|
+
const [draggedColumnId, setDraggedColumnId] = (0, import_react9.useState)(null);
|
|
3448
|
+
const [dropTarget, setDropTarget] = (0, import_react9.useState)(null);
|
|
3435
3449
|
(0, import_react9.useEffect)(() => {
|
|
3436
3450
|
if (!open) return;
|
|
3437
3451
|
setDraftOrder(order);
|
|
@@ -3450,6 +3464,45 @@ function ColumnManager({
|
|
|
3450
3464
|
return next;
|
|
3451
3465
|
});
|
|
3452
3466
|
};
|
|
3467
|
+
const moveTo = (id, targetId) => {
|
|
3468
|
+
if (id === targetId) return;
|
|
3469
|
+
setDraftOrder((current) => {
|
|
3470
|
+
const from = current.indexOf(id);
|
|
3471
|
+
const target = current.indexOf(targetId);
|
|
3472
|
+
if (from < 0 || target < 0) return current;
|
|
3473
|
+
const next = [...current];
|
|
3474
|
+
next.splice(from, 1);
|
|
3475
|
+
const targetAfterRemoval = next.indexOf(targetId);
|
|
3476
|
+
next.splice(targetAfterRemoval, 0, id);
|
|
3477
|
+
return next;
|
|
3478
|
+
});
|
|
3479
|
+
};
|
|
3480
|
+
(0, import_core.useDndMonitor)({
|
|
3481
|
+
onDragStart(event) {
|
|
3482
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3483
|
+
setDraggedColumnId(String(event.active.data.current.columnId));
|
|
3484
|
+
},
|
|
3485
|
+
onDragOver(event) {
|
|
3486
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3487
|
+
const overData = event.over?.data.current;
|
|
3488
|
+
const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
|
|
3489
|
+
setDropTarget(target ? String(target) : null);
|
|
3490
|
+
},
|
|
3491
|
+
onDragCancel(event) {
|
|
3492
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3493
|
+
setDraggedColumnId(null);
|
|
3494
|
+
setDropTarget(null);
|
|
3495
|
+
},
|
|
3496
|
+
onDragEnd(event) {
|
|
3497
|
+
if (event.active.data.current?.matrxDragKind !== "column-manager") return;
|
|
3498
|
+
const dragged = String(event.active.data.current.columnId);
|
|
3499
|
+
const overData = event.over?.data.current;
|
|
3500
|
+
const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
|
|
3501
|
+
setDraggedColumnId(null);
|
|
3502
|
+
setDropTarget(null);
|
|
3503
|
+
if (target) moveTo(dragged, String(target));
|
|
3504
|
+
}
|
|
3505
|
+
});
|
|
3453
3506
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Dialog, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogContent, { className: "max-w-md", children: [
|
|
3454
3507
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(DialogHeader, { children: [
|
|
3455
3508
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(DialogTitle, { children: "Columns" }),
|
|
@@ -3462,14 +3515,16 @@ function ColumnManager({
|
|
|
3462
3515
|
const hideable = column.hideable !== false;
|
|
3463
3516
|
const visible = !draftHidden.has(id);
|
|
3464
3517
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3465
|
-
|
|
3518
|
+
ColumnManagerDropTarget,
|
|
3466
3519
|
{
|
|
3520
|
+
id,
|
|
3467
3521
|
className: cn(
|
|
3468
3522
|
"flex items-center gap-2 px-2 py-2",
|
|
3469
|
-
!visible && "bg-muted/30 text-muted-foreground"
|
|
3523
|
+
!visible && "bg-muted/30 text-muted-foreground",
|
|
3524
|
+
dropTarget === id && draggedColumnId !== id && "border-t-2 border-primary"
|
|
3470
3525
|
),
|
|
3471
3526
|
children: [
|
|
3472
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3527
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ColumnManagerDragHandle, { id, label }),
|
|
3473
3528
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3474
3529
|
Checkbox,
|
|
3475
3530
|
{
|
|
@@ -3535,6 +3590,36 @@ function ColumnManager({
|
|
|
3535
3590
|
] })
|
|
3536
3591
|
] }) });
|
|
3537
3592
|
}
|
|
3593
|
+
function ColumnManagerDropTarget({
|
|
3594
|
+
id,
|
|
3595
|
+
className,
|
|
3596
|
+
children
|
|
3597
|
+
}) {
|
|
3598
|
+
const { setNodeRef } = (0, import_core.useDroppable)({
|
|
3599
|
+
id: `matrx-column-manager:${id}`,
|
|
3600
|
+
data: { matrxDragKind: "column-manager", columnId: id }
|
|
3601
|
+
});
|
|
3602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: setNodeRef, "data-matrx-column-manager-drop-target": id, className, children });
|
|
3603
|
+
}
|
|
3604
|
+
function ColumnManagerDragHandle({ id, label }) {
|
|
3605
|
+
const { attributes, listeners, setNodeRef } = (0, import_core.useDraggable)({
|
|
3606
|
+
id: `matrx-column-manager:${id}`,
|
|
3607
|
+
data: { matrxDragKind: "column-manager", columnId: id }
|
|
3608
|
+
});
|
|
3609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3610
|
+
"button",
|
|
3611
|
+
{
|
|
3612
|
+
ref: setNodeRef,
|
|
3613
|
+
type: "button",
|
|
3614
|
+
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",
|
|
3615
|
+
"aria-label": `Reorder ${label}`,
|
|
3616
|
+
title: `Drag to reorder ${label}`,
|
|
3617
|
+
...attributes,
|
|
3618
|
+
...listeners,
|
|
3619
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(GripVertical, { className: "h-4 w-4" })
|
|
3620
|
+
}
|
|
3621
|
+
);
|
|
3622
|
+
}
|
|
3538
3623
|
|
|
3539
3624
|
// src/data-table/MatrxUuidCell.tsx
|
|
3540
3625
|
var import_react10 = require("react");
|
|
@@ -5004,6 +5089,9 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
|
|
|
5004
5089
|
|
|
5005
5090
|
// src/data-table/MatrxDataTable.tsx
|
|
5006
5091
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
5092
|
+
function hasSameRowReferences(previous, next) {
|
|
5093
|
+
return previous.length === next.length && previous.every((row, index) => row === next[index]);
|
|
5094
|
+
}
|
|
5007
5095
|
function TableRowCopyControl({
|
|
5008
5096
|
copy,
|
|
5009
5097
|
row,
|
|
@@ -5121,6 +5209,9 @@ function MatrxDataTableWithUrlState({
|
|
|
5121
5209
|
function MatrxDataTableCore({
|
|
5122
5210
|
data: suppliedData,
|
|
5123
5211
|
columns,
|
|
5212
|
+
columnState,
|
|
5213
|
+
reorderableColumns = false,
|
|
5214
|
+
columnManager: controlledColumnManager,
|
|
5124
5215
|
getRowId,
|
|
5125
5216
|
searchText,
|
|
5126
5217
|
processLocalRows,
|
|
@@ -5186,8 +5277,8 @@ function MatrxDataTableCore({
|
|
|
5186
5277
|
);
|
|
5187
5278
|
const [internalSearch, setInternalSearch] = (0, import_react14.useState)("");
|
|
5188
5279
|
const [draggedRowId, setDraggedRowId] = (0, import_react14.useState)(null);
|
|
5189
|
-
const hierarchySensors = (0,
|
|
5190
|
-
(0,
|
|
5280
|
+
const hierarchySensors = (0, import_core2.useSensors)(
|
|
5281
|
+
(0, import_core2.useSensor)(import_core2.PointerSensor, { activationConstraint: { distance: 6 } })
|
|
5191
5282
|
);
|
|
5192
5283
|
const toolbarSearchControlled = toolbar?.searchValue !== void 0;
|
|
5193
5284
|
const searchValue = controlledQuery ? controlledQuery.state.search : toolbarSearchControlled ? toolbar?.searchValue ?? "" : internalSearch;
|
|
@@ -5424,13 +5515,67 @@ function MatrxDataTableCore({
|
|
|
5424
5515
|
observer?.disconnect();
|
|
5425
5516
|
};
|
|
5426
5517
|
}, [updateScrollHint, data, columns]);
|
|
5427
|
-
const [columnOrder, setColumnOrder] = (0, import_react14.useState)(() => columns.map(columnId));
|
|
5518
|
+
const [columnOrder, setColumnOrder] = (0, import_react14.useState)(() => columnState?.order ?? columns.map(columnId));
|
|
5428
5519
|
const [hiddenColumnIds, setHiddenColumnIds] = (0, import_react14.useState)(
|
|
5429
|
-
() => new Set(columns.filter((column) => column.hidden).map(columnId))
|
|
5520
|
+
() => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
|
|
5430
5521
|
);
|
|
5431
|
-
const
|
|
5522
|
+
const draggedColumnId = (0, import_react14.useRef)(null);
|
|
5523
|
+
const columnDragActive = (0, import_react14.useRef)(false);
|
|
5524
|
+
const columnDragRaf = (0, import_react14.useRef)(null);
|
|
5525
|
+
const columnDragScrollDirection = (0, import_react14.useRef)(0);
|
|
5526
|
+
const [columnDropTarget, setColumnDropTarget] = (0, import_react14.useState)(null);
|
|
5527
|
+
const stopColumnDragScroll = (0, import_react14.useCallback)(() => {
|
|
5528
|
+
if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
|
|
5529
|
+
columnDragRaf.current = null;
|
|
5530
|
+
columnDragScrollDirection.current = 0;
|
|
5531
|
+
}, []);
|
|
5532
|
+
(0, import_react14.useEffect)(() => () => {
|
|
5533
|
+
columnDragActive.current = false;
|
|
5534
|
+
stopColumnDragScroll();
|
|
5535
|
+
}, [stopColumnDragScroll]);
|
|
5536
|
+
const startColumnDragScroll = (0, import_react14.useCallback)(() => {
|
|
5537
|
+
if (!columnDragActive.current || columnDragRaf.current !== null) return;
|
|
5538
|
+
const scrollStep = () => {
|
|
5539
|
+
const scroll = scrollRef.current;
|
|
5540
|
+
const direction = columnDragScrollDirection.current;
|
|
5541
|
+
if (!columnDragActive.current || !scroll || direction === 0) {
|
|
5542
|
+
columnDragRaf.current = null;
|
|
5543
|
+
return;
|
|
5544
|
+
}
|
|
5545
|
+
const nextScrollLeft = Math.max(
|
|
5546
|
+
0,
|
|
5547
|
+
Math.min(scroll.scrollLeft + direction * 18, scroll.scrollWidth - scroll.clientWidth)
|
|
5548
|
+
);
|
|
5549
|
+
if (nextScrollLeft === scroll.scrollLeft) {
|
|
5550
|
+
columnDragRaf.current = null;
|
|
5551
|
+
columnDragScrollDirection.current = 0;
|
|
5552
|
+
return;
|
|
5553
|
+
}
|
|
5554
|
+
scroll.scrollLeft = nextScrollLeft;
|
|
5555
|
+
if (!columnDragActive.current || columnDragScrollDirection.current === 0) {
|
|
5556
|
+
columnDragRaf.current = null;
|
|
5557
|
+
return;
|
|
5558
|
+
}
|
|
5559
|
+
columnDragRaf.current = requestAnimationFrame(scrollStep);
|
|
5560
|
+
};
|
|
5561
|
+
columnDragRaf.current = requestAnimationFrame(scrollStep);
|
|
5562
|
+
}, []);
|
|
5563
|
+
const commitColumnState = (0, import_react14.useCallback)((order, hidden) => {
|
|
5564
|
+
if (columnState) columnState.onChange({ order, hidden: [...hidden] });
|
|
5565
|
+
else {
|
|
5566
|
+
setColumnOrder(order);
|
|
5567
|
+
setHiddenColumnIds(hidden);
|
|
5568
|
+
}
|
|
5569
|
+
}, [columnState]);
|
|
5570
|
+
const [internalColumnManagerOpen, setInternalColumnManagerOpen] = (0, import_react14.useState)(false);
|
|
5571
|
+
const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
|
|
5572
|
+
const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
|
|
5573
|
+
const columnIds = (0, import_react14.useMemo)(() => columns.map(columnId), [columns]);
|
|
5574
|
+
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]);
|
|
5575
|
+
const effectiveHiddenColumnIds = (0, import_react14.useMemo)(() => columnState ? new Set(columnState.hidden.filter((id) => columnIds.includes(id))) : hiddenColumnIds, [columnIds, columnState, hiddenColumnIds]);
|
|
5432
5576
|
(0, import_react14.useEffect)(() => {
|
|
5433
5577
|
const ids = columns.map(columnId);
|
|
5578
|
+
if (columnState) return;
|
|
5434
5579
|
setColumnOrder((current) => [
|
|
5435
5580
|
...current.filter((id) => ids.includes(id)),
|
|
5436
5581
|
...ids.filter((id) => !current.includes(id))
|
|
@@ -5442,13 +5587,13 @@ function MatrxDataTableCore({
|
|
|
5442
5587
|
}
|
|
5443
5588
|
return next;
|
|
5444
5589
|
});
|
|
5445
|
-
}, [columns]);
|
|
5590
|
+
}, [columns, columnState]);
|
|
5446
5591
|
const visibleColumns = (0, import_react14.useMemo)(() => {
|
|
5447
5592
|
const byId = new Map(columns.map((column) => [columnId(column), column]));
|
|
5448
|
-
return
|
|
5449
|
-
(column) => column !== void 0 && !
|
|
5593
|
+
return effectiveColumnOrder.map((id) => byId.get(id)).filter(
|
|
5594
|
+
(column) => column !== void 0 && !effectiveHiddenColumnIds.has(columnId(column))
|
|
5450
5595
|
);
|
|
5451
|
-
}, [columns,
|
|
5596
|
+
}, [columns, effectiveColumnOrder, effectiveHiddenColumnIds]);
|
|
5452
5597
|
const copySubsetVariant = useCopySubsetVariant();
|
|
5453
5598
|
const copySubsetColumns = () => visibleColumns.filter((c) => c.filter !== false || c.accessorKey || c.accessorFn).map((c) => ({
|
|
5454
5599
|
id: columnId(c),
|
|
@@ -5522,8 +5667,15 @@ function MatrxDataTableCore({
|
|
|
5522
5667
|
sourceOwnsColumnFilters,
|
|
5523
5668
|
sourceOwnsSort
|
|
5524
5669
|
]);
|
|
5670
|
+
const lastNotifiedViewRows = (0, import_react14.useRef)(null);
|
|
5525
5671
|
(0, import_react14.useEffect)(() => {
|
|
5526
|
-
onViewChange
|
|
5672
|
+
if (!onViewChange) {
|
|
5673
|
+
lastNotifiedViewRows.current = null;
|
|
5674
|
+
return;
|
|
5675
|
+
}
|
|
5676
|
+
const changed = lastNotifiedViewRows.current === null || !hasSameRowReferences(lastNotifiedViewRows.current, processed);
|
|
5677
|
+
lastNotifiedViewRows.current = processed;
|
|
5678
|
+
if (changed) onViewChange(processed);
|
|
5527
5679
|
}, [processed, onViewChange]);
|
|
5528
5680
|
(0, import_react14.useEffect)(() => {
|
|
5529
5681
|
if (controlledQuery) return;
|
|
@@ -5953,16 +6105,77 @@ function MatrxDataTableCore({
|
|
|
5953
6105
|
} : facet
|
|
5954
6106
|
) : toolbar?.facets;
|
|
5955
6107
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5956
|
-
|
|
6108
|
+
import_core2.DndContext,
|
|
5957
6109
|
{
|
|
5958
6110
|
sensors: hierarchySensors,
|
|
5959
|
-
collisionDetection:
|
|
5960
|
-
measuring: { droppable: { strategy:
|
|
6111
|
+
collisionDetection: import_core2.pointerWithin,
|
|
6112
|
+
measuring: { droppable: { strategy: import_core2.MeasuringStrategy.Always } },
|
|
5961
6113
|
onDragStart: (event) => {
|
|
6114
|
+
const kind = event.active.data.current?.matrxDragKind;
|
|
6115
|
+
if (kind === "column-header") {
|
|
6116
|
+
draggedColumnId.current = String(event.active.data.current?.columnId);
|
|
6117
|
+
columnDragActive.current = true;
|
|
6118
|
+
return;
|
|
6119
|
+
}
|
|
6120
|
+
if (kind === "column-manager") return;
|
|
5962
6121
|
setDraggedRowId(String(event.active.id));
|
|
5963
6122
|
},
|
|
5964
|
-
|
|
5965
|
-
|
|
6123
|
+
onDragMove: (event) => {
|
|
6124
|
+
if (!columnDragActive.current || event.active.data.current?.matrxDragKind !== "column-header") return;
|
|
6125
|
+
const overData = event.over?.data.current;
|
|
6126
|
+
const overId = overData?.matrxDragKind === "column-header" ? overData.columnId : null;
|
|
6127
|
+
const activeRect = event.active.rect.current.translated;
|
|
6128
|
+
const overRect = event.over?.rect;
|
|
6129
|
+
if (!overId || !activeRect || !overRect) {
|
|
6130
|
+
setColumnDropTarget(null);
|
|
6131
|
+
columnDragScrollDirection.current = 0;
|
|
6132
|
+
stopColumnDragScroll();
|
|
6133
|
+
return;
|
|
6134
|
+
}
|
|
6135
|
+
const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
|
|
6136
|
+
setColumnDropTarget({ id: String(overId), after });
|
|
6137
|
+
const scroll = scrollRef.current;
|
|
6138
|
+
if (!scroll) return;
|
|
6139
|
+
const bounds = scroll.getBoundingClientRect();
|
|
6140
|
+
const center = activeRect.left + activeRect.width / 2;
|
|
6141
|
+
columnDragScrollDirection.current = center - bounds.left < 80 ? -1 : bounds.right - center < 80 ? 1 : 0;
|
|
6142
|
+
if (columnDragScrollDirection.current === 0) stopColumnDragScroll();
|
|
6143
|
+
else startColumnDragScroll();
|
|
6144
|
+
},
|
|
6145
|
+
onDragCancel: () => {
|
|
6146
|
+
columnDragActive.current = false;
|
|
6147
|
+
draggedColumnId.current = null;
|
|
6148
|
+
setColumnDropTarget(null);
|
|
6149
|
+
stopColumnDragScroll();
|
|
6150
|
+
setDraggedRowId(null);
|
|
6151
|
+
},
|
|
6152
|
+
onDragEnd: (event) => {
|
|
6153
|
+
const kind = event.active.data.current?.matrxDragKind;
|
|
6154
|
+
if (kind === "column-manager") return;
|
|
6155
|
+
if (kind !== "column-header") {
|
|
6156
|
+
endHierarchyDrag(event);
|
|
6157
|
+
return;
|
|
6158
|
+
}
|
|
6159
|
+
const from = String(event.active.data.current?.columnId);
|
|
6160
|
+
const targetData = event.over?.data.current;
|
|
6161
|
+
const target = targetData?.matrxDragKind === "column-header" ? targetData.columnId : null;
|
|
6162
|
+
const activeRect = event.active.rect.current.translated;
|
|
6163
|
+
const overRect = event.over?.rect;
|
|
6164
|
+
columnDragActive.current = false;
|
|
6165
|
+
draggedColumnId.current = null;
|
|
6166
|
+
setColumnDropTarget(null);
|
|
6167
|
+
stopColumnDragScroll();
|
|
6168
|
+
if (!target || from === target || !activeRect || !overRect) return;
|
|
6169
|
+
const order = [...effectiveColumnOrder];
|
|
6170
|
+
const fromIndex = order.indexOf(from);
|
|
6171
|
+
const targetIndex = order.indexOf(String(target));
|
|
6172
|
+
if (fromIndex < 0 || targetIndex < 0) return;
|
|
6173
|
+
order.splice(fromIndex, 1);
|
|
6174
|
+
const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
|
|
6175
|
+
const insertion = order.indexOf(String(target)) + (after ? 1 : 0);
|
|
6176
|
+
order.splice(insertion, 0, from);
|
|
6177
|
+
commitColumnState(order, effectiveHiddenColumnIds);
|
|
6178
|
+
},
|
|
5966
6179
|
children: [
|
|
5967
6180
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
5968
6181
|
"div",
|
|
@@ -6184,8 +6397,8 @@ function MatrxDataTableCore({
|
|
|
6184
6397
|
onClick: () => setColumnManagerOpen(true),
|
|
6185
6398
|
children: [
|
|
6186
6399
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(SlidersHorizontal, { className: "h-4 w-4" }),
|
|
6187
|
-
|
|
6188
|
-
|
|
6400
|
+
effectiveHiddenColumnIds.size > 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "sr-only", children: [
|
|
6401
|
+
effectiveHiddenColumnIds.size,
|
|
6189
6402
|
" hidden"
|
|
6190
6403
|
] }) : null
|
|
6191
6404
|
]
|
|
@@ -6439,46 +6652,50 @@ function MatrxDataTableCore({
|
|
|
6439
6652
|
// horizontal-scroll surface.
|
|
6440
6653
|
col.width !== void 0 && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
|
|
6441
6654
|
col.headerClassName,
|
|
6655
|
+
columnDropTarget?.id === id && (columnDropTarget.after ? "border-r-2 border-primary" : "border-l-2 border-primary"),
|
|
6442
6656
|
col.align === "center" && "text-center",
|
|
6443
6657
|
col.align === "right" && "text-right"
|
|
6444
6658
|
),
|
|
6445
6659
|
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
|
-
|
|
6660
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: [
|
|
6661
|
+
reorderableColumns ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ColumnReorderHandle, { id, label: headerLabel }) : null,
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
6663
|
+
ColumnHeaderCell,
|
|
6664
|
+
{
|
|
6665
|
+
label: col.header,
|
|
6666
|
+
labelText: headerLabel,
|
|
6667
|
+
sortable: col.sortable !== false,
|
|
6668
|
+
isSorted: Boolean(isSorted),
|
|
6669
|
+
sortDirection: sort?.direction ?? defaultSortDirection,
|
|
6670
|
+
onSortAsc: () => setSort({ id, direction: "asc" }),
|
|
6671
|
+
onSortDesc: () => setSort({ id, direction: "desc" }),
|
|
6672
|
+
onClearSort: () => setSort(null),
|
|
6673
|
+
onHeaderSortClick: () => {
|
|
6674
|
+
if (!isSorted) {
|
|
6675
|
+
setSort({ id, direction: defaultSortDirection });
|
|
6676
|
+
return;
|
|
6677
|
+
}
|
|
6678
|
+
if (sort?.direction === "asc") {
|
|
6679
|
+
setSort({ id, direction: "desc" });
|
|
6680
|
+
return;
|
|
6681
|
+
}
|
|
6682
|
+
setSort(null);
|
|
6683
|
+
},
|
|
6684
|
+
filterKind: meta?.kind ?? null,
|
|
6685
|
+
filterValue: columnFilters[id],
|
|
6686
|
+
onFilterChange: (next) => setColumnFilter(id, next),
|
|
6687
|
+
selectOptions: meta?.options,
|
|
6688
|
+
selectSingle: col.filterSingle,
|
|
6689
|
+
filterApplyLabel: filterUi?.applyLabel,
|
|
6690
|
+
filterShowCancel: filterUi?.showCancel,
|
|
6691
|
+
filterFooterHint: filterUi?.footerHint,
|
|
6692
|
+
allowNegation: filterUi?.allowNegation,
|
|
6693
|
+
allowNullModes: filterUi?.allowNullModes,
|
|
6694
|
+
align: col.align,
|
|
6695
|
+
compact: col.compact
|
|
6696
|
+
}
|
|
6697
|
+
)
|
|
6698
|
+
] })
|
|
6482
6699
|
},
|
|
6483
6700
|
id
|
|
6484
6701
|
);
|
|
@@ -6777,12 +6994,9 @@ function MatrxDataTableCore({
|
|
|
6777
6994
|
open: columnManagerOpen,
|
|
6778
6995
|
onOpenChange: setColumnManagerOpen,
|
|
6779
6996
|
columns,
|
|
6780
|
-
order:
|
|
6781
|
-
hidden:
|
|
6782
|
-
onApply:
|
|
6783
|
-
setColumnOrder(order);
|
|
6784
|
-
setHiddenColumnIds(hidden);
|
|
6785
|
-
}
|
|
6997
|
+
order: effectiveColumnOrder,
|
|
6998
|
+
hidden: effectiveHiddenColumnIds,
|
|
6999
|
+
onApply: commitColumnState
|
|
6786
7000
|
}
|
|
6787
7001
|
),
|
|
6788
7002
|
detailEnabled && selectedRow ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
@@ -6981,7 +7195,7 @@ function MatrxDataTableCore({
|
|
|
6981
7195
|
]
|
|
6982
7196
|
}
|
|
6983
7197
|
),
|
|
6984
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7198
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_core2.DragOverlay, { children: draggedRow ? (
|
|
6985
7199
|
// w-max: the overlay inherits the ACTIVE node's size, and the active
|
|
6986
7200
|
// node is the 16px grip handle — without it the label wraps to one
|
|
6987
7201
|
// character per line.
|
|
@@ -6996,7 +7210,7 @@ function HierarchyDragHandle({
|
|
|
6996
7210
|
label,
|
|
6997
7211
|
disabled
|
|
6998
7212
|
}) {
|
|
6999
|
-
const { attributes, listeners, setNodeRef } = (0,
|
|
7213
|
+
const { attributes, listeners, setNodeRef } = (0, import_core2.useDraggable)({
|
|
7000
7214
|
id,
|
|
7001
7215
|
disabled
|
|
7002
7216
|
});
|
|
@@ -7020,7 +7234,7 @@ function HierarchyRootDropTarget({
|
|
|
7020
7234
|
label,
|
|
7021
7235
|
draggedLabel
|
|
7022
7236
|
}) {
|
|
7023
|
-
const { isOver, setNodeRef } = (0,
|
|
7237
|
+
const { isOver, setNodeRef } = (0, import_core2.useDroppable)({ id: "__root__" });
|
|
7024
7238
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
7025
7239
|
"div",
|
|
7026
7240
|
{
|
|
@@ -7044,7 +7258,7 @@ function HierarchyDragIndicatorLayer({
|
|
|
7044
7258
|
const [indicator, setIndicator] = (0, import_react14.useState)(
|
|
7045
7259
|
null
|
|
7046
7260
|
);
|
|
7047
|
-
(0,
|
|
7261
|
+
(0, import_core2.useDndMonitor)({
|
|
7048
7262
|
onDragMove(event) {
|
|
7049
7263
|
const container = scrollRef.current;
|
|
7050
7264
|
const overId = event.over ? String(event.over.id) : null;
|
|
@@ -7144,7 +7358,7 @@ function HierarchyDroppableRow({
|
|
|
7144
7358
|
disabled,
|
|
7145
7359
|
children
|
|
7146
7360
|
}) {
|
|
7147
|
-
const { setNodeRef } = (0,
|
|
7361
|
+
const { setNodeRef } = (0, import_core2.useDroppable)({ id, disabled });
|
|
7148
7362
|
if (!(0, import_react14.isValidElement)(children) || children.type !== "tr") return children;
|
|
7149
7363
|
const row = children;
|
|
7150
7364
|
return (0, import_react14.cloneElement)(row, {
|
|
@@ -7152,6 +7366,38 @@ function HierarchyDroppableRow({
|
|
|
7152
7366
|
className: row.props.className
|
|
7153
7367
|
});
|
|
7154
7368
|
}
|
|
7369
|
+
function ColumnHeaderDropZone({
|
|
7370
|
+
id,
|
|
7371
|
+
enabled,
|
|
7372
|
+
children
|
|
7373
|
+
}) {
|
|
7374
|
+
const { setNodeRef } = (0, import_core2.useDroppable)({
|
|
7375
|
+
id: `matrx-column-header:${id}`,
|
|
7376
|
+
disabled: !enabled,
|
|
7377
|
+
data: { matrxDragKind: "column-header", columnId: id }
|
|
7378
|
+
});
|
|
7379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
|
|
7380
|
+
}
|
|
7381
|
+
function ColumnReorderHandle({ id, label }) {
|
|
7382
|
+
const { attributes, listeners, setNodeRef } = (0, import_core2.useDraggable)({
|
|
7383
|
+
id: `matrx-column-header:${id}`,
|
|
7384
|
+
data: { matrxDragKind: "column-header", columnId: id }
|
|
7385
|
+
});
|
|
7386
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
7387
|
+
"button",
|
|
7388
|
+
{
|
|
7389
|
+
ref: setNodeRef,
|
|
7390
|
+
type: "button",
|
|
7391
|
+
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",
|
|
7392
|
+
"aria-label": `Reorder ${label}`,
|
|
7393
|
+
title: `Drag to reorder ${label}`,
|
|
7394
|
+
onClick: (event) => event.stopPropagation(),
|
|
7395
|
+
...attributes,
|
|
7396
|
+
...listeners,
|
|
7397
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(GripVertical, { className: "h-3.5 w-3.5" })
|
|
7398
|
+
}
|
|
7399
|
+
);
|
|
7400
|
+
}
|
|
7155
7401
|
function columnWidthVar(width) {
|
|
7156
7402
|
if (width === void 0) return void 0;
|
|
7157
7403
|
return {
|