@bmsuisse/datagrid 0.34.1 → 0.35.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/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:columns:${persistKey}:order`;
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,18 @@ 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 [draggedId, setDraggedId] = useState11(null);
2751
+ const [overId, setOverId] = useState11(null);
2752
+ function handleDrop(targetId) {
2753
+ if (!draggedId || draggedId === targetId) return;
2754
+ const next = moveColumnBefore(effectiveOrder, draggedId, targetId);
2755
+ onColumnOrderChange?.(next);
2756
+ if (persistKey) writePersistedColumnOrder(persistKey, next);
2757
+ }
2699
2758
  return /* @__PURE__ */ jsxs18(Dialog, { open, onOpenChange, children: [
2700
2759
  /* @__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
2760
  /* @__PURE__ */ jsxs18(DialogContent, { className: "w-fit max-w-[calc(100vw-2rem)] sm:max-w-2xl", children: [
@@ -2707,8 +2766,37 @@ function ColumnSelector({
2707
2766
  return /* @__PURE__ */ jsxs18(
2708
2767
  "label",
2709
2768
  {
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",
2769
+ draggable: canReorder,
2770
+ onDragStart: canReorder ? () => setDraggedId(column.id) : void 0,
2771
+ onDragOver: canReorder ? (event) => {
2772
+ event.preventDefault();
2773
+ setOverId(column.id);
2774
+ } : void 0,
2775
+ onDragLeave: canReorder ? () => setOverId((current) => current === column.id ? null : current) : void 0,
2776
+ onDrop: canReorder ? (event) => {
2777
+ event.preventDefault();
2778
+ handleDrop(column.id);
2779
+ setDraggedId(null);
2780
+ setOverId(null);
2781
+ } : void 0,
2782
+ onDragEnd: canReorder ? () => {
2783
+ setDraggedId(null);
2784
+ setOverId(null);
2785
+ } : void 0,
2786
+ className: cn(
2787
+ "flex items-center gap-2 rounded-md px-1.5 py-1 text-sm hover:bg-accent/50 focus-within:bg-accent/50",
2788
+ canReorder && "cursor-grab",
2789
+ draggedId === column.id && "opacity-40",
2790
+ overId === column.id && draggedId !== null && draggedId !== column.id && "outline -outline-offset-2 outline-2 outline-primary"
2791
+ ),
2711
2792
  children: [
2793
+ canReorder && /* @__PURE__ */ jsx29(
2794
+ GripVertical,
2795
+ {
2796
+ className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/50",
2797
+ "aria-hidden": true
2798
+ }
2799
+ ),
2712
2800
  /* @__PURE__ */ jsx29(
2713
2801
  Checkbox,
2714
2802
  {
@@ -2822,20 +2910,20 @@ import { BarsArrowDownIcon, BarsArrowUpIcon, FunnelIcon as FunnelIcon7 } from "@
2822
2910
  import { columnResizingFeature, columnSizingFeature, flexRender, tableFeatures, useTable } from "@tanstack/react-table";
2823
2911
  import { useVirtualizer } from "@tanstack/react-virtual";
2824
2912
  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";
2913
+ import { Fragment as Fragment3, useEffect as useEffect11, useMemo as useMemo8, useRef as useRef12, useState as useState16 } from "react";
2826
2914
 
2827
2915
  // src/cell-editing/renderAlwaysEditCell.tsx
2828
2916
  import {
2829
2917
  useEffect as useEffect8,
2830
- useState as useState11
2918
+ useState as useState12
2831
2919
  } from "react";
2832
2920
  import { jsx as jsx32 } from "react/jsx-runtime";
2833
2921
  function AlwaysEditCell(props) {
2834
2922
  const { column, row, rawValue, ctx, atomicGesture } = props;
2835
2923
  const rowId = ctx.getRowId(row);
2836
2924
  const resolvedValue = ctx.resolveValue(rowId, column.id, rawValue);
2837
- const [draft, setDraft] = useState11(void 0);
2838
- const [enumOpen, setEnumOpen] = useState11(false);
2925
+ const [draft, setDraft] = useState12(void 0);
2926
+ const [enumOpen, setEnumOpen] = useState12(false);
2839
2927
  const isBuiltinEnum = column.type === "enum" && !column.renderEditCell;
2840
2928
  const shouldOpenEnumNow = isBuiltinEnum && (atomicGesture?.shouldOpenEnum(rowId, column.id) ?? false);
2841
2929
  useEffect8(() => {
@@ -2936,9 +3024,9 @@ function AlwaysEditCell(props) {
2936
3024
  }
2937
3025
 
2938
3026
  // src/hooks/useGroupExpansion.ts
2939
- import { useCallback as useCallback3, useState as useState12 } from "react";
3027
+ import { useCallback as useCallback3, useState as useState13 } from "react";
2940
3028
  function useGroupExpansion(defaultGroupsExpanded, controlledExpandedGroups, onExpandedGroupsChange) {
2941
- const [internalExpandedGroups, setInternalExpandedGroups] = useState12({});
3029
+ const [internalExpandedGroups, setInternalExpandedGroups] = useState13({});
2942
3030
  const expandedGroups = controlledExpandedGroups ?? internalExpandedGroups;
2943
3031
  const updateExpandedGroups = useCallback3(
2944
3032
  (next) => {
@@ -2961,10 +3049,10 @@ function useGroupExpansion(defaultGroupsExpanded, controlledExpandedGroups, onEx
2961
3049
  }
2962
3050
 
2963
3051
  // src/hooks/useStickyGroupHeaderTop.ts
2964
- import { useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState13 } from "react";
3052
+ import { useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState14 } from "react";
2965
3053
  function useStickyGroupHeaderTop(enabled) {
2966
3054
  const theadRef = useRef10(null);
2967
- const [groupHeaderTop, setGroupHeaderTop] = useState13(0);
3055
+ const [groupHeaderTop, setGroupHeaderTop] = useState14(0);
2968
3056
  useLayoutEffect3(() => {
2969
3057
  if (!enabled) return;
2970
3058
  const theadEl = theadRef.current;
@@ -3028,7 +3116,7 @@ function processClientData(data, state) {
3028
3116
  }
3029
3117
 
3030
3118
  // src/grid/useGridState.ts
3031
- import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo7, useState as useState14 } from "react";
3119
+ import { useCallback as useCallback4, useEffect as useEffect10, useMemo as useMemo7, useState as useState15 } from "react";
3032
3120
 
3033
3121
  // src/hooks/useDebouncedCallback.ts
3034
3122
  import { useEffect as useEffect9, useMemo as useMemo6, useRef as useRef11 } from "react";
@@ -3066,7 +3154,7 @@ function nextSortDir(current, descFirst) {
3066
3154
  return void 0;
3067
3155
  }
3068
3156
  function useGridState(dataSource, initialState, externalState, showPagination = true, onGridStateChange) {
3069
- const [state, setState] = useState14(() => {
3157
+ const [state, setState] = useState15(() => {
3070
3158
  if (externalState) return externalState;
3071
3159
  const pageSize = initialState?.pageSize ?? (showPagination ? DEFAULT_STATE.pageSize : Number.MAX_SAFE_INTEGER);
3072
3160
  return { ...DEFAULT_STATE, ...initialState, pageSize };
@@ -3264,19 +3352,19 @@ function DataGrid({
3264
3352
  showPagination,
3265
3353
  onGridStateChange
3266
3354
  );
3267
- const [internalSelectedIds, setInternalSelectedIds] = useState15(/* @__PURE__ */ new Set());
3355
+ const [internalSelectedIds, setInternalSelectedIds] = useState16(/* @__PURE__ */ new Set());
3268
3356
  const selectedIds = controlledSelectedIds ?? internalSelectedIds;
3269
3357
  function updateSelectedIds(next) {
3270
3358
  setInternalSelectedIds(next);
3271
3359
  onSelectedIdsChange?.(next);
3272
3360
  }
3273
- const [internalColumnSizing, setInternalColumnSizing] = useState15({});
3361
+ const [internalColumnSizing, setInternalColumnSizing] = useState16({});
3274
3362
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
3275
3363
  function updateColumnSizing(next) {
3276
3364
  setInternalColumnSizing(next);
3277
3365
  onColumnSizingChange?.(next);
3278
3366
  }
3279
- const [expandedIds, setExpandedIds] = useState15(/* @__PURE__ */ new Set());
3367
+ const [expandedIds, setExpandedIds] = useState16(/* @__PURE__ */ new Set());
3280
3368
  function toggleRowExpanded(id) {
3281
3369
  setExpandedIds((prev) => {
3282
3370
  const next = new Set(prev);
@@ -3528,7 +3616,7 @@ function DataGrid({
3528
3616
  });
3529
3617
  const clickCellRef = useRef12(null);
3530
3618
  const dragMovedRef = useRef12(false);
3531
- const [pendingOpenEnumCell, setPendingOpenEnumCell] = useState15(void 0);
3619
+ const [pendingOpenEnumCell, setPendingOpenEnumCell] = useState16(void 0);
3532
3620
  atomicGestureRef.current = {
3533
3621
  shouldOpenEnum: (rowId, columnId) => pendingOpenEnumCell?.rowId === rowId && pendingOpenEnumCell?.columnId === columnId,
3534
3622
  // Mirrors exactly what `handleCellMouseDown` below does for every other
@@ -4307,7 +4395,7 @@ function computeSelectionStates(roots, accessors, childrenOverride, selectedIds)
4307
4395
  }
4308
4396
 
4309
4397
  // src/tree/useTreeState.ts
4310
- import { useCallback as useCallback5, useMemo as useMemo9, useState as useState16 } from "react";
4398
+ import { useCallback as useCallback5, useMemo as useMemo9, useState as useState17 } from "react";
4311
4399
  function useTreeState({
4312
4400
  data,
4313
4401
  getRowId,
@@ -4319,7 +4407,7 @@ function useTreeState({
4319
4407
  childrenMap: controlledChildrenMap,
4320
4408
  onChildrenMapChange
4321
4409
  }) {
4322
- const [internalExpanded, setInternalExpanded] = useState16({});
4410
+ const [internalExpanded, setInternalExpanded] = useState17({});
4323
4411
  const expanded = controlledExpanded ?? internalExpanded;
4324
4412
  const setExpanded = useCallback5(
4325
4413
  (updater) => {
@@ -4331,7 +4419,7 @@ function useTreeState({
4331
4419
  },
4332
4420
  [controlledExpanded, onExpandedChange]
4333
4421
  );
4334
- const [internalChildrenMap, setInternalChildrenMap] = useState16(/* @__PURE__ */ new Map());
4422
+ const [internalChildrenMap, setInternalChildrenMap] = useState17(/* @__PURE__ */ new Map());
4335
4423
  const childrenMap = controlledChildrenMap ?? internalChildrenMap;
4336
4424
  const setChildrenMap = useCallback5(
4337
4425
  (updater) => {
@@ -4343,8 +4431,8 @@ function useTreeState({
4343
4431
  },
4344
4432
  [controlledChildrenMap, onChildrenMapChange]
4345
4433
  );
4346
- const [loadingIds, setLoadingIds] = useState16(/* @__PURE__ */ new Set());
4347
- const [errorIds, setErrorIds] = useState16(/* @__PURE__ */ new Map());
4434
+ const [loadingIds, setLoadingIds] = useState17(/* @__PURE__ */ new Set());
4435
+ const [errorIds, setErrorIds] = useState17(/* @__PURE__ */ new Map());
4348
4436
  const resolveHasChildren = useMemo9(
4349
4437
  () => hasChildren ?? ((row) => (getChildren(row)?.length ?? 0) > 0),
4350
4438
  [hasChildren, getChildren]
@@ -4843,6 +4931,7 @@ export {
4843
4931
  TreeDataGrid,
4844
4932
  UNARY_OPERATORS,
4845
4933
  alignClassName,
4934
+ applyColumnOrder,
4846
4935
  buildIndexMap,
4847
4936
  canHideColumn,
4848
4937
  canHideGroup,
@@ -4867,7 +4956,9 @@ export {
4867
4956
  isFilterDescriptor,
4868
4957
  isFilterable,
4869
4958
  isSortable,
4959
+ moveColumnBefore,
4870
4960
  normalizeRange,
4961
+ orderStorageKeyFor,
4871
4962
  parseTsv,
4872
4963
  processClientData,
4873
4964
  rangeToTsv,