@bmsuisse/datagrid 0.34.1 → 0.35.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/dist/index.d.ts CHANGED
@@ -1218,6 +1218,27 @@ interface ColumnSelectorProps<TRow> {
1218
1218
  /** Optional controlled open state, for callers that want their own trigger entirely. */
1219
1219
  open?: boolean;
1220
1220
  onOpenChange?: (open: boolean) => void;
1221
+ /**
1222
+ * Column ids in display order (typically the same order already fed to
1223
+ * `<DataGrid columns={...}>`). When given together with
1224
+ * `onColumnOrderChange`, each row gets a drag handle so a column can be
1225
+ * dragged to a new position -- purely within its own group (or the
1226
+ * ungrouped section): a column's `group` is fixed metadata from its
1227
+ * `ColumnDef`, not something dragging can change, so a row only ever
1228
+ * visibly moves among its own group's other rows. Omit both props for the
1229
+ * original visibility-only behavior (no drag handles rendered at all).
1230
+ *
1231
+ * `onColumnOrderChange` is the only thing that ever fires on a drop --
1232
+ * exactly one call, with the fully-computed new order, so a caller can
1233
+ * persist it (to its own state store, a backend, wherever) without also
1234
+ * reaching into this component's internals. `persistKey`, if set,
1235
+ * additionally layers the same kind of localStorage restore-on-mount/write-
1236
+ * on-change sync `visibility` already gets (under a separate storage key --
1237
+ * see `persistence.ts` -- so it can't collide with or migrate previously
1238
+ * stored visibility data).
1239
+ */
1240
+ columnOrder?: string[];
1241
+ onColumnOrderChange?: (order: string[]) => void;
1221
1242
  }
1222
1243
  /**
1223
1244
  * Controlled column-visibility selector: a modal listing every column,
@@ -1230,7 +1251,9 @@ interface ColumnSelectorProps<TRow> {
1230
1251
  * controlled by `visibility`/`onVisibilityChange` — `persistKey`
1231
1252
  * layers an optional localStorage sync on top (restore once on mount, write
1232
1253
  * on every change), it never becomes the source of truth in place of the
1233
- * `visibility` prop.
1254
+ * `visibility` prop. `columnOrder`/`onColumnOrderChange` (both optional,
1255
+ * opt-in) layer the same kind of controlled sync on top for drag-to-reorder
1256
+ * — see their own doc comments above.
1234
1257
  *
1235
1258
  * Not rendered inside `<DataGrid>` automatically — wire it up next to the
1236
1259
  * grid yourself, e.g.:
@@ -1241,7 +1264,7 @@ interface ColumnSelectorProps<TRow> {
1241
1264
  * <DataGrid columns={columns} columnVisibility={visibility} onColumnVisibilityChange={setVisibility} ... />
1242
1265
  * ```
1243
1266
  */
1244
- declare function ColumnSelector<TRow>({ columns, visibility, onVisibilityChange, persistKey, trigger, open, onOpenChange, }: ColumnSelectorProps<TRow>): ReactElement;
1267
+ declare function ColumnSelector<TRow>({ columns, visibility, onVisibilityChange, persistKey, trigger, open, onOpenChange, columnOrder, onColumnOrderChange, }: ColumnSelectorProps<TRow>): ReactElement;
1245
1268
 
1246
1269
  /** A missing key means visible, matching TanStack's own VisibilityState convention. */
1247
1270
  declare function isColumnVisible(visibility: ColumnVisibility, columnId: string): boolean;
@@ -1265,6 +1288,34 @@ declare function canHideColumn<TRow>(columns: readonly ColumnDef<TRow>[], visibi
1265
1288
  declare function canHideGroup<TRow>(columns: readonly ColumnDef<TRow>[], visibility: ColumnVisibility, groupColumnIds: readonly string[]): boolean;
1266
1289
 
1267
1290
  declare function storageKeyFor(persistKey: string): string;
1291
+ declare function orderStorageKeyFor(persistKey: string): string;
1292
+
1293
+ /**
1294
+ * Reorders `columns` to match `order` (an array of column ids in display
1295
+ * order), then hands the result to `groupColumns` -- since that function
1296
+ * preserves each column's position within its own group, pre-sorting the
1297
+ * input array this way is enough to get correctly-ordered groups with no
1298
+ * change to `groupColumns` itself.
1299
+ *
1300
+ * An id in `order` that no longer matches a real column is ignored (e.g. a
1301
+ * column removed from the grid since the order was persisted); a column
1302
+ * present in `columns` but missing from `order` (e.g. one newly added since)
1303
+ * is appended at the end, in its original `columns` position -- the same
1304
+ * "graceful fallback for a stale persisted list" shape `readPersistedVisibility`
1305
+ * already uses for visibility.
1306
+ */
1307
+ declare function applyColumnOrder<TRow>(columns: readonly ColumnDef<TRow>[], order: readonly string[]): ColumnDef<TRow>[];
1308
+ /**
1309
+ * Moves `columnId` to sit immediately before `beforeColumnId` in `order` (or
1310
+ * to the end when `beforeColumnId` is undefined or no longer present) --
1311
+ * the pure reorder-array-splice logic behind `<ColumnSelector>`'s
1312
+ * drag-and-drop, kept separate from the DOM drag wiring so it's unit-testable
1313
+ * without simulating real drag events (jsdom has no working `DataTransfer`).
1314
+ * Recomputing `beforeColumnId`'s index AFTER removing `columnId` (rather than
1315
+ * the caller pre-computing an insert index) makes this correct regardless of
1316
+ * whether the drag moved the column earlier or later in the list.
1317
+ */
1318
+ declare function moveColumnBefore(order: readonly string[], columnId: string, beforeColumnId: string | undefined): string[];
1268
1319
 
1269
1320
  /** The row/selection context a menu item's visible/disabled/onSelect handlers are evaluated against. */
1270
1321
  interface MenuItemContext<TRow> {
@@ -2097,4 +2148,4 @@ interface UseTreeStateOptions<TRow> extends TreeAccessors<TRow> {
2097
2148
  */
2098
2149
  declare function useTreeState<TRow>({ data, getRowId, getChildren, hasChildren, onLoadChildren, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, }: UseTreeStateOptions<TRow>): TreeStateController<TRow>;
2099
2150
 
2100
- export { ActionsMenu, type BaseColumn, type BooleanColumn, BooleanEditor, BooleanFilter, type CellAddress, type CellChange, type CellEditingCellContext, type CellEditingOptions, type CellEditingState, type CellRange, type CellSelectionController, type CellSelectionOptions, type ClientProcessingResult, type ColumnAlign, type ColumnDef, type ColumnGroup, ColumnSelector, type ColumnSelectorProps, type ColumnVisibility, type CompositeFilterDescriptor, DataGrid, type DataGridProps, type DataSource, type DateColumn, DateEditor, DateRangeFilter, type DebouncedCallback, EditFieldError, type EditWidgetProps, type EditedRow, EditingBar, type EditingBarProps, type EditingCellContext, type EditingOptions, type EditingState, type EnumColumn, EnumEditor, EnumFilter, type EnumOption, type FilterDescriptor, type FilterOperator, type FilterWidgetProps, type FlatTreeRow, type GridState, type GridStateController, type GroupExpansionController, type MenuItem, type MenuItemContext, MultilineStringEditor, type NavigationDirection, type NormalizedRange, type NumberColumn, NumberComparisonFilter, NumberEditor, NumberHistogramFilter, type NumberHistogramFilterProps, NumberRangeFilter, type PendingRowEdit, type ResolvedMenuItem, SelectionOverlay, type SortDescriptor, type StickyGroupHeaderTop, type StringColumn, StringEditor, StringFilter, type TreeAccessors, TreeDataGrid, type TreeDataGridProps, type TreeStateController, UNARY_OPERATORS, type UseTreeStateOptions, alignClassName, buildIndexMap, canHideColumn, canHideGroup, cellsInRange, coerceValueForColumn, computeFillChanges, countVisible, defaultAlign, defaultFormat, editErrorId, evaluateFilter, extendRangeForFill, facetedNumberValues, fieldKey, flattenTree, getColumnValue, groupColumns, isCellInRange, isColumnVisible, isCompositeFilterDescriptor, isEditable, isFilterDescriptor, isFilterable, isSortable, normalizeRange, parseTsv, processClientData, rangeToTsv, renderCellModeCell, renderDefaultEditWidget, renderDefaultFilterWidget, renderEditableCell, resolveMenuItems, storageKeyFor, toDate, useCellEditingState, useCellSelection, useDebouncedCallback, useEditingState, useGridState, useGroupExpansion, useStickyGroupHeaderTop, useTreeState, useVisibleColumns };
2151
+ export { ActionsMenu, type BaseColumn, type BooleanColumn, BooleanEditor, BooleanFilter, type CellAddress, type CellChange, type CellEditingCellContext, type CellEditingOptions, type CellEditingState, type CellRange, type CellSelectionController, type CellSelectionOptions, type ClientProcessingResult, type ColumnAlign, type ColumnDef, type ColumnGroup, ColumnSelector, type ColumnSelectorProps, type ColumnVisibility, type CompositeFilterDescriptor, DataGrid, type DataGridProps, type DataSource, type DateColumn, DateEditor, DateRangeFilter, type DebouncedCallback, EditFieldError, type EditWidgetProps, type EditedRow, EditingBar, type EditingBarProps, type EditingCellContext, type EditingOptions, type EditingState, type EnumColumn, EnumEditor, EnumFilter, type EnumOption, type FilterDescriptor, type FilterOperator, type FilterWidgetProps, type FlatTreeRow, type GridState, type GridStateController, type GroupExpansionController, type MenuItem, type MenuItemContext, MultilineStringEditor, type NavigationDirection, type NormalizedRange, type NumberColumn, NumberComparisonFilter, NumberEditor, NumberHistogramFilter, type NumberHistogramFilterProps, NumberRangeFilter, type PendingRowEdit, type ResolvedMenuItem, SelectionOverlay, type SortDescriptor, type StickyGroupHeaderTop, type StringColumn, StringEditor, StringFilter, type TreeAccessors, TreeDataGrid, type TreeDataGridProps, type TreeStateController, UNARY_OPERATORS, type UseTreeStateOptions, alignClassName, applyColumnOrder, buildIndexMap, canHideColumn, canHideGroup, cellsInRange, coerceValueForColumn, computeFillChanges, countVisible, defaultAlign, defaultFormat, editErrorId, evaluateFilter, extendRangeForFill, facetedNumberValues, fieldKey, flattenTree, getColumnValue, groupColumns, isCellInRange, isColumnVisible, isCompositeFilterDescriptor, isEditable, isFilterDescriptor, isFilterable, isSortable, moveColumnBefore, normalizeRange, orderStorageKeyFor, parseTsv, processClientData, rangeToTsv, renderCellModeCell, renderDefaultEditWidget, renderDefaultFilterWidget, renderEditableCell, resolveMenuItems, storageKeyFor, toDate, useCellEditingState, useCellSelection, useDebouncedCallback, useEditingState, useGridState, useGroupExpansion, useStickyGroupHeaderTop, useTreeState, useVisibleColumns };
package/dist/index.js CHANGED
@@ -2556,8 +2556,8 @@ function computeFillChanges(sourceRange, finalRange, rowIds, columnIds, columns,
2556
2556
  }
2557
2557
 
2558
2558
  // src/column-selector/ColumnSelector.tsx
2559
- import { Columns3 } from "lucide-react";
2560
- import { useEffect as useEffect7 } from "react";
2559
+ import { Columns3, GripVertical } from "lucide-react";
2560
+ import { useEffect as useEffect7, useState as useState11 } from "react";
2561
2561
 
2562
2562
  // src/components/ui/dialog.tsx
2563
2563
  import * as DialogPrimitive from "@radix-ui/react-dialog";
@@ -2613,6 +2613,31 @@ var DialogDescription = forwardRef7(({ className, ...props }, ref) => /* @__PURE
2613
2613
  ));
2614
2614
  DialogDescription.displayName = "DialogDescription";
2615
2615
 
2616
+ // src/column-selector/ordering.ts
2617
+ function applyColumnOrder(columns, order) {
2618
+ const byId = new Map(columns.map((column) => [column.id, column]));
2619
+ const seen = /* @__PURE__ */ new Set();
2620
+ const ordered = [];
2621
+ for (const id of order) {
2622
+ const column = byId.get(id);
2623
+ if (column && !seen.has(id)) {
2624
+ ordered.push(column);
2625
+ seen.add(id);
2626
+ }
2627
+ }
2628
+ for (const column of columns) {
2629
+ if (!seen.has(column.id)) ordered.push(column);
2630
+ }
2631
+ return ordered;
2632
+ }
2633
+ function moveColumnBefore(order, columnId, beforeColumnId) {
2634
+ const next = order.filter((id) => id !== columnId);
2635
+ const insertAt = beforeColumnId ? next.indexOf(beforeColumnId) : -1;
2636
+ if (insertAt === -1) next.push(columnId);
2637
+ else next.splice(insertAt, 0, columnId);
2638
+ return next;
2639
+ }
2640
+
2616
2641
  // src/column-selector/persistence.ts
2617
2642
  function storageKeyFor(persistKey) {
2618
2643
  return `bmsui-datagrid:columns:${persistKey}`;
@@ -2633,6 +2658,22 @@ function readPersistedVisibility(persistKey) {
2633
2658
  function writePersistedVisibility(persistKey, visibility) {
2634
2659
  window.localStorage.setItem(storageKeyFor(persistKey), JSON.stringify(visibility));
2635
2660
  }
2661
+ function orderStorageKeyFor(persistKey) {
2662
+ return `bmsui-datagrid:column-order:${persistKey}`;
2663
+ }
2664
+ function readPersistedColumnOrder(persistKey) {
2665
+ const raw = window.localStorage.getItem(orderStorageKeyFor(persistKey));
2666
+ if (raw === null) return null;
2667
+ try {
2668
+ const parsed = JSON.parse(raw);
2669
+ return Array.isArray(parsed) && parsed.every((id) => typeof id === "string") ? parsed : null;
2670
+ } catch {
2671
+ return null;
2672
+ }
2673
+ }
2674
+ function writePersistedColumnOrder(persistKey, order) {
2675
+ window.localStorage.setItem(orderStorageKeyFor(persistKey), JSON.stringify(order));
2676
+ }
2636
2677
 
2637
2678
  // src/column-selector/visibility.ts
2638
2679
  function isColumnVisible(visibility, columnId) {
@@ -2679,13 +2720,20 @@ function ColumnSelector({
2679
2720
  persistKey,
2680
2721
  trigger,
2681
2722
  open,
2682
- onOpenChange
2723
+ onOpenChange,
2724
+ columnOrder,
2725
+ onColumnOrderChange
2683
2726
  }) {
2684
2727
  useEffect7(() => {
2685
2728
  if (!persistKey) return;
2686
2729
  const restored = readPersistedVisibility(persistKey);
2687
2730
  if (restored) onVisibilityChange({ ...visibility, ...restored });
2688
2731
  }, [persistKey]);
2732
+ useEffect7(() => {
2733
+ if (!persistKey || !onColumnOrderChange) return;
2734
+ const restored = readPersistedColumnOrder(persistKey);
2735
+ if (restored) onColumnOrderChange(restored);
2736
+ }, [persistKey]);
2689
2737
  function commit(next) {
2690
2738
  onVisibilityChange(next);
2691
2739
  if (persistKey) writePersistedVisibility(persistKey, next);
@@ -2695,7 +2743,20 @@ function ColumnSelector({
2695
2743
  commit({ ...visibility, [columnId]: !isColumnVisible(visibility, columnId) });
2696
2744
  }
2697
2745
  const totalVisible = countVisible(columns, visibility);
2698
- const groups = groupColumns(columns);
2746
+ const canReorder = Boolean(onColumnOrderChange);
2747
+ const effectiveOrder = columnOrder ?? columns.map((column) => column.id);
2748
+ const orderedColumns = columnOrder ? applyColumnOrder(columns, columnOrder) : columns;
2749
+ const groups = groupColumns(orderedColumns);
2750
+ const groupById = new Map(columns.map((column) => [column.id, column.group]));
2751
+ const [draggedId, setDraggedId] = useState11(null);
2752
+ const [overId, setOverId] = useState11(null);
2753
+ function handleDrop(targetId) {
2754
+ if (!draggedId || draggedId === targetId) return;
2755
+ if (groupById.get(draggedId) !== groupById.get(targetId)) return;
2756
+ const next = moveColumnBefore(effectiveOrder, draggedId, targetId);
2757
+ onColumnOrderChange?.(next);
2758
+ if (persistKey) writePersistedColumnOrder(persistKey, next);
2759
+ }
2699
2760
  return /* @__PURE__ */ jsxs18(Dialog, { open, onOpenChange, children: [
2700
2761
  /* @__PURE__ */ jsx29(DialogTrigger, { asChild: true, children: trigger ?? /* @__PURE__ */ jsx29(Button, { variant: "outline", size: "icon", "aria-label": "Choose columns", children: /* @__PURE__ */ jsx29(Columns3, { className: "h-4 w-4", "aria-hidden": true }) }) }),
2701
2762
  /* @__PURE__ */ jsxs18(DialogContent, { className: "w-fit max-w-[calc(100vw-2rem)] sm:max-w-2xl", children: [
@@ -2707,8 +2768,37 @@ function ColumnSelector({
2707
2768
  return /* @__PURE__ */ jsxs18(
2708
2769
  "label",
2709
2770
  {
2710
- className: "flex items-center gap-2 rounded-md px-1.5 py-1 text-sm hover:bg-accent/50 focus-within:bg-accent/50",
2771
+ draggable: canReorder,
2772
+ onDragStart: canReorder ? () => setDraggedId(column.id) : void 0,
2773
+ onDragOver: canReorder ? (event) => {
2774
+ event.preventDefault();
2775
+ setOverId(column.id);
2776
+ } : void 0,
2777
+ onDragLeave: canReorder ? () => setOverId((current) => current === column.id ? null : current) : void 0,
2778
+ onDrop: canReorder ? (event) => {
2779
+ event.preventDefault();
2780
+ handleDrop(column.id);
2781
+ setDraggedId(null);
2782
+ setOverId(null);
2783
+ } : void 0,
2784
+ onDragEnd: canReorder ? () => {
2785
+ setDraggedId(null);
2786
+ setOverId(null);
2787
+ } : void 0,
2788
+ className: cn(
2789
+ "flex items-center gap-2 rounded-md px-1.5 py-1 text-sm hover:bg-accent/50 focus-within:bg-accent/50",
2790
+ canReorder && "cursor-grab",
2791
+ draggedId === column.id && "opacity-40",
2792
+ overId === column.id && draggedId !== null && draggedId !== column.id && "outline -outline-offset-2 outline-2 outline-primary"
2793
+ ),
2711
2794
  children: [
2795
+ canReorder && /* @__PURE__ */ jsx29(
2796
+ GripVertical,
2797
+ {
2798
+ className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/50",
2799
+ "aria-hidden": true
2800
+ }
2801
+ ),
2712
2802
  /* @__PURE__ */ jsx29(
2713
2803
  Checkbox,
2714
2804
  {
@@ -2822,20 +2912,20 @@ import { BarsArrowDownIcon, BarsArrowUpIcon, FunnelIcon as FunnelIcon7 } from "@
2822
2912
  import { columnResizingFeature, columnSizingFeature, flexRender, tableFeatures, useTable } from "@tanstack/react-table";
2823
2913
  import { useVirtualizer } from "@tanstack/react-virtual";
2824
2914
  import { ChevronRight, Loader2 } from "lucide-react";
2825
- import { Fragment as Fragment3, useEffect as useEffect11, useMemo as useMemo8, useRef as useRef12, useState as useState15 } from "react";
2915
+ import { Fragment as Fragment3, useEffect as useEffect11, useMemo as useMemo8, useRef as useRef12, useState as useState16 } from "react";
2826
2916
 
2827
2917
  // src/cell-editing/renderAlwaysEditCell.tsx
2828
2918
  import {
2829
2919
  useEffect as useEffect8,
2830
- useState as useState11
2920
+ useState as useState12
2831
2921
  } from "react";
2832
2922
  import { jsx as jsx32 } from "react/jsx-runtime";
2833
2923
  function AlwaysEditCell(props) {
2834
2924
  const { column, row, rawValue, ctx, atomicGesture } = props;
2835
2925
  const rowId = ctx.getRowId(row);
2836
2926
  const resolvedValue = ctx.resolveValue(rowId, column.id, rawValue);
2837
- const [draft, setDraft] = useState11(void 0);
2838
- const [enumOpen, setEnumOpen] = useState11(false);
2927
+ const [draft, setDraft] = useState12(void 0);
2928
+ const [enumOpen, setEnumOpen] = useState12(false);
2839
2929
  const isBuiltinEnum = column.type === "enum" && !column.renderEditCell;
2840
2930
  const shouldOpenEnumNow = isBuiltinEnum && (atomicGesture?.shouldOpenEnum(rowId, column.id) ?? false);
2841
2931
  useEffect8(() => {
@@ -2936,9 +3026,9 @@ function AlwaysEditCell(props) {
2936
3026
  }
2937
3027
 
2938
3028
  // src/hooks/useGroupExpansion.ts
2939
- import { useCallback as useCallback3, useState as useState12 } from "react";
3029
+ import { useCallback as useCallback3, useState as useState13 } from "react";
2940
3030
  function useGroupExpansion(defaultGroupsExpanded, controlledExpandedGroups, onExpandedGroupsChange) {
2941
- const [internalExpandedGroups, setInternalExpandedGroups] = useState12({});
3031
+ const [internalExpandedGroups, setInternalExpandedGroups] = useState13({});
2942
3032
  const expandedGroups = controlledExpandedGroups ?? internalExpandedGroups;
2943
3033
  const updateExpandedGroups = useCallback3(
2944
3034
  (next) => {
@@ -2961,10 +3051,10 @@ function useGroupExpansion(defaultGroupsExpanded, controlledExpandedGroups, onEx
2961
3051
  }
2962
3052
 
2963
3053
  // src/hooks/useStickyGroupHeaderTop.ts
2964
- import { useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState13 } from "react";
3054
+ import { useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState14 } from "react";
2965
3055
  function useStickyGroupHeaderTop(enabled) {
2966
3056
  const theadRef = useRef10(null);
2967
- const [groupHeaderTop, setGroupHeaderTop] = useState13(0);
3057
+ const [groupHeaderTop, setGroupHeaderTop] = useState14(0);
2968
3058
  useLayoutEffect3(() => {
2969
3059
  if (!enabled) return;
2970
3060
  const theadEl = theadRef.current;
@@ -3028,7 +3118,7 @@ function processClientData(data, state) {
3028
3118
  }
3029
3119
 
3030
3120
  // src/grid/useGridState.ts
3031
- import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo7, useState as useState14 } from "react";
3121
+ import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo7, useState as useState15 } from "react";
3032
3122
 
3033
3123
  // src/hooks/useDebouncedCallback.ts
3034
3124
  import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef11 } from "react";
@@ -3066,7 +3156,7 @@ function nextSortDir(current, descFirst) {
3066
3156
  return void 0;
3067
3157
  }
3068
3158
  function useGridState(dataSource, initialState, externalState, showPagination = true, onGridStateChange) {
3069
- const [state, setState] = useState14(() => {
3159
+ const [state, setState] = useState15(() => {
3070
3160
  if (externalState) return externalState;
3071
3161
  const pageSize = initialState?.pageSize ?? (showPagination ? DEFAULT_STATE.pageSize : Number.MAX_SAFE_INTEGER);
3072
3162
  return { ...DEFAULT_STATE, ...initialState, pageSize };
@@ -3264,19 +3354,19 @@ function DataGrid({
3264
3354
  showPagination,
3265
3355
  onGridStateChange
3266
3356
  );
3267
- const [internalSelectedIds, setInternalSelectedIds] = useState15(/* @__PURE__ */ new Set());
3357
+ const [internalSelectedIds, setInternalSelectedIds] = useState16(/* @__PURE__ */ new Set());
3268
3358
  const selectedIds = controlledSelectedIds ?? internalSelectedIds;
3269
3359
  function updateSelectedIds(next) {
3270
3360
  setInternalSelectedIds(next);
3271
3361
  onSelectedIdsChange?.(next);
3272
3362
  }
3273
- const [internalColumnSizing, setInternalColumnSizing] = useState15({});
3363
+ const [internalColumnSizing, setInternalColumnSizing] = useState16({});
3274
3364
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
3275
3365
  function updateColumnSizing(next) {
3276
3366
  setInternalColumnSizing(next);
3277
3367
  onColumnSizingChange?.(next);
3278
3368
  }
3279
- const [expandedIds, setExpandedIds] = useState15(/* @__PURE__ */ new Set());
3369
+ const [expandedIds, setExpandedIds] = useState16(/* @__PURE__ */ new Set());
3280
3370
  function toggleRowExpanded(id) {
3281
3371
  setExpandedIds((prev) => {
3282
3372
  const next = new Set(prev);
@@ -3528,7 +3618,7 @@ function DataGrid({
3528
3618
  });
3529
3619
  const clickCellRef = useRef12(null);
3530
3620
  const dragMovedRef = useRef12(false);
3531
- const [pendingOpenEnumCell, setPendingOpenEnumCell] = useState15(void 0);
3621
+ const [pendingOpenEnumCell, setPendingOpenEnumCell] = useState16(void 0);
3532
3622
  atomicGestureRef.current = {
3533
3623
  shouldOpenEnum: (rowId, columnId) => pendingOpenEnumCell?.rowId === rowId && pendingOpenEnumCell?.columnId === columnId,
3534
3624
  // Mirrors exactly what `handleCellMouseDown` below does for every other
@@ -4307,7 +4397,7 @@ function computeSelectionStates(roots, accessors, childrenOverride, selectedIds)
4307
4397
  }
4308
4398
 
4309
4399
  // src/tree/useTreeState.ts
4310
- import { useCallback as useCallback5, useMemo as useMemo9, useState as useState16 } from "react";
4400
+ import { useCallback as useCallback5, useMemo as useMemo9, useState as useState17 } from "react";
4311
4401
  function useTreeState({
4312
4402
  data,
4313
4403
  getRowId,
@@ -4319,7 +4409,7 @@ function useTreeState({
4319
4409
  childrenMap: controlledChildrenMap,
4320
4410
  onChildrenMapChange
4321
4411
  }) {
4322
- const [internalExpanded, setInternalExpanded] = useState16({});
4412
+ const [internalExpanded, setInternalExpanded] = useState17({});
4323
4413
  const expanded = controlledExpanded ?? internalExpanded;
4324
4414
  const setExpanded = useCallback5(
4325
4415
  (updater) => {
@@ -4331,7 +4421,7 @@ function useTreeState({
4331
4421
  },
4332
4422
  [controlledExpanded, onExpandedChange]
4333
4423
  );
4334
- const [internalChildrenMap, setInternalChildrenMap] = useState16(/* @__PURE__ */ new Map());
4424
+ const [internalChildrenMap, setInternalChildrenMap] = useState17(/* @__PURE__ */ new Map());
4335
4425
  const childrenMap = controlledChildrenMap ?? internalChildrenMap;
4336
4426
  const setChildrenMap = useCallback5(
4337
4427
  (updater) => {
@@ -4343,8 +4433,8 @@ function useTreeState({
4343
4433
  },
4344
4434
  [controlledChildrenMap, onChildrenMapChange]
4345
4435
  );
4346
- const [loadingIds, setLoadingIds] = useState16(/* @__PURE__ */ new Set());
4347
- const [errorIds, setErrorIds] = useState16(/* @__PURE__ */ new Map());
4436
+ const [loadingIds, setLoadingIds] = useState17(/* @__PURE__ */ new Set());
4437
+ const [errorIds, setErrorIds] = useState17(/* @__PURE__ */ new Map());
4348
4438
  const resolveHasChildren = useMemo9(
4349
4439
  () => hasChildren ?? ((row) => (getChildren(row)?.length ?? 0) > 0),
4350
4440
  [hasChildren, getChildren]
@@ -4843,6 +4933,7 @@ export {
4843
4933
  TreeDataGrid,
4844
4934
  UNARY_OPERATORS,
4845
4935
  alignClassName,
4936
+ applyColumnOrder,
4846
4937
  buildIndexMap,
4847
4938
  canHideColumn,
4848
4939
  canHideGroup,
@@ -4867,7 +4958,9 @@ export {
4867
4958
  isFilterDescriptor,
4868
4959
  isFilterable,
4869
4960
  isSortable,
4961
+ moveColumnBefore,
4870
4962
  normalizeRange,
4963
+ orderStorageKeyFor,
4871
4964
  parseTsv,
4872
4965
  processClientData,
4873
4966
  rangeToTsv,