react-glide-table 1.4.1 → 1.6.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/compound.cjs CHANGED
@@ -28,7 +28,7 @@ module.exports = __toCommonJS(compound_exports);
28
28
 
29
29
  // src/components/ui/table/components/DataTable/DataTable.tsx
30
30
  var import_react_table3 = require("@tanstack/react-table");
31
- var import_react7 = require("react");
31
+ var import_react8 = require("react");
32
32
 
33
33
  // src/components/ui/table/components/DataTable/DataTableRow.tsx
34
34
  var import_react_table = require("@tanstack/react-table");
@@ -131,6 +131,36 @@ function getCellSelectionBounds(start, end) {
131
131
  endCol: Math.max(start.col, end.col)
132
132
  };
133
133
  }
134
+ function getCellNavigationDelta(key) {
135
+ switch (key) {
136
+ case "ArrowUp":
137
+ case "w":
138
+ case "W":
139
+ return { row: -1, col: 0 };
140
+ case "ArrowDown":
141
+ case "s":
142
+ case "S":
143
+ return { row: 1, col: 0 };
144
+ case "ArrowLeft":
145
+ case "a":
146
+ case "A":
147
+ return { row: 0, col: -1 };
148
+ case "ArrowRight":
149
+ case "d":
150
+ case "D":
151
+ return { row: 0, col: 1 };
152
+ default:
153
+ return null;
154
+ }
155
+ }
156
+ function clampCellPosition(position, rowCount, columnCount) {
157
+ const maxRow = Math.max(rowCount - 1, 0);
158
+ const maxCol = Math.max(columnCount - 1, 0);
159
+ return {
160
+ row: Math.min(Math.max(position.row, 0), maxRow),
161
+ col: Math.min(Math.max(position.col, 0), maxCol)
162
+ };
163
+ }
134
164
  function measureMergedSpanRowHeights(rowIndex, rowSpan, cellElement) {
135
165
  if (rowSpan <= 1) return void 0;
136
166
  const tbody = cellElement?.closest("tbody") ?? (typeof document !== "undefined" ? document.querySelector("tbody.data-table-body") : null);
@@ -484,6 +514,162 @@ function getColumnSizeStyle(size, options) {
484
514
  };
485
515
  }
486
516
 
517
+ // src/components/ui/table/features/inline-search/inlineSearch.ts
518
+ var INLINE_SEARCH_MAX_RESULTS = 1e3;
519
+ var INLINE_SEARCH_TARGET_TICK_MS = 10;
520
+ var INLINE_SEARCH_INITIAL_STRIDE = 10;
521
+ function escapeSearchRegex(value) {
522
+ return value.replace(/([$()*+.?[\\\]^{|}-])/g, "\\$1");
523
+ }
524
+ function createSearchRegex(query) {
525
+ const trimmed = query.trim();
526
+ if (!trimmed) return null;
527
+ return new RegExp(escapeSearchRegex(trimmed), "i");
528
+ }
529
+ function cellValueToSearchText(value) {
530
+ if (value == null) return void 0;
531
+ if (typeof value === "string") return value;
532
+ if (typeof value === "number" || typeof value === "boolean") {
533
+ return String(value);
534
+ }
535
+ if (Array.isArray(value)) {
536
+ return value.map((item) => cellValueToSearchText(item) ?? "").join(" ");
537
+ }
538
+ if (typeof value === "object") {
539
+ try {
540
+ return JSON.stringify(value);
541
+ } catch {
542
+ return String(value);
543
+ }
544
+ }
545
+ return String(value);
546
+ }
547
+ function formatSearchResultLabel(status) {
548
+ const countLabel = status.results >= INLINE_SEARCH_MAX_RESULTS ? `over ${INLINE_SEARCH_MAX_RESULTS}` : `${status.results} result${status.results !== 1 ? "s" : ""}`;
549
+ if (status.selectedIndex >= 0 && status.results > 0) {
550
+ return `${status.selectedIndex + 1} of ${countLabel}`;
551
+ }
552
+ return countLabel;
553
+ }
554
+ function nextSearchIndex(selectedIndex, results) {
555
+ if (results <= 0) return -1;
556
+ if (selectedIndex < 0) return 0;
557
+ return (selectedIndex + 1) % results;
558
+ }
559
+ function previousSearchIndex(selectedIndex, results) {
560
+ if (results <= 0) return -1;
561
+ if (selectedIndex < 0) return results - 1;
562
+ let next = (selectedIndex - 1) % results;
563
+ if (next < 0) next += results;
564
+ return next;
565
+ }
566
+ function buildSearchMatchKey(colIndex, rowIndex) {
567
+ return `${colIndex}:${rowIndex}`;
568
+ }
569
+ function buildSearchMatchKeys(results) {
570
+ const keys = /* @__PURE__ */ new Set();
571
+ for (const [colIndex, rowIndex] of results) {
572
+ keys.add(buildSearchMatchKey(colIndex, rowIndex));
573
+ }
574
+ return keys;
575
+ }
576
+ function collectSearchMatchesInRange(options) {
577
+ const {
578
+ query,
579
+ startRow,
580
+ rowCount,
581
+ columnCount,
582
+ getCellValue,
583
+ maxResults = INLINE_SEARCH_MAX_RESULTS
584
+ } = options;
585
+ const regex = createSearchRegex(query);
586
+ if (!regex || rowCount <= 0 || columnCount <= 0) return [];
587
+ const matches = [];
588
+ for (let rowOffset = 0; rowOffset < rowCount; rowOffset += 1) {
589
+ const rowIndex = startRow + rowOffset;
590
+ for (let colIndex = 0; colIndex < columnCount; colIndex += 1) {
591
+ const text = cellValueToSearchText(getCellValue(rowIndex, colIndex));
592
+ if (text !== void 0 && regex.test(text)) {
593
+ matches.push([colIndex, rowIndex]);
594
+ if (matches.length >= maxResults) {
595
+ return matches;
596
+ }
597
+ }
598
+ }
599
+ }
600
+ return matches;
601
+ }
602
+ function nextSearchStride(currentStride, elapsedMs, targetMs = INLINE_SEARCH_TARGET_TICK_MS) {
603
+ const rounded = Math.max(elapsedMs, 1);
604
+ const scalar = targetMs / rounded;
605
+ return Math.max(1, Math.ceil(currentStride * scalar));
606
+ }
607
+ function buildFlatSearchCorpus(rows, getRowId) {
608
+ return rows.map((data, index) => ({
609
+ id: getRowId(data, index),
610
+ data,
611
+ ancestorToggleKeys: []
612
+ }));
613
+ }
614
+ function buildTreeSearchCorpus(visibleRows, options) {
615
+ const { toggleField, getRowId } = options;
616
+ const corpus = [];
617
+ const seen = /* @__PURE__ */ new Set();
618
+ const walk = (node, ancestorToggleKeys) => {
619
+ const id = getRowId(node, corpus.length);
620
+ if (seen.has(id)) return;
621
+ seen.add(id);
622
+ corpus.push({
623
+ id,
624
+ data: node,
625
+ ancestorToggleKeys
626
+ });
627
+ const children = node.children;
628
+ if (!Array.isArray(children) || children.length === 0) return;
629
+ const toggleValue = node[toggleField];
630
+ const childAncestors = typeof toggleValue === "string" && toggleValue.length > 0 ? [...ancestorToggleKeys, toggleValue] : ancestorToggleKeys;
631
+ for (const child of children) {
632
+ if (child && typeof child === "object") {
633
+ walk(child, childAncestors);
634
+ }
635
+ }
636
+ };
637
+ for (const row of visibleRows) {
638
+ const level = row.level;
639
+ if (level === 0 || level === void 0) {
640
+ walk(row, []);
641
+ }
642
+ }
643
+ for (const row of visibleRows) {
644
+ const id = getRowId(row, corpus.length);
645
+ if (seen.has(id)) continue;
646
+ walk(row, []);
647
+ }
648
+ return corpus;
649
+ }
650
+ function mapSearchResultsToVisibleKeys(results, corpus, visibleRowIndexById) {
651
+ const keys = /* @__PURE__ */ new Set();
652
+ for (const [colIndex, corpusRowIndex] of results) {
653
+ const corpusRow = corpus[corpusRowIndex];
654
+ if (!corpusRow) continue;
655
+ const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
656
+ if (visibleRowIndex === void 0) continue;
657
+ keys.add(buildSearchMatchKey(colIndex, visibleRowIndex));
658
+ }
659
+ return keys;
660
+ }
661
+ function mapSearchResultToVisibleItem(item, corpus, visibleRowIndexById) {
662
+ const [colIndex, corpusRowIndex] = item;
663
+ const corpusRow = corpus[corpusRowIndex];
664
+ if (!corpusRow) return null;
665
+ const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
666
+ if (visibleRowIndex === void 0) return null;
667
+ return [colIndex, visibleRowIndex];
668
+ }
669
+ function collectAncestorKeysToExpand(corpusRow, expandedRows) {
670
+ return corpusRow.ancestorToggleKeys.filter((key) => !expandedRows.has(key));
671
+ }
672
+
487
673
  // src/components/ui/table/features/row-expand/row-expand.ts
488
674
  var import_react2 = require("react");
489
675
 
@@ -929,10 +1115,16 @@ function DataTableRow({
929
1115
  cellEdit,
930
1116
  expand,
931
1117
  columnResize,
932
- columnFreeze
1118
+ columnFreeze,
1119
+ inlineSearch
933
1120
  } = useDataTableRowContext();
934
1121
  const { enableColumnResize } = columnResize;
935
1122
  const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
1123
+ const {
1124
+ enabled: enableInlineSearch,
1125
+ matchKeys: searchMatchKeys,
1126
+ activeMatch
1127
+ } = inlineSearch;
936
1128
  const {
937
1129
  enableRowSpan,
938
1130
  primaryRowSpanColumnId,
@@ -1124,9 +1316,14 @@ function DataTableRow({
1124
1316
  ...freezeStyle,
1125
1317
  ...selectionEdgeStyle
1126
1318
  };
1319
+ const searchMatchKey = buildSearchMatchKey(cellIndex, rowIndex);
1320
+ const isSearchMatch = enableInlineSearch && searchMatchKeys.has(searchMatchKey);
1321
+ const isSearchActive = isSearchMatch && activeMatch !== null && activeMatch[0] === cellIndex && activeMatch[1] === rowIndex;
1127
1322
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1128
1323
  "td",
1129
1324
  {
1325
+ "data-row-index": rowIndex,
1326
+ "data-col-index": cellIndex,
1130
1327
  rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
1131
1328
  "data-merged": isMerged && cellIndex > 0 ? "" : void 0,
1132
1329
  "data-merged-edge-right": showMergedRightEdge ? "" : void 0,
@@ -1136,6 +1333,8 @@ function DataTableRow({
1136
1333
  "data-group-hovered": enableRowSpan && showCellHover && !showCellSelected ? "" : void 0,
1137
1334
  "data-selection-fill": isCellDragSelected ? "" : void 0,
1138
1335
  "data-selection-edges": hasSelectionEdges ? "" : void 0,
1336
+ "data-search-match": isSearchMatch ? "" : void 0,
1337
+ "data-search-active": isSearchActive ? "" : void 0,
1139
1338
  "data-editable": editable ? "" : void 0,
1140
1339
  "data-editing": isEditing ? "" : void 0,
1141
1340
  "data-frozen": freezeOffset?.side,
@@ -1150,7 +1349,8 @@ function DataTableRow({
1150
1349
  event.preventDefault();
1151
1350
  onCellMouseDown(
1152
1351
  resolveCellRowIndex(event.clientY, event.currentTarget),
1153
- cellIndex
1352
+ cellIndex,
1353
+ { shiftKey: event.shiftKey }
1154
1354
  );
1155
1355
  },
1156
1356
  onMouseEnter: (event) => {
@@ -1187,6 +1387,8 @@ function DataTableRow({
1187
1387
  enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
1188
1388
  isCellDragSelected && CELL_SELECTION_FILL_CLASS,
1189
1389
  hasSelectionEdges && CELL_SELECTION_EDGES_CLASS,
1390
+ isSearchMatch && "is-search-match",
1391
+ isSearchActive && "is-search-active",
1190
1392
  editable && "is-editable",
1191
1393
  classNames?.cell
1192
1394
  ),
@@ -1321,8 +1523,169 @@ function DataTableRow({
1321
1523
  );
1322
1524
  }
1323
1525
 
1324
- // src/components/ui/table/components/DataTable/DataTableToolbar.tsx
1526
+ // src/components/ui/table/components/DataTable/DataTableSearch.tsx
1325
1527
  var import_jsx_runtime4 = require("react/jsx-runtime");
1528
+ function SearchCloseIcon({ className }) {
1529
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1530
+ "svg",
1531
+ {
1532
+ className,
1533
+ "aria-hidden": true,
1534
+ width: "16",
1535
+ height: "16",
1536
+ viewBox: "0 0 24 24",
1537
+ fill: "none",
1538
+ stroke: "currentColor",
1539
+ strokeWidth: "2",
1540
+ strokeLinecap: "round",
1541
+ strokeLinejoin: "round",
1542
+ children: [
1543
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 6 6 18" }),
1544
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m6 6 12 12" })
1545
+ ]
1546
+ }
1547
+ );
1548
+ }
1549
+ function DataTableSearch({
1550
+ showSearch,
1551
+ searchValue,
1552
+ searchStatus,
1553
+ searchInputId,
1554
+ searchInputRef,
1555
+ canClose,
1556
+ placeholder,
1557
+ resultHint,
1558
+ previousLabel,
1559
+ nextLabel,
1560
+ closeLabel,
1561
+ rowsTotal,
1562
+ classNames,
1563
+ onSearchValueChange,
1564
+ onClose,
1565
+ onNext,
1566
+ onPrevious
1567
+ }) {
1568
+ if (!showSearch) return null;
1569
+ const resultString = searchStatus ? formatSearchResultLabel(searchStatus) : resultHint;
1570
+ const progress = rowsTotal > 0 ? Math.floor((searchStatus?.rowsSearched ?? 0) / rowsTotal * 100) : 0;
1571
+ const handleKeyDown = (event) => {
1572
+ if ((event.ctrlKey || event.metaKey) && event.code === "KeyF" || event.key === "Escape") {
1573
+ event.preventDefault();
1574
+ event.stopPropagation();
1575
+ if (canClose) {
1576
+ onClose();
1577
+ }
1578
+ return;
1579
+ }
1580
+ if (event.key === "ArrowDown" || event.key === "Enter" && !event.shiftKey) {
1581
+ event.preventDefault();
1582
+ onNext();
1583
+ return;
1584
+ }
1585
+ if (event.key === "ArrowUp" || event.key === "Enter" && event.shiftKey) {
1586
+ event.preventDefault();
1587
+ onPrevious();
1588
+ }
1589
+ };
1590
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1591
+ "div",
1592
+ {
1593
+ className: cn("data-table-search", classNames?.search),
1594
+ role: "search",
1595
+ onMouseDown: (event) => event.stopPropagation(),
1596
+ children: [
1597
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "data-table-search-row", children: [
1598
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1599
+ "input",
1600
+ {
1601
+ ref: searchInputRef,
1602
+ id: searchInputId,
1603
+ type: "search",
1604
+ value: searchValue,
1605
+ placeholder,
1606
+ autoComplete: "off",
1607
+ spellCheck: false,
1608
+ "aria-label": placeholder,
1609
+ className: cn("data-table-search-input", classNames?.searchInput),
1610
+ onChange: (event) => onSearchValueChange(event.target.value),
1611
+ onKeyDown: handleKeyDown
1612
+ }
1613
+ ),
1614
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1615
+ "button",
1616
+ {
1617
+ type: "button",
1618
+ "aria-label": previousLabel,
1619
+ className: cn("data-table-search-button", classNames?.searchButton),
1620
+ onClick: (event) => {
1621
+ event.stopPropagation();
1622
+ onPrevious();
1623
+ },
1624
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChevronUp, { className: "data-table-search-icon" })
1625
+ }
1626
+ ),
1627
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1628
+ "button",
1629
+ {
1630
+ type: "button",
1631
+ "aria-label": nextLabel,
1632
+ className: cn("data-table-search-button", classNames?.searchButton),
1633
+ onClick: (event) => {
1634
+ event.stopPropagation();
1635
+ onNext();
1636
+ },
1637
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChevronDown, { className: "data-table-search-icon" })
1638
+ }
1639
+ ),
1640
+ canClose ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1641
+ "button",
1642
+ {
1643
+ type: "button",
1644
+ "aria-label": closeLabel,
1645
+ className: cn("data-table-search-button", classNames?.searchButton),
1646
+ onClick: (event) => {
1647
+ event.stopPropagation();
1648
+ onClose();
1649
+ },
1650
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SearchCloseIcon, { className: "data-table-search-icon" })
1651
+ }
1652
+ ) : null
1653
+ ] }),
1654
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1655
+ "div",
1656
+ {
1657
+ className: cn("data-table-search-status", classNames?.searchStatus),
1658
+ "aria-live": "polite",
1659
+ children: resultString
1660
+ }
1661
+ ),
1662
+ searchStatus !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1663
+ "div",
1664
+ {
1665
+ className: cn(
1666
+ "data-table-search-progress",
1667
+ classNames?.searchProgress
1668
+ ),
1669
+ role: "progressbar",
1670
+ "aria-valuemin": 0,
1671
+ "aria-valuemax": 100,
1672
+ "aria-valuenow": progress,
1673
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1674
+ "div",
1675
+ {
1676
+ className: "data-table-search-progress-bar",
1677
+ style: { width: `${progress}%` }
1678
+ }
1679
+ )
1680
+ }
1681
+ ) : null
1682
+ ]
1683
+ }
1684
+ );
1685
+ }
1686
+
1687
+ // src/components/ui/table/components/DataTable/DataTableToolbar.tsx
1688
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1326
1689
  function DataTableToolbar({
1327
1690
  filteredCount,
1328
1691
  totalCount,
@@ -1340,20 +1703,20 @@ function DataTableToolbar({
1340
1703
  const selectionContent = selectionLabel?.(selectedCount) ?? null;
1341
1704
  const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
1342
1705
  if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
1343
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("DataTableToolbarJSX", classNames?.toolbar, className), children: [
1344
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("toolbar-left", classNames?.toolbarLeft), children: [
1345
- hasCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn("toolbar-count", classNames?.toolbarCount), children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1346
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered }),
1347
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "toolbar-count-placeholder", children: [
1706
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("DataTableToolbarJSX", classNames?.toolbar, className), children: [
1707
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("toolbar-left", classNames?.toolbarLeft), children: [
1708
+ hasCount && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: cn("toolbar-count", classNames?.toolbarCount), children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1709
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "toolbar-count-placeholder", children: [
1348
1711
  " / ",
1349
1712
  totalCount
1350
1713
  ] })
1351
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
1714
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
1352
1715
  summary
1353
1716
  ] }),
1354
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("toolbar-right", classNames?.toolbarRight), children: [
1355
- hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn("toolbar-selection", classNames?.toolbarSelection), children: selectionContent }) : selectionContent),
1356
- hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("toolbar-actions", classNames?.toolbarActions), children: toolbar })
1717
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("toolbar-right", classNames?.toolbarRight), children: [
1718
+ hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: cn("toolbar-selection", classNames?.toolbarSelection), children: selectionContent }) : selectionContent),
1719
+ hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("toolbar-actions", classNames?.toolbarActions), children: toolbar })
1357
1720
  ] })
1358
1721
  ] });
1359
1722
  }
@@ -1361,7 +1724,7 @@ function DataTableToolbar({
1361
1724
  // src/core/useGlideTable.ts
1362
1725
  var import_react_table2 = require("@tanstack/react-table");
1363
1726
  var import_react_virtual = require("@tanstack/react-virtual");
1364
- var import_react6 = require("react");
1727
+ var import_react7 = require("react");
1365
1728
 
1366
1729
  // src/components/ui/table/features/cell-edit/useCellEdit.ts
1367
1730
  var import_react4 = require("react");
@@ -1689,26 +2052,44 @@ function useCellSelection({
1689
2052
  data,
1690
2053
  rows,
1691
2054
  enabled = true,
2055
+ columnCount = 0,
1692
2056
  enableSubtreeCopy = false,
1693
2057
  enableInsertPaste = true,
1694
2058
  onDataChange,
1695
2059
  onBatchChange,
1696
- onRowsPaste
2060
+ onRowsPaste,
2061
+ onCellNavigate
1697
2062
  }) {
1698
2063
  const [dragState, setDragState] = (0, import_react5.useState)(INITIAL_DRAG_STATE);
1699
2064
  const pendingPasteModeRef = (0, import_react5.useRef)(null);
2065
+ const dragStateRef = (0, import_react5.useRef)(dragState);
2066
+ const onCellNavigateRef = (0, import_react5.useRef)(onCellNavigate);
2067
+ dragStateRef.current = dragState;
2068
+ onCellNavigateRef.current = onCellNavigate;
1700
2069
  const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
1701
2070
  const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
1702
2071
  const handleCellMouseDown = (0, import_react5.useCallback)(
1703
- (rowIndex, colIndex) => {
2072
+ (rowIndex, colIndex, options) => {
1704
2073
  if (!enabled) return;
1705
- setDragState({
1706
- isSelecting: true,
1707
- isFillDragging: false,
1708
- start: { row: rowIndex, col: colIndex },
1709
- end: { row: rowIndex, col: colIndex },
1710
- fillAnchor: null,
1711
- fillEnd: null
2074
+ setDragState((prev) => {
2075
+ if (options?.shiftKey && prev.start) {
2076
+ return {
2077
+ ...prev,
2078
+ isSelecting: true,
2079
+ isFillDragging: false,
2080
+ end: { row: rowIndex, col: colIndex },
2081
+ fillAnchor: null,
2082
+ fillEnd: null
2083
+ };
2084
+ }
2085
+ return {
2086
+ isSelecting: true,
2087
+ isFillDragging: false,
2088
+ start: { row: rowIndex, col: colIndex },
2089
+ end: { row: rowIndex, col: colIndex },
2090
+ fillAnchor: null,
2091
+ fillEnd: null
2092
+ };
1712
2093
  });
1713
2094
  },
1714
2095
  [enabled]
@@ -1750,6 +2131,53 @@ function useCellSelection({
1750
2131
  setDragState(INITIAL_DRAG_STATE);
1751
2132
  }
1752
2133
  }, [enabled]);
2134
+ (0, import_react5.useEffect)(() => {
2135
+ if (!enabled) return;
2136
+ const handleKeyDown = (e) => {
2137
+ if (e.ctrlKey || e.metaKey || e.altKey) return;
2138
+ if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
2139
+ return;
2140
+ }
2141
+ const delta = getCellNavigationDelta(e.key);
2142
+ if (!delta) return;
2143
+ const prev = dragStateRef.current;
2144
+ if (!prev.start || !prev.end) return;
2145
+ if (prev.isSelecting || prev.isFillDragging) return;
2146
+ const rowCount = rows.length;
2147
+ const resolvedColumnCount = columnCount > 0 ? columnCount : rows[0]?.getVisibleCells().length ?? 0;
2148
+ if (rowCount <= 0 || resolvedColumnCount <= 0) return;
2149
+ const nextEnd = clampCellPosition(
2150
+ {
2151
+ row: prev.end.row + delta.row,
2152
+ col: prev.end.col + delta.col
2153
+ },
2154
+ rowCount,
2155
+ resolvedColumnCount
2156
+ );
2157
+ if (nextEnd.row === prev.end.row && nextEnd.col === prev.end.col) return;
2158
+ e.preventDefault();
2159
+ const nextState = e.shiftKey ? {
2160
+ ...prev,
2161
+ isSelecting: false,
2162
+ isFillDragging: false,
2163
+ end: nextEnd,
2164
+ fillAnchor: null,
2165
+ fillEnd: null
2166
+ } : {
2167
+ isSelecting: false,
2168
+ isFillDragging: false,
2169
+ start: nextEnd,
2170
+ end: nextEnd,
2171
+ fillAnchor: null,
2172
+ fillEnd: null
2173
+ };
2174
+ dragStateRef.current = nextState;
2175
+ setDragState(nextState);
2176
+ onCellNavigateRef.current?.(nextEnd);
2177
+ };
2178
+ window.addEventListener("keydown", handleKeyDown);
2179
+ return () => window.removeEventListener("keydown", handleKeyDown);
2180
+ }, [columnCount, enabled, rows]);
1753
2181
  const copySelection = (0, import_react5.useCallback)(
1754
2182
  async (options) => {
1755
2183
  if (!enabled || !activeSelectionBounds) return false;
@@ -1907,6 +2335,304 @@ function useCellSelection({
1907
2335
  };
1908
2336
  }
1909
2337
 
2338
+ // src/components/ui/table/features/inline-search/useInlineSearch.ts
2339
+ var import_react6 = require("react");
2340
+ var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
2341
+ function useInlineSearch({
2342
+ enabled = false,
2343
+ rowCount,
2344
+ columnCount,
2345
+ getCellValue,
2346
+ initialStartRow = 0,
2347
+ showSearch: controlledShowSearch,
2348
+ searchValue: controlledSearchValue,
2349
+ searchResults: controlledSearchResults,
2350
+ onSearchValueChange,
2351
+ onSearchClose,
2352
+ onSearchResultsChanged,
2353
+ onNavigateToResult,
2354
+ rootRef
2355
+ }) {
2356
+ const searchInputId = (0, import_react6.useId)();
2357
+ const searchInputRef = (0, import_react6.useRef)(null);
2358
+ const [internalShowSearch, setInternalShowSearch] = (0, import_react6.useState)(false);
2359
+ const [internalSearchValue, setInternalSearchValue] = (0, import_react6.useState)("");
2360
+ const [internalResults, setInternalResults] = (0, import_react6.useState)(
2361
+ []
2362
+ );
2363
+ const [searchStatus, setSearchStatus] = (0, import_react6.useState)();
2364
+ const searchStatusRef = (0, import_react6.useRef)(searchStatus);
2365
+ searchStatusRef.current = searchStatus;
2366
+ const abortControllerRef = (0, import_react6.useRef)(null);
2367
+ const searchHandleRef = (0, import_react6.useRef)(void 0);
2368
+ const initialStartRowRef = (0, import_react6.useRef)(initialStartRow);
2369
+ initialStartRowRef.current = initialStartRow;
2370
+ const getCellValueRef = (0, import_react6.useRef)(getCellValue);
2371
+ getCellValueRef.current = getCellValue;
2372
+ const showSearch = controlledShowSearch ?? internalShowSearch;
2373
+ const searchValue = controlledSearchValue ?? internalSearchValue;
2374
+ const searchResults = controlledSearchResults ?? internalResults;
2375
+ const setSearchValue = (0, import_react6.useCallback)(
2376
+ (value) => {
2377
+ setInternalSearchValue(value);
2378
+ onSearchValueChange?.(value);
2379
+ },
2380
+ [onSearchValueChange]
2381
+ );
2382
+ const cancelSearch = (0, import_react6.useCallback)(() => {
2383
+ if (searchHandleRef.current !== void 0) {
2384
+ window.cancelAnimationFrame(searchHandleRef.current);
2385
+ searchHandleRef.current = void 0;
2386
+ }
2387
+ abortControllerRef.current?.abort();
2388
+ }, []);
2389
+ const emitResultsChanged = (0, import_react6.useCallback)(
2390
+ (results, navIndex) => {
2391
+ onSearchResultsChanged?.(results, navIndex);
2392
+ },
2393
+ [onSearchResultsChanged]
2394
+ );
2395
+ const navigateToIndex = (0, import_react6.useCallback)(
2396
+ (results, navIndex) => {
2397
+ if (onSearchResultsChanged) return;
2398
+ if (navIndex < 0 || navIndex >= results.length) return;
2399
+ const item = results[navIndex];
2400
+ if (!item) return;
2401
+ onNavigateToResult?.(item);
2402
+ },
2403
+ [onNavigateToResult, onSearchResultsChanged]
2404
+ );
2405
+ const beginSearch = (0, import_react6.useCallback)(
2406
+ (query) => {
2407
+ if (controlledSearchResults !== void 0) return;
2408
+ const totalRows = rowCount;
2409
+ if (totalRows === 0 || columnCount === 0) {
2410
+ setSearchStatus(void 0);
2411
+ setInternalResults([]);
2412
+ emitResultsChanged([], -1);
2413
+ return;
2414
+ }
2415
+ let startY = Math.min(
2416
+ Math.max(0, initialStartRowRef.current),
2417
+ totalRows - 1
2418
+ );
2419
+ let searchStride = Math.min(INLINE_SEARCH_INITIAL_STRIDE, totalRows);
2420
+ let rowsSearched = 0;
2421
+ const runningResult = [];
2422
+ setSearchStatus(void 0);
2423
+ setInternalResults([]);
2424
+ const tick = () => {
2425
+ if (abortControllerRef.current?.signal.aborted) return;
2426
+ const tStart = performance.now();
2427
+ const rowsLeft = totalRows - rowsSearched;
2428
+ const height = Math.min(searchStride, rowsLeft, totalRows - startY);
2429
+ if (height <= 0) {
2430
+ return;
2431
+ }
2432
+ const chunk = collectSearchMatchesInRange({
2433
+ query,
2434
+ startRow: startY,
2435
+ rowCount: height,
2436
+ columnCount,
2437
+ getCellValue: (rowIndex, colIndex) => getCellValueRef.current(rowIndex, colIndex),
2438
+ maxResults: INLINE_SEARCH_MAX_RESULTS - runningResult.length
2439
+ });
2440
+ if (chunk.length > 0) {
2441
+ runningResult.push(...chunk);
2442
+ setInternalResults([...runningResult]);
2443
+ }
2444
+ rowsSearched += height;
2445
+ const selectedIndex = searchStatusRef.current?.selectedIndex ?? -1;
2446
+ setSearchStatus({
2447
+ results: runningResult.length,
2448
+ rowsSearched,
2449
+ selectedIndex
2450
+ });
2451
+ emitResultsChanged(runningResult, selectedIndex);
2452
+ if (startY + height >= totalRows) {
2453
+ startY = 0;
2454
+ } else {
2455
+ startY += height;
2456
+ }
2457
+ searchStride = nextSearchStride(
2458
+ searchStride,
2459
+ performance.now() - tStart
2460
+ );
2461
+ if (rowsSearched < totalRows && runningResult.length < INLINE_SEARCH_MAX_RESULTS) {
2462
+ searchHandleRef.current = window.requestAnimationFrame(tick);
2463
+ }
2464
+ };
2465
+ cancelSearch();
2466
+ abortControllerRef.current = new AbortController();
2467
+ searchHandleRef.current = window.requestAnimationFrame(tick);
2468
+ },
2469
+ [
2470
+ cancelSearch,
2471
+ columnCount,
2472
+ controlledSearchResults,
2473
+ emitResultsChanged,
2474
+ rowCount
2475
+ ]
2476
+ );
2477
+ const openSearch = (0, import_react6.useCallback)(() => {
2478
+ if (controlledShowSearch === void 0) {
2479
+ setInternalShowSearch(true);
2480
+ }
2481
+ }, [controlledShowSearch]);
2482
+ const closeSearch = (0, import_react6.useCallback)(() => {
2483
+ if (controlledShowSearch === void 0) {
2484
+ setInternalShowSearch(false);
2485
+ }
2486
+ onSearchClose?.();
2487
+ setSearchStatus(void 0);
2488
+ setInternalResults([]);
2489
+ emitResultsChanged([], -1);
2490
+ cancelSearch();
2491
+ }, [
2492
+ cancelSearch,
2493
+ controlledShowSearch,
2494
+ emitResultsChanged,
2495
+ onSearchClose
2496
+ ]);
2497
+ const goToNext = (0, import_react6.useCallback)(() => {
2498
+ if (!searchStatus || searchStatus.results === 0) return;
2499
+ const newIndex = nextSearchIndex(
2500
+ searchStatus.selectedIndex,
2501
+ searchStatus.results
2502
+ );
2503
+ setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
2504
+ emitResultsChanged(searchResults, newIndex);
2505
+ navigateToIndex(searchResults, newIndex);
2506
+ }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2507
+ const goToPrevious = (0, import_react6.useCallback)(() => {
2508
+ if (!searchStatus || searchStatus.results === 0) return;
2509
+ const newIndex = previousSearchIndex(
2510
+ searchStatus.selectedIndex,
2511
+ searchStatus.results
2512
+ );
2513
+ setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
2514
+ emitResultsChanged(searchResults, newIndex);
2515
+ navigateToIndex(searchResults, newIndex);
2516
+ }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
2517
+ (0, import_react6.useEffect)(() => {
2518
+ if (controlledSearchResults === void 0) return;
2519
+ if (controlledSearchResults.length > 0) {
2520
+ setSearchStatus((current) => ({
2521
+ rowsSearched: rowCount,
2522
+ results: controlledSearchResults.length,
2523
+ selectedIndex: current?.selectedIndex ?? -1
2524
+ }));
2525
+ } else {
2526
+ setSearchStatus(void 0);
2527
+ }
2528
+ }, [controlledSearchResults, rowCount]);
2529
+ (0, import_react6.useEffect)(() => {
2530
+ if (!enabled) return;
2531
+ setSearchStatus(void 0);
2532
+ setInternalResults([]);
2533
+ emitResultsChanged([], -1);
2534
+ if (showSearch) {
2535
+ queueMicrotask(() => {
2536
+ searchInputRef.current?.focus({ preventScroll: true });
2537
+ });
2538
+ } else {
2539
+ cancelSearch();
2540
+ }
2541
+ }, [enabled, showSearch]);
2542
+ (0, import_react6.useEffect)(() => {
2543
+ if (!enabled || !showSearch) return;
2544
+ if (controlledSearchResults !== void 0) return;
2545
+ if (searchValue.trim() === "") {
2546
+ setSearchStatus(void 0);
2547
+ setInternalResults([]);
2548
+ cancelSearch();
2549
+ emitResultsChanged([], -1);
2550
+ return;
2551
+ }
2552
+ beginSearch(searchValue);
2553
+ }, [
2554
+ beginSearch,
2555
+ cancelSearch,
2556
+ controlledSearchResults,
2557
+ emitResultsChanged,
2558
+ enabled,
2559
+ searchValue,
2560
+ showSearch
2561
+ ]);
2562
+ (0, import_react6.useEffect)(() => {
2563
+ if (!enabled) return;
2564
+ const handleKeyDown = (event) => {
2565
+ if (!(event.ctrlKey || event.metaKey)) return;
2566
+ if (event.key.toLowerCase() !== "f") return;
2567
+ const root = rootRef?.current;
2568
+ if (root) {
2569
+ const active = document.activeElement;
2570
+ const focusInside = active === root || active instanceof Node && root.contains(active);
2571
+ if (!focusInside && active !== document.body) {
2572
+ return;
2573
+ }
2574
+ }
2575
+ event.preventDefault();
2576
+ event.stopPropagation();
2577
+ if (showSearch) {
2578
+ searchInputRef.current?.focus({ preventScroll: true });
2579
+ searchInputRef.current?.select();
2580
+ return;
2581
+ }
2582
+ if (controlledShowSearch === void 0) {
2583
+ setInternalShowSearch(true);
2584
+ }
2585
+ };
2586
+ window.addEventListener("keydown", handleKeyDown, true);
2587
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
2588
+ }, [controlledShowSearch, enabled, rootRef, showSearch]);
2589
+ (0, import_react6.useEffect)(() => () => cancelSearch(), [cancelSearch]);
2590
+ const searchMatchKeys = (0, import_react6.useMemo)(
2591
+ () => buildSearchMatchKeys(searchResults),
2592
+ [searchResults]
2593
+ );
2594
+ const activeMatch = (0, import_react6.useMemo)(() => {
2595
+ if (!searchStatus || searchStatus.selectedIndex < 0) return null;
2596
+ return searchResults[searchStatus.selectedIndex] ?? null;
2597
+ }, [searchResults, searchStatus]);
2598
+ if (!enabled) {
2599
+ return {
2600
+ enabled: false,
2601
+ showSearch: false,
2602
+ searchValue: "",
2603
+ searchResults: [],
2604
+ searchStatus: void 0,
2605
+ searchMatchKeys: EMPTY_MATCH_KEYS,
2606
+ activeMatch: null,
2607
+ searchInputRef,
2608
+ searchInputId,
2609
+ canClose: false,
2610
+ openSearch,
2611
+ closeSearch,
2612
+ setSearchValue,
2613
+ goToNext,
2614
+ goToPrevious
2615
+ };
2616
+ }
2617
+ return {
2618
+ enabled: true,
2619
+ showSearch,
2620
+ searchValue,
2621
+ searchResults,
2622
+ searchStatus,
2623
+ searchMatchKeys,
2624
+ activeMatch,
2625
+ searchInputRef,
2626
+ searchInputId,
2627
+ canClose: controlledShowSearch === void 0 || onSearchClose !== void 0,
2628
+ openSearch,
2629
+ closeSearch,
2630
+ setSearchValue,
2631
+ goToNext,
2632
+ goToPrevious
2633
+ };
2634
+ }
2635
+
1910
2636
  // src/components/ui/table/features/row-selection/rowSelection.ts
1911
2637
  function resolveRowSelection(mode, controlledSelection, internalSelection) {
1912
2638
  if (mode === "none") return {};
@@ -1929,7 +2655,12 @@ var DEFAULT_DATA_TABLE_LABELS = {
1929
2655
  selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
1930
2656
  expandRow: "Expand row",
1931
2657
  collapseRow: "Collapse row",
1932
- resizeColumn: "Resize column"
2658
+ resizeColumn: "Resize column",
2659
+ searchPlaceholder: "Search\u2026",
2660
+ searchResultHint: "Type to search",
2661
+ searchPrevious: "Previous result",
2662
+ searchNext: "Next result",
2663
+ searchClose: "Close search"
1933
2664
  };
1934
2665
  function resolveDataTableLabels(partial) {
1935
2666
  return {
@@ -1940,6 +2671,7 @@ function resolveDataTableLabels(partial) {
1940
2671
 
1941
2672
  // src/core/useGlideTable.ts
1942
2673
  var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
2674
+ var EMPTY_SEARCH_MATCH_KEYS = /* @__PURE__ */ new Set();
1943
2675
  function useGlideTable(options) {
1944
2676
  const {
1945
2677
  data,
@@ -1980,9 +2712,16 @@ function useGlideTable(options) {
1980
2712
  columnSizing: controlledColumnSizing,
1981
2713
  onColumnSizingChange,
1982
2714
  columnResizeMode = "onChange",
1983
- enableColumnFreeze = false
2715
+ enableColumnFreeze = false,
2716
+ enableInlineSearch = false,
2717
+ showSearch,
2718
+ searchValue,
2719
+ onSearchValueChange,
2720
+ onSearchClose,
2721
+ searchResults,
2722
+ onSearchResultsChanged
1984
2723
  } = options;
1985
- const labels = (0, import_react6.useMemo)(() => {
2724
+ const labels = (0, import_react7.useMemo)(() => {
1986
2725
  const resolved = resolveDataTableLabels(labelsProp);
1987
2726
  return {
1988
2727
  ...resolved,
@@ -1993,15 +2732,16 @@ function useGlideTable(options) {
1993
2732
  }, [labelsProp, emptyText, loadingText, selectionLabel]);
1994
2733
  const enableExpand = Boolean(toggleField);
1995
2734
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
1996
- const [internalRowSelection, setInternalRowSelection] = (0, import_react6.useState)({});
1997
- const [internalColumnSizing, setInternalColumnSizing] = (0, import_react6.useState)({});
1998
- const [internalExpandedRows, setInternalExpandedRows] = (0, import_react6.useState)(
2735
+ const [internalRowSelection, setInternalRowSelection] = (0, import_react7.useState)({});
2736
+ const [internalColumnSizing, setInternalColumnSizing] = (0, import_react7.useState)({});
2737
+ const [internalExpandedRows, setInternalExpandedRows] = (0, import_react7.useState)(
1999
2738
  () => /* @__PURE__ */ new Set()
2000
2739
  );
2001
- const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react6.useState)(null);
2002
- const scrollRef = (0, import_react6.useRef)(null);
2740
+ const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react7.useState)(null);
2741
+ const scrollRef = (0, import_react7.useRef)(null);
2742
+ const rootRef = (0, import_react7.useRef)(null);
2003
2743
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
2004
- (0, import_react6.useEffect)(() => {
2744
+ (0, import_react7.useEffect)(() => {
2005
2745
  if (enableVirtualization && enableRowSpan) {
2006
2746
  console.warn(
2007
2747
  "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
@@ -2015,7 +2755,7 @@ function useGlideTable(options) {
2015
2755
  );
2016
2756
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
2017
2757
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
2018
- const handleExpandedRowsChange = (0, import_react6.useCallback)(
2758
+ const handleExpandedRowsChange = (0, import_react7.useCallback)(
2019
2759
  (next) => {
2020
2760
  if (onExpandedRowsChange) {
2021
2761
  onExpandedRowsChange(next);
@@ -2076,13 +2816,13 @@ function useGlideTable(options) {
2076
2816
  getCoreRowModel: (0, import_react_table2.getCoreRowModel)(),
2077
2817
  getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
2078
2818
  });
2079
- const rowSpanColumnKeys = (0, import_react6.useMemo)(() => {
2819
+ const rowSpanColumnKeys = (0, import_react7.useMemo)(() => {
2080
2820
  if (!enableRowSpan) return [];
2081
2821
  return collectRowSpanColumns(columns);
2082
2822
  }, [enableRowSpan, columns]);
2083
2823
  const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
2084
2824
  const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
2085
- const columnRowSpanMap = (0, import_react6.useMemo)(
2825
+ const columnRowSpanMap = (0, import_react7.useMemo)(
2086
2826
  () => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
2087
2827
  [tableData, rowSpanColumnKeys]
2088
2828
  );
@@ -2091,7 +2831,7 @@ function useGlideTable(options) {
2091
2831
  const rows = table.getRowModel().rows;
2092
2832
  const columnCount = table.getAllLeafColumns().length || 1;
2093
2833
  const visibleLeafColumns = table.getVisibleLeafColumns();
2094
- const columnFreezeOffsets = (0, import_react6.useMemo)(() => {
2834
+ const columnFreezeOffsets = (0, import_react7.useMemo)(() => {
2095
2835
  if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
2096
2836
  return buildColumnFreezeOffsets(
2097
2837
  visibleLeafColumns.map((column) => ({
@@ -2111,13 +2851,46 @@ function useGlideTable(options) {
2111
2851
  const totalSize = rowVirtualizer.getTotalSize();
2112
2852
  const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
2113
2853
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
2114
- const selectedRowIndices = (0, import_react6.useMemo)(() => {
2854
+ const selectedRowIndices = (0, import_react7.useMemo)(() => {
2115
2855
  const indices = /* @__PURE__ */ new Set();
2116
2856
  for (const selectedRow of selectedRows) {
2117
2857
  indices.add(selectedRow.index);
2118
2858
  }
2119
2859
  return indices;
2120
2860
  }, [selectedRows]);
2861
+ const scrollCellIntoView = (0, import_react7.useCallback)(
2862
+ (rowIndex, colIndex, options2) => {
2863
+ const align = options2?.align ?? "nearest";
2864
+ const blockAlign = align === "center" ? "center" : "nearest";
2865
+ if (shouldVirtualize) {
2866
+ rowVirtualizer.scrollToIndex(rowIndex, {
2867
+ align: align === "nearest" ? "auto" : align
2868
+ });
2869
+ }
2870
+ const scrollElement = scrollRef.current;
2871
+ if (!scrollElement) return;
2872
+ const scrollToMatchedCell = () => {
2873
+ const cell = scrollElement.querySelector(
2874
+ `[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
2875
+ );
2876
+ if (cell instanceof HTMLElement) {
2877
+ cell.scrollIntoView({ block: blockAlign, inline: "nearest" });
2878
+ }
2879
+ };
2880
+ if (shouldVirtualize) {
2881
+ requestAnimationFrame(scrollToMatchedCell);
2882
+ return;
2883
+ }
2884
+ scrollToMatchedCell();
2885
+ },
2886
+ [rowVirtualizer, shouldVirtualize]
2887
+ );
2888
+ const handleCellNavigate = (0, import_react7.useCallback)(
2889
+ (position) => {
2890
+ scrollCellIntoView(position.row, position.col, { align: "nearest" });
2891
+ },
2892
+ [scrollCellIntoView]
2893
+ );
2121
2894
  const {
2122
2895
  dragState,
2123
2896
  activeSelectionBounds,
@@ -2129,11 +2902,13 @@ function useGlideTable(options) {
2129
2902
  data: tableData,
2130
2903
  rows,
2131
2904
  enabled: enableCellSelection,
2905
+ columnCount: visibleLeafColumns.length,
2132
2906
  enableSubtreeCopy: resolvedEnableSubtreeCopy,
2133
2907
  enableInsertPaste: enableInsertPaste ?? true,
2134
2908
  onDataChange,
2135
2909
  onBatchChange,
2136
- onRowsPaste
2910
+ onRowsPaste,
2911
+ onCellNavigate: handleCellNavigate
2137
2912
  });
2138
2913
  const {
2139
2914
  editingCell,
@@ -2143,23 +2918,193 @@ function useGlideTable(options) {
2143
2918
  commitEdit,
2144
2919
  cancelEdit
2145
2920
  } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
2146
- const handleCellMouseDownWithCommit = (0, import_react6.useCallback)(
2147
- (rowIndex, colIndex) => {
2921
+ const handleCellMouseDownWithCommit = (0, import_react7.useCallback)(
2922
+ (rowIndex, colIndex, options2) => {
2148
2923
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
2149
2924
  if (editingCell && !isSameEditingCell && !commitEdit()) {
2150
2925
  return;
2151
2926
  }
2152
- handleCellMouseDown(rowIndex, colIndex);
2927
+ handleCellMouseDown(rowIndex, colIndex, options2);
2153
2928
  },
2154
2929
  [commitEdit, editingCell, handleCellMouseDown]
2155
2930
  );
2156
- const clearHover = (0, import_react6.useCallback)(() => {
2931
+ const navigateToSearchResult = (0, import_react7.useCallback)(
2932
+ (item) => {
2933
+ const [colIndex, rowIndex] = item;
2934
+ handleCellMouseDownWithCommit(rowIndex, colIndex);
2935
+ scrollCellIntoView(rowIndex, colIndex, { align: "center" });
2936
+ },
2937
+ [handleCellMouseDownWithCommit, scrollCellIntoView]
2938
+ );
2939
+ const resolveSearchRowId = (0, import_react7.useCallback)(
2940
+ (row, index) => {
2941
+ if (getRowId) return getRowId(row, index);
2942
+ if (enableExpand) {
2943
+ const record = row;
2944
+ const idValue = record.id;
2945
+ if (idValue != null && String(idValue).length > 0) {
2946
+ return String(idValue);
2947
+ }
2948
+ const uniqueId = record.uniqueId;
2949
+ if (uniqueId != null && String(uniqueId).length > 0) {
2950
+ return String(uniqueId);
2951
+ }
2952
+ if (toggleField) {
2953
+ const toggleValue = record[toggleField];
2954
+ if (toggleValue != null && String(toggleValue).length > 0) {
2955
+ return String(toggleValue);
2956
+ }
2957
+ }
2958
+ }
2959
+ return String(index);
2960
+ },
2961
+ [enableExpand, getRowId, toggleField]
2962
+ );
2963
+ const searchCorpus = (0, import_react7.useMemo)(() => {
2964
+ if (!enableInlineSearch) return [];
2965
+ if (enableExpand && toggleField) {
2966
+ return buildTreeSearchCorpus(tableData, {
2967
+ toggleField,
2968
+ getRowId: resolveSearchRowId
2969
+ });
2970
+ }
2971
+ return buildFlatSearchCorpus(tableData, resolveSearchRowId);
2972
+ }, [
2973
+ enableExpand,
2974
+ enableInlineSearch,
2975
+ resolveSearchRowId,
2976
+ tableData,
2977
+ toggleField
2978
+ ]);
2979
+ const searchCorpusRef = (0, import_react7.useRef)(searchCorpus);
2980
+ searchCorpusRef.current = searchCorpus;
2981
+ const visibleRowIndexById = (0, import_react7.useMemo)(() => {
2982
+ const map = /* @__PURE__ */ new Map();
2983
+ for (const row of rows) {
2984
+ map.set(resolveSearchRowId(row.original, row.index), row.index);
2985
+ }
2986
+ return map;
2987
+ }, [resolveSearchRowId, rows]);
2988
+ const getSearchCellValue = (0, import_react7.useCallback)(
2989
+ (rowIndex, colIndex) => {
2990
+ const corpusRow = searchCorpusRef.current[rowIndex];
2991
+ const column = visibleLeafColumns[colIndex];
2992
+ if (!corpusRow || !column) return void 0;
2993
+ const visibleIndex = visibleRowIndexById.get(corpusRow.id);
2994
+ if (visibleIndex !== void 0) {
2995
+ const visibleRow = rows[visibleIndex];
2996
+ if (visibleRow) {
2997
+ return visibleRow.getValue(column.id);
2998
+ }
2999
+ }
3000
+ const columnDef = column.columnDef;
3001
+ if ("accessorFn" in columnDef && typeof columnDef.accessorFn === "function") {
3002
+ return columnDef.accessorFn(corpusRow.data, rowIndex);
3003
+ }
3004
+ if ("accessorKey" in columnDef && columnDef.accessorKey != null && columnDef.accessorKey !== "") {
3005
+ return corpusRow.data[String(columnDef.accessorKey)];
3006
+ }
3007
+ return corpusRow.data[column.id];
3008
+ },
3009
+ [rows, visibleLeafColumns, visibleRowIndexById]
3010
+ );
3011
+ const pendingSearchNavRef = (0, import_react7.useRef)(null);
3012
+ const focusSearchResult = (0, import_react7.useCallback)(
3013
+ (colIndex, visibleRowIndex) => {
3014
+ navigateToSearchResult([colIndex, visibleRowIndex]);
3015
+ },
3016
+ [navigateToSearchResult]
3017
+ );
3018
+ const navigateToCorpusSearchResult = (0, import_react7.useCallback)(
3019
+ (item) => {
3020
+ const [colIndex, corpusRowIndex] = item;
3021
+ const corpusRow = searchCorpusRef.current[corpusRowIndex];
3022
+ if (!corpusRow) return;
3023
+ const missingKeys = collectAncestorKeysToExpand(corpusRow, expandedRows);
3024
+ if (missingKeys.length > 0) {
3025
+ pendingSearchNavRef.current = {
3026
+ colIndex,
3027
+ rowId: corpusRow.id
3028
+ };
3029
+ const next = new Set(expandedRows);
3030
+ for (const key of corpusRow.ancestorToggleKeys) {
3031
+ next.add(key);
3032
+ }
3033
+ handleExpandedRowsChange(next);
3034
+ return;
3035
+ }
3036
+ const visibleItem = mapSearchResultToVisibleItem(
3037
+ item,
3038
+ searchCorpusRef.current,
3039
+ visibleRowIndexById
3040
+ );
3041
+ if (!visibleItem) return;
3042
+ focusSearchResult(visibleItem[0], visibleItem[1]);
3043
+ },
3044
+ [
3045
+ expandedRows,
3046
+ focusSearchResult,
3047
+ handleExpandedRowsChange,
3048
+ visibleRowIndexById
3049
+ ]
3050
+ );
3051
+ (0, import_react7.useEffect)(() => {
3052
+ const pending = pendingSearchNavRef.current;
3053
+ if (!pending) return;
3054
+ const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
3055
+ if (visibleRowIndex === void 0) return;
3056
+ pendingSearchNavRef.current = null;
3057
+ focusSearchResult(pending.colIndex, visibleRowIndex);
3058
+ }, [focusSearchResult, rows, visibleRowIndexById]);
3059
+ const initialSearchStartRow = virtualRows[0]?.index ?? 0;
3060
+ const inlineSearch = useInlineSearch({
3061
+ enabled: enableInlineSearch,
3062
+ rowCount: searchCorpus.length,
3063
+ columnCount: visibleLeafColumns.length,
3064
+ getCellValue: getSearchCellValue,
3065
+ initialStartRow: initialSearchStartRow,
3066
+ showSearch,
3067
+ searchValue,
3068
+ searchResults,
3069
+ onSearchValueChange,
3070
+ onSearchClose,
3071
+ onSearchResultsChanged,
3072
+ onNavigateToResult: navigateToCorpusSearchResult,
3073
+ rootRef
3074
+ });
3075
+ const visibleSearchMatchKeys = (0, import_react7.useMemo)(() => {
3076
+ if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
3077
+ return mapSearchResultsToVisibleKeys(
3078
+ inlineSearch.searchResults,
3079
+ searchCorpus,
3080
+ visibleRowIndexById
3081
+ );
3082
+ }, [
3083
+ enableInlineSearch,
3084
+ inlineSearch.searchResults,
3085
+ searchCorpus,
3086
+ visibleRowIndexById
3087
+ ]);
3088
+ const visibleActiveMatch = (0, import_react7.useMemo)(() => {
3089
+ if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
3090
+ return mapSearchResultToVisibleItem(
3091
+ inlineSearch.activeMatch,
3092
+ searchCorpus,
3093
+ visibleRowIndexById
3094
+ );
3095
+ }, [
3096
+ enableInlineSearch,
3097
+ inlineSearch.activeMatch,
3098
+ searchCorpus,
3099
+ visibleRowIndexById
3100
+ ]);
3101
+ const clearHover = (0, import_react7.useCallback)(() => {
2157
3102
  setHoveredRowIndex(null);
2158
3103
  }, []);
2159
- const handleRowHover = (0, import_react6.useCallback)((rowIndex, _rowData) => {
3104
+ const handleRowHover = (0, import_react7.useCallback)((rowIndex, _rowData) => {
2160
3105
  setHoveredRowIndex(rowIndex);
2161
3106
  }, []);
2162
- const handleToggleSelect = (0, import_react6.useCallback)(
3107
+ const handleToggleSelect = (0, import_react7.useCallback)(
2163
3108
  (row) => {
2164
3109
  if (!row.getCanSelect()) return;
2165
3110
  if (preserveRowSelection && row.getIsSelected()) {
@@ -2169,14 +3114,14 @@ function useGlideTable(options) {
2169
3114
  },
2170
3115
  [preserveRowSelection]
2171
3116
  );
2172
- const handleToggleExpand = (0, import_react6.useCallback)(
3117
+ const handleToggleExpand = (0, import_react7.useCallback)(
2173
3118
  (rowKey) => {
2174
3119
  if (preventExpand) return;
2175
3120
  handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
2176
3121
  },
2177
3122
  [preventExpand, handleExpandedRowsChange, expandedRows]
2178
3123
  );
2179
- const rowContextValue = (0, import_react6.useMemo)(() => {
3124
+ const rowContextValue = (0, import_react7.useMemo)(() => {
2180
3125
  return {
2181
3126
  rowSpan: {
2182
3127
  enableRowSpan,
@@ -2224,6 +3169,11 @@ function useGlideTable(options) {
2224
3169
  columnFreeze: {
2225
3170
  enableColumnFreeze,
2226
3171
  offsets: columnFreezeOffsets
3172
+ },
3173
+ inlineSearch: {
3174
+ enabled: enableInlineSearch,
3175
+ matchKeys: visibleSearchMatchKeys,
3176
+ activeMatch: visibleActiveMatch
2227
3177
  }
2228
3178
  };
2229
3179
  }, [
@@ -2259,14 +3209,17 @@ function useGlideTable(options) {
2259
3209
  labels.collapseRow,
2260
3210
  enableColumnResize,
2261
3211
  enableColumnFreeze,
2262
- columnFreezeOffsets
3212
+ columnFreezeOffsets,
3213
+ enableInlineSearch,
3214
+ visibleSearchMatchKeys,
3215
+ visibleActiveMatch
2263
3216
  ]);
2264
- const copySelectionRef = (0, import_react6.useRef)(copySelection);
2265
- (0, import_react6.useEffect)(() => {
3217
+ const copySelectionRef = (0, import_react7.useRef)(copySelection);
3218
+ (0, import_react7.useEffect)(() => {
2266
3219
  copySelectionRef.current = copySelection;
2267
3220
  }, [copySelection]);
2268
- const stableCopySelection = (0, import_react6.useCallback)((options2) => copySelectionRef.current(options2), []);
2269
- (0, import_react6.useEffect)(() => {
3221
+ const stableCopySelection = (0, import_react7.useCallback)((options2) => copySelectionRef.current(options2), []);
3222
+ (0, import_react7.useEffect)(() => {
2270
3223
  onCopyActionsReady?.({ copySelection: stableCopySelection });
2271
3224
  }, [onCopyActionsReady, stableCopySelection]);
2272
3225
  return {
@@ -2282,8 +3235,10 @@ function useGlideTable(options) {
2282
3235
  enableCellSelection,
2283
3236
  enableColumnResize,
2284
3237
  enableColumnFreeze,
3238
+ enableInlineSearch,
2285
3239
  shouldVirtualize,
2286
3240
  scrollRef,
3241
+ rootRef,
2287
3242
  rowVirtualizer,
2288
3243
  virtualRows,
2289
3244
  paddingTop,
@@ -2291,25 +3246,39 @@ function useGlideTable(options) {
2291
3246
  rowContextValue,
2292
3247
  handleToggleSelect,
2293
3248
  clearHover,
2294
- copySelection: stableCopySelection
3249
+ copySelection: stableCopySelection,
3250
+ inlineSearch: {
3251
+ showSearch: inlineSearch.showSearch,
3252
+ searchValue: inlineSearch.searchValue,
3253
+ searchStatus: inlineSearch.searchStatus,
3254
+ searchInputRef: inlineSearch.searchInputRef,
3255
+ searchInputId: inlineSearch.searchInputId,
3256
+ canClose: inlineSearch.canClose,
3257
+ searchRowCount: searchCorpus.length,
3258
+ setSearchValue: inlineSearch.setSearchValue,
3259
+ closeSearch: inlineSearch.closeSearch,
3260
+ goToNext: inlineSearch.goToNext,
3261
+ goToPrevious: inlineSearch.goToPrevious,
3262
+ openSearch: inlineSearch.openSearch
3263
+ }
2295
3264
  };
2296
3265
  }
2297
3266
 
2298
3267
  // src/components/ui/table/components/DataTable/DataTable.tsx
2299
- var import_jsx_runtime5 = require("react/jsx-runtime");
3268
+ var import_jsx_runtime6 = require("react/jsx-runtime");
2300
3269
  function DefaultScroll({
2301
3270
  scrollRef,
2302
3271
  children,
2303
3272
  className
2304
3273
  }) {
2305
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
3274
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
2306
3275
  }
2307
3276
  function DefaultPending({
2308
3277
  loadingText,
2309
3278
  className,
2310
3279
  classNames
2311
3280
  }) {
2312
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3281
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2313
3282
  "div",
2314
3283
  {
2315
3284
  className: cn(
@@ -2319,7 +3288,7 @@ function DefaultPending({
2319
3288
  classNames?.pending,
2320
3289
  className
2321
3290
  ),
2322
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: cn("data-table-loading-text", classNames?.loadingText), children: loadingText })
3291
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: cn("data-table-loading-text", classNames?.loadingText), children: loadingText })
2323
3292
  }
2324
3293
  );
2325
3294
  }
@@ -2328,7 +3297,7 @@ function DefaultEmpty({
2328
3297
  columnCount,
2329
3298
  classNames
2330
3299
  }) {
2331
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3300
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2332
3301
  "td",
2333
3302
  {
2334
3303
  colSpan: columnCount,
@@ -2361,15 +3330,18 @@ function DataTable({
2361
3330
  enableCellSelection,
2362
3331
  enableColumnResize,
2363
3332
  enableColumnFreeze,
3333
+ enableInlineSearch,
2364
3334
  shouldVirtualize,
2365
3335
  scrollRef,
3336
+ rootRef,
2366
3337
  rowVirtualizer,
2367
3338
  virtualRows,
2368
3339
  paddingTop,
2369
3340
  paddingBottom,
2370
3341
  rowContextValue,
2371
3342
  handleToggleSelect,
2372
- clearHover
3343
+ clearHover,
3344
+ inlineSearch
2373
3345
  } = useGlideTable(glideOptions);
2374
3346
  const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
2375
3347
  const ScrollSlot = slots?.Scroll ?? DefaultScroll;
@@ -2377,12 +3349,12 @@ function DataTable({
2377
3349
  const PendingSlot = slots?.Pending ?? DefaultPending;
2378
3350
  const EmptySlot = slots?.Empty ?? DefaultEmpty;
2379
3351
  const freezeOffsets = rowContextValue.columnFreeze.offsets;
2380
- const contextValue = (0, import_react7.useMemo)(
3352
+ const contextValue = (0, import_react8.useMemo)(
2381
3353
  () => ({ ...rowContextValue, classNames }),
2382
3354
  [rowContextValue, classNames]
2383
3355
  );
2384
3356
  if (isPending) {
2385
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3357
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2386
3358
  PendingSlot,
2387
3359
  {
2388
3360
  loadingText,
@@ -2391,19 +3363,21 @@ function DataTable({
2391
3363
  }
2392
3364
  );
2393
3365
  }
2394
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3366
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2395
3367
  "div",
2396
3368
  {
3369
+ ref: rootRef,
2397
3370
  className: cn(
2398
3371
  "DataTableJSX",
2399
3372
  !enableCellSelection && "DataTableJSX--no-cell-selection",
2400
3373
  enableColumnResize && "DataTableJSX--column-resize",
2401
3374
  enableColumnFreeze && "DataTableJSX--column-freeze",
3375
+ enableInlineSearch && "DataTableJSX--inline-search",
2402
3376
  classNames?.root,
2403
3377
  className
2404
3378
  ),
2405
3379
  children: [
2406
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3380
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2407
3381
  ToolbarSlot,
2408
3382
  {
2409
3383
  filteredCount: filteredCount ?? tableData.length,
@@ -2415,14 +3389,36 @@ function DataTable({
2415
3389
  classNames
2416
3390
  }
2417
3391
  ),
2418
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3392
+ enableInlineSearch ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3393
+ DataTableSearch,
3394
+ {
3395
+ showSearch: inlineSearch.showSearch,
3396
+ searchValue: inlineSearch.searchValue,
3397
+ searchStatus: inlineSearch.searchStatus,
3398
+ searchInputId: inlineSearch.searchInputId,
3399
+ searchInputRef: inlineSearch.searchInputRef,
3400
+ canClose: inlineSearch.canClose,
3401
+ placeholder: labels.searchPlaceholder,
3402
+ resultHint: labels.searchResultHint,
3403
+ previousLabel: labels.searchPrevious,
3404
+ nextLabel: labels.searchNext,
3405
+ closeLabel: labels.searchClose,
3406
+ rowsTotal: inlineSearch.searchRowCount,
3407
+ classNames,
3408
+ onSearchValueChange: inlineSearch.setSearchValue,
3409
+ onClose: inlineSearch.closeSearch,
3410
+ onNext: inlineSearch.goToNext,
3411
+ onPrevious: inlineSearch.goToPrevious
3412
+ }
3413
+ ) : null,
3414
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2419
3415
  "table",
2420
3416
  {
2421
3417
  className: cn("data-table", classNames?.table),
2422
3418
  style: enableColumnResize ? { width: table.getTotalSize() } : void 0,
2423
3419
  onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
2424
3420
  children: [
2425
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { className: cn("data-table-head", classNames?.head), children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3421
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { className: cn("data-table-head", classNames?.head), children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2426
3422
  "tr",
2427
3423
  {
2428
3424
  className: cn("data-table-head-row", classNames?.headRow),
@@ -2442,7 +3438,7 @@ function DataTable({
2442
3438
  ...sizeStyle,
2443
3439
  ...freezeStyle
2444
3440
  };
2445
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3441
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2446
3442
  "th",
2447
3443
  {
2448
3444
  "data-resizing": header.column.getIsResizing() ? "" : void 0,
@@ -2458,7 +3454,7 @@ function DataTable({
2458
3454
  ),
2459
3455
  children: [
2460
3456
  header.isPlaceholder ? null : (0, import_react_table3.flexRender)(header.column.columnDef.header, header.getContext()),
2461
- canResize ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3457
+ canResize ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2462
3458
  "div",
2463
3459
  {
2464
3460
  role: "separator",
@@ -2484,20 +3480,20 @@ function DataTable({
2484
3480
  },
2485
3481
  headerGroup.id
2486
3482
  )) }),
2487
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DataTableContextProvider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3483
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DataTableContextProvider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2488
3484
  "tbody",
2489
3485
  {
2490
3486
  onMouseLeave: clearHover,
2491
3487
  className: cn("data-table-body", classNames?.body),
2492
- children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3488
+ children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2493
3489
  EmptySlot,
2494
3490
  {
2495
3491
  emptyText,
2496
3492
  columnCount,
2497
3493
  classNames
2498
3494
  }
2499
- ) : shouldVirtualize ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
2500
- paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3495
+ ) : shouldVirtualize ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
3496
+ paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2501
3497
  "tr",
2502
3498
  {
2503
3499
  "aria-hidden": true,
@@ -2505,7 +3501,7 @@ function DataTable({
2505
3501
  "data-table-virtual-spacer",
2506
3502
  classNames?.virtualSpacer
2507
3503
  ),
2508
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3504
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2509
3505
  "td",
2510
3506
  {
2511
3507
  colSpan: columnCount,
@@ -2521,7 +3517,7 @@ function DataTable({
2521
3517
  virtualRows.map((virtualRow) => {
2522
3518
  const row = rows[virtualRow.index];
2523
3519
  if (!row) return null;
2524
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3520
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2525
3521
  RowSlot,
2526
3522
  {
2527
3523
  row,
@@ -2532,7 +3528,7 @@ function DataTable({
2532
3528
  row.id
2533
3529
  );
2534
3530
  }),
2535
- paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3531
+ paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2536
3532
  "tr",
2537
3533
  {
2538
3534
  "aria-hidden": true,
@@ -2540,7 +3536,7 @@ function DataTable({
2540
3536
  "data-table-virtual-spacer",
2541
3537
  classNames?.virtualSpacer
2542
3538
  ),
2543
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3539
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2544
3540
  "td",
2545
3541
  {
2546
3542
  colSpan: columnCount,
@@ -2553,7 +3549,7 @@ function DataTable({
2553
3549
  )
2554
3550
  }
2555
3551
  )
2556
- ] }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3552
+ ] }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2557
3553
  RowSlot,
2558
3554
  {
2559
3555
  row,
@@ -2572,10 +3568,10 @@ function DataTable({
2572
3568
  }
2573
3569
 
2574
3570
  // src/components/ui/table/components/Table/Table.tsx
2575
- var import_react10 = require("react");
3571
+ var import_react11 = require("react");
2576
3572
 
2577
3573
  // src/components/ui/table/components/Table/buildColumnDef.tsx
2578
- var import_jsx_runtime6 = require("react/jsx-runtime");
3574
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2579
3575
  function SortableHeader({
2580
3576
  label,
2581
3577
  field,
@@ -2584,15 +3580,15 @@ function SortableHeader({
2584
3580
  }) {
2585
3581
  const isActive = sort?.field === field;
2586
3582
  const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
2587
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
3583
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2588
3584
  "button",
2589
3585
  {
2590
3586
  type: "button",
2591
3587
  className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
2592
3588
  onClick: () => onSort(field),
2593
3589
  children: [
2594
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label }),
2595
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { className: "sortable-header-icon" })
3590
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label }),
3591
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { className: "sortable-header-icon" })
2596
3592
  ]
2597
3593
  }
2598
3594
  );
@@ -2625,7 +3621,7 @@ function buildColumnDef(props, sort, onSort) {
2625
3621
  ...minWidth != null ? { minSize: minWidth } : {},
2626
3622
  ...maxWidth != null ? { maxSize: maxWidth } : {},
2627
3623
  ...resizable === false ? { enableResizing: false } : {},
2628
- header: sortable ? () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SortableHeader, { label: children, field, sort, onSort }) : (
3624
+ header: sortable ? () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SortableHeader, { label: children, field, sort, onSort }) : (
2629
3625
  // eslint-disable-next-line @typescript-eslint/promise-function-async
2630
3626
  () => children
2631
3627
  ),
@@ -2652,10 +3648,10 @@ function buildColumnDef(props, sort, onSort) {
2652
3648
  }
2653
3649
 
2654
3650
  // src/components/ui/table/components/Table/parseTableChildren.ts
2655
- var import_react9 = require("react");
3651
+ var import_react10 = require("react");
2656
3652
 
2657
3653
  // src/components/ui/table/components/Table/tableChildTypes.ts
2658
- var import_react8 = require("react");
3654
+ var import_react9 = require("react");
2659
3655
  var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
2660
3656
  var TABLE_BODY_DISPLAY_NAME = "Table.Body";
2661
3657
  var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
@@ -2667,16 +3663,16 @@ function getComponentDisplayName(type) {
2667
3663
  return void 0;
2668
3664
  }
2669
3665
  function isTableHeaderElement(child) {
2670
- return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
3666
+ return (0, import_react9.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
2671
3667
  }
2672
3668
  function isTableBodyElement(child) {
2673
- return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
3669
+ return (0, import_react9.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
2674
3670
  }
2675
3671
  function isTableColumnElement(child) {
2676
- return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
3672
+ return (0, import_react9.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
2677
3673
  }
2678
3674
  function isTablePaginationElement(child) {
2679
- return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
3675
+ return (0, import_react9.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
2680
3676
  }
2681
3677
 
2682
3678
  // src/components/ui/table/components/Table/parseTableChildren.ts
@@ -2686,7 +3682,7 @@ function parseTableChildren(children) {
2686
3682
  body: null,
2687
3683
  pagination: null
2688
3684
  };
2689
- for (const child of import_react9.Children.toArray(children)) {
3685
+ for (const child of import_react10.Children.toArray(children)) {
2690
3686
  if (isTableHeaderElement(child)) {
2691
3687
  slots.header = child;
2692
3688
  continue;
@@ -2703,12 +3699,12 @@ function parseTableChildren(children) {
2703
3699
  }
2704
3700
  function flattenColumnElements(children) {
2705
3701
  const result = [];
2706
- for (const child of import_react9.Children.toArray(children)) {
3702
+ for (const child of import_react10.Children.toArray(children)) {
2707
3703
  if (isTableColumnElement(child)) {
2708
3704
  result.push(child);
2709
3705
  continue;
2710
3706
  }
2711
- if ((0, import_react9.isValidElement)(child)) {
3707
+ if ((0, import_react10.isValidElement)(child)) {
2712
3708
  const nested = child.props.children;
2713
3709
  if (nested != null) {
2714
3710
  result.push(...flattenColumnElements(nested));
@@ -2773,7 +3769,7 @@ function TableHeader(props) {
2773
3769
  TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
2774
3770
 
2775
3771
  // src/components/ui/table/components/Table/TablePagination.tsx
2776
- var import_jsx_runtime7 = require("react/jsx-runtime");
3772
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2777
3773
  function TablePagination({
2778
3774
  page,
2779
3775
  pageSize = 10,
@@ -2785,8 +3781,8 @@ function TablePagination({
2785
3781
  const safePage = Math.min(Math.max(1, page), totalPages);
2786
3782
  const canGoPrev = safePage > 1;
2787
3783
  const canGoNext = safePage < totalPages;
2788
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("TablePaginationJSX", className), children: [
2789
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3784
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: cn("TablePaginationJSX", className), children: [
3785
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2790
3786
  "button",
2791
3787
  {
2792
3788
  type: "button",
@@ -2794,15 +3790,15 @@ function TablePagination({
2794
3790
  disabled: !canGoPrev,
2795
3791
  onClick: () => onChange(safePage - 1),
2796
3792
  "aria-label": "Previous page",
2797
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeft, { className: "pagination-button-icon" })
3793
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronLeft, { className: "pagination-button-icon" })
2798
3794
  }
2799
3795
  ),
2800
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "pagination-label", children: [
3796
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "pagination-label", children: [
2801
3797
  safePage,
2802
3798
  " / ",
2803
3799
  totalPages
2804
3800
  ] }),
2805
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3801
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2806
3802
  "button",
2807
3803
  {
2808
3804
  type: "button",
@@ -2810,7 +3806,7 @@ function TablePagination({
2810
3806
  disabled: !canGoNext,
2811
3807
  onClick: () => onChange(safePage + 1),
2812
3808
  "aria-label": "Next page",
2813
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRight, { className: "pagination-button-icon" })
3809
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChevronRight, { className: "pagination-button-icon" })
2814
3810
  }
2815
3811
  )
2816
3812
  ] });
@@ -2818,7 +3814,7 @@ function TablePagination({
2818
3814
  TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
2819
3815
 
2820
3816
  // src/components/ui/table/components/Table/Table.tsx
2821
- var import_jsx_runtime8 = require("react/jsx-runtime");
3817
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2822
3818
  function TableRoot({
2823
3819
  data,
2824
3820
  children,
@@ -2827,12 +3823,12 @@ function TableRoot({
2827
3823
  filteredCount,
2828
3824
  ...dataTableProps
2829
3825
  }) {
2830
- const { header, pagination: paginationElement } = (0, import_react10.useMemo)(
3826
+ const { header, pagination: paginationElement } = (0, import_react11.useMemo)(
2831
3827
  () => parseTableChildren(children),
2832
3828
  [children]
2833
3829
  );
2834
- const [sort, setSort] = (0, import_react10.useState)(null);
2835
- const handleSort = (0, import_react10.useCallback)((field) => {
3830
+ const [sort, setSort] = (0, import_react11.useState)(null);
3831
+ const handleSort = (0, import_react11.useCallback)((field) => {
2836
3832
  setSort((previous) => {
2837
3833
  if (previous?.field !== field) {
2838
3834
  return { field, direction: "asc" };
@@ -2843,7 +3839,7 @@ function TableRoot({
2843
3839
  return null;
2844
3840
  });
2845
3841
  }, []);
2846
- const columns = (0, import_react10.useMemo)(() => {
3842
+ const columns = (0, import_react11.useMemo)(() => {
2847
3843
  return extractColumnElements(header).map(
2848
3844
  (columnElement) => buildColumnDef(columnElement.props, sort, handleSort)
2849
3845
  );
@@ -2852,7 +3848,7 @@ function TableRoot({
2852
3848
  const pageSize = paginationProps?.pageSize ?? 10;
2853
3849
  const page = paginationProps?.page ?? 1;
2854
3850
  const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
2855
- const tableData = (0, import_react10.useMemo)(() => {
3851
+ const tableData = (0, import_react11.useMemo)(() => {
2856
3852
  const sortedData = sortTableData(data, sort);
2857
3853
  if (!paginationProps) return sortedData;
2858
3854
  return paginateTableData(sortedData, page, pageSize);
@@ -2860,8 +3856,8 @@ function TableRoot({
2860
3856
  if (columns.length === 0) {
2861
3857
  console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
2862
3858
  }
2863
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "TableJSX", children: [
2864
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3859
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "TableJSX", children: [
3860
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2865
3861
  DataTable,
2866
3862
  {
2867
3863
  ...dataTableProps,
@@ -2872,7 +3868,7 @@ function TableRoot({
2872
3868
  className: cn(className, paginationProps && "DataTableJSX--with-pagination")
2873
3869
  }
2874
3870
  ),
2875
- paginationProps && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
3871
+ paginationProps && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2876
3872
  TablePagination,
2877
3873
  {
2878
3874
  page,
@@ -2892,7 +3888,7 @@ function createTable() {
2892
3888
  Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
2893
3889
  return Object.assign(
2894
3890
  function BoundTable(props) {
2895
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TableRoot, { ...props });
3891
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableRoot, { ...props });
2896
3892
  },
2897
3893
  {
2898
3894
  Header: TableHeader,