react-glide-table 1.1.8 → 1.2.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/core.cjs CHANGED
@@ -29,6 +29,7 @@ __export(core_exports, {
29
29
  applyCellEdit: () => applyCellEdit,
30
30
  applyFillData: () => applyFillData,
31
31
  applySelectionUpdater: () => applySelectionUpdater,
32
+ buildColumnFreezeOffsets: () => buildColumnFreezeOffsets,
32
33
  buildColumnRowSpanMap: () => buildColumnRowSpanMap,
33
34
  buildRowsPastePayload: () => buildRowsPastePayload,
34
35
  canExpandRow: () => canExpandRow,
@@ -40,6 +41,8 @@ __export(core_exports, {
40
41
  getCellEditDraftValue: () => getCellEditDraftValue,
41
42
  getCellSelectionEdgeStyle: () => getCellSelectionEdgeStyle,
42
43
  getColumnEditType: () => getColumnEditType,
44
+ getColumnFreezeStyle: () => getColumnFreezeStyle,
45
+ getColumnSizeStyle: () => getColumnSizeStyle,
43
46
  getRowIndexInMergedCell: () => getRowIndexInMergedCell,
44
47
  hasCellSelectionEdges: () => hasCellSelectionEdges,
45
48
  isCellInSelection: () => isCellInSelection,
@@ -49,6 +52,7 @@ __export(core_exports, {
49
52
  parseCellEditValue: () => parseCellEditValue,
50
53
  parseClipboardTSV: () => parseClipboardTSV,
51
54
  parseClipboardTSVWithDepths: () => parseClipboardTSVWithDepths,
55
+ resolveColumnFreezeSide: () => resolveColumnFreezeSide,
52
56
  resolveDataTableLabels: () => resolveDataTableLabels,
53
57
  resolvePasteColumnIds: () => resolvePasteColumnIds,
54
58
  resolveRowSelection: () => resolveRowSelection,
@@ -71,7 +75,8 @@ var DEFAULT_DATA_TABLE_LABELS = {
71
75
  loading: "Loading...",
72
76
  selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
73
77
  expandRow: "Expand row",
74
- collapseRow: "Collapse row"
78
+ collapseRow: "Collapse row",
79
+ resizeColumn: "Resize column"
75
80
  };
76
81
  function resolveDataTableLabels(partial) {
77
82
  return {
@@ -94,6 +99,9 @@ var import_react4 = require("react");
94
99
  // src/components/ui/table/constants.ts
95
100
  var DATA_TABLE_ROW_HEIGHT = 44;
96
101
  var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
102
+ var DATA_TABLE_COLUMN_SIZE = 150;
103
+ var DATA_TABLE_COLUMN_MIN_SIZE = 40;
104
+ var DATA_TABLE_COLUMN_MAX_SIZE = 800;
97
105
 
98
106
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
99
107
  var import_react = require("react");
@@ -984,6 +992,68 @@ function useCellSelection({
984
992
  };
985
993
  }
986
994
 
995
+ // src/components/ui/table/features/column-freeze/columnFreeze.ts
996
+ var HEADER_Z_BASE = 30;
997
+ var BODY_Z_BASE = 5;
998
+ function resolveColumnFreezeSide(frozen) {
999
+ if (frozen === true || frozen === "left") return "left";
1000
+ if (frozen === "right") return "right";
1001
+ return void 0;
1002
+ }
1003
+ function buildColumnFreezeOffsets(columns) {
1004
+ const result = /* @__PURE__ */ new Map();
1005
+ let leftOffset = 0;
1006
+ const leftIds = [];
1007
+ for (const column of columns) {
1008
+ if (column.side !== "left") continue;
1009
+ leftIds.push(column.id);
1010
+ result.set(column.id, {
1011
+ side: "left",
1012
+ offset: leftOffset,
1013
+ isEdge: false,
1014
+ stack: 0
1015
+ });
1016
+ leftOffset += column.size;
1017
+ }
1018
+ leftIds.forEach((id, index) => {
1019
+ const entry = result.get(id);
1020
+ if (!entry) return;
1021
+ entry.isEdge = index === leftIds.length - 1;
1022
+ entry.stack = leftIds.length - index;
1023
+ });
1024
+ let rightOffset = 0;
1025
+ const rightIds = [];
1026
+ for (let index = columns.length - 1; index >= 0; index -= 1) {
1027
+ const column = columns[index];
1028
+ if (!column || column.side !== "right") continue;
1029
+ rightIds.push(column.id);
1030
+ result.set(column.id, {
1031
+ side: "right",
1032
+ offset: rightOffset,
1033
+ isEdge: false,
1034
+ stack: 0
1035
+ });
1036
+ rightOffset += column.size;
1037
+ }
1038
+ rightIds.forEach((id, index) => {
1039
+ const entry = result.get(id);
1040
+ if (!entry) return;
1041
+ entry.isEdge = index === rightIds.length - 1;
1042
+ entry.stack = rightIds.length - index;
1043
+ });
1044
+ return result;
1045
+ }
1046
+ function getColumnFreezeStyle(offset, options) {
1047
+ if (!offset) return void 0;
1048
+ const zBase = options?.isHeader ? HEADER_Z_BASE : BODY_Z_BASE;
1049
+ return {
1050
+ position: "sticky",
1051
+ ...offset.side === "left" ? { left: offset.offset } : { right: offset.offset },
1052
+ zIndex: zBase + offset.stack,
1053
+ ...options?.isHeader ? { top: 0 } : {}
1054
+ };
1055
+ }
1056
+
987
1057
  // src/components/ui/table/features/row-expand/row-expand.ts
988
1058
  var import_react3 = require("react");
989
1059
  function getFieldValue(row, key) {
@@ -1249,6 +1319,7 @@ function collectRowSpanColumns(columns) {
1249
1319
  }
1250
1320
 
1251
1321
  // src/core/useGlideTable.ts
1322
+ var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
1252
1323
  function useGlideTable(options) {
1253
1324
  const {
1254
1325
  data,
@@ -1284,7 +1355,12 @@ function useGlideTable(options) {
1284
1355
  enableInsertPaste,
1285
1356
  enableVirtualization = true,
1286
1357
  estimateRowHeight = DATA_TABLE_ROW_HEIGHT,
1287
- virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN
1358
+ virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN,
1359
+ enableColumnResize = false,
1360
+ columnSizing: controlledColumnSizing,
1361
+ onColumnSizingChange,
1362
+ columnResizeMode = "onChange",
1363
+ enableColumnFreeze = false
1288
1364
  } = options;
1289
1365
  const labels = (0, import_react4.useMemo)(() => {
1290
1366
  const resolved = resolveDataTableLabels(labelsProp);
@@ -1298,6 +1374,7 @@ function useGlideTable(options) {
1298
1374
  const enableExpand = Boolean(toggleField);
1299
1375
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
1300
1376
  const [internalRowSelection, setInternalRowSelection] = (0, import_react4.useState)({});
1377
+ const [internalColumnSizing, setInternalColumnSizing] = (0, import_react4.useState)({});
1301
1378
  const [internalExpandedRows, setInternalExpandedRows] = (0, import_react4.useState)(
1302
1379
  () => /* @__PURE__ */ new Set()
1303
1380
  );
@@ -1316,6 +1393,7 @@ function useGlideTable(options) {
1316
1393
  controlledRowSelection,
1317
1394
  internalRowSelection
1318
1395
  );
1396
+ const columnSizing = controlledColumnSizing ?? internalColumnSizing;
1319
1397
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
1320
1398
  const handleExpandedRowsChange = (0, import_react4.useCallback)(
1321
1399
  (next) => {
@@ -1341,9 +1419,27 @@ function useGlideTable(options) {
1341
1419
  const table = (0, import_react_table.useReactTable)({
1342
1420
  data: tableData,
1343
1421
  columns,
1422
+ ...enableColumnResize ? {
1423
+ defaultColumn: {
1424
+ minSize: DATA_TABLE_COLUMN_MIN_SIZE,
1425
+ maxSize: DATA_TABLE_COLUMN_MAX_SIZE
1426
+ }
1427
+ } : {},
1428
+ enableColumnResizing: enableColumnResize,
1429
+ columnResizeMode,
1344
1430
  state: {
1345
- rowSelection: rowSelectionMode === "none" ? {} : rowSelection
1431
+ rowSelection: rowSelectionMode === "none" ? {} : rowSelection,
1432
+ ...enableColumnResize ? { columnSizing } : {}
1346
1433
  },
1434
+ onColumnSizingChange: enableColumnResize ? (updater) => {
1435
+ if (onColumnSizingChange) {
1436
+ onColumnSizingChange(updater);
1437
+ return;
1438
+ }
1439
+ setInternalColumnSizing(
1440
+ (previous) => typeof updater === "function" ? updater(previous) : updater
1441
+ );
1442
+ } : void 0,
1347
1443
  enableRowSelection: rowSelectionMode === "none" ? false : getRowCanSelect ? (row) => getRowCanSelect(row.original, row.index) : true,
1348
1444
  enableMultiRowSelection: rowSelectionMode === "multi",
1349
1445
  onRowSelectionChange: (updater) => {
@@ -1374,6 +1470,17 @@ function useGlideTable(options) {
1374
1470
  const selectedCount = selectedRows.length;
1375
1471
  const rows = table.getRowModel().rows;
1376
1472
  const columnCount = table.getAllLeafColumns().length || 1;
1473
+ const visibleLeafColumns = table.getVisibleLeafColumns();
1474
+ const columnFreezeOffsets = (0, import_react4.useMemo)(() => {
1475
+ if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
1476
+ return buildColumnFreezeOffsets(
1477
+ visibleLeafColumns.map((column) => ({
1478
+ id: column.id,
1479
+ size: column.getSize(),
1480
+ side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
1481
+ }))
1482
+ );
1483
+ }, [enableColumnFreeze, visibleLeafColumns, columnSizing]);
1377
1484
  const rowVirtualizer = (0, import_react_virtual.useVirtualizer)({
1378
1485
  count: shouldVirtualize ? rows.length : 0,
1379
1486
  getScrollElement: () => scrollRef.current,
@@ -1490,6 +1597,13 @@ function useGlideTable(options) {
1490
1597
  onToggleExpand: handleToggleExpand,
1491
1598
  expandRowLabel: labels.expandRow,
1492
1599
  collapseRowLabel: labels.collapseRow
1600
+ },
1601
+ columnResize: {
1602
+ enableColumnResize
1603
+ },
1604
+ columnFreeze: {
1605
+ enableColumnFreeze,
1606
+ offsets: columnFreezeOffsets
1493
1607
  }
1494
1608
  };
1495
1609
  }, [
@@ -1522,7 +1636,10 @@ function useGlideTable(options) {
1522
1636
  preventExpand,
1523
1637
  handleToggleExpand,
1524
1638
  labels.expandRow,
1525
- labels.collapseRow
1639
+ labels.collapseRow,
1640
+ enableColumnResize,
1641
+ enableColumnFreeze,
1642
+ columnFreezeOffsets
1526
1643
  ]);
1527
1644
  const copySelectionRef = (0, import_react4.useRef)(copySelection);
1528
1645
  (0, import_react4.useEffect)(() => {
@@ -1543,6 +1660,8 @@ function useGlideTable(options) {
1543
1660
  loadingText: labels.loading,
1544
1661
  selectionLabel: labels.selection,
1545
1662
  enableCellSelection,
1663
+ enableColumnResize,
1664
+ enableColumnFreeze,
1546
1665
  shouldVirtualize,
1547
1666
  scrollRef,
1548
1667
  rowVirtualizer,
@@ -1555,6 +1674,19 @@ function useGlideTable(options) {
1555
1674
  copySelection: stableCopySelection
1556
1675
  };
1557
1676
  }
1677
+
1678
+ // src/components/ui/table/features/column-resize/columnResize.ts
1679
+ function getColumnSizeStyle(size, options) {
1680
+ const { force = false, lockMax = false } = options ?? {};
1681
+ if (!force && size === DATA_TABLE_COLUMN_SIZE) {
1682
+ return void 0;
1683
+ }
1684
+ return {
1685
+ width: size,
1686
+ minWidth: size,
1687
+ ...lockMax ? { maxWidth: size } : {}
1688
+ };
1689
+ }
1558
1690
  // Annotate the CommonJS export names for ESM import in node:
1559
1691
  0 && (module.exports = {
1560
1692
  CELL_SELECTION_EDGES_CLASS,
@@ -1566,6 +1698,7 @@ function useGlideTable(options) {
1566
1698
  applyCellEdit,
1567
1699
  applyFillData,
1568
1700
  applySelectionUpdater,
1701
+ buildColumnFreezeOffsets,
1569
1702
  buildColumnRowSpanMap,
1570
1703
  buildRowsPastePayload,
1571
1704
  canExpandRow,
@@ -1577,6 +1710,8 @@ function useGlideTable(options) {
1577
1710
  getCellEditDraftValue,
1578
1711
  getCellSelectionEdgeStyle,
1579
1712
  getColumnEditType,
1713
+ getColumnFreezeStyle,
1714
+ getColumnSizeStyle,
1580
1715
  getRowIndexInMergedCell,
1581
1716
  hasCellSelectionEdges,
1582
1717
  isCellInSelection,
@@ -1586,6 +1721,7 @@ function useGlideTable(options) {
1586
1721
  parseCellEditValue,
1587
1722
  parseClipboardTSV,
1588
1723
  parseClipboardTSVWithDepths,
1724
+ resolveColumnFreezeSide,
1589
1725
  resolveDataTableLabels,
1590
1726
  resolvePasteColumnIds,
1591
1727
  resolveRowSelection,
package/dist/core.d.cts CHANGED
@@ -1,10 +1,10 @@
1
- import { C as CellEditType, a as DataTableClassNames, R as RowSelectionMode, d as DataTableProps, c as DataTableLabels, b as DataTableCopyActions, P as PasteMode, f as RowsPastePayload } from './types-Ce4qepIU.cjs';
2
- export { D as DEFAULT_DATA_TABLE_LABELS, r as resolveDataTableLabels } from './types-Ce4qepIU.cjs';
1
+ import { n as CellEditType, d as DataTableClassNames, R as RowSelectionMode, b as ColumnFreezeOffset, g as DataTableProps, f as DataTableLabels, e as DataTableCopyActions, P as PasteMode, i as RowsPastePayload } from './types-D031_07N.cjs';
2
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeMeta, c as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, k as buildColumnFreezeOffsets, l as getColumnFreezeStyle, r as resolveColumnFreezeSide, m as resolveDataTableLabels } from './types-D031_07N.cjs';
3
3
  import { Row, ColumnDef, Table, Updater, RowSelectionState } from '@tanstack/react-table';
4
- export { ColumnDef, RowSelectionState } from '@tanstack/react-table';
4
+ export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
5
5
  import { Virtualizer, VirtualItem } from '@tanstack/react-virtual';
6
6
  import * as react from 'react';
7
- import { RefObject } from 'react';
7
+ import { RefObject, CSSProperties } from 'react';
8
8
 
9
9
  /** Neutral default field names for tree conversion */
10
10
  declare const DEFAULT_TREE_ID_FIELD = "id";
@@ -170,6 +170,13 @@ type DataTableRowContextValue = {
170
170
  expandRowLabel: string;
171
171
  collapseRowLabel: string;
172
172
  };
173
+ columnResize: {
174
+ enableColumnResize: boolean;
175
+ };
176
+ columnFreeze: {
177
+ enableColumnFreeze: boolean;
178
+ offsets: Map<string, ColumnFreezeOffset>;
179
+ };
173
180
  };
174
181
 
175
182
  type UseGlideTableOptions<T extends Record<string, unknown>> = Omit<DataTableProps<T>, "className" | "classNames" | "slots" | "summary" | "toolbar" | "isPending" | "totalCount" | "filteredCount">;
@@ -184,6 +191,8 @@ type UseGlideTableResult<T extends Record<string, unknown>> = {
184
191
  loadingText: string;
185
192
  selectionLabel: DataTableLabels["selection"];
186
193
  enableCellSelection: boolean;
194
+ enableColumnResize: boolean;
195
+ enableColumnFreeze: boolean;
187
196
  shouldVirtualize: boolean;
188
197
  scrollRef: RefObject<HTMLDivElement | null>;
189
198
  rowVirtualizer: Virtualizer<HTMLDivElement, Element>;
@@ -212,6 +221,12 @@ declare function useCellEdit<T extends Record<string, unknown>>({ data, rows, on
212
221
  cancelEdit: () => void;
213
222
  };
214
223
 
224
+ /** Width styles for header/body cells when column sizing is active. */
225
+ declare function getColumnSizeStyle(size: number, options?: {
226
+ force?: boolean;
227
+ lockMax?: boolean;
228
+ }): CSSProperties | undefined;
229
+
215
230
  type ParsedClipboardTSV = {
216
231
  values: string[][];
217
232
  /**
@@ -327,4 +342,4 @@ declare const useConvertTreeData: <T extends Record<string, unknown>>({ data, en
327
342
  declare function resolveRowSelection(mode: RowSelectionMode, controlledSelection: RowSelectionState | undefined, internalSelection: RowSelectionState): RowSelectionState;
328
343
  declare function applySelectionUpdater(mode: RowSelectionMode, updater: Updater<RowSelectionState>, previous: RowSelectionState): RowSelectionState;
329
344
 
330
- export { CELL_SELECTION_EDGES_CLASS, type CellSelectionBounds, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, RowSelectionMode, type RowSpanInfo, RowsPastePayload, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, applyCellEdit, applyFillData, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectRowSpanColumns, flattenSubtreeRows, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useConvertTreeData, useGlideTable, writeSelectionToClipboard };
345
+ export { CELL_SELECTION_EDGES_CLASS, type CellSelectionBounds, ColumnFreezeOffset, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, RowSelectionMode, type RowSpanInfo, RowsPastePayload, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, applyCellEdit, applyFillData, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectRowSpanColumns, flattenSubtreeRows, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getColumnSizeStyle, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useConvertTreeData, useGlideTable, writeSelectionToClipboard };
package/dist/core.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { C as CellEditType, a as DataTableClassNames, R as RowSelectionMode, d as DataTableProps, c as DataTableLabels, b as DataTableCopyActions, P as PasteMode, f as RowsPastePayload } from './types-Ce4qepIU.js';
2
- export { D as DEFAULT_DATA_TABLE_LABELS, r as resolveDataTableLabels } from './types-Ce4qepIU.js';
1
+ import { n as CellEditType, d as DataTableClassNames, R as RowSelectionMode, b as ColumnFreezeOffset, g as DataTableProps, f as DataTableLabels, e as DataTableCopyActions, P as PasteMode, i as RowsPastePayload } from './types-D031_07N.js';
2
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeMeta, c as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, k as buildColumnFreezeOffsets, l as getColumnFreezeStyle, r as resolveColumnFreezeSide, m as resolveDataTableLabels } from './types-D031_07N.js';
3
3
  import { Row, ColumnDef, Table, Updater, RowSelectionState } from '@tanstack/react-table';
4
- export { ColumnDef, RowSelectionState } from '@tanstack/react-table';
4
+ export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
5
5
  import { Virtualizer, VirtualItem } from '@tanstack/react-virtual';
6
6
  import * as react from 'react';
7
- import { RefObject } from 'react';
7
+ import { RefObject, CSSProperties } from 'react';
8
8
 
9
9
  /** Neutral default field names for tree conversion */
10
10
  declare const DEFAULT_TREE_ID_FIELD = "id";
@@ -170,6 +170,13 @@ type DataTableRowContextValue = {
170
170
  expandRowLabel: string;
171
171
  collapseRowLabel: string;
172
172
  };
173
+ columnResize: {
174
+ enableColumnResize: boolean;
175
+ };
176
+ columnFreeze: {
177
+ enableColumnFreeze: boolean;
178
+ offsets: Map<string, ColumnFreezeOffset>;
179
+ };
173
180
  };
174
181
 
175
182
  type UseGlideTableOptions<T extends Record<string, unknown>> = Omit<DataTableProps<T>, "className" | "classNames" | "slots" | "summary" | "toolbar" | "isPending" | "totalCount" | "filteredCount">;
@@ -184,6 +191,8 @@ type UseGlideTableResult<T extends Record<string, unknown>> = {
184
191
  loadingText: string;
185
192
  selectionLabel: DataTableLabels["selection"];
186
193
  enableCellSelection: boolean;
194
+ enableColumnResize: boolean;
195
+ enableColumnFreeze: boolean;
187
196
  shouldVirtualize: boolean;
188
197
  scrollRef: RefObject<HTMLDivElement | null>;
189
198
  rowVirtualizer: Virtualizer<HTMLDivElement, Element>;
@@ -212,6 +221,12 @@ declare function useCellEdit<T extends Record<string, unknown>>({ data, rows, on
212
221
  cancelEdit: () => void;
213
222
  };
214
223
 
224
+ /** Width styles for header/body cells when column sizing is active. */
225
+ declare function getColumnSizeStyle(size: number, options?: {
226
+ force?: boolean;
227
+ lockMax?: boolean;
228
+ }): CSSProperties | undefined;
229
+
215
230
  type ParsedClipboardTSV = {
216
231
  values: string[][];
217
232
  /**
@@ -327,4 +342,4 @@ declare const useConvertTreeData: <T extends Record<string, unknown>>({ data, en
327
342
  declare function resolveRowSelection(mode: RowSelectionMode, controlledSelection: RowSelectionState | undefined, internalSelection: RowSelectionState): RowSelectionState;
328
343
  declare function applySelectionUpdater(mode: RowSelectionMode, updater: Updater<RowSelectionState>, previous: RowSelectionState): RowSelectionState;
329
344
 
330
- export { CELL_SELECTION_EDGES_CLASS, type CellSelectionBounds, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, RowSelectionMode, type RowSpanInfo, RowsPastePayload, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, applyCellEdit, applyFillData, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectRowSpanColumns, flattenSubtreeRows, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useConvertTreeData, useGlideTable, writeSelectionToClipboard };
345
+ export { CELL_SELECTION_EDGES_CLASS, type CellSelectionBounds, ColumnFreezeOffset, type ColumnRowSpanMap, type CopyRowEntry, type CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DataTableCopyActions, DataTableLabels, DataTableProps, type DragState, type EditingCell, PasteMode, RowSelectionMode, type RowSpanInfo, RowsPastePayload, type TreeRow, type UseConvertTreeDataParams, type UseGlideTableOptions, type UseGlideTableResult, applyCellEdit, applyFillData, applySelectionUpdater, buildColumnRowSpanMap, buildRowsPastePayload, canExpandRow, collectCopyRowEntries, collectCopyRows, collectFillChanges, collectRowSpanColumns, flattenSubtreeRows, getCellEditDraftValue, getCellSelectionEdgeStyle, getColumnEditType, getColumnSizeStyle, getRowIndexInMergedCell, hasCellSelectionEdges, isCellInSelection, isColumnEditable, isEditablePasteTarget, measureMergedSpanRowHeights, parseCellEditValue, parseClipboardTSV, parseClipboardTSVWithDepths, resolvePasteColumnIds, resolveRowSelection, resolveRowSpanAt, rowRangeToHeightRatios, serializeCopyRowsToTSV, serializeSelectionToTSV, toggleExpandedRowId, useCellEdit, useCellSelection, useConvertTreeData, useGlideTable, writeSelectionToClipboard };
package/dist/core.js CHANGED
@@ -4,7 +4,8 @@ var DEFAULT_DATA_TABLE_LABELS = {
4
4
  loading: "Loading...",
5
5
  selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
6
6
  expandRow: "Expand row",
7
- collapseRow: "Collapse row"
7
+ collapseRow: "Collapse row",
8
+ resizeColumn: "Resize column"
8
9
  };
9
10
  function resolveDataTableLabels(partial) {
10
11
  return {
@@ -38,6 +39,9 @@ import {
38
39
  // src/components/ui/table/constants.ts
39
40
  var DATA_TABLE_ROW_HEIGHT = 44;
40
41
  var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
42
+ var DATA_TABLE_COLUMN_SIZE = 150;
43
+ var DATA_TABLE_COLUMN_MIN_SIZE = 40;
44
+ var DATA_TABLE_COLUMN_MAX_SIZE = 800;
41
45
 
42
46
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
43
47
  import { useCallback, useEffect, useRef, useState } from "react";
@@ -928,6 +932,68 @@ function useCellSelection({
928
932
  };
929
933
  }
930
934
 
935
+ // src/components/ui/table/features/column-freeze/columnFreeze.ts
936
+ var HEADER_Z_BASE = 30;
937
+ var BODY_Z_BASE = 5;
938
+ function resolveColumnFreezeSide(frozen) {
939
+ if (frozen === true || frozen === "left") return "left";
940
+ if (frozen === "right") return "right";
941
+ return void 0;
942
+ }
943
+ function buildColumnFreezeOffsets(columns) {
944
+ const result = /* @__PURE__ */ new Map();
945
+ let leftOffset = 0;
946
+ const leftIds = [];
947
+ for (const column of columns) {
948
+ if (column.side !== "left") continue;
949
+ leftIds.push(column.id);
950
+ result.set(column.id, {
951
+ side: "left",
952
+ offset: leftOffset,
953
+ isEdge: false,
954
+ stack: 0
955
+ });
956
+ leftOffset += column.size;
957
+ }
958
+ leftIds.forEach((id, index) => {
959
+ const entry = result.get(id);
960
+ if (!entry) return;
961
+ entry.isEdge = index === leftIds.length - 1;
962
+ entry.stack = leftIds.length - index;
963
+ });
964
+ let rightOffset = 0;
965
+ const rightIds = [];
966
+ for (let index = columns.length - 1; index >= 0; index -= 1) {
967
+ const column = columns[index];
968
+ if (!column || column.side !== "right") continue;
969
+ rightIds.push(column.id);
970
+ result.set(column.id, {
971
+ side: "right",
972
+ offset: rightOffset,
973
+ isEdge: false,
974
+ stack: 0
975
+ });
976
+ rightOffset += column.size;
977
+ }
978
+ rightIds.forEach((id, index) => {
979
+ const entry = result.get(id);
980
+ if (!entry) return;
981
+ entry.isEdge = index === rightIds.length - 1;
982
+ entry.stack = rightIds.length - index;
983
+ });
984
+ return result;
985
+ }
986
+ function getColumnFreezeStyle(offset, options) {
987
+ if (!offset) return void 0;
988
+ const zBase = options?.isHeader ? HEADER_Z_BASE : BODY_Z_BASE;
989
+ return {
990
+ position: "sticky",
991
+ ...offset.side === "left" ? { left: offset.offset } : { right: offset.offset },
992
+ zIndex: zBase + offset.stack,
993
+ ...options?.isHeader ? { top: 0 } : {}
994
+ };
995
+ }
996
+
931
997
  // src/components/ui/table/features/row-expand/row-expand.ts
932
998
  import { useEffect as useEffect3, useMemo, useRef as useRef3 } from "react";
933
999
  function getFieldValue(row, key) {
@@ -1193,6 +1259,7 @@ function collectRowSpanColumns(columns) {
1193
1259
  }
1194
1260
 
1195
1261
  // src/core/useGlideTable.ts
1262
+ var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
1196
1263
  function useGlideTable(options) {
1197
1264
  const {
1198
1265
  data,
@@ -1228,7 +1295,12 @@ function useGlideTable(options) {
1228
1295
  enableInsertPaste,
1229
1296
  enableVirtualization = true,
1230
1297
  estimateRowHeight = DATA_TABLE_ROW_HEIGHT,
1231
- virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN
1298
+ virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN,
1299
+ enableColumnResize = false,
1300
+ columnSizing: controlledColumnSizing,
1301
+ onColumnSizingChange,
1302
+ columnResizeMode = "onChange",
1303
+ enableColumnFreeze = false
1232
1304
  } = options;
1233
1305
  const labels = useMemo2(() => {
1234
1306
  const resolved = resolveDataTableLabels(labelsProp);
@@ -1242,6 +1314,7 @@ function useGlideTable(options) {
1242
1314
  const enableExpand = Boolean(toggleField);
1243
1315
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
1244
1316
  const [internalRowSelection, setInternalRowSelection] = useState3({});
1317
+ const [internalColumnSizing, setInternalColumnSizing] = useState3({});
1245
1318
  const [internalExpandedRows, setInternalExpandedRows] = useState3(
1246
1319
  () => /* @__PURE__ */ new Set()
1247
1320
  );
@@ -1260,6 +1333,7 @@ function useGlideTable(options) {
1260
1333
  controlledRowSelection,
1261
1334
  internalRowSelection
1262
1335
  );
1336
+ const columnSizing = controlledColumnSizing ?? internalColumnSizing;
1263
1337
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
1264
1338
  const handleExpandedRowsChange = useCallback3(
1265
1339
  (next) => {
@@ -1285,9 +1359,27 @@ function useGlideTable(options) {
1285
1359
  const table = useReactTable({
1286
1360
  data: tableData,
1287
1361
  columns,
1362
+ ...enableColumnResize ? {
1363
+ defaultColumn: {
1364
+ minSize: DATA_TABLE_COLUMN_MIN_SIZE,
1365
+ maxSize: DATA_TABLE_COLUMN_MAX_SIZE
1366
+ }
1367
+ } : {},
1368
+ enableColumnResizing: enableColumnResize,
1369
+ columnResizeMode,
1288
1370
  state: {
1289
- rowSelection: rowSelectionMode === "none" ? {} : rowSelection
1371
+ rowSelection: rowSelectionMode === "none" ? {} : rowSelection,
1372
+ ...enableColumnResize ? { columnSizing } : {}
1290
1373
  },
1374
+ onColumnSizingChange: enableColumnResize ? (updater) => {
1375
+ if (onColumnSizingChange) {
1376
+ onColumnSizingChange(updater);
1377
+ return;
1378
+ }
1379
+ setInternalColumnSizing(
1380
+ (previous) => typeof updater === "function" ? updater(previous) : updater
1381
+ );
1382
+ } : void 0,
1291
1383
  enableRowSelection: rowSelectionMode === "none" ? false : getRowCanSelect ? (row) => getRowCanSelect(row.original, row.index) : true,
1292
1384
  enableMultiRowSelection: rowSelectionMode === "multi",
1293
1385
  onRowSelectionChange: (updater) => {
@@ -1318,6 +1410,17 @@ function useGlideTable(options) {
1318
1410
  const selectedCount = selectedRows.length;
1319
1411
  const rows = table.getRowModel().rows;
1320
1412
  const columnCount = table.getAllLeafColumns().length || 1;
1413
+ const visibleLeafColumns = table.getVisibleLeafColumns();
1414
+ const columnFreezeOffsets = useMemo2(() => {
1415
+ if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
1416
+ return buildColumnFreezeOffsets(
1417
+ visibleLeafColumns.map((column) => ({
1418
+ id: column.id,
1419
+ size: column.getSize(),
1420
+ side: resolveColumnFreezeSide(column.columnDef.meta?.frozen)
1421
+ }))
1422
+ );
1423
+ }, [enableColumnFreeze, visibleLeafColumns, columnSizing]);
1321
1424
  const rowVirtualizer = useVirtualizer({
1322
1425
  count: shouldVirtualize ? rows.length : 0,
1323
1426
  getScrollElement: () => scrollRef.current,
@@ -1434,6 +1537,13 @@ function useGlideTable(options) {
1434
1537
  onToggleExpand: handleToggleExpand,
1435
1538
  expandRowLabel: labels.expandRow,
1436
1539
  collapseRowLabel: labels.collapseRow
1540
+ },
1541
+ columnResize: {
1542
+ enableColumnResize
1543
+ },
1544
+ columnFreeze: {
1545
+ enableColumnFreeze,
1546
+ offsets: columnFreezeOffsets
1437
1547
  }
1438
1548
  };
1439
1549
  }, [
@@ -1466,7 +1576,10 @@ function useGlideTable(options) {
1466
1576
  preventExpand,
1467
1577
  handleToggleExpand,
1468
1578
  labels.expandRow,
1469
- labels.collapseRow
1579
+ labels.collapseRow,
1580
+ enableColumnResize,
1581
+ enableColumnFreeze,
1582
+ columnFreezeOffsets
1470
1583
  ]);
1471
1584
  const copySelectionRef = useRef4(copySelection);
1472
1585
  useEffect4(() => {
@@ -1487,6 +1600,8 @@ function useGlideTable(options) {
1487
1600
  loadingText: labels.loading,
1488
1601
  selectionLabel: labels.selection,
1489
1602
  enableCellSelection,
1603
+ enableColumnResize,
1604
+ enableColumnFreeze,
1490
1605
  shouldVirtualize,
1491
1606
  scrollRef,
1492
1607
  rowVirtualizer,
@@ -1499,6 +1614,19 @@ function useGlideTable(options) {
1499
1614
  copySelection: stableCopySelection
1500
1615
  };
1501
1616
  }
1617
+
1618
+ // src/components/ui/table/features/column-resize/columnResize.ts
1619
+ function getColumnSizeStyle(size, options) {
1620
+ const { force = false, lockMax = false } = options ?? {};
1621
+ if (!force && size === DATA_TABLE_COLUMN_SIZE) {
1622
+ return void 0;
1623
+ }
1624
+ return {
1625
+ width: size,
1626
+ minWidth: size,
1627
+ ...lockMax ? { maxWidth: size } : {}
1628
+ };
1629
+ }
1502
1630
  export {
1503
1631
  CELL_SELECTION_EDGES_CLASS,
1504
1632
  DEFAULT_DATA_TABLE_LABELS,
@@ -1509,6 +1637,7 @@ export {
1509
1637
  applyCellEdit,
1510
1638
  applyFillData,
1511
1639
  applySelectionUpdater,
1640
+ buildColumnFreezeOffsets,
1512
1641
  buildColumnRowSpanMap,
1513
1642
  buildRowsPastePayload,
1514
1643
  canExpandRow,
@@ -1520,6 +1649,8 @@ export {
1520
1649
  getCellEditDraftValue,
1521
1650
  getCellSelectionEdgeStyle,
1522
1651
  getColumnEditType,
1652
+ getColumnFreezeStyle,
1653
+ getColumnSizeStyle,
1523
1654
  getRowIndexInMergedCell,
1524
1655
  hasCellSelectionEdges,
1525
1656
  isCellInSelection,
@@ -1529,6 +1660,7 @@ export {
1529
1660
  parseCellEditValue,
1530
1661
  parseClipboardTSV,
1531
1662
  parseClipboardTSVWithDepths,
1663
+ resolveColumnFreezeSide,
1532
1664
  resolveDataTableLabels,
1533
1665
  resolvePasteColumnIds,
1534
1666
  resolveRowSelection,