react-glide-table 1.2.0 → 1.4.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/README.md CHANGED
@@ -69,6 +69,7 @@ export function Products({ data }: { data: Product[] }) {
69
69
  | ---------------------------------------------------- | --------------------------------------------------------------------------------- |
70
70
  | `classNames` | Per-part Tailwind/utility classes (`root`, `scroll`, `row`, `cell`, `toolbar`, …) |
71
71
  | `slots.Toolbar` | Top summary / actions region |
72
+ | `slots.Scroll` | Scroll container (must attach `scrollRef` to the real overflow element) |
72
73
  | `slots.Row` | Full row replacement (cells, selection, edit UI) |
73
74
  | `slots.Pending` / `slots.Empty` | Loading and empty states |
74
75
  | `className` / column `className` / `headerClassName` | Extra class hooks |
@@ -84,6 +85,8 @@ Example: `row: "data-[selected]:bg-blue-600"`.
84
85
 
85
86
  Row-level UI → `slots.Row`. Cell content → `Column.render`. Header/Cell are not separate slots.
86
87
 
88
+ `slots.Scroll` receives `{ scrollRef, className, children }`. Attach `scrollRef` to the element that owns overflow scrolling — virtualization depends on it. Styling-only changes can stay on `classNames.scroll`.
89
+
87
90
  ## Escape hatch (`useGlideTable`)
88
91
 
89
92
  ```tsx
@@ -234,9 +237,12 @@ Opt in with `enableColumnFreeze`. Mark columns with `frozen` — sticky insets a
234
237
  | ---------------------------------- | --------------------------------------- |
235
238
  | `enableColumnFreeze` | Turn on sticky freeze (default `false`) |
236
239
  | `Column.frozen` / `meta.frozen` | `true` / `"left"` or `"right"` |
237
- | `data-frozen` / `data-freeze-edge` | State hooks for custom styling |
240
+ | `data-frozen` | `"left"` / `"right"` on frozen cells |
241
+ | `data-freeze-edge` | `"left"` / `"right"` / `"both"` on island boundaries |
242
+
243
+ Helpers (`/core`): `buildColumnFreezeOffsets`, `getColumnFreezeEdgeAttr`, `getColumnFreezeStyle`, `resolveColumnFreezeSide`.
238
244
 
239
- Helpers (`/core`): `buildColumnFreezeOffsets`, `getColumnFreezeStyle`, `resolveColumnFreezeSide`.
245
+ Contiguous same-side freezes share one island (shadow only on the outer boundary). A gap between frozen columns creates separate islands, so both sides of the gap get an edge shadow.
240
246
 
241
247
  ## Public API
242
248
 
@@ -250,7 +256,7 @@ Helpers (`/core`): `buildColumnFreezeOffsets`, `getColumnFreezeStyle`, `resolveC
250
256
  | `DEFAULT_DATA_TABLE_LABELS` / `resolveDataTableLabels` | `/core` | Optional English UI copy helpers |
251
257
  | Tree field defaults | `/core` | `id` / `parentId` / `children` / `qty` |
252
258
 
253
- Root `react-glide-table` re-exports both surfaces. Related types: `TableProps`, `TableColumnProps`, `DataTableProps`, `DataTableSlots`, `TableCompoundComponent`, `ColumnDef`, `RowsPastePayload`, `PasteMode`, …
259
+ Root `react-glide-table` re-exports both surfaces. Related types: `TableProps`, `TableColumnProps`, `DataTableProps`, `DataTableSlots`, `DataTableScrollSlotProps`, `TableCompoundComponent`, `ColumnDef`, `RowsPastePayload`, `PasteMode`, …
254
260
 
255
261
  ## Notable constraints
256
262
 
package/dist/compound.cjs CHANGED
@@ -396,6 +396,13 @@ function resolveColumnFreezeSide(frozen) {
396
396
  if (frozen === "right") return "right";
397
397
  return void 0;
398
398
  }
399
+ function getColumnFreezeEdgeAttr(offset) {
400
+ if (!offset) return void 0;
401
+ if (offset.edgeLeft && offset.edgeRight) return "both";
402
+ if (offset.edgeLeft) return "left";
403
+ if (offset.edgeRight) return "right";
404
+ return void 0;
405
+ }
399
406
  function buildColumnFreezeOffsets(columns) {
400
407
  const result = /* @__PURE__ */ new Map();
401
408
  let leftOffset = 0;
@@ -407,6 +414,8 @@ function buildColumnFreezeOffsets(columns) {
407
414
  side: "left",
408
415
  offset: leftOffset,
409
416
  isEdge: false,
417
+ edgeLeft: false,
418
+ edgeRight: false,
410
419
  stack: 0
411
420
  });
412
421
  leftOffset += column.size;
@@ -414,7 +423,6 @@ function buildColumnFreezeOffsets(columns) {
414
423
  leftIds.forEach((id, index) => {
415
424
  const entry = result.get(id);
416
425
  if (!entry) return;
417
- entry.isEdge = index === leftIds.length - 1;
418
426
  entry.stack = leftIds.length - index;
419
427
  });
420
428
  let rightOffset = 0;
@@ -427,6 +435,8 @@ function buildColumnFreezeOffsets(columns) {
427
435
  side: "right",
428
436
  offset: rightOffset,
429
437
  isEdge: false,
438
+ edgeLeft: false,
439
+ edgeRight: false,
430
440
  stack: 0
431
441
  });
432
442
  rightOffset += column.size;
@@ -434,9 +444,20 @@ function buildColumnFreezeOffsets(columns) {
434
444
  rightIds.forEach((id, index) => {
435
445
  const entry = result.get(id);
436
446
  if (!entry) return;
437
- entry.isEdge = index === rightIds.length - 1;
438
447
  entry.stack = rightIds.length - index;
439
448
  });
449
+ columns.forEach((column, index) => {
450
+ if (!column.side) return;
451
+ const entry = result.get(column.id);
452
+ if (!entry) return;
453
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
454
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
455
+ entry.edgeLeft = prevSide !== column.side;
456
+ entry.edgeRight = nextSide !== column.side;
457
+ if (index === 0) entry.edgeLeft = false;
458
+ if (index === columns.length - 1) entry.edgeRight = false;
459
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
460
+ });
440
461
  return result;
441
462
  }
442
463
  function getColumnFreezeStyle(offset, options) {
@@ -1117,7 +1138,7 @@ function DataTableRow({
1117
1138
  "data-editable": editable ? "" : void 0,
1118
1139
  "data-editing": isEditing ? "" : void 0,
1119
1140
  "data-frozen": freezeOffset?.side,
1120
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
1141
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
1121
1142
  onMouseDown: (event) => {
1122
1143
  if (isEditing) {
1123
1144
  event.stopPropagation();
@@ -2275,6 +2296,13 @@ function useGlideTable(options) {
2275
2296
 
2276
2297
  // src/components/ui/table/components/DataTable/DataTable.tsx
2277
2298
  var import_jsx_runtime5 = require("react/jsx-runtime");
2299
+ function DefaultScroll({
2300
+ scrollRef,
2301
+ children,
2302
+ className
2303
+ }) {
2304
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
2305
+ }
2278
2306
  function DefaultPending({
2279
2307
  loadingText,
2280
2308
  className,
@@ -2343,6 +2371,7 @@ function DataTable({
2343
2371
  clearHover
2344
2372
  } = useGlideTable(glideOptions);
2345
2373
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
2374
+ const ScrollSlot = slots?.Scroll ?? DefaultScroll;
2346
2375
  const RowSlot = slots?.Row ?? DataTableRow;
2347
2376
  const PendingSlot = slots?.Pending ?? DefaultPending;
2348
2377
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
@@ -2385,7 +2414,7 @@ function DataTable({
2385
2414
  classNames
2386
2415
  }
2387
2416
  ),
2388
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", classNames?.scroll), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2417
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2389
2418
  "table",
2390
2419
  {
2391
2420
  className: cn("data-table", classNames?.table),
@@ -2417,7 +2446,7 @@ function DataTable({
2417
2446
  {
2418
2447
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
2419
2448
  "data-frozen": freezeOffset?.side,
2420
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2449
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2421
2450
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
2422
2451
  className: cn(
2423
2452
  "data-table-head-cell",
@@ -1,14 +1,15 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ReactElement } from 'react';
3
- import { g as DataTableProps, T as TableColumnProps, j as TableProps } from './types-D031_07N.cjs';
4
- export { a as ColumnFreezeMeta, c as ColumnFreezeSide, d as DataTableClassNames, f as DataTableLabels, h as DataTableSlots, P as PasteMode, R as RowSelectionMode, i as RowsPastePayload } from './types-D031_07N.cjs';
3
+ import { h as DataTableProps, T as TableColumnProps, l as TableProps } from './types-CHQnBz91.cjs';
4
+ export { b as ColumnFreezeMeta, d as ColumnFreezeSide, e as DataTableClassNames, g as DataTableLabels, i as DataTableScrollSlotProps, j as DataTableSlots, P as PasteMode, R as RowSelectionMode, k as RowsPastePayload } from './types-CHQnBz91.cjs';
5
5
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
6
6
 
7
7
  /**
8
8
  * Unstyled DataTable shell: semantic HTML + interaction behavior.
9
9
  * Class hooks (`DataTableJSX`, `data-table`, …) are opt-in — no CSS is shipped.
10
10
  * Customize via `className`, `classNames` (Tailwind-friendly part map), column
11
- * `className` / `headerClassName`, `labels`, `summary` / `toolbar`, `Column.render`, and `slots`.
11
+ * `className` / `headerClassName`, `labels`, `summary` / `toolbar`, `Column.render`, and `slots`
12
+ * (`Toolbar`, `Scroll`, `Row`, `Pending`, `Empty`).
12
13
  */
13
14
  declare function DataTable<T extends Record<string, unknown>>({ isPending, summary, toolbar, filteredCount, totalCount, className, classNames, slots, ...glideOptions }: DataTableProps<T>): react.JSX.Element;
14
15
 
@@ -1,14 +1,15 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ReactElement } from 'react';
3
- import { g as DataTableProps, T as TableColumnProps, j as TableProps } from './types-D031_07N.js';
4
- export { a as ColumnFreezeMeta, c as ColumnFreezeSide, d as DataTableClassNames, f as DataTableLabels, h as DataTableSlots, P as PasteMode, R as RowSelectionMode, i as RowsPastePayload } from './types-D031_07N.js';
3
+ import { h as DataTableProps, T as TableColumnProps, l as TableProps } from './types-CHQnBz91.js';
4
+ export { b as ColumnFreezeMeta, d as ColumnFreezeSide, e as DataTableClassNames, g as DataTableLabels, i as DataTableScrollSlotProps, j as DataTableSlots, P as PasteMode, R as RowSelectionMode, k as RowsPastePayload } from './types-CHQnBz91.js';
5
5
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
6
6
 
7
7
  /**
8
8
  * Unstyled DataTable shell: semantic HTML + interaction behavior.
9
9
  * Class hooks (`DataTableJSX`, `data-table`, …) are opt-in — no CSS is shipped.
10
10
  * Customize via `className`, `classNames` (Tailwind-friendly part map), column
11
- * `className` / `headerClassName`, `labels`, `summary` / `toolbar`, `Column.render`, and `slots`.
11
+ * `className` / `headerClassName`, `labels`, `summary` / `toolbar`, `Column.render`, and `slots`
12
+ * (`Toolbar`, `Scroll`, `Row`, `Pending`, `Empty`).
12
13
  */
13
14
  declare function DataTable<T extends Record<string, unknown>>({ isPending, summary, toolbar, filteredCount, totalCount, className, classNames, slots, ...glideOptions }: DataTableProps<T>): react.JSX.Element;
14
15
 
package/dist/compound.js CHANGED
@@ -368,6 +368,13 @@ function resolveColumnFreezeSide(frozen) {
368
368
  if (frozen === "right") return "right";
369
369
  return void 0;
370
370
  }
371
+ function getColumnFreezeEdgeAttr(offset) {
372
+ if (!offset) return void 0;
373
+ if (offset.edgeLeft && offset.edgeRight) return "both";
374
+ if (offset.edgeLeft) return "left";
375
+ if (offset.edgeRight) return "right";
376
+ return void 0;
377
+ }
371
378
  function buildColumnFreezeOffsets(columns) {
372
379
  const result = /* @__PURE__ */ new Map();
373
380
  let leftOffset = 0;
@@ -379,6 +386,8 @@ function buildColumnFreezeOffsets(columns) {
379
386
  side: "left",
380
387
  offset: leftOffset,
381
388
  isEdge: false,
389
+ edgeLeft: false,
390
+ edgeRight: false,
382
391
  stack: 0
383
392
  });
384
393
  leftOffset += column.size;
@@ -386,7 +395,6 @@ function buildColumnFreezeOffsets(columns) {
386
395
  leftIds.forEach((id, index) => {
387
396
  const entry = result.get(id);
388
397
  if (!entry) return;
389
- entry.isEdge = index === leftIds.length - 1;
390
398
  entry.stack = leftIds.length - index;
391
399
  });
392
400
  let rightOffset = 0;
@@ -399,6 +407,8 @@ function buildColumnFreezeOffsets(columns) {
399
407
  side: "right",
400
408
  offset: rightOffset,
401
409
  isEdge: false,
410
+ edgeLeft: false,
411
+ edgeRight: false,
402
412
  stack: 0
403
413
  });
404
414
  rightOffset += column.size;
@@ -406,9 +416,20 @@ function buildColumnFreezeOffsets(columns) {
406
416
  rightIds.forEach((id, index) => {
407
417
  const entry = result.get(id);
408
418
  if (!entry) return;
409
- entry.isEdge = index === rightIds.length - 1;
410
419
  entry.stack = rightIds.length - index;
411
420
  });
421
+ columns.forEach((column, index) => {
422
+ if (!column.side) return;
423
+ const entry = result.get(column.id);
424
+ if (!entry) return;
425
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
426
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
427
+ entry.edgeLeft = prevSide !== column.side;
428
+ entry.edgeRight = nextSide !== column.side;
429
+ if (index === 0) entry.edgeLeft = false;
430
+ if (index === columns.length - 1) entry.edgeRight = false;
431
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
432
+ });
412
433
  return result;
413
434
  }
414
435
  function getColumnFreezeStyle(offset, options) {
@@ -1089,7 +1110,7 @@ function DataTableRow({
1089
1110
  "data-editable": editable ? "" : void 0,
1090
1111
  "data-editing": isEditing ? "" : void 0,
1091
1112
  "data-frozen": freezeOffset?.side,
1092
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
1113
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
1093
1114
  onMouseDown: (event) => {
1094
1115
  if (isEditing) {
1095
1116
  event.stopPropagation();
@@ -2258,6 +2279,13 @@ function useGlideTable(options) {
2258
2279
 
2259
2280
  // src/components/ui/table/components/DataTable/DataTable.tsx
2260
2281
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2282
+ function DefaultScroll({
2283
+ scrollRef,
2284
+ children,
2285
+ className
2286
+ }) {
2287
+ return /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
2288
+ }
2261
2289
  function DefaultPending({
2262
2290
  loadingText,
2263
2291
  className,
@@ -2326,6 +2354,7 @@ function DataTable({
2326
2354
  clearHover
2327
2355
  } = useGlideTable(glideOptions);
2328
2356
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
2357
+ const ScrollSlot = slots?.Scroll ?? DefaultScroll;
2329
2358
  const RowSlot = slots?.Row ?? DataTableRow;
2330
2359
  const PendingSlot = slots?.Pending ?? DefaultPending;
2331
2360
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
@@ -2368,7 +2397,7 @@ function DataTable({
2368
2397
  classNames
2369
2398
  }
2370
2399
  ),
2371
- /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: cn("data-table-scroll", classNames?.scroll), children: /* @__PURE__ */ jsxs4(
2400
+ /* @__PURE__ */ jsx5(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ jsxs4(
2372
2401
  "table",
2373
2402
  {
2374
2403
  className: cn("data-table", classNames?.table),
@@ -2400,7 +2429,7 @@ function DataTable({
2400
2429
  {
2401
2430
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
2402
2431
  "data-frozen": freezeOffset?.side,
2403
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2432
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2404
2433
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
2405
2434
  className: cn(
2406
2435
  "data-table-head-cell",
package/dist/core.cjs CHANGED
@@ -41,6 +41,7 @@ __export(core_exports, {
41
41
  getCellEditDraftValue: () => getCellEditDraftValue,
42
42
  getCellSelectionEdgeStyle: () => getCellSelectionEdgeStyle,
43
43
  getColumnEditType: () => getColumnEditType,
44
+ getColumnFreezeEdgeAttr: () => getColumnFreezeEdgeAttr,
44
45
  getColumnFreezeStyle: () => getColumnFreezeStyle,
45
46
  getColumnSizeStyle: () => getColumnSizeStyle,
46
47
  getRowIndexInMergedCell: () => getRowIndexInMergedCell,
@@ -1000,6 +1001,13 @@ function resolveColumnFreezeSide(frozen) {
1000
1001
  if (frozen === "right") return "right";
1001
1002
  return void 0;
1002
1003
  }
1004
+ function getColumnFreezeEdgeAttr(offset) {
1005
+ if (!offset) return void 0;
1006
+ if (offset.edgeLeft && offset.edgeRight) return "both";
1007
+ if (offset.edgeLeft) return "left";
1008
+ if (offset.edgeRight) return "right";
1009
+ return void 0;
1010
+ }
1003
1011
  function buildColumnFreezeOffsets(columns) {
1004
1012
  const result = /* @__PURE__ */ new Map();
1005
1013
  let leftOffset = 0;
@@ -1011,6 +1019,8 @@ function buildColumnFreezeOffsets(columns) {
1011
1019
  side: "left",
1012
1020
  offset: leftOffset,
1013
1021
  isEdge: false,
1022
+ edgeLeft: false,
1023
+ edgeRight: false,
1014
1024
  stack: 0
1015
1025
  });
1016
1026
  leftOffset += column.size;
@@ -1018,7 +1028,6 @@ function buildColumnFreezeOffsets(columns) {
1018
1028
  leftIds.forEach((id, index) => {
1019
1029
  const entry = result.get(id);
1020
1030
  if (!entry) return;
1021
- entry.isEdge = index === leftIds.length - 1;
1022
1031
  entry.stack = leftIds.length - index;
1023
1032
  });
1024
1033
  let rightOffset = 0;
@@ -1031,6 +1040,8 @@ function buildColumnFreezeOffsets(columns) {
1031
1040
  side: "right",
1032
1041
  offset: rightOffset,
1033
1042
  isEdge: false,
1043
+ edgeLeft: false,
1044
+ edgeRight: false,
1034
1045
  stack: 0
1035
1046
  });
1036
1047
  rightOffset += column.size;
@@ -1038,9 +1049,20 @@ function buildColumnFreezeOffsets(columns) {
1038
1049
  rightIds.forEach((id, index) => {
1039
1050
  const entry = result.get(id);
1040
1051
  if (!entry) return;
1041
- entry.isEdge = index === rightIds.length - 1;
1042
1052
  entry.stack = rightIds.length - index;
1043
1053
  });
1054
+ columns.forEach((column, index) => {
1055
+ if (!column.side) return;
1056
+ const entry = result.get(column.id);
1057
+ if (!entry) return;
1058
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
1059
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
1060
+ entry.edgeLeft = prevSide !== column.side;
1061
+ entry.edgeRight = nextSide !== column.side;
1062
+ if (index === 0) entry.edgeLeft = false;
1063
+ if (index === columns.length - 1) entry.edgeRight = false;
1064
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
1065
+ });
1044
1066
  return result;
1045
1067
  }
1046
1068
  function getColumnFreezeStyle(offset, options) {
@@ -1710,6 +1732,7 @@ function getColumnSizeStyle(size, options) {
1710
1732
  getCellEditDraftValue,
1711
1733
  getCellSelectionEdgeStyle,
1712
1734
  getColumnEditType,
1735
+ getColumnFreezeEdgeAttr,
1713
1736
  getColumnFreezeStyle,
1714
1737
  getColumnSizeStyle,
1715
1738
  getRowIndexInMergedCell,
package/dist/core.d.cts CHANGED
@@ -1,5 +1,5 @@
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';
1
+ import { q as CellEditType, e as DataTableClassNames, R as RowSelectionMode, c as ColumnFreezeOffset, h as DataTableProps, g as DataTableLabels, f as DataTableCopyActions, P as PasteMode, k as RowsPastePayload } from './types-CHQnBz91.cjs';
2
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeEdgeSide, b as ColumnFreezeMeta, d as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, m as buildColumnFreezeOffsets, n as getColumnFreezeEdgeAttr, o as getColumnFreezeStyle, r as resolveColumnFreezeSide, p as resolveDataTableLabels } from './types-CHQnBz91.cjs';
3
3
  import { Row, ColumnDef, Table, Updater, RowSelectionState } from '@tanstack/react-table';
4
4
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
5
5
  import { Virtualizer, VirtualItem } from '@tanstack/react-virtual';
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
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';
1
+ import { q as CellEditType, e as DataTableClassNames, R as RowSelectionMode, c as ColumnFreezeOffset, h as DataTableProps, g as DataTableLabels, f as DataTableCopyActions, P as PasteMode, k as RowsPastePayload } from './types-CHQnBz91.js';
2
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeEdgeSide, b as ColumnFreezeMeta, d as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, m as buildColumnFreezeOffsets, n as getColumnFreezeEdgeAttr, o as getColumnFreezeStyle, r as resolveColumnFreezeSide, p as resolveDataTableLabels } from './types-CHQnBz91.js';
3
3
  import { Row, ColumnDef, Table, Updater, RowSelectionState } from '@tanstack/react-table';
4
4
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
5
5
  import { Virtualizer, VirtualItem } from '@tanstack/react-virtual';
package/dist/core.js CHANGED
@@ -940,6 +940,13 @@ function resolveColumnFreezeSide(frozen) {
940
940
  if (frozen === "right") return "right";
941
941
  return void 0;
942
942
  }
943
+ function getColumnFreezeEdgeAttr(offset) {
944
+ if (!offset) return void 0;
945
+ if (offset.edgeLeft && offset.edgeRight) return "both";
946
+ if (offset.edgeLeft) return "left";
947
+ if (offset.edgeRight) return "right";
948
+ return void 0;
949
+ }
943
950
  function buildColumnFreezeOffsets(columns) {
944
951
  const result = /* @__PURE__ */ new Map();
945
952
  let leftOffset = 0;
@@ -951,6 +958,8 @@ function buildColumnFreezeOffsets(columns) {
951
958
  side: "left",
952
959
  offset: leftOffset,
953
960
  isEdge: false,
961
+ edgeLeft: false,
962
+ edgeRight: false,
954
963
  stack: 0
955
964
  });
956
965
  leftOffset += column.size;
@@ -958,7 +967,6 @@ function buildColumnFreezeOffsets(columns) {
958
967
  leftIds.forEach((id, index) => {
959
968
  const entry = result.get(id);
960
969
  if (!entry) return;
961
- entry.isEdge = index === leftIds.length - 1;
962
970
  entry.stack = leftIds.length - index;
963
971
  });
964
972
  let rightOffset = 0;
@@ -971,6 +979,8 @@ function buildColumnFreezeOffsets(columns) {
971
979
  side: "right",
972
980
  offset: rightOffset,
973
981
  isEdge: false,
982
+ edgeLeft: false,
983
+ edgeRight: false,
974
984
  stack: 0
975
985
  });
976
986
  rightOffset += column.size;
@@ -978,9 +988,20 @@ function buildColumnFreezeOffsets(columns) {
978
988
  rightIds.forEach((id, index) => {
979
989
  const entry = result.get(id);
980
990
  if (!entry) return;
981
- entry.isEdge = index === rightIds.length - 1;
982
991
  entry.stack = rightIds.length - index;
983
992
  });
993
+ columns.forEach((column, index) => {
994
+ if (!column.side) return;
995
+ const entry = result.get(column.id);
996
+ if (!entry) return;
997
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
998
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
999
+ entry.edgeLeft = prevSide !== column.side;
1000
+ entry.edgeRight = nextSide !== column.side;
1001
+ if (index === 0) entry.edgeLeft = false;
1002
+ if (index === columns.length - 1) entry.edgeRight = false;
1003
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
1004
+ });
984
1005
  return result;
985
1006
  }
986
1007
  function getColumnFreezeStyle(offset, options) {
@@ -1649,6 +1670,7 @@ export {
1649
1670
  getCellEditDraftValue,
1650
1671
  getCellSelectionEdgeStyle,
1651
1672
  getColumnEditType,
1673
+ getColumnFreezeEdgeAttr,
1652
1674
  getColumnFreezeStyle,
1653
1675
  getColumnSizeStyle,
1654
1676
  getRowIndexInMergedCell,
package/dist/index.cjs CHANGED
@@ -44,6 +44,7 @@ __export(src_exports, {
44
44
  getCellEditDraftValue: () => getCellEditDraftValue,
45
45
  getCellSelectionEdgeStyle: () => getCellSelectionEdgeStyle,
46
46
  getColumnEditType: () => getColumnEditType,
47
+ getColumnFreezeEdgeAttr: () => getColumnFreezeEdgeAttr,
47
48
  getColumnFreezeStyle: () => getColumnFreezeStyle,
48
49
  getColumnSizeStyle: () => getColumnSizeStyle,
49
50
  getRowIndexInMergedCell: () => getRowIndexInMergedCell,
@@ -1011,6 +1012,13 @@ function resolveColumnFreezeSide(frozen) {
1011
1012
  if (frozen === "right") return "right";
1012
1013
  return void 0;
1013
1014
  }
1015
+ function getColumnFreezeEdgeAttr(offset) {
1016
+ if (!offset) return void 0;
1017
+ if (offset.edgeLeft && offset.edgeRight) return "both";
1018
+ if (offset.edgeLeft) return "left";
1019
+ if (offset.edgeRight) return "right";
1020
+ return void 0;
1021
+ }
1014
1022
  function buildColumnFreezeOffsets(columns) {
1015
1023
  const result = /* @__PURE__ */ new Map();
1016
1024
  let leftOffset = 0;
@@ -1022,6 +1030,8 @@ function buildColumnFreezeOffsets(columns) {
1022
1030
  side: "left",
1023
1031
  offset: leftOffset,
1024
1032
  isEdge: false,
1033
+ edgeLeft: false,
1034
+ edgeRight: false,
1025
1035
  stack: 0
1026
1036
  });
1027
1037
  leftOffset += column.size;
@@ -1029,7 +1039,6 @@ function buildColumnFreezeOffsets(columns) {
1029
1039
  leftIds.forEach((id, index) => {
1030
1040
  const entry = result.get(id);
1031
1041
  if (!entry) return;
1032
- entry.isEdge = index === leftIds.length - 1;
1033
1042
  entry.stack = leftIds.length - index;
1034
1043
  });
1035
1044
  let rightOffset = 0;
@@ -1042,6 +1051,8 @@ function buildColumnFreezeOffsets(columns) {
1042
1051
  side: "right",
1043
1052
  offset: rightOffset,
1044
1053
  isEdge: false,
1054
+ edgeLeft: false,
1055
+ edgeRight: false,
1045
1056
  stack: 0
1046
1057
  });
1047
1058
  rightOffset += column.size;
@@ -1049,9 +1060,20 @@ function buildColumnFreezeOffsets(columns) {
1049
1060
  rightIds.forEach((id, index) => {
1050
1061
  const entry = result.get(id);
1051
1062
  if (!entry) return;
1052
- entry.isEdge = index === rightIds.length - 1;
1053
1063
  entry.stack = rightIds.length - index;
1054
1064
  });
1065
+ columns.forEach((column, index) => {
1066
+ if (!column.side) return;
1067
+ const entry = result.get(column.id);
1068
+ if (!entry) return;
1069
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
1070
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
1071
+ entry.edgeLeft = prevSide !== column.side;
1072
+ entry.edgeRight = nextSide !== column.side;
1073
+ if (index === 0) entry.edgeLeft = false;
1074
+ if (index === columns.length - 1) entry.edgeRight = false;
1075
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
1076
+ });
1055
1077
  return result;
1056
1078
  }
1057
1079
  function getColumnFreezeStyle(offset, options) {
@@ -2122,7 +2144,7 @@ function DataTableRow({
2122
2144
  "data-editable": editable ? "" : void 0,
2123
2145
  "data-editing": isEditing ? "" : void 0,
2124
2146
  "data-frozen": freezeOffset?.side,
2125
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2147
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2126
2148
  onMouseDown: (event) => {
2127
2149
  if (isEditing) {
2128
2150
  event.stopPropagation();
@@ -2343,6 +2365,13 @@ function DataTableToolbar({
2343
2365
 
2344
2366
  // src/components/ui/table/components/DataTable/DataTable.tsx
2345
2367
  var import_jsx_runtime5 = require("react/jsx-runtime");
2368
+ function DefaultScroll({
2369
+ scrollRef,
2370
+ children,
2371
+ className
2372
+ }) {
2373
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
2374
+ }
2346
2375
  function DefaultPending({
2347
2376
  loadingText,
2348
2377
  className,
@@ -2411,6 +2440,7 @@ function DataTable({
2411
2440
  clearHover
2412
2441
  } = useGlideTable(glideOptions);
2413
2442
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
2443
+ const ScrollSlot = slots?.Scroll ?? DefaultScroll;
2414
2444
  const RowSlot = slots?.Row ?? DataTableRow;
2415
2445
  const PendingSlot = slots?.Pending ?? DefaultPending;
2416
2446
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
@@ -2453,7 +2483,7 @@ function DataTable({
2453
2483
  classNames
2454
2484
  }
2455
2485
  ),
2456
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", classNames?.scroll), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2486
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
2457
2487
  "table",
2458
2488
  {
2459
2489
  className: cn("data-table", classNames?.table),
@@ -2485,7 +2515,7 @@ function DataTable({
2485
2515
  {
2486
2516
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
2487
2517
  "data-frozen": freezeOffset?.side,
2488
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2518
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2489
2519
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
2490
2520
  className: cn(
2491
2521
  "data-table-head-cell",
@@ -2972,6 +3002,7 @@ var Table = Object.assign(TableRoot, {
2972
3002
  getCellEditDraftValue,
2973
3003
  getCellSelectionEdgeStyle,
2974
3004
  getColumnEditType,
3005
+ getColumnFreezeEdgeAttr,
2975
3006
  getColumnFreezeStyle,
2976
3007
  getColumnSizeStyle,
2977
3008
  getRowIndexInMergedCell,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as ColumnFreezeColumnInput, a as ColumnFreezeMeta, b as ColumnFreezeOffset, c as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, d as DataTableClassNames, e as DataTableCopyActions, f as DataTableLabels, g as DataTableProps, h as DataTableSlots, P as PasteMode, R as RowSelectionMode, i as RowsPastePayload, T as TableColumnProps, j as TableProps, k as buildColumnFreezeOffsets, l as getColumnFreezeStyle, r as resolveColumnFreezeSide, m as resolveDataTableLabels } from './types-D031_07N.cjs';
1
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeEdgeSide, b as ColumnFreezeMeta, c as ColumnFreezeOffset, d as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, e as DataTableClassNames, f as DataTableCopyActions, g as DataTableLabels, h as DataTableProps, i as DataTableScrollSlotProps, j as DataTableSlots, P as PasteMode, R as RowSelectionMode, k as RowsPastePayload, T as TableColumnProps, l as TableProps, m as buildColumnFreezeOffsets, n as getColumnFreezeEdgeAttr, o as getColumnFreezeStyle, r as resolveColumnFreezeSide, p as resolveDataTableLabels } from './types-CHQnBz91.cjs';
2
2
  export { CELL_SELECTION_EDGES_CLASS, CellSelectionBounds, ColumnRowSpanMap, CopyRowEntry, CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DragState, EditingCell, RowSpanInfo, TreeRow, UseConvertTreeDataParams, UseGlideTableOptions, 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 } from './core.cjs';
3
3
  export { DataTable, Table, TableCompoundComponent, createTable } from './compound.cjs';
4
4
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as ColumnFreezeColumnInput, a as ColumnFreezeMeta, b as ColumnFreezeOffset, c as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, d as DataTableClassNames, e as DataTableCopyActions, f as DataTableLabels, g as DataTableProps, h as DataTableSlots, P as PasteMode, R as RowSelectionMode, i as RowsPastePayload, T as TableColumnProps, j as TableProps, k as buildColumnFreezeOffsets, l as getColumnFreezeStyle, r as resolveColumnFreezeSide, m as resolveDataTableLabels } from './types-D031_07N.js';
1
+ export { C as ColumnFreezeColumnInput, a as ColumnFreezeEdgeSide, b as ColumnFreezeMeta, c as ColumnFreezeOffset, d as ColumnFreezeSide, D as DEFAULT_DATA_TABLE_LABELS, e as DataTableClassNames, f as DataTableCopyActions, g as DataTableLabels, h as DataTableProps, i as DataTableScrollSlotProps, j as DataTableSlots, P as PasteMode, R as RowSelectionMode, k as RowsPastePayload, T as TableColumnProps, l as TableProps, m as buildColumnFreezeOffsets, n as getColumnFreezeEdgeAttr, o as getColumnFreezeStyle, r as resolveColumnFreezeSide, p as resolveDataTableLabels } from './types-CHQnBz91.js';
2
2
  export { CELL_SELECTION_EDGES_CLASS, CellSelectionBounds, ColumnRowSpanMap, CopyRowEntry, CopySelectionMode, DEFAULT_TREE_CHILDREN_FIELD, DEFAULT_TREE_ID_FIELD, DEFAULT_TREE_PARENT_ID_FIELD, DEFAULT_TREE_QTY_FIELD, DragState, EditingCell, RowSpanInfo, TreeRow, UseConvertTreeDataParams, UseGlideTableOptions, 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 } from './core.js';
3
3
  export { DataTable, Table, TableCompoundComponent, createTable } from './compound.js';
4
4
  export { ColumnDef, ColumnResizeMode, ColumnSizingState, RowSelectionState } from '@tanstack/react-table';
package/dist/index.js CHANGED
@@ -948,6 +948,13 @@ function resolveColumnFreezeSide(frozen) {
948
948
  if (frozen === "right") return "right";
949
949
  return void 0;
950
950
  }
951
+ function getColumnFreezeEdgeAttr(offset) {
952
+ if (!offset) return void 0;
953
+ if (offset.edgeLeft && offset.edgeRight) return "both";
954
+ if (offset.edgeLeft) return "left";
955
+ if (offset.edgeRight) return "right";
956
+ return void 0;
957
+ }
951
958
  function buildColumnFreezeOffsets(columns) {
952
959
  const result = /* @__PURE__ */ new Map();
953
960
  let leftOffset = 0;
@@ -959,6 +966,8 @@ function buildColumnFreezeOffsets(columns) {
959
966
  side: "left",
960
967
  offset: leftOffset,
961
968
  isEdge: false,
969
+ edgeLeft: false,
970
+ edgeRight: false,
962
971
  stack: 0
963
972
  });
964
973
  leftOffset += column.size;
@@ -966,7 +975,6 @@ function buildColumnFreezeOffsets(columns) {
966
975
  leftIds.forEach((id, index) => {
967
976
  const entry = result.get(id);
968
977
  if (!entry) return;
969
- entry.isEdge = index === leftIds.length - 1;
970
978
  entry.stack = leftIds.length - index;
971
979
  });
972
980
  let rightOffset = 0;
@@ -979,6 +987,8 @@ function buildColumnFreezeOffsets(columns) {
979
987
  side: "right",
980
988
  offset: rightOffset,
981
989
  isEdge: false,
990
+ edgeLeft: false,
991
+ edgeRight: false,
982
992
  stack: 0
983
993
  });
984
994
  rightOffset += column.size;
@@ -986,9 +996,20 @@ function buildColumnFreezeOffsets(columns) {
986
996
  rightIds.forEach((id, index) => {
987
997
  const entry = result.get(id);
988
998
  if (!entry) return;
989
- entry.isEdge = index === rightIds.length - 1;
990
999
  entry.stack = rightIds.length - index;
991
1000
  });
1001
+ columns.forEach((column, index) => {
1002
+ if (!column.side) return;
1003
+ const entry = result.get(column.id);
1004
+ if (!entry) return;
1005
+ const prevSide = index > 0 ? columns[index - 1]?.side : void 0;
1006
+ const nextSide = index < columns.length - 1 ? columns[index + 1]?.side : void 0;
1007
+ entry.edgeLeft = prevSide !== column.side;
1008
+ entry.edgeRight = nextSide !== column.side;
1009
+ if (index === 0) entry.edgeLeft = false;
1010
+ if (index === columns.length - 1) entry.edgeRight = false;
1011
+ entry.isEdge = entry.edgeLeft || entry.edgeRight;
1012
+ });
992
1013
  return result;
993
1014
  }
994
1015
  function getColumnFreezeStyle(offset, options) {
@@ -2059,7 +2080,7 @@ function DataTableRow({
2059
2080
  "data-editable": editable ? "" : void 0,
2060
2081
  "data-editing": isEditing ? "" : void 0,
2061
2082
  "data-frozen": freezeOffset?.side,
2062
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2083
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2063
2084
  onMouseDown: (event) => {
2064
2085
  if (isEditing) {
2065
2086
  event.stopPropagation();
@@ -2280,6 +2301,13 @@ function DataTableToolbar({
2280
2301
 
2281
2302
  // src/components/ui/table/components/DataTable/DataTable.tsx
2282
2303
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2304
+ function DefaultScroll({
2305
+ scrollRef,
2306
+ children,
2307
+ className
2308
+ }) {
2309
+ return /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
2310
+ }
2283
2311
  function DefaultPending({
2284
2312
  loadingText,
2285
2313
  className,
@@ -2348,6 +2376,7 @@ function DataTable({
2348
2376
  clearHover
2349
2377
  } = useGlideTable(glideOptions);
2350
2378
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
2379
+ const ScrollSlot = slots?.Scroll ?? DefaultScroll;
2351
2380
  const RowSlot = slots?.Row ?? DataTableRow;
2352
2381
  const PendingSlot = slots?.Pending ?? DefaultPending;
2353
2382
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
@@ -2390,7 +2419,7 @@ function DataTable({
2390
2419
  classNames
2391
2420
  }
2392
2421
  ),
2393
- /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: cn("data-table-scroll", classNames?.scroll), children: /* @__PURE__ */ jsxs4(
2422
+ /* @__PURE__ */ jsx5(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ jsxs4(
2394
2423
  "table",
2395
2424
  {
2396
2425
  className: cn("data-table", classNames?.table),
@@ -2422,7 +2451,7 @@ function DataTable({
2422
2451
  {
2423
2452
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
2424
2453
  "data-frozen": freezeOffset?.side,
2425
- "data-freeze-edge": freezeOffset?.isEdge ? "" : void 0,
2454
+ "data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
2426
2455
  style: Object.keys(headerStyle).length > 0 ? headerStyle : void 0,
2427
2456
  className: cn(
2428
2457
  "data-table-head-cell",
@@ -2908,6 +2937,7 @@ export {
2908
2937
  getCellEditDraftValue,
2909
2938
  getCellSelectionEdgeStyle,
2910
2939
  getColumnEditType,
2940
+ getColumnFreezeEdgeAttr,
2911
2941
  getColumnFreezeStyle,
2912
2942
  getColumnSizeStyle,
2913
2943
  getRowIndexInMergedCell,
@@ -1,5 +1,5 @@
1
1
  import { ColumnDef, RowSelectionState, Updater, ColumnSizingState, OnChangeFn, ColumnResizeMode, Row } from '@tanstack/react-table';
2
- import { CSSProperties, ReactNode, InputHTMLAttributes, ComponentType } from 'react';
2
+ import { CSSProperties, ReactNode, InputHTMLAttributes, ComponentType, Ref } from 'react';
3
3
 
4
4
  /** Sticky edge for a frozen column. Does not reorder columns. */
5
5
  type ColumnFreezeSide = "left" | "right";
@@ -13,24 +13,34 @@ type ColumnFreezeColumnInput = {
13
13
  size: number;
14
14
  side?: ColumnFreezeSide;
15
15
  };
16
+ /** Which outer sides of a freeze island get a divider shadow. */
17
+ type ColumnFreezeEdgeSide = "left" | "right" | "both";
16
18
  type ColumnFreezeOffset = {
17
19
  side: ColumnFreezeSide;
18
20
  /** Cumulative sticky inset (`left` or `right` in px). */
19
21
  offset: number;
20
- /** Inner edge of the sticky group (shadow / divider). */
22
+ /** True when this cell is on an island boundary (any side). */
21
23
  isEdge: boolean;
24
+ /** Shadow toward the previous column (scrollable / other island). */
25
+ edgeLeft: boolean;
26
+ /** Shadow toward the next column (scrollable / other island). */
27
+ edgeRight: boolean;
22
28
  /** Relative stack order within the freeze side (higher = closer to the viewport edge). */
23
29
  stack: number;
24
30
  };
25
31
  /** Normalize column `frozen` meta into a sticky side. */
26
32
  declare function resolveColumnFreezeSide(frozen?: ColumnFreezeMeta): ColumnFreezeSide | undefined;
33
+ /** Serialize freeze-edge flags for `data-freeze-edge`. */
34
+ declare function getColumnFreezeEdgeAttr(offset: Pick<ColumnFreezeOffset, "edgeLeft" | "edgeRight"> | undefined): ColumnFreezeEdgeSide | undefined;
27
35
  /**
28
36
  * Build sticky insets for frozen columns without changing DOM/column order.
29
37
  *
30
38
  * - `left`: `left = Σ(widths of left-frozen columns before this one)`
31
39
  * - `right`: `right = Σ(widths of right-frozen columns after this one)`
32
40
  *
33
- * Middle columns may be frozen; non-frozen neighbors scroll underneath.
41
+ * Contiguous same-side freezes form one island only the outer boundaries
42
+ * get edge shadows. Gaps between same-side freezes create separate islands,
43
+ * so both sides of the gap receive a shadow.
34
44
  */
35
45
  declare function buildColumnFreezeOffsets(columns: ColumnFreezeColumnInput[]): Map<string, ColumnFreezeOffset>;
36
46
  /** Sticky position styles for a frozen header or body cell. */
@@ -302,6 +312,17 @@ type DataTableRowSlotProps<T extends Record<string, unknown>> = {
302
312
  virtualIndex?: number;
303
313
  measureElement?: (node: Element | null) => void;
304
314
  };
315
+ /**
316
+ * Scroll-region slot props for the semantic DataTable shell.
317
+ *
318
+ * `scrollRef` must be attached to the element that actually owns overflow
319
+ * scrolling — row virtualization reads it via `getScrollElement`.
320
+ */
321
+ type DataTableScrollSlotProps = {
322
+ children: ReactNode;
323
+ className?: string;
324
+ scrollRef: Ref<HTMLDivElement | null>;
325
+ };
305
326
  /**
306
327
  * Slot replacements for the default DataTable shell (semantic HTML + behavior only).
307
328
  * Row-level custom UI → `Row`; cell content → `Table.Column` / column `render`.
@@ -310,6 +331,11 @@ type DataTableRowSlotProps<T extends Record<string, unknown>> = {
310
331
  type DataTableSlots<T extends Record<string, unknown>> = {
311
332
  /** Top summary / actions region */
312
333
  Toolbar?: ComponentType<DataTableToolbarSlotProps>;
334
+ /**
335
+ * Table scroll container. Must forward `scrollRef` to the real scroll element
336
+ * (required for virtualization).
337
+ */
338
+ Scroll?: ComponentType<DataTableScrollSlotProps>;
313
339
  /** Full row replacement (cells, selection, edit UI) */
314
340
  Row?: ComponentType<DataTableRowSlotProps<T>>;
315
341
  /** Replace the pending state view */
@@ -364,4 +390,4 @@ type TableProps<T extends Record<string, unknown>> = Omit<DataTableProps<T>, "co
364
390
  children: ReactNode;
365
391
  };
366
392
 
367
- export { type ColumnFreezeColumnInput as C, DEFAULT_DATA_TABLE_LABELS as D, type PasteMode as P, type RowSelectionMode as R, type TableColumnProps as T, type ColumnFreezeMeta as a, type ColumnFreezeOffset as b, type ColumnFreezeSide as c, type DataTableClassNames as d, type DataTableCopyActions as e, type DataTableLabels as f, type DataTableProps as g, type DataTableSlots as h, type RowsPastePayload as i, type TableProps as j, buildColumnFreezeOffsets as k, getColumnFreezeStyle as l, resolveDataTableLabels as m, type CellEditType as n, resolveColumnFreezeSide as r };
393
+ export { type ColumnFreezeColumnInput as C, DEFAULT_DATA_TABLE_LABELS as D, type PasteMode as P, type RowSelectionMode as R, type TableColumnProps as T, type ColumnFreezeEdgeSide as a, type ColumnFreezeMeta as b, type ColumnFreezeOffset as c, type ColumnFreezeSide as d, type DataTableClassNames as e, type DataTableCopyActions as f, type DataTableLabels as g, type DataTableProps as h, type DataTableScrollSlotProps as i, type DataTableSlots as j, type RowsPastePayload as k, type TableProps as l, buildColumnFreezeOffsets as m, getColumnFreezeEdgeAttr as n, getColumnFreezeStyle as o, resolveDataTableLabels as p, type CellEditType as q, resolveColumnFreezeSide as r };
@@ -1,5 +1,5 @@
1
1
  import { ColumnDef, RowSelectionState, Updater, ColumnSizingState, OnChangeFn, ColumnResizeMode, Row } from '@tanstack/react-table';
2
- import { CSSProperties, ReactNode, InputHTMLAttributes, ComponentType } from 'react';
2
+ import { CSSProperties, ReactNode, InputHTMLAttributes, ComponentType, Ref } from 'react';
3
3
 
4
4
  /** Sticky edge for a frozen column. Does not reorder columns. */
5
5
  type ColumnFreezeSide = "left" | "right";
@@ -13,24 +13,34 @@ type ColumnFreezeColumnInput = {
13
13
  size: number;
14
14
  side?: ColumnFreezeSide;
15
15
  };
16
+ /** Which outer sides of a freeze island get a divider shadow. */
17
+ type ColumnFreezeEdgeSide = "left" | "right" | "both";
16
18
  type ColumnFreezeOffset = {
17
19
  side: ColumnFreezeSide;
18
20
  /** Cumulative sticky inset (`left` or `right` in px). */
19
21
  offset: number;
20
- /** Inner edge of the sticky group (shadow / divider). */
22
+ /** True when this cell is on an island boundary (any side). */
21
23
  isEdge: boolean;
24
+ /** Shadow toward the previous column (scrollable / other island). */
25
+ edgeLeft: boolean;
26
+ /** Shadow toward the next column (scrollable / other island). */
27
+ edgeRight: boolean;
22
28
  /** Relative stack order within the freeze side (higher = closer to the viewport edge). */
23
29
  stack: number;
24
30
  };
25
31
  /** Normalize column `frozen` meta into a sticky side. */
26
32
  declare function resolveColumnFreezeSide(frozen?: ColumnFreezeMeta): ColumnFreezeSide | undefined;
33
+ /** Serialize freeze-edge flags for `data-freeze-edge`. */
34
+ declare function getColumnFreezeEdgeAttr(offset: Pick<ColumnFreezeOffset, "edgeLeft" | "edgeRight"> | undefined): ColumnFreezeEdgeSide | undefined;
27
35
  /**
28
36
  * Build sticky insets for frozen columns without changing DOM/column order.
29
37
  *
30
38
  * - `left`: `left = Σ(widths of left-frozen columns before this one)`
31
39
  * - `right`: `right = Σ(widths of right-frozen columns after this one)`
32
40
  *
33
- * Middle columns may be frozen; non-frozen neighbors scroll underneath.
41
+ * Contiguous same-side freezes form one island only the outer boundaries
42
+ * get edge shadows. Gaps between same-side freezes create separate islands,
43
+ * so both sides of the gap receive a shadow.
34
44
  */
35
45
  declare function buildColumnFreezeOffsets(columns: ColumnFreezeColumnInput[]): Map<string, ColumnFreezeOffset>;
36
46
  /** Sticky position styles for a frozen header or body cell. */
@@ -302,6 +312,17 @@ type DataTableRowSlotProps<T extends Record<string, unknown>> = {
302
312
  virtualIndex?: number;
303
313
  measureElement?: (node: Element | null) => void;
304
314
  };
315
+ /**
316
+ * Scroll-region slot props for the semantic DataTable shell.
317
+ *
318
+ * `scrollRef` must be attached to the element that actually owns overflow
319
+ * scrolling — row virtualization reads it via `getScrollElement`.
320
+ */
321
+ type DataTableScrollSlotProps = {
322
+ children: ReactNode;
323
+ className?: string;
324
+ scrollRef: Ref<HTMLDivElement | null>;
325
+ };
305
326
  /**
306
327
  * Slot replacements for the default DataTable shell (semantic HTML + behavior only).
307
328
  * Row-level custom UI → `Row`; cell content → `Table.Column` / column `render`.
@@ -310,6 +331,11 @@ type DataTableRowSlotProps<T extends Record<string, unknown>> = {
310
331
  type DataTableSlots<T extends Record<string, unknown>> = {
311
332
  /** Top summary / actions region */
312
333
  Toolbar?: ComponentType<DataTableToolbarSlotProps>;
334
+ /**
335
+ * Table scroll container. Must forward `scrollRef` to the real scroll element
336
+ * (required for virtualization).
337
+ */
338
+ Scroll?: ComponentType<DataTableScrollSlotProps>;
313
339
  /** Full row replacement (cells, selection, edit UI) */
314
340
  Row?: ComponentType<DataTableRowSlotProps<T>>;
315
341
  /** Replace the pending state view */
@@ -364,4 +390,4 @@ type TableProps<T extends Record<string, unknown>> = Omit<DataTableProps<T>, "co
364
390
  children: ReactNode;
365
391
  };
366
392
 
367
- export { type ColumnFreezeColumnInput as C, DEFAULT_DATA_TABLE_LABELS as D, type PasteMode as P, type RowSelectionMode as R, type TableColumnProps as T, type ColumnFreezeMeta as a, type ColumnFreezeOffset as b, type ColumnFreezeSide as c, type DataTableClassNames as d, type DataTableCopyActions as e, type DataTableLabels as f, type DataTableProps as g, type DataTableSlots as h, type RowsPastePayload as i, type TableProps as j, buildColumnFreezeOffsets as k, getColumnFreezeStyle as l, resolveDataTableLabels as m, type CellEditType as n, resolveColumnFreezeSide as r };
393
+ export { type ColumnFreezeColumnInput as C, DEFAULT_DATA_TABLE_LABELS as D, type PasteMode as P, type RowSelectionMode as R, type TableColumnProps as T, type ColumnFreezeEdgeSide as a, type ColumnFreezeMeta as b, type ColumnFreezeOffset as c, type ColumnFreezeSide as d, type DataTableClassNames as e, type DataTableCopyActions as f, type DataTableLabels as g, type DataTableProps as h, type DataTableScrollSlotProps as i, type DataTableSlots as j, type RowsPastePayload as k, type TableProps as l, buildColumnFreezeOffsets as m, getColumnFreezeEdgeAttr as n, getColumnFreezeStyle as o, resolveDataTableLabels as p, type CellEditType as q, resolveColumnFreezeSide as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-glide-table",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/zpxlffjrm/react-glide-table.git"