react-glide-table 1.4.0 → 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/core.js CHANGED
@@ -5,7 +5,12 @@ var DEFAULT_DATA_TABLE_LABELS = {
5
5
  selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
6
6
  expandRow: "Expand row",
7
7
  collapseRow: "Collapse row",
8
- resizeColumn: "Resize column"
8
+ resizeColumn: "Resize column",
9
+ searchPlaceholder: "Search\u2026",
10
+ searchResultHint: "Type to search",
11
+ searchPrevious: "Previous result",
12
+ searchNext: "Next result",
13
+ searchClose: "Close search"
9
14
  };
10
15
  function resolveDataTableLabels(partial) {
11
16
  return {
@@ -29,11 +34,11 @@ import {
29
34
  useVirtualizer
30
35
  } from "@tanstack/react-virtual";
31
36
  import {
32
- useCallback as useCallback3,
33
- useEffect as useEffect4,
34
- useMemo as useMemo2,
35
- useRef as useRef4,
36
- useState as useState3
37
+ useCallback as useCallback4,
38
+ useEffect as useEffect5,
39
+ useMemo as useMemo3,
40
+ useRef as useRef5,
41
+ useState as useState4
37
42
  } from "react";
38
43
 
39
44
  // src/components/ui/table/constants.ts
@@ -191,6 +196,36 @@ function getCellSelectionBounds(start, end) {
191
196
  endCol: Math.max(start.col, end.col)
192
197
  };
193
198
  }
199
+ function getCellNavigationDelta(key) {
200
+ switch (key) {
201
+ case "ArrowUp":
202
+ case "w":
203
+ case "W":
204
+ return { row: -1, col: 0 };
205
+ case "ArrowDown":
206
+ case "s":
207
+ case "S":
208
+ return { row: 1, col: 0 };
209
+ case "ArrowLeft":
210
+ case "a":
211
+ case "A":
212
+ return { row: 0, col: -1 };
213
+ case "ArrowRight":
214
+ case "d":
215
+ case "D":
216
+ return { row: 0, col: 1 };
217
+ default:
218
+ return null;
219
+ }
220
+ }
221
+ function clampCellPosition(position, rowCount, columnCount) {
222
+ const maxRow = Math.max(rowCount - 1, 0);
223
+ const maxCol = Math.max(columnCount - 1, 0);
224
+ return {
225
+ row: Math.min(Math.max(position.row, 0), maxRow),
226
+ col: Math.min(Math.max(position.col, 0), maxCol)
227
+ };
228
+ }
194
229
  function measureMergedSpanRowHeights(rowIndex, rowSpan, cellElement) {
195
230
  if (rowSpan <= 1) return void 0;
196
231
  const tbody = cellElement?.closest("tbody") ?? (typeof document !== "undefined" ? document.querySelector("tbody.data-table-body") : null);
@@ -714,26 +749,44 @@ function useCellSelection({
714
749
  data,
715
750
  rows,
716
751
  enabled = true,
752
+ columnCount = 0,
717
753
  enableSubtreeCopy = false,
718
754
  enableInsertPaste = true,
719
755
  onDataChange,
720
756
  onBatchChange,
721
- onRowsPaste
757
+ onRowsPaste,
758
+ onCellNavigate
722
759
  }) {
723
760
  const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
724
761
  const pendingPasteModeRef = useRef2(null);
762
+ const dragStateRef = useRef2(dragState);
763
+ const onCellNavigateRef = useRef2(onCellNavigate);
764
+ dragStateRef.current = dragState;
765
+ onCellNavigateRef.current = onCellNavigate;
725
766
  const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
726
767
  const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
727
768
  const handleCellMouseDown = useCallback2(
728
- (rowIndex, colIndex) => {
769
+ (rowIndex, colIndex, options) => {
729
770
  if (!enabled) return;
730
- setDragState({
731
- isSelecting: true,
732
- isFillDragging: false,
733
- start: { row: rowIndex, col: colIndex },
734
- end: { row: rowIndex, col: colIndex },
735
- fillAnchor: null,
736
- fillEnd: null
771
+ setDragState((prev) => {
772
+ if (options?.shiftKey && prev.start) {
773
+ return {
774
+ ...prev,
775
+ isSelecting: true,
776
+ isFillDragging: false,
777
+ end: { row: rowIndex, col: colIndex },
778
+ fillAnchor: null,
779
+ fillEnd: null
780
+ };
781
+ }
782
+ return {
783
+ isSelecting: true,
784
+ isFillDragging: false,
785
+ start: { row: rowIndex, col: colIndex },
786
+ end: { row: rowIndex, col: colIndex },
787
+ fillAnchor: null,
788
+ fillEnd: null
789
+ };
737
790
  });
738
791
  },
739
792
  [enabled]
@@ -775,6 +828,53 @@ function useCellSelection({
775
828
  setDragState(INITIAL_DRAG_STATE);
776
829
  }
777
830
  }, [enabled]);
831
+ useEffect2(() => {
832
+ if (!enabled) return;
833
+ const handleKeyDown = (e) => {
834
+ if (e.ctrlKey || e.metaKey || e.altKey) return;
835
+ if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
836
+ return;
837
+ }
838
+ const delta = getCellNavigationDelta(e.key);
839
+ if (!delta) return;
840
+ const prev = dragStateRef.current;
841
+ if (!prev.start || !prev.end) return;
842
+ if (prev.isSelecting || prev.isFillDragging) return;
843
+ const rowCount = rows.length;
844
+ const resolvedColumnCount = columnCount > 0 ? columnCount : rows[0]?.getVisibleCells().length ?? 0;
845
+ if (rowCount <= 0 || resolvedColumnCount <= 0) return;
846
+ const nextEnd = clampCellPosition(
847
+ {
848
+ row: prev.end.row + delta.row,
849
+ col: prev.end.col + delta.col
850
+ },
851
+ rowCount,
852
+ resolvedColumnCount
853
+ );
854
+ if (nextEnd.row === prev.end.row && nextEnd.col === prev.end.col) return;
855
+ e.preventDefault();
856
+ const nextState = e.shiftKey ? {
857
+ ...prev,
858
+ isSelecting: false,
859
+ isFillDragging: false,
860
+ end: nextEnd,
861
+ fillAnchor: null,
862
+ fillEnd: null
863
+ } : {
864
+ isSelecting: false,
865
+ isFillDragging: false,
866
+ start: nextEnd,
867
+ end: nextEnd,
868
+ fillAnchor: null,
869
+ fillEnd: null
870
+ };
871
+ dragStateRef.current = nextState;
872
+ setDragState(nextState);
873
+ onCellNavigateRef.current?.(nextEnd);
874
+ };
875
+ window.addEventListener("keydown", handleKeyDown);
876
+ return () => window.removeEventListener("keydown", handleKeyDown);
877
+ }, [columnCount, enabled, rows]);
778
878
  const copySelection = useCallback2(
779
879
  async (options) => {
780
880
  if (!enabled || !activeSelectionBounds) return false;
@@ -1015,8 +1115,469 @@ function getColumnFreezeStyle(offset, options) {
1015
1115
  };
1016
1116
  }
1017
1117
 
1118
+ // src/components/ui/table/features/inline-search/inlineSearch.ts
1119
+ var INLINE_SEARCH_MAX_RESULTS = 1e3;
1120
+ var INLINE_SEARCH_TARGET_TICK_MS = 10;
1121
+ var INLINE_SEARCH_INITIAL_STRIDE = 10;
1122
+ function escapeSearchRegex(value) {
1123
+ return value.replace(/([$()*+.?[\\\]^{|}-])/g, "\\$1");
1124
+ }
1125
+ function createSearchRegex(query) {
1126
+ const trimmed = query.trim();
1127
+ if (!trimmed) return null;
1128
+ return new RegExp(escapeSearchRegex(trimmed), "i");
1129
+ }
1130
+ function cellValueToSearchText(value) {
1131
+ if (value == null) return void 0;
1132
+ if (typeof value === "string") return value;
1133
+ if (typeof value === "number" || typeof value === "boolean") {
1134
+ return String(value);
1135
+ }
1136
+ if (Array.isArray(value)) {
1137
+ return value.map((item) => cellValueToSearchText(item) ?? "").join(" ");
1138
+ }
1139
+ if (typeof value === "object") {
1140
+ try {
1141
+ return JSON.stringify(value);
1142
+ } catch {
1143
+ return String(value);
1144
+ }
1145
+ }
1146
+ return String(value);
1147
+ }
1148
+ function formatSearchResultLabel(status) {
1149
+ const countLabel = status.results >= INLINE_SEARCH_MAX_RESULTS ? `over ${INLINE_SEARCH_MAX_RESULTS}` : `${status.results} result${status.results !== 1 ? "s" : ""}`;
1150
+ if (status.selectedIndex >= 0 && status.results > 0) {
1151
+ return `${status.selectedIndex + 1} of ${countLabel}`;
1152
+ }
1153
+ return countLabel;
1154
+ }
1155
+ function nextSearchIndex(selectedIndex, results) {
1156
+ if (results <= 0) return -1;
1157
+ if (selectedIndex < 0) return 0;
1158
+ return (selectedIndex + 1) % results;
1159
+ }
1160
+ function previousSearchIndex(selectedIndex, results) {
1161
+ if (results <= 0) return -1;
1162
+ if (selectedIndex < 0) return results - 1;
1163
+ let next = (selectedIndex - 1) % results;
1164
+ if (next < 0) next += results;
1165
+ return next;
1166
+ }
1167
+ function buildSearchMatchKey(colIndex, rowIndex) {
1168
+ return `${colIndex}:${rowIndex}`;
1169
+ }
1170
+ function buildSearchMatchKeys(results) {
1171
+ const keys = /* @__PURE__ */ new Set();
1172
+ for (const [colIndex, rowIndex] of results) {
1173
+ keys.add(buildSearchMatchKey(colIndex, rowIndex));
1174
+ }
1175
+ return keys;
1176
+ }
1177
+ function collectSearchMatchesInRange(options) {
1178
+ const {
1179
+ query,
1180
+ startRow,
1181
+ rowCount,
1182
+ columnCount,
1183
+ getCellValue,
1184
+ maxResults = INLINE_SEARCH_MAX_RESULTS
1185
+ } = options;
1186
+ const regex = createSearchRegex(query);
1187
+ if (!regex || rowCount <= 0 || columnCount <= 0) return [];
1188
+ const matches = [];
1189
+ for (let rowOffset = 0; rowOffset < rowCount; rowOffset += 1) {
1190
+ const rowIndex = startRow + rowOffset;
1191
+ for (let colIndex = 0; colIndex < columnCount; colIndex += 1) {
1192
+ const text = cellValueToSearchText(getCellValue(rowIndex, colIndex));
1193
+ if (text !== void 0 && regex.test(text)) {
1194
+ matches.push([colIndex, rowIndex]);
1195
+ if (matches.length >= maxResults) {
1196
+ return matches;
1197
+ }
1198
+ }
1199
+ }
1200
+ }
1201
+ return matches;
1202
+ }
1203
+ function nextSearchStride(currentStride, elapsedMs, targetMs = INLINE_SEARCH_TARGET_TICK_MS) {
1204
+ const rounded = Math.max(elapsedMs, 1);
1205
+ const scalar = targetMs / rounded;
1206
+ return Math.max(1, Math.ceil(currentStride * scalar));
1207
+ }
1208
+ function buildFlatSearchCorpus(rows, getRowId) {
1209
+ return rows.map((data, index) => ({
1210
+ id: getRowId(data, index),
1211
+ data,
1212
+ ancestorToggleKeys: []
1213
+ }));
1214
+ }
1215
+ function buildTreeSearchCorpus(visibleRows, options) {
1216
+ const { toggleField, getRowId } = options;
1217
+ const corpus = [];
1218
+ const seen = /* @__PURE__ */ new Set();
1219
+ const walk = (node, ancestorToggleKeys) => {
1220
+ const id = getRowId(node, corpus.length);
1221
+ if (seen.has(id)) return;
1222
+ seen.add(id);
1223
+ corpus.push({
1224
+ id,
1225
+ data: node,
1226
+ ancestorToggleKeys
1227
+ });
1228
+ const children = node.children;
1229
+ if (!Array.isArray(children) || children.length === 0) return;
1230
+ const toggleValue = node[toggleField];
1231
+ const childAncestors = typeof toggleValue === "string" && toggleValue.length > 0 ? [...ancestorToggleKeys, toggleValue] : ancestorToggleKeys;
1232
+ for (const child of children) {
1233
+ if (child && typeof child === "object") {
1234
+ walk(child, childAncestors);
1235
+ }
1236
+ }
1237
+ };
1238
+ for (const row of visibleRows) {
1239
+ const level = row.level;
1240
+ if (level === 0 || level === void 0) {
1241
+ walk(row, []);
1242
+ }
1243
+ }
1244
+ for (const row of visibleRows) {
1245
+ const id = getRowId(row, corpus.length);
1246
+ if (seen.has(id)) continue;
1247
+ walk(row, []);
1248
+ }
1249
+ return corpus;
1250
+ }
1251
+ function mapSearchResultsToVisibleKeys(results, corpus, visibleRowIndexById) {
1252
+ const keys = /* @__PURE__ */ new Set();
1253
+ for (const [colIndex, corpusRowIndex] of results) {
1254
+ const corpusRow = corpus[corpusRowIndex];
1255
+ if (!corpusRow) continue;
1256
+ const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
1257
+ if (visibleRowIndex === void 0) continue;
1258
+ keys.add(buildSearchMatchKey(colIndex, visibleRowIndex));
1259
+ }
1260
+ return keys;
1261
+ }
1262
+ function mapSearchResultToVisibleItem(item, corpus, visibleRowIndexById) {
1263
+ const [colIndex, corpusRowIndex] = item;
1264
+ const corpusRow = corpus[corpusRowIndex];
1265
+ if (!corpusRow) return null;
1266
+ const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
1267
+ if (visibleRowIndex === void 0) return null;
1268
+ return [colIndex, visibleRowIndex];
1269
+ }
1270
+ function collectAncestorKeysToExpand(corpusRow, expandedRows) {
1271
+ return corpusRow.ancestorToggleKeys.filter((key) => !expandedRows.has(key));
1272
+ }
1273
+
1274
+ // src/components/ui/table/features/inline-search/useInlineSearch.ts
1275
+ import {
1276
+ useCallback as useCallback3,
1277
+ useEffect as useEffect3,
1278
+ useId,
1279
+ useMemo,
1280
+ useRef as useRef3,
1281
+ useState as useState3
1282
+ } from "react";
1283
+ var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
1284
+ function useInlineSearch({
1285
+ enabled = false,
1286
+ rowCount,
1287
+ columnCount,
1288
+ getCellValue,
1289
+ initialStartRow = 0,
1290
+ showSearch: controlledShowSearch,
1291
+ searchValue: controlledSearchValue,
1292
+ searchResults: controlledSearchResults,
1293
+ onSearchValueChange,
1294
+ onSearchClose,
1295
+ onSearchResultsChanged,
1296
+ onNavigateToResult,
1297
+ rootRef
1298
+ }) {
1299
+ const searchInputId = useId();
1300
+ const searchInputRef = useRef3(null);
1301
+ const [internalShowSearch, setInternalShowSearch] = useState3(false);
1302
+ const [internalSearchValue, setInternalSearchValue] = useState3("");
1303
+ const [internalResults, setInternalResults] = useState3(
1304
+ []
1305
+ );
1306
+ const [searchStatus, setSearchStatus] = useState3();
1307
+ const searchStatusRef = useRef3(searchStatus);
1308
+ searchStatusRef.current = searchStatus;
1309
+ const abortControllerRef = useRef3(null);
1310
+ const searchHandleRef = useRef3(void 0);
1311
+ const initialStartRowRef = useRef3(initialStartRow);
1312
+ initialStartRowRef.current = initialStartRow;
1313
+ const getCellValueRef = useRef3(getCellValue);
1314
+ getCellValueRef.current = getCellValue;
1315
+ const showSearch = controlledShowSearch ?? internalShowSearch;
1316
+ const searchValue = controlledSearchValue ?? internalSearchValue;
1317
+ const searchResults = controlledSearchResults ?? internalResults;
1318
+ const setSearchValue = useCallback3(
1319
+ (value) => {
1320
+ setInternalSearchValue(value);
1321
+ onSearchValueChange?.(value);
1322
+ },
1323
+ [onSearchValueChange]
1324
+ );
1325
+ const cancelSearch = useCallback3(() => {
1326
+ if (searchHandleRef.current !== void 0) {
1327
+ window.cancelAnimationFrame(searchHandleRef.current);
1328
+ searchHandleRef.current = void 0;
1329
+ }
1330
+ abortControllerRef.current?.abort();
1331
+ }, []);
1332
+ const emitResultsChanged = useCallback3(
1333
+ (results, navIndex) => {
1334
+ onSearchResultsChanged?.(results, navIndex);
1335
+ },
1336
+ [onSearchResultsChanged]
1337
+ );
1338
+ const navigateToIndex = useCallback3(
1339
+ (results, navIndex) => {
1340
+ if (onSearchResultsChanged) return;
1341
+ if (navIndex < 0 || navIndex >= results.length) return;
1342
+ const item = results[navIndex];
1343
+ if (!item) return;
1344
+ onNavigateToResult?.(item);
1345
+ },
1346
+ [onNavigateToResult, onSearchResultsChanged]
1347
+ );
1348
+ const beginSearch = useCallback3(
1349
+ (query) => {
1350
+ if (controlledSearchResults !== void 0) return;
1351
+ const totalRows = rowCount;
1352
+ if (totalRows === 0 || columnCount === 0) {
1353
+ setSearchStatus(void 0);
1354
+ setInternalResults([]);
1355
+ emitResultsChanged([], -1);
1356
+ return;
1357
+ }
1358
+ let startY = Math.min(
1359
+ Math.max(0, initialStartRowRef.current),
1360
+ totalRows - 1
1361
+ );
1362
+ let searchStride = Math.min(INLINE_SEARCH_INITIAL_STRIDE, totalRows);
1363
+ let rowsSearched = 0;
1364
+ const runningResult = [];
1365
+ setSearchStatus(void 0);
1366
+ setInternalResults([]);
1367
+ const tick = () => {
1368
+ if (abortControllerRef.current?.signal.aborted) return;
1369
+ const tStart = performance.now();
1370
+ const rowsLeft = totalRows - rowsSearched;
1371
+ const height = Math.min(searchStride, rowsLeft, totalRows - startY);
1372
+ if (height <= 0) {
1373
+ return;
1374
+ }
1375
+ const chunk = collectSearchMatchesInRange({
1376
+ query,
1377
+ startRow: startY,
1378
+ rowCount: height,
1379
+ columnCount,
1380
+ getCellValue: (rowIndex, colIndex) => getCellValueRef.current(rowIndex, colIndex),
1381
+ maxResults: INLINE_SEARCH_MAX_RESULTS - runningResult.length
1382
+ });
1383
+ if (chunk.length > 0) {
1384
+ runningResult.push(...chunk);
1385
+ setInternalResults([...runningResult]);
1386
+ }
1387
+ rowsSearched += height;
1388
+ const selectedIndex = searchStatusRef.current?.selectedIndex ?? -1;
1389
+ setSearchStatus({
1390
+ results: runningResult.length,
1391
+ rowsSearched,
1392
+ selectedIndex
1393
+ });
1394
+ emitResultsChanged(runningResult, selectedIndex);
1395
+ if (startY + height >= totalRows) {
1396
+ startY = 0;
1397
+ } else {
1398
+ startY += height;
1399
+ }
1400
+ searchStride = nextSearchStride(
1401
+ searchStride,
1402
+ performance.now() - tStart
1403
+ );
1404
+ if (rowsSearched < totalRows && runningResult.length < INLINE_SEARCH_MAX_RESULTS) {
1405
+ searchHandleRef.current = window.requestAnimationFrame(tick);
1406
+ }
1407
+ };
1408
+ cancelSearch();
1409
+ abortControllerRef.current = new AbortController();
1410
+ searchHandleRef.current = window.requestAnimationFrame(tick);
1411
+ },
1412
+ [
1413
+ cancelSearch,
1414
+ columnCount,
1415
+ controlledSearchResults,
1416
+ emitResultsChanged,
1417
+ rowCount
1418
+ ]
1419
+ );
1420
+ const openSearch = useCallback3(() => {
1421
+ if (controlledShowSearch === void 0) {
1422
+ setInternalShowSearch(true);
1423
+ }
1424
+ }, [controlledShowSearch]);
1425
+ const closeSearch = useCallback3(() => {
1426
+ if (controlledShowSearch === void 0) {
1427
+ setInternalShowSearch(false);
1428
+ }
1429
+ onSearchClose?.();
1430
+ setSearchStatus(void 0);
1431
+ setInternalResults([]);
1432
+ emitResultsChanged([], -1);
1433
+ cancelSearch();
1434
+ }, [
1435
+ cancelSearch,
1436
+ controlledShowSearch,
1437
+ emitResultsChanged,
1438
+ onSearchClose
1439
+ ]);
1440
+ const goToNext = useCallback3(() => {
1441
+ if (!searchStatus || searchStatus.results === 0) return;
1442
+ const newIndex = nextSearchIndex(
1443
+ searchStatus.selectedIndex,
1444
+ searchStatus.results
1445
+ );
1446
+ setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
1447
+ emitResultsChanged(searchResults, newIndex);
1448
+ navigateToIndex(searchResults, newIndex);
1449
+ }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
1450
+ const goToPrevious = useCallback3(() => {
1451
+ if (!searchStatus || searchStatus.results === 0) return;
1452
+ const newIndex = previousSearchIndex(
1453
+ searchStatus.selectedIndex,
1454
+ searchStatus.results
1455
+ );
1456
+ setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
1457
+ emitResultsChanged(searchResults, newIndex);
1458
+ navigateToIndex(searchResults, newIndex);
1459
+ }, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
1460
+ useEffect3(() => {
1461
+ if (controlledSearchResults === void 0) return;
1462
+ if (controlledSearchResults.length > 0) {
1463
+ setSearchStatus((current) => ({
1464
+ rowsSearched: rowCount,
1465
+ results: controlledSearchResults.length,
1466
+ selectedIndex: current?.selectedIndex ?? -1
1467
+ }));
1468
+ } else {
1469
+ setSearchStatus(void 0);
1470
+ }
1471
+ }, [controlledSearchResults, rowCount]);
1472
+ useEffect3(() => {
1473
+ if (!enabled) return;
1474
+ setSearchStatus(void 0);
1475
+ setInternalResults([]);
1476
+ emitResultsChanged([], -1);
1477
+ if (showSearch) {
1478
+ queueMicrotask(() => {
1479
+ searchInputRef.current?.focus({ preventScroll: true });
1480
+ });
1481
+ } else {
1482
+ cancelSearch();
1483
+ }
1484
+ }, [enabled, showSearch]);
1485
+ useEffect3(() => {
1486
+ if (!enabled || !showSearch) return;
1487
+ if (controlledSearchResults !== void 0) return;
1488
+ if (searchValue.trim() === "") {
1489
+ setSearchStatus(void 0);
1490
+ setInternalResults([]);
1491
+ cancelSearch();
1492
+ emitResultsChanged([], -1);
1493
+ return;
1494
+ }
1495
+ beginSearch(searchValue);
1496
+ }, [
1497
+ beginSearch,
1498
+ cancelSearch,
1499
+ controlledSearchResults,
1500
+ emitResultsChanged,
1501
+ enabled,
1502
+ searchValue,
1503
+ showSearch
1504
+ ]);
1505
+ useEffect3(() => {
1506
+ if (!enabled) return;
1507
+ const handleKeyDown = (event) => {
1508
+ if (!(event.ctrlKey || event.metaKey)) return;
1509
+ if (event.key.toLowerCase() !== "f") return;
1510
+ const root = rootRef?.current;
1511
+ if (root) {
1512
+ const active = document.activeElement;
1513
+ const focusInside = active === root || active instanceof Node && root.contains(active);
1514
+ if (!focusInside && active !== document.body) {
1515
+ return;
1516
+ }
1517
+ }
1518
+ event.preventDefault();
1519
+ event.stopPropagation();
1520
+ if (showSearch) {
1521
+ searchInputRef.current?.focus({ preventScroll: true });
1522
+ searchInputRef.current?.select();
1523
+ return;
1524
+ }
1525
+ if (controlledShowSearch === void 0) {
1526
+ setInternalShowSearch(true);
1527
+ }
1528
+ };
1529
+ window.addEventListener("keydown", handleKeyDown, true);
1530
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
1531
+ }, [controlledShowSearch, enabled, rootRef, showSearch]);
1532
+ useEffect3(() => () => cancelSearch(), [cancelSearch]);
1533
+ const searchMatchKeys = useMemo(
1534
+ () => buildSearchMatchKeys(searchResults),
1535
+ [searchResults]
1536
+ );
1537
+ const activeMatch = useMemo(() => {
1538
+ if (!searchStatus || searchStatus.selectedIndex < 0) return null;
1539
+ return searchResults[searchStatus.selectedIndex] ?? null;
1540
+ }, [searchResults, searchStatus]);
1541
+ if (!enabled) {
1542
+ return {
1543
+ enabled: false,
1544
+ showSearch: false,
1545
+ searchValue: "",
1546
+ searchResults: [],
1547
+ searchStatus: void 0,
1548
+ searchMatchKeys: EMPTY_MATCH_KEYS,
1549
+ activeMatch: null,
1550
+ searchInputRef,
1551
+ searchInputId,
1552
+ canClose: false,
1553
+ openSearch,
1554
+ closeSearch,
1555
+ setSearchValue,
1556
+ goToNext,
1557
+ goToPrevious
1558
+ };
1559
+ }
1560
+ return {
1561
+ enabled: true,
1562
+ showSearch,
1563
+ searchValue,
1564
+ searchResults,
1565
+ searchStatus,
1566
+ searchMatchKeys,
1567
+ activeMatch,
1568
+ searchInputRef,
1569
+ searchInputId,
1570
+ canClose: controlledShowSearch === void 0 || onSearchClose !== void 0,
1571
+ openSearch,
1572
+ closeSearch,
1573
+ setSearchValue,
1574
+ goToNext,
1575
+ goToPrevious
1576
+ };
1577
+ }
1578
+
1018
1579
  // src/components/ui/table/features/row-expand/row-expand.ts
1019
- import { useEffect as useEffect3, useMemo, useRef as useRef3 } from "react";
1580
+ import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4 } from "react";
1020
1581
  function getFieldValue(row, key) {
1021
1582
  return row[key];
1022
1583
  }
@@ -1046,12 +1607,12 @@ var useConvertTreeData = ({
1046
1607
  expandedRows,
1047
1608
  onExpandedRowsChange
1048
1609
  }) => {
1049
- const onExpandedRowsChangeRef = useRef3(onExpandedRowsChange);
1050
- const hasInitializedRef = useRef3(false);
1051
- useEffect3(() => {
1610
+ const onExpandedRowsChangeRef = useRef4(onExpandedRowsChange);
1611
+ const hasInitializedRef = useRef4(false);
1612
+ useEffect4(() => {
1052
1613
  onExpandedRowsChangeRef.current = onExpandedRowsChange;
1053
1614
  }, [onExpandedRowsChange]);
1054
- useEffect3(() => {
1615
+ useEffect4(() => {
1055
1616
  if (!data || data.length === 0) {
1056
1617
  hasInitializedRef.current = false;
1057
1618
  return;
@@ -1061,7 +1622,7 @@ var useConvertTreeData = ({
1061
1622
  onExpandedRowsChangeRef.current?.(new Set(ids));
1062
1623
  hasInitializedRef.current = true;
1063
1624
  }, [enabled, data, toggleField]);
1064
- const processedData = useMemo(() => {
1625
+ const processedData = useMemo2(() => {
1065
1626
  if (!enabled || !data || data.length === 0) return [];
1066
1627
  const flattenedData = [];
1067
1628
  const flattenItems = (items) => {
@@ -1125,7 +1686,7 @@ var useConvertTreeData = ({
1125
1686
  });
1126
1687
  return rootItems;
1127
1688
  }, [enabled, data, toggleField, childField, flattenField]);
1128
- const flattenTree = useMemo(() => {
1689
+ const flattenTree = useMemo2(() => {
1129
1690
  if (!enabled) return [];
1130
1691
  const flatten = (nodes, result = [], level = 0) => {
1131
1692
  nodes.forEach((node, index) => {
@@ -1175,7 +1736,7 @@ var useConvertTreeData = ({
1175
1736
  preventExpand,
1176
1737
  expandedRows
1177
1738
  ]);
1178
- const sortedData = useMemo(() => {
1739
+ const sortedData = useMemo2(() => {
1179
1740
  if (!enabled) {
1180
1741
  return data ?? [];
1181
1742
  }
@@ -1281,6 +1842,7 @@ function collectRowSpanColumns(columns) {
1281
1842
 
1282
1843
  // src/core/useGlideTable.ts
1283
1844
  var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
1845
+ var EMPTY_SEARCH_MATCH_KEYS = /* @__PURE__ */ new Set();
1284
1846
  function useGlideTable(options) {
1285
1847
  const {
1286
1848
  data,
@@ -1321,9 +1883,16 @@ function useGlideTable(options) {
1321
1883
  columnSizing: controlledColumnSizing,
1322
1884
  onColumnSizingChange,
1323
1885
  columnResizeMode = "onChange",
1324
- enableColumnFreeze = false
1886
+ enableColumnFreeze = false,
1887
+ enableInlineSearch = false,
1888
+ showSearch,
1889
+ searchValue,
1890
+ onSearchValueChange,
1891
+ onSearchClose,
1892
+ searchResults,
1893
+ onSearchResultsChanged
1325
1894
  } = options;
1326
- const labels = useMemo2(() => {
1895
+ const labels = useMemo3(() => {
1327
1896
  const resolved = resolveDataTableLabels(labelsProp);
1328
1897
  return {
1329
1898
  ...resolved,
@@ -1334,15 +1903,16 @@ function useGlideTable(options) {
1334
1903
  }, [labelsProp, emptyText, loadingText, selectionLabel]);
1335
1904
  const enableExpand = Boolean(toggleField);
1336
1905
  const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
1337
- const [internalRowSelection, setInternalRowSelection] = useState3({});
1338
- const [internalColumnSizing, setInternalColumnSizing] = useState3({});
1339
- const [internalExpandedRows, setInternalExpandedRows] = useState3(
1906
+ const [internalRowSelection, setInternalRowSelection] = useState4({});
1907
+ const [internalColumnSizing, setInternalColumnSizing] = useState4({});
1908
+ const [internalExpandedRows, setInternalExpandedRows] = useState4(
1340
1909
  () => /* @__PURE__ */ new Set()
1341
1910
  );
1342
- const [hoveredRowIndex, setHoveredRowIndex] = useState3(null);
1343
- const scrollRef = useRef4(null);
1911
+ const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
1912
+ const scrollRef = useRef5(null);
1913
+ const rootRef = useRef5(null);
1344
1914
  const shouldVirtualize = enableVirtualization && !enableRowSpan;
1345
- useEffect4(() => {
1915
+ useEffect5(() => {
1346
1916
  if (enableVirtualization && enableRowSpan) {
1347
1917
  console.warn(
1348
1918
  "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
@@ -1356,7 +1926,7 @@ function useGlideTable(options) {
1356
1926
  );
1357
1927
  const columnSizing = controlledColumnSizing ?? internalColumnSizing;
1358
1928
  const expandedRows = controlledExpandedRows ?? internalExpandedRows;
1359
- const handleExpandedRowsChange = useCallback3(
1929
+ const handleExpandedRowsChange = useCallback4(
1360
1930
  (next) => {
1361
1931
  if (onExpandedRowsChange) {
1362
1932
  onExpandedRowsChange(next);
@@ -1417,13 +1987,13 @@ function useGlideTable(options) {
1417
1987
  getCoreRowModel: getCoreRowModel(),
1418
1988
  getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
1419
1989
  });
1420
- const rowSpanColumnKeys = useMemo2(() => {
1990
+ const rowSpanColumnKeys = useMemo3(() => {
1421
1991
  if (!enableRowSpan) return [];
1422
1992
  return collectRowSpanColumns(columns);
1423
1993
  }, [enableRowSpan, columns]);
1424
1994
  const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
1425
1995
  const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
1426
- const columnRowSpanMap = useMemo2(
1996
+ const columnRowSpanMap = useMemo3(
1427
1997
  () => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
1428
1998
  [tableData, rowSpanColumnKeys]
1429
1999
  );
@@ -1432,7 +2002,7 @@ function useGlideTable(options) {
1432
2002
  const rows = table.getRowModel().rows;
1433
2003
  const columnCount = table.getAllLeafColumns().length || 1;
1434
2004
  const visibleLeafColumns = table.getVisibleLeafColumns();
1435
- const columnFreezeOffsets = useMemo2(() => {
2005
+ const columnFreezeOffsets = useMemo3(() => {
1436
2006
  if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
1437
2007
  return buildColumnFreezeOffsets(
1438
2008
  visibleLeafColumns.map((column) => ({
@@ -1452,13 +2022,46 @@ function useGlideTable(options) {
1452
2022
  const totalSize = rowVirtualizer.getTotalSize();
1453
2023
  const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
1454
2024
  const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
1455
- const selectedRowIndices = useMemo2(() => {
2025
+ const selectedRowIndices = useMemo3(() => {
1456
2026
  const indices = /* @__PURE__ */ new Set();
1457
2027
  for (const selectedRow of selectedRows) {
1458
2028
  indices.add(selectedRow.index);
1459
2029
  }
1460
2030
  return indices;
1461
2031
  }, [selectedRows]);
2032
+ const scrollCellIntoView = useCallback4(
2033
+ (rowIndex, colIndex, options2) => {
2034
+ const align = options2?.align ?? "nearest";
2035
+ const blockAlign = align === "center" ? "center" : "nearest";
2036
+ if (shouldVirtualize) {
2037
+ rowVirtualizer.scrollToIndex(rowIndex, {
2038
+ align: align === "nearest" ? "auto" : align
2039
+ });
2040
+ }
2041
+ const scrollElement = scrollRef.current;
2042
+ if (!scrollElement) return;
2043
+ const scrollToMatchedCell = () => {
2044
+ const cell = scrollElement.querySelector(
2045
+ `[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
2046
+ );
2047
+ if (cell instanceof HTMLElement) {
2048
+ cell.scrollIntoView({ block: blockAlign, inline: "nearest" });
2049
+ }
2050
+ };
2051
+ if (shouldVirtualize) {
2052
+ requestAnimationFrame(scrollToMatchedCell);
2053
+ return;
2054
+ }
2055
+ scrollToMatchedCell();
2056
+ },
2057
+ [rowVirtualizer, shouldVirtualize]
2058
+ );
2059
+ const handleCellNavigate = useCallback4(
2060
+ (position) => {
2061
+ scrollCellIntoView(position.row, position.col, { align: "nearest" });
2062
+ },
2063
+ [scrollCellIntoView]
2064
+ );
1462
2065
  const {
1463
2066
  dragState,
1464
2067
  activeSelectionBounds,
@@ -1470,11 +2073,13 @@ function useGlideTable(options) {
1470
2073
  data: tableData,
1471
2074
  rows,
1472
2075
  enabled: enableCellSelection,
2076
+ columnCount: visibleLeafColumns.length,
1473
2077
  enableSubtreeCopy: resolvedEnableSubtreeCopy,
1474
2078
  enableInsertPaste: enableInsertPaste ?? true,
1475
2079
  onDataChange,
1476
2080
  onBatchChange,
1477
- onRowsPaste
2081
+ onRowsPaste,
2082
+ onCellNavigate: handleCellNavigate
1478
2083
  });
1479
2084
  const {
1480
2085
  editingCell,
@@ -1484,23 +2089,193 @@ function useGlideTable(options) {
1484
2089
  commitEdit,
1485
2090
  cancelEdit
1486
2091
  } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
1487
- const handleCellMouseDownWithCommit = useCallback3(
1488
- (rowIndex, colIndex) => {
2092
+ const handleCellMouseDownWithCommit = useCallback4(
2093
+ (rowIndex, colIndex, options2) => {
1489
2094
  const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
1490
2095
  if (editingCell && !isSameEditingCell && !commitEdit()) {
1491
2096
  return;
1492
2097
  }
1493
- handleCellMouseDown(rowIndex, colIndex);
2098
+ handleCellMouseDown(rowIndex, colIndex, options2);
1494
2099
  },
1495
2100
  [commitEdit, editingCell, handleCellMouseDown]
1496
2101
  );
1497
- const clearHover = useCallback3(() => {
2102
+ const navigateToSearchResult = useCallback4(
2103
+ (item) => {
2104
+ const [colIndex, rowIndex] = item;
2105
+ handleCellMouseDownWithCommit(rowIndex, colIndex);
2106
+ scrollCellIntoView(rowIndex, colIndex, { align: "center" });
2107
+ },
2108
+ [handleCellMouseDownWithCommit, scrollCellIntoView]
2109
+ );
2110
+ const resolveSearchRowId = useCallback4(
2111
+ (row, index) => {
2112
+ if (getRowId) return getRowId(row, index);
2113
+ if (enableExpand) {
2114
+ const record = row;
2115
+ const idValue = record.id;
2116
+ if (idValue != null && String(idValue).length > 0) {
2117
+ return String(idValue);
2118
+ }
2119
+ const uniqueId = record.uniqueId;
2120
+ if (uniqueId != null && String(uniqueId).length > 0) {
2121
+ return String(uniqueId);
2122
+ }
2123
+ if (toggleField) {
2124
+ const toggleValue = record[toggleField];
2125
+ if (toggleValue != null && String(toggleValue).length > 0) {
2126
+ return String(toggleValue);
2127
+ }
2128
+ }
2129
+ }
2130
+ return String(index);
2131
+ },
2132
+ [enableExpand, getRowId, toggleField]
2133
+ );
2134
+ const searchCorpus = useMemo3(() => {
2135
+ if (!enableInlineSearch) return [];
2136
+ if (enableExpand && toggleField) {
2137
+ return buildTreeSearchCorpus(tableData, {
2138
+ toggleField,
2139
+ getRowId: resolveSearchRowId
2140
+ });
2141
+ }
2142
+ return buildFlatSearchCorpus(tableData, resolveSearchRowId);
2143
+ }, [
2144
+ enableExpand,
2145
+ enableInlineSearch,
2146
+ resolveSearchRowId,
2147
+ tableData,
2148
+ toggleField
2149
+ ]);
2150
+ const searchCorpusRef = useRef5(searchCorpus);
2151
+ searchCorpusRef.current = searchCorpus;
2152
+ const visibleRowIndexById = useMemo3(() => {
2153
+ const map = /* @__PURE__ */ new Map();
2154
+ for (const row of rows) {
2155
+ map.set(resolveSearchRowId(row.original, row.index), row.index);
2156
+ }
2157
+ return map;
2158
+ }, [resolveSearchRowId, rows]);
2159
+ const getSearchCellValue = useCallback4(
2160
+ (rowIndex, colIndex) => {
2161
+ const corpusRow = searchCorpusRef.current[rowIndex];
2162
+ const column = visibleLeafColumns[colIndex];
2163
+ if (!corpusRow || !column) return void 0;
2164
+ const visibleIndex = visibleRowIndexById.get(corpusRow.id);
2165
+ if (visibleIndex !== void 0) {
2166
+ const visibleRow = rows[visibleIndex];
2167
+ if (visibleRow) {
2168
+ return visibleRow.getValue(column.id);
2169
+ }
2170
+ }
2171
+ const columnDef = column.columnDef;
2172
+ if ("accessorFn" in columnDef && typeof columnDef.accessorFn === "function") {
2173
+ return columnDef.accessorFn(corpusRow.data, rowIndex);
2174
+ }
2175
+ if ("accessorKey" in columnDef && columnDef.accessorKey != null && columnDef.accessorKey !== "") {
2176
+ return corpusRow.data[String(columnDef.accessorKey)];
2177
+ }
2178
+ return corpusRow.data[column.id];
2179
+ },
2180
+ [rows, visibleLeafColumns, visibleRowIndexById]
2181
+ );
2182
+ const pendingSearchNavRef = useRef5(null);
2183
+ const focusSearchResult = useCallback4(
2184
+ (colIndex, visibleRowIndex) => {
2185
+ navigateToSearchResult([colIndex, visibleRowIndex]);
2186
+ },
2187
+ [navigateToSearchResult]
2188
+ );
2189
+ const navigateToCorpusSearchResult = useCallback4(
2190
+ (item) => {
2191
+ const [colIndex, corpusRowIndex] = item;
2192
+ const corpusRow = searchCorpusRef.current[corpusRowIndex];
2193
+ if (!corpusRow) return;
2194
+ const missingKeys = collectAncestorKeysToExpand(corpusRow, expandedRows);
2195
+ if (missingKeys.length > 0) {
2196
+ pendingSearchNavRef.current = {
2197
+ colIndex,
2198
+ rowId: corpusRow.id
2199
+ };
2200
+ const next = new Set(expandedRows);
2201
+ for (const key of corpusRow.ancestorToggleKeys) {
2202
+ next.add(key);
2203
+ }
2204
+ handleExpandedRowsChange(next);
2205
+ return;
2206
+ }
2207
+ const visibleItem = mapSearchResultToVisibleItem(
2208
+ item,
2209
+ searchCorpusRef.current,
2210
+ visibleRowIndexById
2211
+ );
2212
+ if (!visibleItem) return;
2213
+ focusSearchResult(visibleItem[0], visibleItem[1]);
2214
+ },
2215
+ [
2216
+ expandedRows,
2217
+ focusSearchResult,
2218
+ handleExpandedRowsChange,
2219
+ visibleRowIndexById
2220
+ ]
2221
+ );
2222
+ useEffect5(() => {
2223
+ const pending = pendingSearchNavRef.current;
2224
+ if (!pending) return;
2225
+ const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
2226
+ if (visibleRowIndex === void 0) return;
2227
+ pendingSearchNavRef.current = null;
2228
+ focusSearchResult(pending.colIndex, visibleRowIndex);
2229
+ }, [focusSearchResult, rows, visibleRowIndexById]);
2230
+ const initialSearchStartRow = virtualRows[0]?.index ?? 0;
2231
+ const inlineSearch = useInlineSearch({
2232
+ enabled: enableInlineSearch,
2233
+ rowCount: searchCorpus.length,
2234
+ columnCount: visibleLeafColumns.length,
2235
+ getCellValue: getSearchCellValue,
2236
+ initialStartRow: initialSearchStartRow,
2237
+ showSearch,
2238
+ searchValue,
2239
+ searchResults,
2240
+ onSearchValueChange,
2241
+ onSearchClose,
2242
+ onSearchResultsChanged,
2243
+ onNavigateToResult: navigateToCorpusSearchResult,
2244
+ rootRef
2245
+ });
2246
+ const visibleSearchMatchKeys = useMemo3(() => {
2247
+ if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
2248
+ return mapSearchResultsToVisibleKeys(
2249
+ inlineSearch.searchResults,
2250
+ searchCorpus,
2251
+ visibleRowIndexById
2252
+ );
2253
+ }, [
2254
+ enableInlineSearch,
2255
+ inlineSearch.searchResults,
2256
+ searchCorpus,
2257
+ visibleRowIndexById
2258
+ ]);
2259
+ const visibleActiveMatch = useMemo3(() => {
2260
+ if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
2261
+ return mapSearchResultToVisibleItem(
2262
+ inlineSearch.activeMatch,
2263
+ searchCorpus,
2264
+ visibleRowIndexById
2265
+ );
2266
+ }, [
2267
+ enableInlineSearch,
2268
+ inlineSearch.activeMatch,
2269
+ searchCorpus,
2270
+ visibleRowIndexById
2271
+ ]);
2272
+ const clearHover = useCallback4(() => {
1498
2273
  setHoveredRowIndex(null);
1499
2274
  }, []);
1500
- const handleRowHover = useCallback3((rowIndex, _rowData) => {
2275
+ const handleRowHover = useCallback4((rowIndex, _rowData) => {
1501
2276
  setHoveredRowIndex(rowIndex);
1502
2277
  }, []);
1503
- const handleToggleSelect = useCallback3(
2278
+ const handleToggleSelect = useCallback4(
1504
2279
  (row) => {
1505
2280
  if (!row.getCanSelect()) return;
1506
2281
  if (preserveRowSelection && row.getIsSelected()) {
@@ -1510,14 +2285,14 @@ function useGlideTable(options) {
1510
2285
  },
1511
2286
  [preserveRowSelection]
1512
2287
  );
1513
- const handleToggleExpand = useCallback3(
2288
+ const handleToggleExpand = useCallback4(
1514
2289
  (rowKey) => {
1515
2290
  if (preventExpand) return;
1516
2291
  handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
1517
2292
  },
1518
2293
  [preventExpand, handleExpandedRowsChange, expandedRows]
1519
2294
  );
1520
- const rowContextValue = useMemo2(() => {
2295
+ const rowContextValue = useMemo3(() => {
1521
2296
  return {
1522
2297
  rowSpan: {
1523
2298
  enableRowSpan,
@@ -1565,6 +2340,11 @@ function useGlideTable(options) {
1565
2340
  columnFreeze: {
1566
2341
  enableColumnFreeze,
1567
2342
  offsets: columnFreezeOffsets
2343
+ },
2344
+ inlineSearch: {
2345
+ enabled: enableInlineSearch,
2346
+ matchKeys: visibleSearchMatchKeys,
2347
+ activeMatch: visibleActiveMatch
1568
2348
  }
1569
2349
  };
1570
2350
  }, [
@@ -1600,14 +2380,17 @@ function useGlideTable(options) {
1600
2380
  labels.collapseRow,
1601
2381
  enableColumnResize,
1602
2382
  enableColumnFreeze,
1603
- columnFreezeOffsets
2383
+ columnFreezeOffsets,
2384
+ enableInlineSearch,
2385
+ visibleSearchMatchKeys,
2386
+ visibleActiveMatch
1604
2387
  ]);
1605
- const copySelectionRef = useRef4(copySelection);
1606
- useEffect4(() => {
2388
+ const copySelectionRef = useRef5(copySelection);
2389
+ useEffect5(() => {
1607
2390
  copySelectionRef.current = copySelection;
1608
2391
  }, [copySelection]);
1609
- const stableCopySelection = useCallback3((options2) => copySelectionRef.current(options2), []);
1610
- useEffect4(() => {
2392
+ const stableCopySelection = useCallback4((options2) => copySelectionRef.current(options2), []);
2393
+ useEffect5(() => {
1611
2394
  onCopyActionsReady?.({ copySelection: stableCopySelection });
1612
2395
  }, [onCopyActionsReady, stableCopySelection]);
1613
2396
  return {
@@ -1623,8 +2406,10 @@ function useGlideTable(options) {
1623
2406
  enableCellSelection,
1624
2407
  enableColumnResize,
1625
2408
  enableColumnFreeze,
2409
+ enableInlineSearch,
1626
2410
  shouldVirtualize,
1627
2411
  scrollRef,
2412
+ rootRef,
1628
2413
  rowVirtualizer,
1629
2414
  virtualRows,
1630
2415
  paddingTop,
@@ -1632,7 +2417,21 @@ function useGlideTable(options) {
1632
2417
  rowContextValue,
1633
2418
  handleToggleSelect,
1634
2419
  clearHover,
1635
- copySelection: stableCopySelection
2420
+ copySelection: stableCopySelection,
2421
+ inlineSearch: {
2422
+ showSearch: inlineSearch.showSearch,
2423
+ searchValue: inlineSearch.searchValue,
2424
+ searchStatus: inlineSearch.searchStatus,
2425
+ searchInputRef: inlineSearch.searchInputRef,
2426
+ searchInputId: inlineSearch.searchInputId,
2427
+ canClose: inlineSearch.canClose,
2428
+ searchRowCount: searchCorpus.length,
2429
+ setSearchValue: inlineSearch.setSearchValue,
2430
+ closeSearch: inlineSearch.closeSearch,
2431
+ goToNext: inlineSearch.goToNext,
2432
+ goToPrevious: inlineSearch.goToPrevious,
2433
+ openSearch: inlineSearch.openSearch
2434
+ }
1636
2435
  };
1637
2436
  }
1638
2437
 
@@ -1655,18 +2454,29 @@ export {
1655
2454
  DEFAULT_TREE_ID_FIELD,
1656
2455
  DEFAULT_TREE_PARENT_ID_FIELD,
1657
2456
  DEFAULT_TREE_QTY_FIELD,
2457
+ INLINE_SEARCH_MAX_RESULTS,
1658
2458
  applyCellEdit,
1659
2459
  applyFillData,
1660
2460
  applySelectionUpdater,
1661
2461
  buildColumnFreezeOffsets,
1662
2462
  buildColumnRowSpanMap,
2463
+ buildFlatSearchCorpus,
1663
2464
  buildRowsPastePayload,
2465
+ buildSearchMatchKey,
2466
+ buildSearchMatchKeys,
2467
+ buildTreeSearchCorpus,
1664
2468
  canExpandRow,
2469
+ cellValueToSearchText,
2470
+ collectAncestorKeysToExpand,
1665
2471
  collectCopyRowEntries,
1666
2472
  collectCopyRows,
1667
2473
  collectFillChanges,
1668
2474
  collectRowSpanColumns,
2475
+ collectSearchMatchesInRange,
2476
+ createSearchRegex,
2477
+ escapeSearchRegex,
1669
2478
  flattenSubtreeRows,
2479
+ formatSearchResultLabel,
1670
2480
  getCellEditDraftValue,
1671
2481
  getCellSelectionEdgeStyle,
1672
2482
  getColumnEditType,
@@ -1678,10 +2488,15 @@ export {
1678
2488
  isCellInSelection,
1679
2489
  isColumnEditable,
1680
2490
  isEditablePasteTarget,
2491
+ mapSearchResultToVisibleItem,
2492
+ mapSearchResultsToVisibleKeys,
1681
2493
  measureMergedSpanRowHeights,
2494
+ nextSearchIndex,
2495
+ nextSearchStride,
1682
2496
  parseCellEditValue,
1683
2497
  parseClipboardTSV,
1684
2498
  parseClipboardTSVWithDepths,
2499
+ previousSearchIndex,
1685
2500
  resolveColumnFreezeSide,
1686
2501
  resolveDataTableLabels,
1687
2502
  resolvePasteColumnIds,
@@ -1695,5 +2510,6 @@ export {
1695
2510
  useCellSelection,
1696
2511
  useConvertTreeData,
1697
2512
  useGlideTable,
2513
+ useInlineSearch,
1698
2514
  writeSelectionToClipboard
1699
2515
  };