@ai-matrx/design-system 0.16.0 → 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.
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { b as MatrxDataTableProps } from '../types-XXbVB1sh.cjs';
3
- export { A as AnyOfColumnSearch, c as CellEditType, d as CellEditsMap, e as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, M as MatrxColumnDef, f as MatrxDataTableCopyConfig, g as MatrxDataTableDetailConfig, h as MatrxDataTableEditConfig, i as MatrxDataTableEmptyState, j as MatrxDataTableFilterUi, k as MatrxDataTableHierarchyConfig, l as MatrxDataTableHierarchyMove, m as MatrxDataTableMobileCardControls, n as MatrxDataTableQueryControl, o as MatrxDataTableQueryState, p as MatrxDataTableRecordControls, q as MatrxDataTableSelectionConfig, r as MatrxDataTableSourceProcessing, s as MatrxDataTableToolbar, t as MatrxDataTableUrlStateConfig, u as MatrxDataTableWindowConfig, v as MatrxTablePagination, w as SortDirection, S as SortState, T as TableSearchMatchMode, x as TextFilterMode, y as ToolbarFacet } from '../types-XXbVB1sh.cjs';
2
+ import { b as MatrxDataTableProps } from '../types-4fmLG5AN.cjs';
3
+ export { A as AnyOfColumnSearch, c as CellEditType, d as CellEditsMap, e as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, M as MatrxColumnDef, f as MatrxDataTableCopyConfig, g as MatrxDataTableDetailConfig, h as MatrxDataTableEditConfig, i as MatrxDataTableEmptyState, j as MatrxDataTableFilterUi, k as MatrxDataTableHierarchyConfig, l as MatrxDataTableHierarchyMove, m as MatrxDataTableMobileCardControls, n as MatrxDataTableQueryControl, o as MatrxDataTableQueryState, p as MatrxDataTableRecordControls, q as MatrxDataTableSelectionConfig, r as MatrxDataTableSourceProcessing, s as MatrxDataTableToolbar, t as MatrxDataTableUrlStateConfig, u as MatrxDataTableWindowConfig, v as MatrxTablePagination, w as SortDirection, S as SortState, T as TableSearchMatchMode, x as TextFilterMode, y as ToolbarFacet } from '../types-4fmLG5AN.cjs';
4
4
  export { MatrxDataTableHost, MatrxDataTableProvider, TableDoors, TableEntityRefProps, TableLinkProps, TablePeekProps, TableSidePanelProps, TableWindowPanelProps, useMatrxDataTableHost } from './host.cjs';
5
5
  export { DataRowInspector } from './data-row-inspector.cjs';
6
6
  export { DataRowWindow, DataRowWindowProps, DataRowWindowTab } from './data-row-window.cjs';
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
- import { b as MatrxDataTableProps } from '../types-ClaxTaXq.js';
3
- export { A as AnyOfColumnSearch, c as CellEditType, d as CellEditsMap, e as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, M as MatrxColumnDef, f as MatrxDataTableCopyConfig, g as MatrxDataTableDetailConfig, h as MatrxDataTableEditConfig, i as MatrxDataTableEmptyState, j as MatrxDataTableFilterUi, k as MatrxDataTableHierarchyConfig, l as MatrxDataTableHierarchyMove, m as MatrxDataTableMobileCardControls, n as MatrxDataTableQueryControl, o as MatrxDataTableQueryState, p as MatrxDataTableRecordControls, q as MatrxDataTableSelectionConfig, r as MatrxDataTableSourceProcessing, s as MatrxDataTableToolbar, t as MatrxDataTableUrlStateConfig, u as MatrxDataTableWindowConfig, v as MatrxTablePagination, w as SortDirection, S as SortState, T as TableSearchMatchMode, x as TextFilterMode, y as ToolbarFacet } from '../types-ClaxTaXq.js';
2
+ import { b as MatrxDataTableProps } from '../types-pZ95iFk5.js';
3
+ export { A as AnyOfColumnSearch, c as CellEditType, d as CellEditsMap, e as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, M as MatrxColumnDef, f as MatrxDataTableCopyConfig, g as MatrxDataTableDetailConfig, h as MatrxDataTableEditConfig, i as MatrxDataTableEmptyState, j as MatrxDataTableFilterUi, k as MatrxDataTableHierarchyConfig, l as MatrxDataTableHierarchyMove, m as MatrxDataTableMobileCardControls, n as MatrxDataTableQueryControl, o as MatrxDataTableQueryState, p as MatrxDataTableRecordControls, q as MatrxDataTableSelectionConfig, r as MatrxDataTableSourceProcessing, s as MatrxDataTableToolbar, t as MatrxDataTableUrlStateConfig, u as MatrxDataTableWindowConfig, v as MatrxTablePagination, w as SortDirection, S as SortState, T as TableSearchMatchMode, x as TextFilterMode, y as ToolbarFacet } from '../types-pZ95iFk5.js';
4
4
  export { MatrxDataTableHost, MatrxDataTableProvider, TableDoors, TableEntityRefProps, TableLinkProps, TablePeekProps, TableSidePanelProps, TableWindowPanelProps, useMatrxDataTableHost } from './host.js';
5
5
  export { DataRowInspector } from './data-row-inspector.js';
6
6
  export { DataRowWindow, DataRowWindowProps, DataRowWindowTab } from './data-row-window.js';
@@ -425,9 +425,9 @@ import {
425
425
  MeasuringStrategy,
426
426
  PointerSensor,
427
427
  pointerWithin,
428
- useDndMonitor,
429
- useDraggable,
430
- useDroppable,
428
+ useDndMonitor as useDndMonitor2,
429
+ useDraggable as useDraggable2,
430
+ useDroppable as useDroppable2,
431
431
  useSensor,
432
432
  useSensors
433
433
  } from "@dnd-kit/core";
@@ -3393,6 +3393,7 @@ function parseOptionalNumber(raw) {
3393
3393
 
3394
3394
  // src/data-table/ColumnManager.tsx
3395
3395
  import { useEffect as useEffect6, useMemo as useMemo3, useState as useState9 } from "react";
3396
+ import { useDndMonitor, useDraggable, useDroppable } from "@dnd-kit/core";
3396
3397
  init_filter_engine();
3397
3398
  import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
3398
3399
  function ColumnManager({
@@ -3409,6 +3410,8 @@ function ColumnManager({
3409
3410
  );
3410
3411
  const [draftOrder, setDraftOrder] = useState9(order);
3411
3412
  const [draftHidden, setDraftHidden] = useState9(() => new Set(hidden));
3413
+ const [draggedColumnId, setDraggedColumnId] = useState9(null);
3414
+ const [dropTarget, setDropTarget] = useState9(null);
3412
3415
  useEffect6(() => {
3413
3416
  if (!open) return;
3414
3417
  setDraftOrder(order);
@@ -3427,6 +3430,45 @@ function ColumnManager({
3427
3430
  return next;
3428
3431
  });
3429
3432
  };
3433
+ const moveTo = (id, targetId) => {
3434
+ if (id === targetId) return;
3435
+ setDraftOrder((current) => {
3436
+ const from = current.indexOf(id);
3437
+ const target = current.indexOf(targetId);
3438
+ if (from < 0 || target < 0) return current;
3439
+ const next = [...current];
3440
+ next.splice(from, 1);
3441
+ const targetAfterRemoval = next.indexOf(targetId);
3442
+ next.splice(targetAfterRemoval, 0, id);
3443
+ return next;
3444
+ });
3445
+ };
3446
+ useDndMonitor({
3447
+ onDragStart(event) {
3448
+ if (event.active.data.current?.matrxDragKind !== "column-manager") return;
3449
+ setDraggedColumnId(String(event.active.data.current.columnId));
3450
+ },
3451
+ onDragOver(event) {
3452
+ if (event.active.data.current?.matrxDragKind !== "column-manager") return;
3453
+ const overData = event.over?.data.current;
3454
+ const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
3455
+ setDropTarget(target ? String(target) : null);
3456
+ },
3457
+ onDragCancel(event) {
3458
+ if (event.active.data.current?.matrxDragKind !== "column-manager") return;
3459
+ setDraggedColumnId(null);
3460
+ setDropTarget(null);
3461
+ },
3462
+ onDragEnd(event) {
3463
+ if (event.active.data.current?.matrxDragKind !== "column-manager") return;
3464
+ const dragged = String(event.active.data.current.columnId);
3465
+ const overData = event.over?.data.current;
3466
+ const target = overData?.matrxDragKind === "column-manager" ? overData.columnId : null;
3467
+ setDraggedColumnId(null);
3468
+ setDropTarget(null);
3469
+ if (target) moveTo(dragged, String(target));
3470
+ }
3471
+ });
3430
3472
  return /* @__PURE__ */ jsx23(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs16(DialogContent, { className: "max-w-md", children: [
3431
3473
  /* @__PURE__ */ jsxs16(DialogHeader, { children: [
3432
3474
  /* @__PURE__ */ jsx23(DialogTitle, { children: "Columns" }),
@@ -3439,14 +3481,16 @@ function ColumnManager({
3439
3481
  const hideable = column.hideable !== false;
3440
3482
  const visible = !draftHidden.has(id);
3441
3483
  return /* @__PURE__ */ jsxs16(
3442
- "div",
3484
+ ColumnManagerDropTarget,
3443
3485
  {
3486
+ id,
3444
3487
  className: cn(
3445
3488
  "flex items-center gap-2 px-2 py-2",
3446
- !visible && "bg-muted/30 text-muted-foreground"
3489
+ !visible && "bg-muted/30 text-muted-foreground",
3490
+ dropTarget === id && draggedColumnId !== id && "border-t-2 border-primary"
3447
3491
  ),
3448
3492
  children: [
3449
- /* @__PURE__ */ jsx23(GripVertical, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
3493
+ /* @__PURE__ */ jsx23(ColumnManagerDragHandle, { id, label }),
3450
3494
  /* @__PURE__ */ jsx23(
3451
3495
  Checkbox,
3452
3496
  {
@@ -3512,6 +3556,36 @@ function ColumnManager({
3512
3556
  ] })
3513
3557
  ] }) });
3514
3558
  }
3559
+ function ColumnManagerDropTarget({
3560
+ id,
3561
+ className,
3562
+ children
3563
+ }) {
3564
+ const { setNodeRef } = useDroppable({
3565
+ id: `matrx-column-manager:${id}`,
3566
+ data: { matrxDragKind: "column-manager", columnId: id }
3567
+ });
3568
+ return /* @__PURE__ */ jsx23("div", { ref: setNodeRef, "data-matrx-column-manager-drop-target": id, className, children });
3569
+ }
3570
+ function ColumnManagerDragHandle({ id, label }) {
3571
+ const { attributes, listeners, setNodeRef } = useDraggable({
3572
+ id: `matrx-column-manager:${id}`,
3573
+ data: { matrxDragKind: "column-manager", columnId: id }
3574
+ });
3575
+ return /* @__PURE__ */ jsx23(
3576
+ "button",
3577
+ {
3578
+ ref: setNodeRef,
3579
+ type: "button",
3580
+ 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",
3581
+ "aria-label": `Reorder ${label}`,
3582
+ title: `Drag to reorder ${label}`,
3583
+ ...attributes,
3584
+ ...listeners,
3585
+ children: /* @__PURE__ */ jsx23(GripVertical, { className: "h-4 w-4" })
3586
+ }
3587
+ );
3588
+ }
3515
3589
 
3516
3590
  // src/data-table/MatrxUuidCell.tsx
3517
3591
  import {
@@ -4985,6 +5059,9 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
4985
5059
 
4986
5060
  // src/data-table/MatrxDataTable.tsx
4987
5061
  import { Fragment as Fragment5, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
5062
+ function hasSameRowReferences(previous, next) {
5063
+ return previous.length === next.length && previous.every((row, index) => row === next[index]);
5064
+ }
4988
5065
  function TableRowCopyControl({
4989
5066
  copy,
4990
5067
  row,
@@ -5102,6 +5179,9 @@ function MatrxDataTableWithUrlState({
5102
5179
  function MatrxDataTableCore({
5103
5180
  data: suppliedData,
5104
5181
  columns,
5182
+ columnState,
5183
+ reorderableColumns = false,
5184
+ columnManager: controlledColumnManager,
5105
5185
  getRowId,
5106
5186
  searchText,
5107
5187
  processLocalRows,
@@ -5405,13 +5485,67 @@ function MatrxDataTableCore({
5405
5485
  observer?.disconnect();
5406
5486
  };
5407
5487
  }, [updateScrollHint, data, columns]);
5408
- const [columnOrder, setColumnOrder] = useState14(() => columns.map(columnId));
5488
+ const [columnOrder, setColumnOrder] = useState14(() => columnState?.order ?? columns.map(columnId));
5409
5489
  const [hiddenColumnIds, setHiddenColumnIds] = useState14(
5410
- () => new Set(columns.filter((column) => column.hidden).map(columnId))
5490
+ () => new Set(columnState?.hidden ?? columns.filter((column) => column.hidden).map(columnId))
5411
5491
  );
5412
- const [columnManagerOpen, setColumnManagerOpen] = useState14(false);
5492
+ const draggedColumnId = useRef4(null);
5493
+ const columnDragActive = useRef4(false);
5494
+ const columnDragRaf = useRef4(null);
5495
+ const columnDragScrollDirection = useRef4(0);
5496
+ const [columnDropTarget, setColumnDropTarget] = useState14(null);
5497
+ const stopColumnDragScroll = useCallback3(() => {
5498
+ if (columnDragRaf.current !== null) cancelAnimationFrame(columnDragRaf.current);
5499
+ columnDragRaf.current = null;
5500
+ columnDragScrollDirection.current = 0;
5501
+ }, []);
5502
+ useEffect9(() => () => {
5503
+ columnDragActive.current = false;
5504
+ stopColumnDragScroll();
5505
+ }, [stopColumnDragScroll]);
5506
+ const startColumnDragScroll = useCallback3(() => {
5507
+ if (!columnDragActive.current || columnDragRaf.current !== null) return;
5508
+ const scrollStep = () => {
5509
+ const scroll = scrollRef.current;
5510
+ const direction = columnDragScrollDirection.current;
5511
+ if (!columnDragActive.current || !scroll || direction === 0) {
5512
+ columnDragRaf.current = null;
5513
+ return;
5514
+ }
5515
+ const nextScrollLeft = Math.max(
5516
+ 0,
5517
+ Math.min(scroll.scrollLeft + direction * 18, scroll.scrollWidth - scroll.clientWidth)
5518
+ );
5519
+ if (nextScrollLeft === scroll.scrollLeft) {
5520
+ columnDragRaf.current = null;
5521
+ columnDragScrollDirection.current = 0;
5522
+ return;
5523
+ }
5524
+ scroll.scrollLeft = nextScrollLeft;
5525
+ if (!columnDragActive.current || columnDragScrollDirection.current === 0) {
5526
+ columnDragRaf.current = null;
5527
+ return;
5528
+ }
5529
+ columnDragRaf.current = requestAnimationFrame(scrollStep);
5530
+ };
5531
+ columnDragRaf.current = requestAnimationFrame(scrollStep);
5532
+ }, []);
5533
+ const commitColumnState = useCallback3((order, hidden) => {
5534
+ if (columnState) columnState.onChange({ order, hidden: [...hidden] });
5535
+ else {
5536
+ setColumnOrder(order);
5537
+ setHiddenColumnIds(hidden);
5538
+ }
5539
+ }, [columnState]);
5540
+ const [internalColumnManagerOpen, setInternalColumnManagerOpen] = useState14(false);
5541
+ const columnManagerOpen = controlledColumnManager?.open ?? internalColumnManagerOpen;
5542
+ const setColumnManagerOpen = controlledColumnManager?.onOpenChange ?? setInternalColumnManagerOpen;
5543
+ const columnIds = useMemo4(() => columns.map(columnId), [columns]);
5544
+ const effectiveColumnOrder = useMemo4(() => 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]);
5545
+ const effectiveHiddenColumnIds = useMemo4(() => columnState ? new Set(columnState.hidden.filter((id) => columnIds.includes(id))) : hiddenColumnIds, [columnIds, columnState, hiddenColumnIds]);
5413
5546
  useEffect9(() => {
5414
5547
  const ids = columns.map(columnId);
5548
+ if (columnState) return;
5415
5549
  setColumnOrder((current) => [
5416
5550
  ...current.filter((id) => ids.includes(id)),
5417
5551
  ...ids.filter((id) => !current.includes(id))
@@ -5423,13 +5557,13 @@ function MatrxDataTableCore({
5423
5557
  }
5424
5558
  return next;
5425
5559
  });
5426
- }, [columns]);
5560
+ }, [columns, columnState]);
5427
5561
  const visibleColumns = useMemo4(() => {
5428
5562
  const byId = new Map(columns.map((column) => [columnId(column), column]));
5429
- return columnOrder.map((id) => byId.get(id)).filter(
5430
- (column) => column !== void 0 && !hiddenColumnIds.has(columnId(column))
5563
+ return effectiveColumnOrder.map((id) => byId.get(id)).filter(
5564
+ (column) => column !== void 0 && !effectiveHiddenColumnIds.has(columnId(column))
5431
5565
  );
5432
- }, [columns, columnOrder, hiddenColumnIds]);
5566
+ }, [columns, effectiveColumnOrder, effectiveHiddenColumnIds]);
5433
5567
  const copySubsetVariant = useCopySubsetVariant();
5434
5568
  const copySubsetColumns = () => visibleColumns.filter((c) => c.filter !== false || c.accessorKey || c.accessorFn).map((c) => ({
5435
5569
  id: columnId(c),
@@ -5503,8 +5637,15 @@ function MatrxDataTableCore({
5503
5637
  sourceOwnsColumnFilters,
5504
5638
  sourceOwnsSort
5505
5639
  ]);
5640
+ const lastNotifiedViewRows = useRef4(null);
5506
5641
  useEffect9(() => {
5507
- onViewChange?.(processed);
5642
+ if (!onViewChange) {
5643
+ lastNotifiedViewRows.current = null;
5644
+ return;
5645
+ }
5646
+ const changed = lastNotifiedViewRows.current === null || !hasSameRowReferences(lastNotifiedViewRows.current, processed);
5647
+ lastNotifiedViewRows.current = processed;
5648
+ if (changed) onViewChange(processed);
5508
5649
  }, [processed, onViewChange]);
5509
5650
  useEffect9(() => {
5510
5651
  if (controlledQuery) return;
@@ -5940,10 +6081,71 @@ function MatrxDataTableCore({
5940
6081
  collisionDetection: pointerWithin,
5941
6082
  measuring: { droppable: { strategy: MeasuringStrategy.Always } },
5942
6083
  onDragStart: (event) => {
6084
+ const kind = event.active.data.current?.matrxDragKind;
6085
+ if (kind === "column-header") {
6086
+ draggedColumnId.current = String(event.active.data.current?.columnId);
6087
+ columnDragActive.current = true;
6088
+ return;
6089
+ }
6090
+ if (kind === "column-manager") return;
5943
6091
  setDraggedRowId(String(event.active.id));
5944
6092
  },
5945
- onDragCancel: () => setDraggedRowId(null),
5946
- onDragEnd: endHierarchyDrag,
6093
+ onDragMove: (event) => {
6094
+ if (!columnDragActive.current || event.active.data.current?.matrxDragKind !== "column-header") return;
6095
+ const overData = event.over?.data.current;
6096
+ const overId = overData?.matrxDragKind === "column-header" ? overData.columnId : null;
6097
+ const activeRect = event.active.rect.current.translated;
6098
+ const overRect = event.over?.rect;
6099
+ if (!overId || !activeRect || !overRect) {
6100
+ setColumnDropTarget(null);
6101
+ columnDragScrollDirection.current = 0;
6102
+ stopColumnDragScroll();
6103
+ return;
6104
+ }
6105
+ const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
6106
+ setColumnDropTarget({ id: String(overId), after });
6107
+ const scroll = scrollRef.current;
6108
+ if (!scroll) return;
6109
+ const bounds = scroll.getBoundingClientRect();
6110
+ const center = activeRect.left + activeRect.width / 2;
6111
+ columnDragScrollDirection.current = center - bounds.left < 80 ? -1 : bounds.right - center < 80 ? 1 : 0;
6112
+ if (columnDragScrollDirection.current === 0) stopColumnDragScroll();
6113
+ else startColumnDragScroll();
6114
+ },
6115
+ onDragCancel: () => {
6116
+ columnDragActive.current = false;
6117
+ draggedColumnId.current = null;
6118
+ setColumnDropTarget(null);
6119
+ stopColumnDragScroll();
6120
+ setDraggedRowId(null);
6121
+ },
6122
+ onDragEnd: (event) => {
6123
+ const kind = event.active.data.current?.matrxDragKind;
6124
+ if (kind === "column-manager") return;
6125
+ if (kind !== "column-header") {
6126
+ endHierarchyDrag(event);
6127
+ return;
6128
+ }
6129
+ const from = String(event.active.data.current?.columnId);
6130
+ const targetData = event.over?.data.current;
6131
+ const target = targetData?.matrxDragKind === "column-header" ? targetData.columnId : null;
6132
+ const activeRect = event.active.rect.current.translated;
6133
+ const overRect = event.over?.rect;
6134
+ columnDragActive.current = false;
6135
+ draggedColumnId.current = null;
6136
+ setColumnDropTarget(null);
6137
+ stopColumnDragScroll();
6138
+ if (!target || from === target || !activeRect || !overRect) return;
6139
+ const order = [...effectiveColumnOrder];
6140
+ const fromIndex = order.indexOf(from);
6141
+ const targetIndex = order.indexOf(String(target));
6142
+ if (fromIndex < 0 || targetIndex < 0) return;
6143
+ order.splice(fromIndex, 1);
6144
+ const after = activeRect.left + activeRect.width / 2 >= overRect.left + overRect.width / 2;
6145
+ const insertion = order.indexOf(String(target)) + (after ? 1 : 0);
6146
+ order.splice(insertion, 0, from);
6147
+ commitColumnState(order, effectiveHiddenColumnIds);
6148
+ },
5947
6149
  children: [
5948
6150
  /* @__PURE__ */ jsxs24(
5949
6151
  "div",
@@ -6165,8 +6367,8 @@ function MatrxDataTableCore({
6165
6367
  onClick: () => setColumnManagerOpen(true),
6166
6368
  children: [
6167
6369
  /* @__PURE__ */ jsx32(SlidersHorizontal, { className: "h-4 w-4" }),
6168
- hiddenColumnIds.size > 0 ? /* @__PURE__ */ jsxs24("span", { className: "sr-only", children: [
6169
- hiddenColumnIds.size,
6370
+ effectiveHiddenColumnIds.size > 0 ? /* @__PURE__ */ jsxs24("span", { className: "sr-only", children: [
6371
+ effectiveHiddenColumnIds.size,
6170
6372
  " hidden"
6171
6373
  ] }) : null
6172
6374
  ]
@@ -6420,46 +6622,50 @@ function MatrxDataTableCore({
6420
6622
  // horizontal-scroll surface.
6421
6623
  col.width !== void 0 && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
6422
6624
  col.headerClassName,
6625
+ columnDropTarget?.id === id && (columnDropTarget.after ? "border-r-2 border-primary" : "border-l-2 border-primary"),
6423
6626
  col.align === "center" && "text-center",
6424
6627
  col.align === "right" && "text-right"
6425
6628
  ),
6426
6629
  style: columnWidthVar(col.width),
6427
- children: /* @__PURE__ */ jsx32(
6428
- ColumnHeaderCell,
6429
- {
6430
- label: col.header,
6431
- labelText: headerLabel,
6432
- sortable: col.sortable !== false,
6433
- isSorted: Boolean(isSorted),
6434
- sortDirection: sort?.direction ?? defaultSortDirection,
6435
- onSortAsc: () => setSort({ id, direction: "asc" }),
6436
- onSortDesc: () => setSort({ id, direction: "desc" }),
6437
- onClearSort: () => setSort(null),
6438
- onHeaderSortClick: () => {
6439
- if (!isSorted) {
6440
- setSort({ id, direction: defaultSortDirection });
6441
- return;
6442
- }
6443
- if (sort?.direction === "asc") {
6444
- setSort({ id, direction: "desc" });
6445
- return;
6446
- }
6447
- setSort(null);
6448
- },
6449
- filterKind: meta?.kind ?? null,
6450
- filterValue: columnFilters[id],
6451
- onFilterChange: (next) => setColumnFilter(id, next),
6452
- selectOptions: meta?.options,
6453
- selectSingle: col.filterSingle,
6454
- filterApplyLabel: filterUi?.applyLabel,
6455
- filterShowCancel: filterUi?.showCancel,
6456
- filterFooterHint: filterUi?.footerHint,
6457
- allowNegation: filterUi?.allowNegation,
6458
- allowNullModes: filterUi?.allowNullModes,
6459
- align: col.align,
6460
- compact: col.compact
6461
- }
6462
- )
6630
+ children: /* @__PURE__ */ jsxs24(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: [
6631
+ reorderableColumns ? /* @__PURE__ */ jsx32(ColumnReorderHandle, { id, label: headerLabel }) : null,
6632
+ /* @__PURE__ */ jsx32(
6633
+ ColumnHeaderCell,
6634
+ {
6635
+ label: col.header,
6636
+ labelText: headerLabel,
6637
+ sortable: col.sortable !== false,
6638
+ isSorted: Boolean(isSorted),
6639
+ sortDirection: sort?.direction ?? defaultSortDirection,
6640
+ onSortAsc: () => setSort({ id, direction: "asc" }),
6641
+ onSortDesc: () => setSort({ id, direction: "desc" }),
6642
+ onClearSort: () => setSort(null),
6643
+ onHeaderSortClick: () => {
6644
+ if (!isSorted) {
6645
+ setSort({ id, direction: defaultSortDirection });
6646
+ return;
6647
+ }
6648
+ if (sort?.direction === "asc") {
6649
+ setSort({ id, direction: "desc" });
6650
+ return;
6651
+ }
6652
+ setSort(null);
6653
+ },
6654
+ filterKind: meta?.kind ?? null,
6655
+ filterValue: columnFilters[id],
6656
+ onFilterChange: (next) => setColumnFilter(id, next),
6657
+ selectOptions: meta?.options,
6658
+ selectSingle: col.filterSingle,
6659
+ filterApplyLabel: filterUi?.applyLabel,
6660
+ filterShowCancel: filterUi?.showCancel,
6661
+ filterFooterHint: filterUi?.footerHint,
6662
+ allowNegation: filterUi?.allowNegation,
6663
+ allowNullModes: filterUi?.allowNullModes,
6664
+ align: col.align,
6665
+ compact: col.compact
6666
+ }
6667
+ )
6668
+ ] })
6463
6669
  },
6464
6670
  id
6465
6671
  );
@@ -6758,12 +6964,9 @@ function MatrxDataTableCore({
6758
6964
  open: columnManagerOpen,
6759
6965
  onOpenChange: setColumnManagerOpen,
6760
6966
  columns,
6761
- order: columnOrder,
6762
- hidden: hiddenColumnIds,
6763
- onApply: (order, hidden) => {
6764
- setColumnOrder(order);
6765
- setHiddenColumnIds(hidden);
6766
- }
6967
+ order: effectiveColumnOrder,
6968
+ hidden: effectiveHiddenColumnIds,
6969
+ onApply: commitColumnState
6767
6970
  }
6768
6971
  ),
6769
6972
  detailEnabled && selectedRow ? /* @__PURE__ */ jsx32(
@@ -6977,7 +7180,7 @@ function HierarchyDragHandle({
6977
7180
  label,
6978
7181
  disabled
6979
7182
  }) {
6980
- const { attributes, listeners, setNodeRef } = useDraggable({
7183
+ const { attributes, listeners, setNodeRef } = useDraggable2({
6981
7184
  id,
6982
7185
  disabled
6983
7186
  });
@@ -7001,7 +7204,7 @@ function HierarchyRootDropTarget({
7001
7204
  label,
7002
7205
  draggedLabel
7003
7206
  }) {
7004
- const { isOver, setNodeRef } = useDroppable({ id: "__root__" });
7207
+ const { isOver, setNodeRef } = useDroppable2({ id: "__root__" });
7005
7208
  return /* @__PURE__ */ jsxs24(
7006
7209
  "div",
7007
7210
  {
@@ -7025,7 +7228,7 @@ function HierarchyDragIndicatorLayer({
7025
7228
  const [indicator, setIndicator] = useState14(
7026
7229
  null
7027
7230
  );
7028
- useDndMonitor({
7231
+ useDndMonitor2({
7029
7232
  onDragMove(event) {
7030
7233
  const container = scrollRef.current;
7031
7234
  const overId = event.over ? String(event.over.id) : null;
@@ -7125,7 +7328,7 @@ function HierarchyDroppableRow({
7125
7328
  disabled,
7126
7329
  children
7127
7330
  }) {
7128
- const { setNodeRef } = useDroppable({ id, disabled });
7331
+ const { setNodeRef } = useDroppable2({ id, disabled });
7129
7332
  if (!isValidElement(children) || children.type !== "tr") return children;
7130
7333
  const row = children;
7131
7334
  return cloneElement(row, {
@@ -7133,6 +7336,38 @@ function HierarchyDroppableRow({
7133
7336
  className: row.props.className
7134
7337
  });
7135
7338
  }
7339
+ function ColumnHeaderDropZone({
7340
+ id,
7341
+ enabled,
7342
+ children
7343
+ }) {
7344
+ const { setNodeRef } = useDroppable2({
7345
+ id: `matrx-column-header:${id}`,
7346
+ disabled: !enabled,
7347
+ data: { matrxDragKind: "column-header", columnId: id }
7348
+ });
7349
+ return /* @__PURE__ */ jsx32("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
7350
+ }
7351
+ function ColumnReorderHandle({ id, label }) {
7352
+ const { attributes, listeners, setNodeRef } = useDraggable2({
7353
+ id: `matrx-column-header:${id}`,
7354
+ data: { matrxDragKind: "column-header", columnId: id }
7355
+ });
7356
+ return /* @__PURE__ */ jsx32(
7357
+ "button",
7358
+ {
7359
+ ref: setNodeRef,
7360
+ type: "button",
7361
+ 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",
7362
+ "aria-label": `Reorder ${label}`,
7363
+ title: `Drag to reorder ${label}`,
7364
+ onClick: (event) => event.stopPropagation(),
7365
+ ...attributes,
7366
+ ...listeners,
7367
+ children: /* @__PURE__ */ jsx32(GripVertical, { className: "h-3.5 w-3.5" })
7368
+ }
7369
+ );
7370
+ }
7136
7371
  function columnWidthVar(width) {
7137
7372
  if (width === void 0) return void 0;
7138
7373
  return {