react-glide-table 1.4.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -2
- package/dist/compound.cjs +1222 -119
- package/dist/compound.d.cts +11 -3
- package/dist/compound.d.ts +11 -3
- package/dist/compound.js +1224 -114
- package/dist/core.cjs +874 -48
- package/dist/core.d.cts +73 -6
- package/dist/core.d.ts +73 -6
- package/dist/core.js +868 -52
- package/dist/index.cjs +1270 -133
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1252 -125
- package/dist/{types-CHQnBz91.d.cts → types-Cs9MiZs1.d.cts} +104 -1
- package/dist/{types-CHQnBz91.d.ts → types-Cs9MiZs1.d.ts} +104 -1
- package/package.json +1 -1
package/dist/compound.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
2
2
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
3
|
-
import { useMemo as
|
|
3
|
+
import { useMemo as useMemo4 } from "react";
|
|
4
4
|
|
|
5
5
|
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
6
6
|
import { flexRender } from "@tanstack/react-table";
|
|
@@ -16,6 +16,7 @@ var ROW_HOVER_CLASS = "row-hoverable";
|
|
|
16
16
|
var ROW_HOVERED_BG_CLASS = "row-hovered";
|
|
17
17
|
var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
|
|
18
18
|
var DATA_TABLE_ROW_HEIGHT = 44;
|
|
19
|
+
var DATA_TABLE_HEADER_ROW_HEIGHT = 40;
|
|
19
20
|
var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
20
21
|
var DATA_TABLE_COLUMN_SIZE = 150;
|
|
21
22
|
var DATA_TABLE_COLUMN_MIN_SIZE = 40;
|
|
@@ -103,6 +104,36 @@ function getCellSelectionBounds(start, end) {
|
|
|
103
104
|
endCol: Math.max(start.col, end.col)
|
|
104
105
|
};
|
|
105
106
|
}
|
|
107
|
+
function getCellNavigationDelta(key) {
|
|
108
|
+
switch (key) {
|
|
109
|
+
case "ArrowUp":
|
|
110
|
+
case "w":
|
|
111
|
+
case "W":
|
|
112
|
+
return { row: -1, col: 0 };
|
|
113
|
+
case "ArrowDown":
|
|
114
|
+
case "s":
|
|
115
|
+
case "S":
|
|
116
|
+
return { row: 1, col: 0 };
|
|
117
|
+
case "ArrowLeft":
|
|
118
|
+
case "a":
|
|
119
|
+
case "A":
|
|
120
|
+
return { row: 0, col: -1 };
|
|
121
|
+
case "ArrowRight":
|
|
122
|
+
case "d":
|
|
123
|
+
case "D":
|
|
124
|
+
return { row: 0, col: 1 };
|
|
125
|
+
default:
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function clampCellPosition(position, rowCount, columnCount) {
|
|
130
|
+
const maxRow = Math.max(rowCount - 1, 0);
|
|
131
|
+
const maxCol = Math.max(columnCount - 1, 0);
|
|
132
|
+
return {
|
|
133
|
+
row: Math.min(Math.max(position.row, 0), maxRow),
|
|
134
|
+
col: Math.min(Math.max(position.col, 0), maxCol)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
106
137
|
function measureMergedSpanRowHeights(rowIndex, rowSpan, cellElement) {
|
|
107
138
|
if (rowSpan <= 1) return void 0;
|
|
108
139
|
const tbody = cellElement?.closest("tbody") ?? (typeof document !== "undefined" ? document.querySelector("tbody.data-table-body") : null);
|
|
@@ -439,7 +470,7 @@ function getColumnFreezeStyle(offset, options) {
|
|
|
439
470
|
position: "sticky",
|
|
440
471
|
...offset.side === "left" ? { left: offset.offset } : { right: offset.offset },
|
|
441
472
|
zIndex: zBase + offset.stack,
|
|
442
|
-
...options?.isHeader ? { top: 0 } : {}
|
|
473
|
+
...options?.isHeader ? { top: options.headerTop ?? 0 } : {}
|
|
443
474
|
};
|
|
444
475
|
}
|
|
445
476
|
|
|
@@ -456,6 +487,162 @@ function getColumnSizeStyle(size, options) {
|
|
|
456
487
|
};
|
|
457
488
|
}
|
|
458
489
|
|
|
490
|
+
// src/components/ui/table/features/inline-search/inlineSearch.ts
|
|
491
|
+
var INLINE_SEARCH_MAX_RESULTS = 1e3;
|
|
492
|
+
var INLINE_SEARCH_TARGET_TICK_MS = 10;
|
|
493
|
+
var INLINE_SEARCH_INITIAL_STRIDE = 10;
|
|
494
|
+
function escapeSearchRegex(value) {
|
|
495
|
+
return value.replace(/([$()*+.?[\\\]^{|}-])/g, "\\$1");
|
|
496
|
+
}
|
|
497
|
+
function createSearchRegex(query) {
|
|
498
|
+
const trimmed = query.trim();
|
|
499
|
+
if (!trimmed) return null;
|
|
500
|
+
return new RegExp(escapeSearchRegex(trimmed), "i");
|
|
501
|
+
}
|
|
502
|
+
function cellValueToSearchText(value) {
|
|
503
|
+
if (value == null) return void 0;
|
|
504
|
+
if (typeof value === "string") return value;
|
|
505
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
506
|
+
return String(value);
|
|
507
|
+
}
|
|
508
|
+
if (Array.isArray(value)) {
|
|
509
|
+
return value.map((item) => cellValueToSearchText(item) ?? "").join(" ");
|
|
510
|
+
}
|
|
511
|
+
if (typeof value === "object") {
|
|
512
|
+
try {
|
|
513
|
+
return JSON.stringify(value);
|
|
514
|
+
} catch {
|
|
515
|
+
return String(value);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return String(value);
|
|
519
|
+
}
|
|
520
|
+
function formatSearchResultLabel(status) {
|
|
521
|
+
const countLabel = status.results >= INLINE_SEARCH_MAX_RESULTS ? `over ${INLINE_SEARCH_MAX_RESULTS}` : `${status.results} result${status.results !== 1 ? "s" : ""}`;
|
|
522
|
+
if (status.selectedIndex >= 0 && status.results > 0) {
|
|
523
|
+
return `${status.selectedIndex + 1} of ${countLabel}`;
|
|
524
|
+
}
|
|
525
|
+
return countLabel;
|
|
526
|
+
}
|
|
527
|
+
function nextSearchIndex(selectedIndex, results) {
|
|
528
|
+
if (results <= 0) return -1;
|
|
529
|
+
if (selectedIndex < 0) return 0;
|
|
530
|
+
return (selectedIndex + 1) % results;
|
|
531
|
+
}
|
|
532
|
+
function previousSearchIndex(selectedIndex, results) {
|
|
533
|
+
if (results <= 0) return -1;
|
|
534
|
+
if (selectedIndex < 0) return results - 1;
|
|
535
|
+
let next = (selectedIndex - 1) % results;
|
|
536
|
+
if (next < 0) next += results;
|
|
537
|
+
return next;
|
|
538
|
+
}
|
|
539
|
+
function buildSearchMatchKey(colIndex, rowIndex) {
|
|
540
|
+
return `${colIndex}:${rowIndex}`;
|
|
541
|
+
}
|
|
542
|
+
function buildSearchMatchKeys(results) {
|
|
543
|
+
const keys = /* @__PURE__ */ new Set();
|
|
544
|
+
for (const [colIndex, rowIndex] of results) {
|
|
545
|
+
keys.add(buildSearchMatchKey(colIndex, rowIndex));
|
|
546
|
+
}
|
|
547
|
+
return keys;
|
|
548
|
+
}
|
|
549
|
+
function collectSearchMatchesInRange(options) {
|
|
550
|
+
const {
|
|
551
|
+
query,
|
|
552
|
+
startRow,
|
|
553
|
+
rowCount,
|
|
554
|
+
columnCount,
|
|
555
|
+
getCellValue,
|
|
556
|
+
maxResults = INLINE_SEARCH_MAX_RESULTS
|
|
557
|
+
} = options;
|
|
558
|
+
const regex = createSearchRegex(query);
|
|
559
|
+
if (!regex || rowCount <= 0 || columnCount <= 0) return [];
|
|
560
|
+
const matches = [];
|
|
561
|
+
for (let rowOffset = 0; rowOffset < rowCount; rowOffset += 1) {
|
|
562
|
+
const rowIndex = startRow + rowOffset;
|
|
563
|
+
for (let colIndex = 0; colIndex < columnCount; colIndex += 1) {
|
|
564
|
+
const text = cellValueToSearchText(getCellValue(rowIndex, colIndex));
|
|
565
|
+
if (text !== void 0 && regex.test(text)) {
|
|
566
|
+
matches.push([colIndex, rowIndex]);
|
|
567
|
+
if (matches.length >= maxResults) {
|
|
568
|
+
return matches;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return matches;
|
|
574
|
+
}
|
|
575
|
+
function nextSearchStride(currentStride, elapsedMs, targetMs = INLINE_SEARCH_TARGET_TICK_MS) {
|
|
576
|
+
const rounded = Math.max(elapsedMs, 1);
|
|
577
|
+
const scalar = targetMs / rounded;
|
|
578
|
+
return Math.max(1, Math.ceil(currentStride * scalar));
|
|
579
|
+
}
|
|
580
|
+
function buildFlatSearchCorpus(rows, getRowId) {
|
|
581
|
+
return rows.map((data, index) => ({
|
|
582
|
+
id: getRowId(data, index),
|
|
583
|
+
data,
|
|
584
|
+
ancestorToggleKeys: []
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
function buildTreeSearchCorpus(visibleRows, options) {
|
|
588
|
+
const { toggleField, getRowId } = options;
|
|
589
|
+
const corpus = [];
|
|
590
|
+
const seen = /* @__PURE__ */ new Set();
|
|
591
|
+
const walk = (node, ancestorToggleKeys) => {
|
|
592
|
+
const id = getRowId(node, corpus.length);
|
|
593
|
+
if (seen.has(id)) return;
|
|
594
|
+
seen.add(id);
|
|
595
|
+
corpus.push({
|
|
596
|
+
id,
|
|
597
|
+
data: node,
|
|
598
|
+
ancestorToggleKeys
|
|
599
|
+
});
|
|
600
|
+
const children = node.children;
|
|
601
|
+
if (!Array.isArray(children) || children.length === 0) return;
|
|
602
|
+
const toggleValue = node[toggleField];
|
|
603
|
+
const childAncestors = typeof toggleValue === "string" && toggleValue.length > 0 ? [...ancestorToggleKeys, toggleValue] : ancestorToggleKeys;
|
|
604
|
+
for (const child of children) {
|
|
605
|
+
if (child && typeof child === "object") {
|
|
606
|
+
walk(child, childAncestors);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
for (const row of visibleRows) {
|
|
611
|
+
const level = row.level;
|
|
612
|
+
if (level === 0 || level === void 0) {
|
|
613
|
+
walk(row, []);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
for (const row of visibleRows) {
|
|
617
|
+
const id = getRowId(row, corpus.length);
|
|
618
|
+
if (seen.has(id)) continue;
|
|
619
|
+
walk(row, []);
|
|
620
|
+
}
|
|
621
|
+
return corpus;
|
|
622
|
+
}
|
|
623
|
+
function mapSearchResultsToVisibleKeys(results, corpus, visibleRowIndexById) {
|
|
624
|
+
const keys = /* @__PURE__ */ new Set();
|
|
625
|
+
for (const [colIndex, corpusRowIndex] of results) {
|
|
626
|
+
const corpusRow = corpus[corpusRowIndex];
|
|
627
|
+
if (!corpusRow) continue;
|
|
628
|
+
const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
|
|
629
|
+
if (visibleRowIndex === void 0) continue;
|
|
630
|
+
keys.add(buildSearchMatchKey(colIndex, visibleRowIndex));
|
|
631
|
+
}
|
|
632
|
+
return keys;
|
|
633
|
+
}
|
|
634
|
+
function mapSearchResultToVisibleItem(item, corpus, visibleRowIndexById) {
|
|
635
|
+
const [colIndex, corpusRowIndex] = item;
|
|
636
|
+
const corpusRow = corpus[corpusRowIndex];
|
|
637
|
+
if (!corpusRow) return null;
|
|
638
|
+
const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
|
|
639
|
+
if (visibleRowIndex === void 0) return null;
|
|
640
|
+
return [colIndex, visibleRowIndex];
|
|
641
|
+
}
|
|
642
|
+
function collectAncestorKeysToExpand(corpusRow, expandedRows) {
|
|
643
|
+
return corpusRow.ancestorToggleKeys.filter((key) => !expandedRows.has(key));
|
|
644
|
+
}
|
|
645
|
+
|
|
459
646
|
// src/components/ui/table/features/row-expand/row-expand.ts
|
|
460
647
|
import { useEffect, useMemo, useRef } from "react";
|
|
461
648
|
|
|
@@ -901,10 +1088,16 @@ function DataTableRow({
|
|
|
901
1088
|
cellEdit,
|
|
902
1089
|
expand,
|
|
903
1090
|
columnResize,
|
|
904
|
-
columnFreeze
|
|
1091
|
+
columnFreeze,
|
|
1092
|
+
inlineSearch
|
|
905
1093
|
} = useDataTableRowContext();
|
|
906
1094
|
const { enableColumnResize } = columnResize;
|
|
907
1095
|
const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
|
|
1096
|
+
const {
|
|
1097
|
+
enabled: enableInlineSearch,
|
|
1098
|
+
matchKeys: searchMatchKeys,
|
|
1099
|
+
activeMatch
|
|
1100
|
+
} = inlineSearch;
|
|
908
1101
|
const {
|
|
909
1102
|
enableRowSpan,
|
|
910
1103
|
primaryRowSpanColumnId,
|
|
@@ -1096,9 +1289,14 @@ function DataTableRow({
|
|
|
1096
1289
|
...freezeStyle,
|
|
1097
1290
|
...selectionEdgeStyle
|
|
1098
1291
|
};
|
|
1292
|
+
const searchMatchKey = buildSearchMatchKey(cellIndex, rowIndex);
|
|
1293
|
+
const isSearchMatch = enableInlineSearch && searchMatchKeys.has(searchMatchKey);
|
|
1294
|
+
const isSearchActive = isSearchMatch && activeMatch !== null && activeMatch[0] === cellIndex && activeMatch[1] === rowIndex;
|
|
1099
1295
|
return /* @__PURE__ */ jsxs2(
|
|
1100
1296
|
"td",
|
|
1101
1297
|
{
|
|
1298
|
+
"data-row-index": rowIndex,
|
|
1299
|
+
"data-col-index": cellIndex,
|
|
1102
1300
|
rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
|
|
1103
1301
|
"data-merged": isMerged && cellIndex > 0 ? "" : void 0,
|
|
1104
1302
|
"data-merged-edge-right": showMergedRightEdge ? "" : void 0,
|
|
@@ -1108,6 +1306,8 @@ function DataTableRow({
|
|
|
1108
1306
|
"data-group-hovered": enableRowSpan && showCellHover && !showCellSelected ? "" : void 0,
|
|
1109
1307
|
"data-selection-fill": isCellDragSelected ? "" : void 0,
|
|
1110
1308
|
"data-selection-edges": hasSelectionEdges ? "" : void 0,
|
|
1309
|
+
"data-search-match": isSearchMatch ? "" : void 0,
|
|
1310
|
+
"data-search-active": isSearchActive ? "" : void 0,
|
|
1111
1311
|
"data-editable": editable ? "" : void 0,
|
|
1112
1312
|
"data-editing": isEditing ? "" : void 0,
|
|
1113
1313
|
"data-frozen": freezeOffset?.side,
|
|
@@ -1122,7 +1322,8 @@ function DataTableRow({
|
|
|
1122
1322
|
event.preventDefault();
|
|
1123
1323
|
onCellMouseDown(
|
|
1124
1324
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
1125
|
-
cellIndex
|
|
1325
|
+
cellIndex,
|
|
1326
|
+
{ shiftKey: event.shiftKey }
|
|
1126
1327
|
);
|
|
1127
1328
|
},
|
|
1128
1329
|
onMouseEnter: (event) => {
|
|
@@ -1159,6 +1360,8 @@ function DataTableRow({
|
|
|
1159
1360
|
enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
|
|
1160
1361
|
isCellDragSelected && CELL_SELECTION_FILL_CLASS,
|
|
1161
1362
|
hasSelectionEdges && CELL_SELECTION_EDGES_CLASS,
|
|
1363
|
+
isSearchMatch && "is-search-match",
|
|
1364
|
+
isSearchActive && "is-search-active",
|
|
1162
1365
|
editable && "is-editable",
|
|
1163
1366
|
classNames?.cell
|
|
1164
1367
|
),
|
|
@@ -1293,8 +1496,169 @@ function DataTableRow({
|
|
|
1293
1496
|
);
|
|
1294
1497
|
}
|
|
1295
1498
|
|
|
1499
|
+
// src/components/ui/table/components/DataTable/DataTableSearch.tsx
|
|
1500
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1501
|
+
function SearchCloseIcon({ className }) {
|
|
1502
|
+
return /* @__PURE__ */ jsxs3(
|
|
1503
|
+
"svg",
|
|
1504
|
+
{
|
|
1505
|
+
className,
|
|
1506
|
+
"aria-hidden": true,
|
|
1507
|
+
width: "16",
|
|
1508
|
+
height: "16",
|
|
1509
|
+
viewBox: "0 0 24 24",
|
|
1510
|
+
fill: "none",
|
|
1511
|
+
stroke: "currentColor",
|
|
1512
|
+
strokeWidth: "2",
|
|
1513
|
+
strokeLinecap: "round",
|
|
1514
|
+
strokeLinejoin: "round",
|
|
1515
|
+
children: [
|
|
1516
|
+
/* @__PURE__ */ jsx4("path", { d: "M18 6 6 18" }),
|
|
1517
|
+
/* @__PURE__ */ jsx4("path", { d: "m6 6 12 12" })
|
|
1518
|
+
]
|
|
1519
|
+
}
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
function DataTableSearch({
|
|
1523
|
+
showSearch,
|
|
1524
|
+
searchValue,
|
|
1525
|
+
searchStatus,
|
|
1526
|
+
searchInputId,
|
|
1527
|
+
searchInputRef,
|
|
1528
|
+
canClose,
|
|
1529
|
+
placeholder,
|
|
1530
|
+
resultHint,
|
|
1531
|
+
previousLabel,
|
|
1532
|
+
nextLabel,
|
|
1533
|
+
closeLabel,
|
|
1534
|
+
rowsTotal,
|
|
1535
|
+
classNames,
|
|
1536
|
+
onSearchValueChange,
|
|
1537
|
+
onClose,
|
|
1538
|
+
onNext,
|
|
1539
|
+
onPrevious
|
|
1540
|
+
}) {
|
|
1541
|
+
if (!showSearch) return null;
|
|
1542
|
+
const resultString = searchStatus ? formatSearchResultLabel(searchStatus) : resultHint;
|
|
1543
|
+
const progress = rowsTotal > 0 ? Math.floor((searchStatus?.rowsSearched ?? 0) / rowsTotal * 100) : 0;
|
|
1544
|
+
const handleKeyDown = (event) => {
|
|
1545
|
+
if ((event.ctrlKey || event.metaKey) && event.code === "KeyF" || event.key === "Escape") {
|
|
1546
|
+
event.preventDefault();
|
|
1547
|
+
event.stopPropagation();
|
|
1548
|
+
if (canClose) {
|
|
1549
|
+
onClose();
|
|
1550
|
+
}
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
if (event.key === "ArrowDown" || event.key === "Enter" && !event.shiftKey) {
|
|
1554
|
+
event.preventDefault();
|
|
1555
|
+
onNext();
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
if (event.key === "ArrowUp" || event.key === "Enter" && event.shiftKey) {
|
|
1559
|
+
event.preventDefault();
|
|
1560
|
+
onPrevious();
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
return /* @__PURE__ */ jsxs3(
|
|
1564
|
+
"div",
|
|
1565
|
+
{
|
|
1566
|
+
className: cn("data-table-search", classNames?.search),
|
|
1567
|
+
role: "search",
|
|
1568
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
1569
|
+
children: [
|
|
1570
|
+
/* @__PURE__ */ jsxs3("div", { className: "data-table-search-row", children: [
|
|
1571
|
+
/* @__PURE__ */ jsx4(
|
|
1572
|
+
"input",
|
|
1573
|
+
{
|
|
1574
|
+
ref: searchInputRef,
|
|
1575
|
+
id: searchInputId,
|
|
1576
|
+
type: "search",
|
|
1577
|
+
value: searchValue,
|
|
1578
|
+
placeholder,
|
|
1579
|
+
autoComplete: "off",
|
|
1580
|
+
spellCheck: false,
|
|
1581
|
+
"aria-label": placeholder,
|
|
1582
|
+
className: cn("data-table-search-input", classNames?.searchInput),
|
|
1583
|
+
onChange: (event) => onSearchValueChange(event.target.value),
|
|
1584
|
+
onKeyDown: handleKeyDown
|
|
1585
|
+
}
|
|
1586
|
+
),
|
|
1587
|
+
/* @__PURE__ */ jsx4(
|
|
1588
|
+
"button",
|
|
1589
|
+
{
|
|
1590
|
+
type: "button",
|
|
1591
|
+
"aria-label": previousLabel,
|
|
1592
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
1593
|
+
onClick: (event) => {
|
|
1594
|
+
event.stopPropagation();
|
|
1595
|
+
onPrevious();
|
|
1596
|
+
},
|
|
1597
|
+
children: /* @__PURE__ */ jsx4(ChevronUp, { className: "data-table-search-icon" })
|
|
1598
|
+
}
|
|
1599
|
+
),
|
|
1600
|
+
/* @__PURE__ */ jsx4(
|
|
1601
|
+
"button",
|
|
1602
|
+
{
|
|
1603
|
+
type: "button",
|
|
1604
|
+
"aria-label": nextLabel,
|
|
1605
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
1606
|
+
onClick: (event) => {
|
|
1607
|
+
event.stopPropagation();
|
|
1608
|
+
onNext();
|
|
1609
|
+
},
|
|
1610
|
+
children: /* @__PURE__ */ jsx4(ChevronDown, { className: "data-table-search-icon" })
|
|
1611
|
+
}
|
|
1612
|
+
),
|
|
1613
|
+
canClose ? /* @__PURE__ */ jsx4(
|
|
1614
|
+
"button",
|
|
1615
|
+
{
|
|
1616
|
+
type: "button",
|
|
1617
|
+
"aria-label": closeLabel,
|
|
1618
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
1619
|
+
onClick: (event) => {
|
|
1620
|
+
event.stopPropagation();
|
|
1621
|
+
onClose();
|
|
1622
|
+
},
|
|
1623
|
+
children: /* @__PURE__ */ jsx4(SearchCloseIcon, { className: "data-table-search-icon" })
|
|
1624
|
+
}
|
|
1625
|
+
) : null
|
|
1626
|
+
] }),
|
|
1627
|
+
/* @__PURE__ */ jsx4(
|
|
1628
|
+
"div",
|
|
1629
|
+
{
|
|
1630
|
+
className: cn("data-table-search-status", classNames?.searchStatus),
|
|
1631
|
+
"aria-live": "polite",
|
|
1632
|
+
children: resultString
|
|
1633
|
+
}
|
|
1634
|
+
),
|
|
1635
|
+
searchStatus !== void 0 ? /* @__PURE__ */ jsx4(
|
|
1636
|
+
"div",
|
|
1637
|
+
{
|
|
1638
|
+
className: cn(
|
|
1639
|
+
"data-table-search-progress",
|
|
1640
|
+
classNames?.searchProgress
|
|
1641
|
+
),
|
|
1642
|
+
role: "progressbar",
|
|
1643
|
+
"aria-valuemin": 0,
|
|
1644
|
+
"aria-valuemax": 100,
|
|
1645
|
+
"aria-valuenow": progress,
|
|
1646
|
+
children: /* @__PURE__ */ jsx4(
|
|
1647
|
+
"div",
|
|
1648
|
+
{
|
|
1649
|
+
className: "data-table-search-progress-bar",
|
|
1650
|
+
style: { width: `${progress}%` }
|
|
1651
|
+
}
|
|
1652
|
+
)
|
|
1653
|
+
}
|
|
1654
|
+
) : null
|
|
1655
|
+
]
|
|
1656
|
+
}
|
|
1657
|
+
);
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1296
1660
|
// src/components/ui/table/components/DataTable/DataTableToolbar.tsx
|
|
1297
|
-
import { Fragment, jsx as
|
|
1661
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1298
1662
|
function DataTableToolbar({
|
|
1299
1663
|
filteredCount,
|
|
1300
1664
|
totalCount,
|
|
@@ -1312,24 +1676,56 @@ function DataTableToolbar({
|
|
|
1312
1676
|
const selectionContent = selectionLabel?.(selectedCount) ?? null;
|
|
1313
1677
|
const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
|
|
1314
1678
|
if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
|
|
1315
|
-
return /* @__PURE__ */
|
|
1316
|
-
/* @__PURE__ */
|
|
1317
|
-
hasCount && /* @__PURE__ */
|
|
1318
|
-
/* @__PURE__ */
|
|
1319
|
-
/* @__PURE__ */
|
|
1679
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("DataTableToolbarJSX", classNames?.toolbar, className), children: [
|
|
1680
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("toolbar-left", classNames?.toolbarLeft), children: [
|
|
1681
|
+
hasCount && /* @__PURE__ */ jsx5("span", { className: cn("toolbar-count", classNames?.toolbarCount), children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1682
|
+
/* @__PURE__ */ jsx5("span", { className: "toolbar-count-primary", children: displayFiltered }),
|
|
1683
|
+
/* @__PURE__ */ jsxs4("span", { className: "toolbar-count-placeholder", children: [
|
|
1320
1684
|
" / ",
|
|
1321
1685
|
totalCount
|
|
1322
1686
|
] })
|
|
1323
|
-
] }) : /* @__PURE__ */
|
|
1687
|
+
] }) : /* @__PURE__ */ jsx5("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
|
|
1324
1688
|
summary
|
|
1325
1689
|
] }),
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */
|
|
1328
|
-
hasToolbar && /* @__PURE__ */
|
|
1690
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("toolbar-right", classNames?.toolbarRight), children: [
|
|
1691
|
+
hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ jsx5("span", { className: cn("toolbar-selection", classNames?.toolbarSelection), children: selectionContent }) : selectionContent),
|
|
1692
|
+
hasToolbar && /* @__PURE__ */ jsx5("div", { className: cn("toolbar-actions", classNames?.toolbarActions), children: toolbar })
|
|
1329
1693
|
] })
|
|
1330
1694
|
] });
|
|
1331
1695
|
}
|
|
1332
1696
|
|
|
1697
|
+
// src/components/ui/table/features/column-groups/mergeHeaderGroups.ts
|
|
1698
|
+
function getMergedHeaderGroups(headerGroups) {
|
|
1699
|
+
if (headerGroups.length <= 1) {
|
|
1700
|
+
return headerGroups.map((group) => ({
|
|
1701
|
+
...group,
|
|
1702
|
+
headers: group.headers.map((header) => ({
|
|
1703
|
+
...header,
|
|
1704
|
+
mergedRowSpan: 1
|
|
1705
|
+
}))
|
|
1706
|
+
}));
|
|
1707
|
+
}
|
|
1708
|
+
const seenColumnIds = /* @__PURE__ */ new Set();
|
|
1709
|
+
const fullDepth = headerGroups.length;
|
|
1710
|
+
return headerGroups.map((group, depth) => ({
|
|
1711
|
+
...group,
|
|
1712
|
+
headers: group.headers.filter((header) => !seenColumnIds.has(header.column.id)).map((header) => {
|
|
1713
|
+
seenColumnIds.add(header.column.id);
|
|
1714
|
+
if (header.isPlaceholder) {
|
|
1715
|
+
return {
|
|
1716
|
+
...header,
|
|
1717
|
+
isPlaceholder: false,
|
|
1718
|
+
mergedRowSpan: fullDepth - depth
|
|
1719
|
+
};
|
|
1720
|
+
}
|
|
1721
|
+
return {
|
|
1722
|
+
...header,
|
|
1723
|
+
mergedRowSpan: 1
|
|
1724
|
+
};
|
|
1725
|
+
})
|
|
1726
|
+
}));
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1333
1729
|
// src/core/useGlideTable.ts
|
|
1334
1730
|
import {
|
|
1335
1731
|
getCoreRowModel,
|
|
@@ -1339,11 +1735,11 @@ import {
|
|
|
1339
1735
|
useVirtualizer
|
|
1340
1736
|
} from "@tanstack/react-virtual";
|
|
1341
1737
|
import {
|
|
1342
|
-
useCallback as
|
|
1343
|
-
useEffect as
|
|
1344
|
-
useMemo as
|
|
1345
|
-
useRef as
|
|
1346
|
-
useState as
|
|
1738
|
+
useCallback as useCallback4,
|
|
1739
|
+
useEffect as useEffect6,
|
|
1740
|
+
useMemo as useMemo3,
|
|
1741
|
+
useRef as useRef6,
|
|
1742
|
+
useState as useState4
|
|
1347
1743
|
} from "react";
|
|
1348
1744
|
|
|
1349
1745
|
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
@@ -1672,26 +2068,44 @@ function useCellSelection({
|
|
|
1672
2068
|
data,
|
|
1673
2069
|
rows,
|
|
1674
2070
|
enabled = true,
|
|
2071
|
+
columnCount = 0,
|
|
1675
2072
|
enableSubtreeCopy = false,
|
|
1676
2073
|
enableInsertPaste = true,
|
|
1677
2074
|
onDataChange,
|
|
1678
2075
|
onBatchChange,
|
|
1679
|
-
onRowsPaste
|
|
2076
|
+
onRowsPaste,
|
|
2077
|
+
onCellNavigate
|
|
1680
2078
|
}) {
|
|
1681
2079
|
const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
|
|
1682
2080
|
const pendingPasteModeRef = useRef4(null);
|
|
2081
|
+
const dragStateRef = useRef4(dragState);
|
|
2082
|
+
const onCellNavigateRef = useRef4(onCellNavigate);
|
|
2083
|
+
dragStateRef.current = dragState;
|
|
2084
|
+
onCellNavigateRef.current = onCellNavigate;
|
|
1683
2085
|
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
1684
2086
|
const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
|
|
1685
2087
|
const handleCellMouseDown = useCallback2(
|
|
1686
|
-
(rowIndex, colIndex) => {
|
|
2088
|
+
(rowIndex, colIndex, options) => {
|
|
1687
2089
|
if (!enabled) return;
|
|
1688
|
-
setDragState({
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
2090
|
+
setDragState((prev) => {
|
|
2091
|
+
if (options?.shiftKey && prev.start) {
|
|
2092
|
+
return {
|
|
2093
|
+
...prev,
|
|
2094
|
+
isSelecting: true,
|
|
2095
|
+
isFillDragging: false,
|
|
2096
|
+
end: { row: rowIndex, col: colIndex },
|
|
2097
|
+
fillAnchor: null,
|
|
2098
|
+
fillEnd: null
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
return {
|
|
2102
|
+
isSelecting: true,
|
|
2103
|
+
isFillDragging: false,
|
|
2104
|
+
start: { row: rowIndex, col: colIndex },
|
|
2105
|
+
end: { row: rowIndex, col: colIndex },
|
|
2106
|
+
fillAnchor: null,
|
|
2107
|
+
fillEnd: null
|
|
2108
|
+
};
|
|
1695
2109
|
});
|
|
1696
2110
|
},
|
|
1697
2111
|
[enabled]
|
|
@@ -1733,6 +2147,53 @@ function useCellSelection({
|
|
|
1733
2147
|
setDragState(INITIAL_DRAG_STATE);
|
|
1734
2148
|
}
|
|
1735
2149
|
}, [enabled]);
|
|
2150
|
+
useEffect4(() => {
|
|
2151
|
+
if (!enabled) return;
|
|
2152
|
+
const handleKeyDown = (e) => {
|
|
2153
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
2154
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2157
|
+
const delta = getCellNavigationDelta(e.key);
|
|
2158
|
+
if (!delta) return;
|
|
2159
|
+
const prev = dragStateRef.current;
|
|
2160
|
+
if (!prev.start || !prev.end) return;
|
|
2161
|
+
if (prev.isSelecting || prev.isFillDragging) return;
|
|
2162
|
+
const rowCount = rows.length;
|
|
2163
|
+
const resolvedColumnCount = columnCount > 0 ? columnCount : rows[0]?.getVisibleCells().length ?? 0;
|
|
2164
|
+
if (rowCount <= 0 || resolvedColumnCount <= 0) return;
|
|
2165
|
+
const nextEnd = clampCellPosition(
|
|
2166
|
+
{
|
|
2167
|
+
row: prev.end.row + delta.row,
|
|
2168
|
+
col: prev.end.col + delta.col
|
|
2169
|
+
},
|
|
2170
|
+
rowCount,
|
|
2171
|
+
resolvedColumnCount
|
|
2172
|
+
);
|
|
2173
|
+
if (nextEnd.row === prev.end.row && nextEnd.col === prev.end.col) return;
|
|
2174
|
+
e.preventDefault();
|
|
2175
|
+
const nextState = e.shiftKey ? {
|
|
2176
|
+
...prev,
|
|
2177
|
+
isSelecting: false,
|
|
2178
|
+
isFillDragging: false,
|
|
2179
|
+
end: nextEnd,
|
|
2180
|
+
fillAnchor: null,
|
|
2181
|
+
fillEnd: null
|
|
2182
|
+
} : {
|
|
2183
|
+
isSelecting: false,
|
|
2184
|
+
isFillDragging: false,
|
|
2185
|
+
start: nextEnd,
|
|
2186
|
+
end: nextEnd,
|
|
2187
|
+
fillAnchor: null,
|
|
2188
|
+
fillEnd: null
|
|
2189
|
+
};
|
|
2190
|
+
dragStateRef.current = nextState;
|
|
2191
|
+
setDragState(nextState);
|
|
2192
|
+
onCellNavigateRef.current?.(nextEnd);
|
|
2193
|
+
};
|
|
2194
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2195
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
2196
|
+
}, [columnCount, enabled, rows]);
|
|
1736
2197
|
const copySelection = useCallback2(
|
|
1737
2198
|
async (options) => {
|
|
1738
2199
|
if (!enabled || !activeSelectionBounds) return false;
|
|
@@ -1890,6 +2351,311 @@ function useCellSelection({
|
|
|
1890
2351
|
};
|
|
1891
2352
|
}
|
|
1892
2353
|
|
|
2354
|
+
// src/components/ui/table/features/inline-search/useInlineSearch.ts
|
|
2355
|
+
import {
|
|
2356
|
+
useCallback as useCallback3,
|
|
2357
|
+
useEffect as useEffect5,
|
|
2358
|
+
useId,
|
|
2359
|
+
useMemo as useMemo2,
|
|
2360
|
+
useRef as useRef5,
|
|
2361
|
+
useState as useState3
|
|
2362
|
+
} from "react";
|
|
2363
|
+
var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
2364
|
+
function useInlineSearch({
|
|
2365
|
+
enabled = false,
|
|
2366
|
+
rowCount,
|
|
2367
|
+
columnCount,
|
|
2368
|
+
getCellValue,
|
|
2369
|
+
initialStartRow = 0,
|
|
2370
|
+
showSearch: controlledShowSearch,
|
|
2371
|
+
searchValue: controlledSearchValue,
|
|
2372
|
+
searchResults: controlledSearchResults,
|
|
2373
|
+
onSearchValueChange,
|
|
2374
|
+
onSearchClose,
|
|
2375
|
+
onSearchResultsChanged,
|
|
2376
|
+
onNavigateToResult,
|
|
2377
|
+
rootRef
|
|
2378
|
+
}) {
|
|
2379
|
+
const searchInputId = useId();
|
|
2380
|
+
const searchInputRef = useRef5(null);
|
|
2381
|
+
const [internalShowSearch, setInternalShowSearch] = useState3(false);
|
|
2382
|
+
const [internalSearchValue, setInternalSearchValue] = useState3("");
|
|
2383
|
+
const [internalResults, setInternalResults] = useState3(
|
|
2384
|
+
[]
|
|
2385
|
+
);
|
|
2386
|
+
const [searchStatus, setSearchStatus] = useState3();
|
|
2387
|
+
const searchStatusRef = useRef5(searchStatus);
|
|
2388
|
+
searchStatusRef.current = searchStatus;
|
|
2389
|
+
const abortControllerRef = useRef5(null);
|
|
2390
|
+
const searchHandleRef = useRef5(void 0);
|
|
2391
|
+
const initialStartRowRef = useRef5(initialStartRow);
|
|
2392
|
+
initialStartRowRef.current = initialStartRow;
|
|
2393
|
+
const getCellValueRef = useRef5(getCellValue);
|
|
2394
|
+
getCellValueRef.current = getCellValue;
|
|
2395
|
+
const showSearch = controlledShowSearch ?? internalShowSearch;
|
|
2396
|
+
const searchValue = controlledSearchValue ?? internalSearchValue;
|
|
2397
|
+
const searchResults = controlledSearchResults ?? internalResults;
|
|
2398
|
+
const setSearchValue = useCallback3(
|
|
2399
|
+
(value) => {
|
|
2400
|
+
setInternalSearchValue(value);
|
|
2401
|
+
onSearchValueChange?.(value);
|
|
2402
|
+
},
|
|
2403
|
+
[onSearchValueChange]
|
|
2404
|
+
);
|
|
2405
|
+
const cancelSearch = useCallback3(() => {
|
|
2406
|
+
if (searchHandleRef.current !== void 0) {
|
|
2407
|
+
window.cancelAnimationFrame(searchHandleRef.current);
|
|
2408
|
+
searchHandleRef.current = void 0;
|
|
2409
|
+
}
|
|
2410
|
+
abortControllerRef.current?.abort();
|
|
2411
|
+
}, []);
|
|
2412
|
+
const emitResultsChanged = useCallback3(
|
|
2413
|
+
(results, navIndex) => {
|
|
2414
|
+
onSearchResultsChanged?.(results, navIndex);
|
|
2415
|
+
},
|
|
2416
|
+
[onSearchResultsChanged]
|
|
2417
|
+
);
|
|
2418
|
+
const navigateToIndex = useCallback3(
|
|
2419
|
+
(results, navIndex) => {
|
|
2420
|
+
if (onSearchResultsChanged) return;
|
|
2421
|
+
if (navIndex < 0 || navIndex >= results.length) return;
|
|
2422
|
+
const item = results[navIndex];
|
|
2423
|
+
if (!item) return;
|
|
2424
|
+
onNavigateToResult?.(item);
|
|
2425
|
+
},
|
|
2426
|
+
[onNavigateToResult, onSearchResultsChanged]
|
|
2427
|
+
);
|
|
2428
|
+
const beginSearch = useCallback3(
|
|
2429
|
+
(query) => {
|
|
2430
|
+
if (controlledSearchResults !== void 0) return;
|
|
2431
|
+
const totalRows = rowCount;
|
|
2432
|
+
if (totalRows === 0 || columnCount === 0) {
|
|
2433
|
+
setSearchStatus(void 0);
|
|
2434
|
+
setInternalResults([]);
|
|
2435
|
+
emitResultsChanged([], -1);
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
let startY = Math.min(
|
|
2439
|
+
Math.max(0, initialStartRowRef.current),
|
|
2440
|
+
totalRows - 1
|
|
2441
|
+
);
|
|
2442
|
+
let searchStride = Math.min(INLINE_SEARCH_INITIAL_STRIDE, totalRows);
|
|
2443
|
+
let rowsSearched = 0;
|
|
2444
|
+
const runningResult = [];
|
|
2445
|
+
setSearchStatus(void 0);
|
|
2446
|
+
setInternalResults([]);
|
|
2447
|
+
const tick = () => {
|
|
2448
|
+
if (abortControllerRef.current?.signal.aborted) return;
|
|
2449
|
+
const tStart = performance.now();
|
|
2450
|
+
const rowsLeft = totalRows - rowsSearched;
|
|
2451
|
+
const height = Math.min(searchStride, rowsLeft, totalRows - startY);
|
|
2452
|
+
if (height <= 0) {
|
|
2453
|
+
return;
|
|
2454
|
+
}
|
|
2455
|
+
const chunk = collectSearchMatchesInRange({
|
|
2456
|
+
query,
|
|
2457
|
+
startRow: startY,
|
|
2458
|
+
rowCount: height,
|
|
2459
|
+
columnCount,
|
|
2460
|
+
getCellValue: (rowIndex, colIndex) => getCellValueRef.current(rowIndex, colIndex),
|
|
2461
|
+
maxResults: INLINE_SEARCH_MAX_RESULTS - runningResult.length
|
|
2462
|
+
});
|
|
2463
|
+
if (chunk.length > 0) {
|
|
2464
|
+
runningResult.push(...chunk);
|
|
2465
|
+
setInternalResults([...runningResult]);
|
|
2466
|
+
}
|
|
2467
|
+
rowsSearched += height;
|
|
2468
|
+
const selectedIndex = searchStatusRef.current?.selectedIndex ?? -1;
|
|
2469
|
+
setSearchStatus({
|
|
2470
|
+
results: runningResult.length,
|
|
2471
|
+
rowsSearched,
|
|
2472
|
+
selectedIndex
|
|
2473
|
+
});
|
|
2474
|
+
emitResultsChanged(runningResult, selectedIndex);
|
|
2475
|
+
if (startY + height >= totalRows) {
|
|
2476
|
+
startY = 0;
|
|
2477
|
+
} else {
|
|
2478
|
+
startY += height;
|
|
2479
|
+
}
|
|
2480
|
+
searchStride = nextSearchStride(
|
|
2481
|
+
searchStride,
|
|
2482
|
+
performance.now() - tStart
|
|
2483
|
+
);
|
|
2484
|
+
if (rowsSearched < totalRows && runningResult.length < INLINE_SEARCH_MAX_RESULTS) {
|
|
2485
|
+
searchHandleRef.current = window.requestAnimationFrame(tick);
|
|
2486
|
+
}
|
|
2487
|
+
};
|
|
2488
|
+
cancelSearch();
|
|
2489
|
+
abortControllerRef.current = new AbortController();
|
|
2490
|
+
searchHandleRef.current = window.requestAnimationFrame(tick);
|
|
2491
|
+
},
|
|
2492
|
+
[
|
|
2493
|
+
cancelSearch,
|
|
2494
|
+
columnCount,
|
|
2495
|
+
controlledSearchResults,
|
|
2496
|
+
emitResultsChanged,
|
|
2497
|
+
rowCount
|
|
2498
|
+
]
|
|
2499
|
+
);
|
|
2500
|
+
const openSearch = useCallback3(() => {
|
|
2501
|
+
if (controlledShowSearch === void 0) {
|
|
2502
|
+
setInternalShowSearch(true);
|
|
2503
|
+
}
|
|
2504
|
+
}, [controlledShowSearch]);
|
|
2505
|
+
const closeSearch = useCallback3(() => {
|
|
2506
|
+
if (controlledShowSearch === void 0) {
|
|
2507
|
+
setInternalShowSearch(false);
|
|
2508
|
+
}
|
|
2509
|
+
onSearchClose?.();
|
|
2510
|
+
setSearchStatus(void 0);
|
|
2511
|
+
setInternalResults([]);
|
|
2512
|
+
emitResultsChanged([], -1);
|
|
2513
|
+
cancelSearch();
|
|
2514
|
+
}, [
|
|
2515
|
+
cancelSearch,
|
|
2516
|
+
controlledShowSearch,
|
|
2517
|
+
emitResultsChanged,
|
|
2518
|
+
onSearchClose
|
|
2519
|
+
]);
|
|
2520
|
+
const goToNext = useCallback3(() => {
|
|
2521
|
+
if (!searchStatus || searchStatus.results === 0) return;
|
|
2522
|
+
const newIndex = nextSearchIndex(
|
|
2523
|
+
searchStatus.selectedIndex,
|
|
2524
|
+
searchStatus.results
|
|
2525
|
+
);
|
|
2526
|
+
setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
|
|
2527
|
+
emitResultsChanged(searchResults, newIndex);
|
|
2528
|
+
navigateToIndex(searchResults, newIndex);
|
|
2529
|
+
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
2530
|
+
const goToPrevious = useCallback3(() => {
|
|
2531
|
+
if (!searchStatus || searchStatus.results === 0) return;
|
|
2532
|
+
const newIndex = previousSearchIndex(
|
|
2533
|
+
searchStatus.selectedIndex,
|
|
2534
|
+
searchStatus.results
|
|
2535
|
+
);
|
|
2536
|
+
setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
|
|
2537
|
+
emitResultsChanged(searchResults, newIndex);
|
|
2538
|
+
navigateToIndex(searchResults, newIndex);
|
|
2539
|
+
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
2540
|
+
useEffect5(() => {
|
|
2541
|
+
if (controlledSearchResults === void 0) return;
|
|
2542
|
+
if (controlledSearchResults.length > 0) {
|
|
2543
|
+
setSearchStatus((current) => ({
|
|
2544
|
+
rowsSearched: rowCount,
|
|
2545
|
+
results: controlledSearchResults.length,
|
|
2546
|
+
selectedIndex: current?.selectedIndex ?? -1
|
|
2547
|
+
}));
|
|
2548
|
+
} else {
|
|
2549
|
+
setSearchStatus(void 0);
|
|
2550
|
+
}
|
|
2551
|
+
}, [controlledSearchResults, rowCount]);
|
|
2552
|
+
useEffect5(() => {
|
|
2553
|
+
if (!enabled) return;
|
|
2554
|
+
setSearchStatus(void 0);
|
|
2555
|
+
setInternalResults([]);
|
|
2556
|
+
emitResultsChanged([], -1);
|
|
2557
|
+
if (showSearch) {
|
|
2558
|
+
queueMicrotask(() => {
|
|
2559
|
+
searchInputRef.current?.focus({ preventScroll: true });
|
|
2560
|
+
});
|
|
2561
|
+
} else {
|
|
2562
|
+
cancelSearch();
|
|
2563
|
+
}
|
|
2564
|
+
}, [enabled, showSearch]);
|
|
2565
|
+
useEffect5(() => {
|
|
2566
|
+
if (!enabled || !showSearch) return;
|
|
2567
|
+
if (controlledSearchResults !== void 0) return;
|
|
2568
|
+
if (searchValue.trim() === "") {
|
|
2569
|
+
setSearchStatus(void 0);
|
|
2570
|
+
setInternalResults([]);
|
|
2571
|
+
cancelSearch();
|
|
2572
|
+
emitResultsChanged([], -1);
|
|
2573
|
+
return;
|
|
2574
|
+
}
|
|
2575
|
+
beginSearch(searchValue);
|
|
2576
|
+
}, [
|
|
2577
|
+
beginSearch,
|
|
2578
|
+
cancelSearch,
|
|
2579
|
+
controlledSearchResults,
|
|
2580
|
+
emitResultsChanged,
|
|
2581
|
+
enabled,
|
|
2582
|
+
searchValue,
|
|
2583
|
+
showSearch
|
|
2584
|
+
]);
|
|
2585
|
+
useEffect5(() => {
|
|
2586
|
+
if (!enabled) return;
|
|
2587
|
+
const handleKeyDown = (event) => {
|
|
2588
|
+
if (!(event.ctrlKey || event.metaKey)) return;
|
|
2589
|
+
if (event.key.toLowerCase() !== "f") return;
|
|
2590
|
+
const root = rootRef?.current;
|
|
2591
|
+
if (root) {
|
|
2592
|
+
const active = document.activeElement;
|
|
2593
|
+
const focusInside = active === root || active instanceof Node && root.contains(active);
|
|
2594
|
+
if (!focusInside && active !== document.body) {
|
|
2595
|
+
return;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
event.preventDefault();
|
|
2599
|
+
event.stopPropagation();
|
|
2600
|
+
if (showSearch) {
|
|
2601
|
+
searchInputRef.current?.focus({ preventScroll: true });
|
|
2602
|
+
searchInputRef.current?.select();
|
|
2603
|
+
return;
|
|
2604
|
+
}
|
|
2605
|
+
if (controlledShowSearch === void 0) {
|
|
2606
|
+
setInternalShowSearch(true);
|
|
2607
|
+
}
|
|
2608
|
+
};
|
|
2609
|
+
window.addEventListener("keydown", handleKeyDown, true);
|
|
2610
|
+
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
2611
|
+
}, [controlledShowSearch, enabled, rootRef, showSearch]);
|
|
2612
|
+
useEffect5(() => () => cancelSearch(), [cancelSearch]);
|
|
2613
|
+
const searchMatchKeys = useMemo2(
|
|
2614
|
+
() => buildSearchMatchKeys(searchResults),
|
|
2615
|
+
[searchResults]
|
|
2616
|
+
);
|
|
2617
|
+
const activeMatch = useMemo2(() => {
|
|
2618
|
+
if (!searchStatus || searchStatus.selectedIndex < 0) return null;
|
|
2619
|
+
return searchResults[searchStatus.selectedIndex] ?? null;
|
|
2620
|
+
}, [searchResults, searchStatus]);
|
|
2621
|
+
if (!enabled) {
|
|
2622
|
+
return {
|
|
2623
|
+
enabled: false,
|
|
2624
|
+
showSearch: false,
|
|
2625
|
+
searchValue: "",
|
|
2626
|
+
searchResults: [],
|
|
2627
|
+
searchStatus: void 0,
|
|
2628
|
+
searchMatchKeys: EMPTY_MATCH_KEYS,
|
|
2629
|
+
activeMatch: null,
|
|
2630
|
+
searchInputRef,
|
|
2631
|
+
searchInputId,
|
|
2632
|
+
canClose: false,
|
|
2633
|
+
openSearch,
|
|
2634
|
+
closeSearch,
|
|
2635
|
+
setSearchValue,
|
|
2636
|
+
goToNext,
|
|
2637
|
+
goToPrevious
|
|
2638
|
+
};
|
|
2639
|
+
}
|
|
2640
|
+
return {
|
|
2641
|
+
enabled: true,
|
|
2642
|
+
showSearch,
|
|
2643
|
+
searchValue,
|
|
2644
|
+
searchResults,
|
|
2645
|
+
searchStatus,
|
|
2646
|
+
searchMatchKeys,
|
|
2647
|
+
activeMatch,
|
|
2648
|
+
searchInputRef,
|
|
2649
|
+
searchInputId,
|
|
2650
|
+
canClose: controlledShowSearch === void 0 || onSearchClose !== void 0,
|
|
2651
|
+
openSearch,
|
|
2652
|
+
closeSearch,
|
|
2653
|
+
setSearchValue,
|
|
2654
|
+
goToNext,
|
|
2655
|
+
goToPrevious
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
|
|
1893
2659
|
// src/components/ui/table/features/row-selection/rowSelection.ts
|
|
1894
2660
|
function resolveRowSelection(mode, controlledSelection, internalSelection) {
|
|
1895
2661
|
if (mode === "none") return {};
|
|
@@ -1912,7 +2678,12 @@ var DEFAULT_DATA_TABLE_LABELS = {
|
|
|
1912
2678
|
selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
|
|
1913
2679
|
expandRow: "Expand row",
|
|
1914
2680
|
collapseRow: "Collapse row",
|
|
1915
|
-
resizeColumn: "Resize column"
|
|
2681
|
+
resizeColumn: "Resize column",
|
|
2682
|
+
searchPlaceholder: "Search\u2026",
|
|
2683
|
+
searchResultHint: "Type to search",
|
|
2684
|
+
searchPrevious: "Previous result",
|
|
2685
|
+
searchNext: "Next result",
|
|
2686
|
+
searchClose: "Close search"
|
|
1916
2687
|
};
|
|
1917
2688
|
function resolveDataTableLabels(partial) {
|
|
1918
2689
|
return {
|
|
@@ -1923,6 +2694,7 @@ function resolveDataTableLabels(partial) {
|
|
|
1923
2694
|
|
|
1924
2695
|
// src/core/useGlideTable.ts
|
|
1925
2696
|
var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
|
|
2697
|
+
var EMPTY_SEARCH_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
1926
2698
|
function useGlideTable(options) {
|
|
1927
2699
|
const {
|
|
1928
2700
|
data,
|
|
@@ -1963,9 +2735,16 @@ function useGlideTable(options) {
|
|
|
1963
2735
|
columnSizing: controlledColumnSizing,
|
|
1964
2736
|
onColumnSizingChange,
|
|
1965
2737
|
columnResizeMode = "onChange",
|
|
1966
|
-
enableColumnFreeze = false
|
|
2738
|
+
enableColumnFreeze = false,
|
|
2739
|
+
enableInlineSearch = false,
|
|
2740
|
+
showSearch,
|
|
2741
|
+
searchValue,
|
|
2742
|
+
onSearchValueChange,
|
|
2743
|
+
onSearchClose,
|
|
2744
|
+
searchResults,
|
|
2745
|
+
onSearchResultsChanged
|
|
1967
2746
|
} = options;
|
|
1968
|
-
const labels =
|
|
2747
|
+
const labels = useMemo3(() => {
|
|
1969
2748
|
const resolved = resolveDataTableLabels(labelsProp);
|
|
1970
2749
|
return {
|
|
1971
2750
|
...resolved,
|
|
@@ -1976,15 +2755,16 @@ function useGlideTable(options) {
|
|
|
1976
2755
|
}, [labelsProp, emptyText, loadingText, selectionLabel]);
|
|
1977
2756
|
const enableExpand = Boolean(toggleField);
|
|
1978
2757
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
1979
|
-
const [internalRowSelection, setInternalRowSelection] =
|
|
1980
|
-
const [internalColumnSizing, setInternalColumnSizing] =
|
|
1981
|
-
const [internalExpandedRows, setInternalExpandedRows] =
|
|
2758
|
+
const [internalRowSelection, setInternalRowSelection] = useState4({});
|
|
2759
|
+
const [internalColumnSizing, setInternalColumnSizing] = useState4({});
|
|
2760
|
+
const [internalExpandedRows, setInternalExpandedRows] = useState4(
|
|
1982
2761
|
() => /* @__PURE__ */ new Set()
|
|
1983
2762
|
);
|
|
1984
|
-
const [hoveredRowIndex, setHoveredRowIndex] =
|
|
1985
|
-
const scrollRef =
|
|
2763
|
+
const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
|
|
2764
|
+
const scrollRef = useRef6(null);
|
|
2765
|
+
const rootRef = useRef6(null);
|
|
1986
2766
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
1987
|
-
|
|
2767
|
+
useEffect6(() => {
|
|
1988
2768
|
if (enableVirtualization && enableRowSpan) {
|
|
1989
2769
|
console.warn(
|
|
1990
2770
|
"[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
|
|
@@ -1998,7 +2778,7 @@ function useGlideTable(options) {
|
|
|
1998
2778
|
);
|
|
1999
2779
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
2000
2780
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
2001
|
-
const handleExpandedRowsChange =
|
|
2781
|
+
const handleExpandedRowsChange = useCallback4(
|
|
2002
2782
|
(next) => {
|
|
2003
2783
|
if (onExpandedRowsChange) {
|
|
2004
2784
|
onExpandedRowsChange(next);
|
|
@@ -2059,13 +2839,13 @@ function useGlideTable(options) {
|
|
|
2059
2839
|
getCoreRowModel: getCoreRowModel(),
|
|
2060
2840
|
getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
|
|
2061
2841
|
});
|
|
2062
|
-
const rowSpanColumnKeys =
|
|
2842
|
+
const rowSpanColumnKeys = useMemo3(() => {
|
|
2063
2843
|
if (!enableRowSpan) return [];
|
|
2064
2844
|
return collectRowSpanColumns(columns);
|
|
2065
2845
|
}, [enableRowSpan, columns]);
|
|
2066
2846
|
const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
|
|
2067
2847
|
const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
|
|
2068
|
-
const columnRowSpanMap =
|
|
2848
|
+
const columnRowSpanMap = useMemo3(
|
|
2069
2849
|
() => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
|
|
2070
2850
|
[tableData, rowSpanColumnKeys]
|
|
2071
2851
|
);
|
|
@@ -2074,7 +2854,7 @@ function useGlideTable(options) {
|
|
|
2074
2854
|
const rows = table.getRowModel().rows;
|
|
2075
2855
|
const columnCount = table.getAllLeafColumns().length || 1;
|
|
2076
2856
|
const visibleLeafColumns = table.getVisibleLeafColumns();
|
|
2077
|
-
const columnFreezeOffsets =
|
|
2857
|
+
const columnFreezeOffsets = useMemo3(() => {
|
|
2078
2858
|
if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
|
|
2079
2859
|
return buildColumnFreezeOffsets(
|
|
2080
2860
|
visibleLeafColumns.map((column) => ({
|
|
@@ -2094,13 +2874,46 @@ function useGlideTable(options) {
|
|
|
2094
2874
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
2095
2875
|
const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
2096
2876
|
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
|
|
2097
|
-
const selectedRowIndices =
|
|
2877
|
+
const selectedRowIndices = useMemo3(() => {
|
|
2098
2878
|
const indices = /* @__PURE__ */ new Set();
|
|
2099
2879
|
for (const selectedRow of selectedRows) {
|
|
2100
2880
|
indices.add(selectedRow.index);
|
|
2101
2881
|
}
|
|
2102
2882
|
return indices;
|
|
2103
2883
|
}, [selectedRows]);
|
|
2884
|
+
const scrollCellIntoView = useCallback4(
|
|
2885
|
+
(rowIndex, colIndex, options2) => {
|
|
2886
|
+
const align = options2?.align ?? "nearest";
|
|
2887
|
+
const blockAlign = align === "center" ? "center" : "nearest";
|
|
2888
|
+
if (shouldVirtualize) {
|
|
2889
|
+
rowVirtualizer.scrollToIndex(rowIndex, {
|
|
2890
|
+
align: align === "nearest" ? "auto" : align
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
const scrollElement = scrollRef.current;
|
|
2894
|
+
if (!scrollElement) return;
|
|
2895
|
+
const scrollToMatchedCell = () => {
|
|
2896
|
+
const cell = scrollElement.querySelector(
|
|
2897
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
2898
|
+
);
|
|
2899
|
+
if (cell instanceof HTMLElement) {
|
|
2900
|
+
cell.scrollIntoView({ block: blockAlign, inline: "nearest" });
|
|
2901
|
+
}
|
|
2902
|
+
};
|
|
2903
|
+
if (shouldVirtualize) {
|
|
2904
|
+
requestAnimationFrame(scrollToMatchedCell);
|
|
2905
|
+
return;
|
|
2906
|
+
}
|
|
2907
|
+
scrollToMatchedCell();
|
|
2908
|
+
},
|
|
2909
|
+
[rowVirtualizer, shouldVirtualize]
|
|
2910
|
+
);
|
|
2911
|
+
const handleCellNavigate = useCallback4(
|
|
2912
|
+
(position) => {
|
|
2913
|
+
scrollCellIntoView(position.row, position.col, { align: "nearest" });
|
|
2914
|
+
},
|
|
2915
|
+
[scrollCellIntoView]
|
|
2916
|
+
);
|
|
2104
2917
|
const {
|
|
2105
2918
|
dragState,
|
|
2106
2919
|
activeSelectionBounds,
|
|
@@ -2112,11 +2925,13 @@ function useGlideTable(options) {
|
|
|
2112
2925
|
data: tableData,
|
|
2113
2926
|
rows,
|
|
2114
2927
|
enabled: enableCellSelection,
|
|
2928
|
+
columnCount: visibleLeafColumns.length,
|
|
2115
2929
|
enableSubtreeCopy: resolvedEnableSubtreeCopy,
|
|
2116
2930
|
enableInsertPaste: enableInsertPaste ?? true,
|
|
2117
2931
|
onDataChange,
|
|
2118
2932
|
onBatchChange,
|
|
2119
|
-
onRowsPaste
|
|
2933
|
+
onRowsPaste,
|
|
2934
|
+
onCellNavigate: handleCellNavigate
|
|
2120
2935
|
});
|
|
2121
2936
|
const {
|
|
2122
2937
|
editingCell,
|
|
@@ -2126,23 +2941,193 @@ function useGlideTable(options) {
|
|
|
2126
2941
|
commitEdit,
|
|
2127
2942
|
cancelEdit
|
|
2128
2943
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
2129
|
-
const handleCellMouseDownWithCommit =
|
|
2130
|
-
(rowIndex, colIndex) => {
|
|
2944
|
+
const handleCellMouseDownWithCommit = useCallback4(
|
|
2945
|
+
(rowIndex, colIndex, options2) => {
|
|
2131
2946
|
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
2132
2947
|
if (editingCell && !isSameEditingCell && !commitEdit()) {
|
|
2133
2948
|
return;
|
|
2134
2949
|
}
|
|
2135
|
-
handleCellMouseDown(rowIndex, colIndex);
|
|
2950
|
+
handleCellMouseDown(rowIndex, colIndex, options2);
|
|
2136
2951
|
},
|
|
2137
2952
|
[commitEdit, editingCell, handleCellMouseDown]
|
|
2138
2953
|
);
|
|
2139
|
-
const
|
|
2954
|
+
const navigateToSearchResult = useCallback4(
|
|
2955
|
+
(item) => {
|
|
2956
|
+
const [colIndex, rowIndex] = item;
|
|
2957
|
+
handleCellMouseDownWithCommit(rowIndex, colIndex);
|
|
2958
|
+
scrollCellIntoView(rowIndex, colIndex, { align: "center" });
|
|
2959
|
+
},
|
|
2960
|
+
[handleCellMouseDownWithCommit, scrollCellIntoView]
|
|
2961
|
+
);
|
|
2962
|
+
const resolveSearchRowId = useCallback4(
|
|
2963
|
+
(row, index) => {
|
|
2964
|
+
if (getRowId) return getRowId(row, index);
|
|
2965
|
+
if (enableExpand) {
|
|
2966
|
+
const record = row;
|
|
2967
|
+
const idValue = record.id;
|
|
2968
|
+
if (idValue != null && String(idValue).length > 0) {
|
|
2969
|
+
return String(idValue);
|
|
2970
|
+
}
|
|
2971
|
+
const uniqueId = record.uniqueId;
|
|
2972
|
+
if (uniqueId != null && String(uniqueId).length > 0) {
|
|
2973
|
+
return String(uniqueId);
|
|
2974
|
+
}
|
|
2975
|
+
if (toggleField) {
|
|
2976
|
+
const toggleValue = record[toggleField];
|
|
2977
|
+
if (toggleValue != null && String(toggleValue).length > 0) {
|
|
2978
|
+
return String(toggleValue);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
return String(index);
|
|
2983
|
+
},
|
|
2984
|
+
[enableExpand, getRowId, toggleField]
|
|
2985
|
+
);
|
|
2986
|
+
const searchCorpus = useMemo3(() => {
|
|
2987
|
+
if (!enableInlineSearch) return [];
|
|
2988
|
+
if (enableExpand && toggleField) {
|
|
2989
|
+
return buildTreeSearchCorpus(tableData, {
|
|
2990
|
+
toggleField,
|
|
2991
|
+
getRowId: resolveSearchRowId
|
|
2992
|
+
});
|
|
2993
|
+
}
|
|
2994
|
+
return buildFlatSearchCorpus(tableData, resolveSearchRowId);
|
|
2995
|
+
}, [
|
|
2996
|
+
enableExpand,
|
|
2997
|
+
enableInlineSearch,
|
|
2998
|
+
resolveSearchRowId,
|
|
2999
|
+
tableData,
|
|
3000
|
+
toggleField
|
|
3001
|
+
]);
|
|
3002
|
+
const searchCorpusRef = useRef6(searchCorpus);
|
|
3003
|
+
searchCorpusRef.current = searchCorpus;
|
|
3004
|
+
const visibleRowIndexById = useMemo3(() => {
|
|
3005
|
+
const map = /* @__PURE__ */ new Map();
|
|
3006
|
+
for (const row of rows) {
|
|
3007
|
+
map.set(resolveSearchRowId(row.original, row.index), row.index);
|
|
3008
|
+
}
|
|
3009
|
+
return map;
|
|
3010
|
+
}, [resolveSearchRowId, rows]);
|
|
3011
|
+
const getSearchCellValue = useCallback4(
|
|
3012
|
+
(rowIndex, colIndex) => {
|
|
3013
|
+
const corpusRow = searchCorpusRef.current[rowIndex];
|
|
3014
|
+
const column = visibleLeafColumns[colIndex];
|
|
3015
|
+
if (!corpusRow || !column) return void 0;
|
|
3016
|
+
const visibleIndex = visibleRowIndexById.get(corpusRow.id);
|
|
3017
|
+
if (visibleIndex !== void 0) {
|
|
3018
|
+
const visibleRow = rows[visibleIndex];
|
|
3019
|
+
if (visibleRow) {
|
|
3020
|
+
return visibleRow.getValue(column.id);
|
|
3021
|
+
}
|
|
3022
|
+
}
|
|
3023
|
+
const columnDef = column.columnDef;
|
|
3024
|
+
if ("accessorFn" in columnDef && typeof columnDef.accessorFn === "function") {
|
|
3025
|
+
return columnDef.accessorFn(corpusRow.data, rowIndex);
|
|
3026
|
+
}
|
|
3027
|
+
if ("accessorKey" in columnDef && columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
3028
|
+
return corpusRow.data[String(columnDef.accessorKey)];
|
|
3029
|
+
}
|
|
3030
|
+
return corpusRow.data[column.id];
|
|
3031
|
+
},
|
|
3032
|
+
[rows, visibleLeafColumns, visibleRowIndexById]
|
|
3033
|
+
);
|
|
3034
|
+
const pendingSearchNavRef = useRef6(null);
|
|
3035
|
+
const focusSearchResult = useCallback4(
|
|
3036
|
+
(colIndex, visibleRowIndex) => {
|
|
3037
|
+
navigateToSearchResult([colIndex, visibleRowIndex]);
|
|
3038
|
+
},
|
|
3039
|
+
[navigateToSearchResult]
|
|
3040
|
+
);
|
|
3041
|
+
const navigateToCorpusSearchResult = useCallback4(
|
|
3042
|
+
(item) => {
|
|
3043
|
+
const [colIndex, corpusRowIndex] = item;
|
|
3044
|
+
const corpusRow = searchCorpusRef.current[corpusRowIndex];
|
|
3045
|
+
if (!corpusRow) return;
|
|
3046
|
+
const missingKeys = collectAncestorKeysToExpand(corpusRow, expandedRows);
|
|
3047
|
+
if (missingKeys.length > 0) {
|
|
3048
|
+
pendingSearchNavRef.current = {
|
|
3049
|
+
colIndex,
|
|
3050
|
+
rowId: corpusRow.id
|
|
3051
|
+
};
|
|
3052
|
+
const next = new Set(expandedRows);
|
|
3053
|
+
for (const key of corpusRow.ancestorToggleKeys) {
|
|
3054
|
+
next.add(key);
|
|
3055
|
+
}
|
|
3056
|
+
handleExpandedRowsChange(next);
|
|
3057
|
+
return;
|
|
3058
|
+
}
|
|
3059
|
+
const visibleItem = mapSearchResultToVisibleItem(
|
|
3060
|
+
item,
|
|
3061
|
+
searchCorpusRef.current,
|
|
3062
|
+
visibleRowIndexById
|
|
3063
|
+
);
|
|
3064
|
+
if (!visibleItem) return;
|
|
3065
|
+
focusSearchResult(visibleItem[0], visibleItem[1]);
|
|
3066
|
+
},
|
|
3067
|
+
[
|
|
3068
|
+
expandedRows,
|
|
3069
|
+
focusSearchResult,
|
|
3070
|
+
handleExpandedRowsChange,
|
|
3071
|
+
visibleRowIndexById
|
|
3072
|
+
]
|
|
3073
|
+
);
|
|
3074
|
+
useEffect6(() => {
|
|
3075
|
+
const pending = pendingSearchNavRef.current;
|
|
3076
|
+
if (!pending) return;
|
|
3077
|
+
const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
|
|
3078
|
+
if (visibleRowIndex === void 0) return;
|
|
3079
|
+
pendingSearchNavRef.current = null;
|
|
3080
|
+
focusSearchResult(pending.colIndex, visibleRowIndex);
|
|
3081
|
+
}, [focusSearchResult, rows, visibleRowIndexById]);
|
|
3082
|
+
const initialSearchStartRow = virtualRows[0]?.index ?? 0;
|
|
3083
|
+
const inlineSearch = useInlineSearch({
|
|
3084
|
+
enabled: enableInlineSearch,
|
|
3085
|
+
rowCount: searchCorpus.length,
|
|
3086
|
+
columnCount: visibleLeafColumns.length,
|
|
3087
|
+
getCellValue: getSearchCellValue,
|
|
3088
|
+
initialStartRow: initialSearchStartRow,
|
|
3089
|
+
showSearch,
|
|
3090
|
+
searchValue,
|
|
3091
|
+
searchResults,
|
|
3092
|
+
onSearchValueChange,
|
|
3093
|
+
onSearchClose,
|
|
3094
|
+
onSearchResultsChanged,
|
|
3095
|
+
onNavigateToResult: navigateToCorpusSearchResult,
|
|
3096
|
+
rootRef
|
|
3097
|
+
});
|
|
3098
|
+
const visibleSearchMatchKeys = useMemo3(() => {
|
|
3099
|
+
if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
|
|
3100
|
+
return mapSearchResultsToVisibleKeys(
|
|
3101
|
+
inlineSearch.searchResults,
|
|
3102
|
+
searchCorpus,
|
|
3103
|
+
visibleRowIndexById
|
|
3104
|
+
);
|
|
3105
|
+
}, [
|
|
3106
|
+
enableInlineSearch,
|
|
3107
|
+
inlineSearch.searchResults,
|
|
3108
|
+
searchCorpus,
|
|
3109
|
+
visibleRowIndexById
|
|
3110
|
+
]);
|
|
3111
|
+
const visibleActiveMatch = useMemo3(() => {
|
|
3112
|
+
if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
|
|
3113
|
+
return mapSearchResultToVisibleItem(
|
|
3114
|
+
inlineSearch.activeMatch,
|
|
3115
|
+
searchCorpus,
|
|
3116
|
+
visibleRowIndexById
|
|
3117
|
+
);
|
|
3118
|
+
}, [
|
|
3119
|
+
enableInlineSearch,
|
|
3120
|
+
inlineSearch.activeMatch,
|
|
3121
|
+
searchCorpus,
|
|
3122
|
+
visibleRowIndexById
|
|
3123
|
+
]);
|
|
3124
|
+
const clearHover = useCallback4(() => {
|
|
2140
3125
|
setHoveredRowIndex(null);
|
|
2141
3126
|
}, []);
|
|
2142
|
-
const handleRowHover =
|
|
3127
|
+
const handleRowHover = useCallback4((rowIndex, _rowData) => {
|
|
2143
3128
|
setHoveredRowIndex(rowIndex);
|
|
2144
3129
|
}, []);
|
|
2145
|
-
const handleToggleSelect =
|
|
3130
|
+
const handleToggleSelect = useCallback4(
|
|
2146
3131
|
(row) => {
|
|
2147
3132
|
if (!row.getCanSelect()) return;
|
|
2148
3133
|
if (preserveRowSelection && row.getIsSelected()) {
|
|
@@ -2152,14 +3137,14 @@ function useGlideTable(options) {
|
|
|
2152
3137
|
},
|
|
2153
3138
|
[preserveRowSelection]
|
|
2154
3139
|
);
|
|
2155
|
-
const handleToggleExpand =
|
|
3140
|
+
const handleToggleExpand = useCallback4(
|
|
2156
3141
|
(rowKey) => {
|
|
2157
3142
|
if (preventExpand) return;
|
|
2158
3143
|
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
2159
3144
|
},
|
|
2160
3145
|
[preventExpand, handleExpandedRowsChange, expandedRows]
|
|
2161
3146
|
);
|
|
2162
|
-
const rowContextValue =
|
|
3147
|
+
const rowContextValue = useMemo3(() => {
|
|
2163
3148
|
return {
|
|
2164
3149
|
rowSpan: {
|
|
2165
3150
|
enableRowSpan,
|
|
@@ -2207,6 +3192,11 @@ function useGlideTable(options) {
|
|
|
2207
3192
|
columnFreeze: {
|
|
2208
3193
|
enableColumnFreeze,
|
|
2209
3194
|
offsets: columnFreezeOffsets
|
|
3195
|
+
},
|
|
3196
|
+
inlineSearch: {
|
|
3197
|
+
enabled: enableInlineSearch,
|
|
3198
|
+
matchKeys: visibleSearchMatchKeys,
|
|
3199
|
+
activeMatch: visibleActiveMatch
|
|
2210
3200
|
}
|
|
2211
3201
|
};
|
|
2212
3202
|
}, [
|
|
@@ -2242,14 +3232,17 @@ function useGlideTable(options) {
|
|
|
2242
3232
|
labels.collapseRow,
|
|
2243
3233
|
enableColumnResize,
|
|
2244
3234
|
enableColumnFreeze,
|
|
2245
|
-
columnFreezeOffsets
|
|
3235
|
+
columnFreezeOffsets,
|
|
3236
|
+
enableInlineSearch,
|
|
3237
|
+
visibleSearchMatchKeys,
|
|
3238
|
+
visibleActiveMatch
|
|
2246
3239
|
]);
|
|
2247
|
-
const copySelectionRef =
|
|
2248
|
-
|
|
3240
|
+
const copySelectionRef = useRef6(copySelection);
|
|
3241
|
+
useEffect6(() => {
|
|
2249
3242
|
copySelectionRef.current = copySelection;
|
|
2250
3243
|
}, [copySelection]);
|
|
2251
|
-
const stableCopySelection =
|
|
2252
|
-
|
|
3244
|
+
const stableCopySelection = useCallback4((options2) => copySelectionRef.current(options2), []);
|
|
3245
|
+
useEffect6(() => {
|
|
2253
3246
|
onCopyActionsReady?.({ copySelection: stableCopySelection });
|
|
2254
3247
|
}, [onCopyActionsReady, stableCopySelection]);
|
|
2255
3248
|
return {
|
|
@@ -2265,8 +3258,10 @@ function useGlideTable(options) {
|
|
|
2265
3258
|
enableCellSelection,
|
|
2266
3259
|
enableColumnResize,
|
|
2267
3260
|
enableColumnFreeze,
|
|
3261
|
+
enableInlineSearch,
|
|
2268
3262
|
shouldVirtualize,
|
|
2269
3263
|
scrollRef,
|
|
3264
|
+
rootRef,
|
|
2270
3265
|
rowVirtualizer,
|
|
2271
3266
|
virtualRows,
|
|
2272
3267
|
paddingTop,
|
|
@@ -2274,25 +3269,39 @@ function useGlideTable(options) {
|
|
|
2274
3269
|
rowContextValue,
|
|
2275
3270
|
handleToggleSelect,
|
|
2276
3271
|
clearHover,
|
|
2277
|
-
copySelection: stableCopySelection
|
|
3272
|
+
copySelection: stableCopySelection,
|
|
3273
|
+
inlineSearch: {
|
|
3274
|
+
showSearch: inlineSearch.showSearch,
|
|
3275
|
+
searchValue: inlineSearch.searchValue,
|
|
3276
|
+
searchStatus: inlineSearch.searchStatus,
|
|
3277
|
+
searchInputRef: inlineSearch.searchInputRef,
|
|
3278
|
+
searchInputId: inlineSearch.searchInputId,
|
|
3279
|
+
canClose: inlineSearch.canClose,
|
|
3280
|
+
searchRowCount: searchCorpus.length,
|
|
3281
|
+
setSearchValue: inlineSearch.setSearchValue,
|
|
3282
|
+
closeSearch: inlineSearch.closeSearch,
|
|
3283
|
+
goToNext: inlineSearch.goToNext,
|
|
3284
|
+
goToPrevious: inlineSearch.goToPrevious,
|
|
3285
|
+
openSearch: inlineSearch.openSearch
|
|
3286
|
+
}
|
|
2278
3287
|
};
|
|
2279
3288
|
}
|
|
2280
3289
|
|
|
2281
3290
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
2282
|
-
import { Fragment as Fragment2, jsx as
|
|
3291
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2283
3292
|
function DefaultScroll({
|
|
2284
3293
|
scrollRef,
|
|
2285
3294
|
children,
|
|
2286
3295
|
className
|
|
2287
3296
|
}) {
|
|
2288
|
-
return /* @__PURE__ */
|
|
3297
|
+
return /* @__PURE__ */ jsx6("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
|
|
2289
3298
|
}
|
|
2290
3299
|
function DefaultPending({
|
|
2291
3300
|
loadingText,
|
|
2292
3301
|
className,
|
|
2293
3302
|
classNames
|
|
2294
3303
|
}) {
|
|
2295
|
-
return /* @__PURE__ */
|
|
3304
|
+
return /* @__PURE__ */ jsx6(
|
|
2296
3305
|
"div",
|
|
2297
3306
|
{
|
|
2298
3307
|
className: cn(
|
|
@@ -2302,7 +3311,7 @@ function DefaultPending({
|
|
|
2302
3311
|
classNames?.pending,
|
|
2303
3312
|
className
|
|
2304
3313
|
),
|
|
2305
|
-
children: /* @__PURE__ */
|
|
3314
|
+
children: /* @__PURE__ */ jsx6("span", { className: cn("data-table-loading-text", classNames?.loadingText), children: loadingText })
|
|
2306
3315
|
}
|
|
2307
3316
|
);
|
|
2308
3317
|
}
|
|
@@ -2311,7 +3320,7 @@ function DefaultEmpty({
|
|
|
2311
3320
|
columnCount,
|
|
2312
3321
|
classNames
|
|
2313
3322
|
}) {
|
|
2314
|
-
return /* @__PURE__ */
|
|
3323
|
+
return /* @__PURE__ */ jsx6("tr", { children: /* @__PURE__ */ jsx6(
|
|
2315
3324
|
"td",
|
|
2316
3325
|
{
|
|
2317
3326
|
colSpan: columnCount,
|
|
@@ -2344,15 +3353,18 @@ function DataTable({
|
|
|
2344
3353
|
enableCellSelection,
|
|
2345
3354
|
enableColumnResize,
|
|
2346
3355
|
enableColumnFreeze,
|
|
3356
|
+
enableInlineSearch,
|
|
2347
3357
|
shouldVirtualize,
|
|
2348
3358
|
scrollRef,
|
|
3359
|
+
rootRef,
|
|
2349
3360
|
rowVirtualizer,
|
|
2350
3361
|
virtualRows,
|
|
2351
3362
|
paddingTop,
|
|
2352
3363
|
paddingBottom,
|
|
2353
3364
|
rowContextValue,
|
|
2354
3365
|
handleToggleSelect,
|
|
2355
|
-
clearHover
|
|
3366
|
+
clearHover,
|
|
3367
|
+
inlineSearch
|
|
2356
3368
|
} = useGlideTable(glideOptions);
|
|
2357
3369
|
const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
|
|
2358
3370
|
const ScrollSlot = slots?.Scroll ?? DefaultScroll;
|
|
@@ -2360,12 +3372,13 @@ function DataTable({
|
|
|
2360
3372
|
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
2361
3373
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
2362
3374
|
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
2363
|
-
const
|
|
3375
|
+
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
3376
|
+
const contextValue = useMemo4(
|
|
2364
3377
|
() => ({ ...rowContextValue, classNames }),
|
|
2365
3378
|
[rowContextValue, classNames]
|
|
2366
3379
|
);
|
|
2367
3380
|
if (isPending) {
|
|
2368
|
-
return /* @__PURE__ */
|
|
3381
|
+
return /* @__PURE__ */ jsx6(
|
|
2369
3382
|
PendingSlot,
|
|
2370
3383
|
{
|
|
2371
3384
|
loadingText,
|
|
@@ -2374,19 +3387,21 @@ function DataTable({
|
|
|
2374
3387
|
}
|
|
2375
3388
|
);
|
|
2376
3389
|
}
|
|
2377
|
-
return /* @__PURE__ */
|
|
3390
|
+
return /* @__PURE__ */ jsxs5(
|
|
2378
3391
|
"div",
|
|
2379
3392
|
{
|
|
3393
|
+
ref: rootRef,
|
|
2380
3394
|
className: cn(
|
|
2381
3395
|
"DataTableJSX",
|
|
2382
3396
|
!enableCellSelection && "DataTableJSX--no-cell-selection",
|
|
2383
3397
|
enableColumnResize && "DataTableJSX--column-resize",
|
|
2384
3398
|
enableColumnFreeze && "DataTableJSX--column-freeze",
|
|
3399
|
+
enableInlineSearch && "DataTableJSX--inline-search",
|
|
2385
3400
|
classNames?.root,
|
|
2386
3401
|
className
|
|
2387
3402
|
),
|
|
2388
3403
|
children: [
|
|
2389
|
-
/* @__PURE__ */
|
|
3404
|
+
/* @__PURE__ */ jsx6(
|
|
2390
3405
|
ToolbarSlot,
|
|
2391
3406
|
{
|
|
2392
3407
|
filteredCount: filteredCount ?? tableData.length,
|
|
@@ -2398,14 +3413,36 @@ function DataTable({
|
|
|
2398
3413
|
classNames
|
|
2399
3414
|
}
|
|
2400
3415
|
),
|
|
2401
|
-
|
|
3416
|
+
enableInlineSearch ? /* @__PURE__ */ jsx6(
|
|
3417
|
+
DataTableSearch,
|
|
3418
|
+
{
|
|
3419
|
+
showSearch: inlineSearch.showSearch,
|
|
3420
|
+
searchValue: inlineSearch.searchValue,
|
|
3421
|
+
searchStatus: inlineSearch.searchStatus,
|
|
3422
|
+
searchInputId: inlineSearch.searchInputId,
|
|
3423
|
+
searchInputRef: inlineSearch.searchInputRef,
|
|
3424
|
+
canClose: inlineSearch.canClose,
|
|
3425
|
+
placeholder: labels.searchPlaceholder,
|
|
3426
|
+
resultHint: labels.searchResultHint,
|
|
3427
|
+
previousLabel: labels.searchPrevious,
|
|
3428
|
+
nextLabel: labels.searchNext,
|
|
3429
|
+
closeLabel: labels.searchClose,
|
|
3430
|
+
rowsTotal: inlineSearch.searchRowCount,
|
|
3431
|
+
classNames,
|
|
3432
|
+
onSearchValueChange: inlineSearch.setSearchValue,
|
|
3433
|
+
onClose: inlineSearch.closeSearch,
|
|
3434
|
+
onNext: inlineSearch.goToNext,
|
|
3435
|
+
onPrevious: inlineSearch.goToPrevious
|
|
3436
|
+
}
|
|
3437
|
+
) : null,
|
|
3438
|
+
/* @__PURE__ */ jsx6(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ jsxs5(
|
|
2402
3439
|
"table",
|
|
2403
3440
|
{
|
|
2404
3441
|
className: cn("data-table", classNames?.table),
|
|
2405
3442
|
style: enableColumnResize ? { width: table.getTotalSize() } : void 0,
|
|
2406
3443
|
onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
|
|
2407
3444
|
children: [
|
|
2408
|
-
/* @__PURE__ */
|
|
3445
|
+
/* @__PURE__ */ jsx6("thead", { className: cn("data-table-head", classNames?.head), children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx6(
|
|
2409
3446
|
"tr",
|
|
2410
3447
|
{
|
|
2411
3448
|
className: cn("data-table-head-row", classNames?.headRow),
|
|
@@ -2419,15 +3456,18 @@ function DataTable({
|
|
|
2419
3456
|
});
|
|
2420
3457
|
const freezeOffset = enableColumnFreeze ? freezeOffsets.get(header.column.id) : void 0;
|
|
2421
3458
|
const freezeStyle = getColumnFreezeStyle(freezeOffset, {
|
|
2422
|
-
isHeader: true
|
|
3459
|
+
isHeader: true,
|
|
3460
|
+
headerTop: header.depth * DATA_TABLE_HEADER_ROW_HEIGHT
|
|
2423
3461
|
});
|
|
2424
3462
|
const headerStyle = {
|
|
2425
3463
|
...sizeStyle,
|
|
2426
3464
|
...freezeStyle
|
|
2427
3465
|
};
|
|
2428
|
-
return /* @__PURE__ */
|
|
3466
|
+
return /* @__PURE__ */ jsxs5(
|
|
2429
3467
|
"th",
|
|
2430
3468
|
{
|
|
3469
|
+
colSpan: header.colSpan,
|
|
3470
|
+
rowSpan: header.mergedRowSpan,
|
|
2431
3471
|
"data-resizing": header.column.getIsResizing() ? "" : void 0,
|
|
2432
3472
|
"data-frozen": freezeOffset?.side,
|
|
2433
3473
|
"data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
|
|
@@ -2441,7 +3481,7 @@ function DataTable({
|
|
|
2441
3481
|
),
|
|
2442
3482
|
children: [
|
|
2443
3483
|
header.isPlaceholder ? null : flexRender2(header.column.columnDef.header, header.getContext()),
|
|
2444
|
-
canResize ? /* @__PURE__ */
|
|
3484
|
+
canResize ? /* @__PURE__ */ jsx6(
|
|
2445
3485
|
"div",
|
|
2446
3486
|
{
|
|
2447
3487
|
role: "separator",
|
|
@@ -2467,20 +3507,20 @@ function DataTable({
|
|
|
2467
3507
|
},
|
|
2468
3508
|
headerGroup.id
|
|
2469
3509
|
)) }),
|
|
2470
|
-
/* @__PURE__ */
|
|
3510
|
+
/* @__PURE__ */ jsx6(DataTableContextProvider, { value: contextValue, children: /* @__PURE__ */ jsx6(
|
|
2471
3511
|
"tbody",
|
|
2472
3512
|
{
|
|
2473
3513
|
onMouseLeave: clearHover,
|
|
2474
3514
|
className: cn("data-table-body", classNames?.body),
|
|
2475
|
-
children: rows.length === 0 ? /* @__PURE__ */
|
|
3515
|
+
children: rows.length === 0 ? /* @__PURE__ */ jsx6(
|
|
2476
3516
|
EmptySlot,
|
|
2477
3517
|
{
|
|
2478
3518
|
emptyText,
|
|
2479
3519
|
columnCount,
|
|
2480
3520
|
classNames
|
|
2481
3521
|
}
|
|
2482
|
-
) : shouldVirtualize ? /* @__PURE__ */
|
|
2483
|
-
paddingTop > 0 && /* @__PURE__ */
|
|
3522
|
+
) : shouldVirtualize ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3523
|
+
paddingTop > 0 && /* @__PURE__ */ jsx6(
|
|
2484
3524
|
"tr",
|
|
2485
3525
|
{
|
|
2486
3526
|
"aria-hidden": true,
|
|
@@ -2488,7 +3528,7 @@ function DataTable({
|
|
|
2488
3528
|
"data-table-virtual-spacer",
|
|
2489
3529
|
classNames?.virtualSpacer
|
|
2490
3530
|
),
|
|
2491
|
-
children: /* @__PURE__ */
|
|
3531
|
+
children: /* @__PURE__ */ jsx6(
|
|
2492
3532
|
"td",
|
|
2493
3533
|
{
|
|
2494
3534
|
colSpan: columnCount,
|
|
@@ -2504,7 +3544,7 @@ function DataTable({
|
|
|
2504
3544
|
virtualRows.map((virtualRow) => {
|
|
2505
3545
|
const row = rows[virtualRow.index];
|
|
2506
3546
|
if (!row) return null;
|
|
2507
|
-
return /* @__PURE__ */
|
|
3547
|
+
return /* @__PURE__ */ jsx6(
|
|
2508
3548
|
RowSlot,
|
|
2509
3549
|
{
|
|
2510
3550
|
row,
|
|
@@ -2515,7 +3555,7 @@ function DataTable({
|
|
|
2515
3555
|
row.id
|
|
2516
3556
|
);
|
|
2517
3557
|
}),
|
|
2518
|
-
paddingBottom > 0 && /* @__PURE__ */
|
|
3558
|
+
paddingBottom > 0 && /* @__PURE__ */ jsx6(
|
|
2519
3559
|
"tr",
|
|
2520
3560
|
{
|
|
2521
3561
|
"aria-hidden": true,
|
|
@@ -2523,7 +3563,7 @@ function DataTable({
|
|
|
2523
3563
|
"data-table-virtual-spacer",
|
|
2524
3564
|
classNames?.virtualSpacer
|
|
2525
3565
|
),
|
|
2526
|
-
children: /* @__PURE__ */
|
|
3566
|
+
children: /* @__PURE__ */ jsx6(
|
|
2527
3567
|
"td",
|
|
2528
3568
|
{
|
|
2529
3569
|
colSpan: columnCount,
|
|
@@ -2536,7 +3576,7 @@ function DataTable({
|
|
|
2536
3576
|
)
|
|
2537
3577
|
}
|
|
2538
3578
|
)
|
|
2539
|
-
] }) : rows.map((row) => /* @__PURE__ */
|
|
3579
|
+
] }) : rows.map((row) => /* @__PURE__ */ jsx6(
|
|
2540
3580
|
RowSlot,
|
|
2541
3581
|
{
|
|
2542
3582
|
row,
|
|
@@ -2555,10 +3595,10 @@ function DataTable({
|
|
|
2555
3595
|
}
|
|
2556
3596
|
|
|
2557
3597
|
// src/components/ui/table/components/Table/Table.tsx
|
|
2558
|
-
import { useCallback as
|
|
3598
|
+
import { useCallback as useCallback5, useMemo as useMemo5, useState as useState5 } from "react";
|
|
2559
3599
|
|
|
2560
3600
|
// src/components/ui/table/components/Table/buildColumnDef.tsx
|
|
2561
|
-
import { jsx as
|
|
3601
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2562
3602
|
function SortableHeader({
|
|
2563
3603
|
label,
|
|
2564
3604
|
field,
|
|
@@ -2567,15 +3607,15 @@ function SortableHeader({
|
|
|
2567
3607
|
}) {
|
|
2568
3608
|
const isActive = sort?.field === field;
|
|
2569
3609
|
const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
|
|
2570
|
-
return /* @__PURE__ */
|
|
3610
|
+
return /* @__PURE__ */ jsxs6(
|
|
2571
3611
|
"button",
|
|
2572
3612
|
{
|
|
2573
3613
|
type: "button",
|
|
2574
3614
|
className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
|
|
2575
3615
|
onClick: () => onSort(field),
|
|
2576
3616
|
children: [
|
|
2577
|
-
/* @__PURE__ */
|
|
2578
|
-
/* @__PURE__ */
|
|
3617
|
+
/* @__PURE__ */ jsx7("span", { children: label }),
|
|
3618
|
+
/* @__PURE__ */ jsx7(Icon, { className: "sortable-header-icon" })
|
|
2579
3619
|
]
|
|
2580
3620
|
}
|
|
2581
3621
|
);
|
|
@@ -2608,7 +3648,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
2608
3648
|
...minWidth != null ? { minSize: minWidth } : {},
|
|
2609
3649
|
...maxWidth != null ? { maxSize: maxWidth } : {},
|
|
2610
3650
|
...resizable === false ? { enableResizing: false } : {},
|
|
2611
|
-
header: sortable ? () => /* @__PURE__ */
|
|
3651
|
+
header: sortable ? () => /* @__PURE__ */ jsx7(SortableHeader, { label: children, field, sort, onSort }) : (
|
|
2612
3652
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
2613
3653
|
() => children
|
|
2614
3654
|
),
|
|
@@ -2633,6 +3673,46 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
2633
3673
|
}
|
|
2634
3674
|
};
|
|
2635
3675
|
}
|
|
3676
|
+
function resolveGroupId(props, index) {
|
|
3677
|
+
if (props.id) return props.id;
|
|
3678
|
+
if (typeof props.header === "string" || typeof props.header === "number") {
|
|
3679
|
+
return `group:${props.header}:${index}`;
|
|
3680
|
+
}
|
|
3681
|
+
return `group:${index}`;
|
|
3682
|
+
}
|
|
3683
|
+
function buildColumnDefsFromTree(nodes, sort, onSort) {
|
|
3684
|
+
return nodes.map((node, index) => {
|
|
3685
|
+
if (node.type === "leaf") {
|
|
3686
|
+
return buildColumnDef(node.props, sort, onSort);
|
|
3687
|
+
}
|
|
3688
|
+
const childDefs = buildColumnDefsFromTree(node.columns, sort, onSort);
|
|
3689
|
+
const { header, align, headerClassName } = node.props;
|
|
3690
|
+
return {
|
|
3691
|
+
id: resolveGroupId(node.props, index),
|
|
3692
|
+
header: (
|
|
3693
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
3694
|
+
() => header
|
|
3695
|
+
),
|
|
3696
|
+
columns: childDefs,
|
|
3697
|
+
enableResizing: false,
|
|
3698
|
+
meta: {
|
|
3699
|
+
align,
|
|
3700
|
+
headerClassName
|
|
3701
|
+
}
|
|
3702
|
+
};
|
|
3703
|
+
});
|
|
3704
|
+
}
|
|
3705
|
+
function countLeafColumns(nodes) {
|
|
3706
|
+
let count = 0;
|
|
3707
|
+
for (const node of nodes) {
|
|
3708
|
+
if (node.type === "leaf") {
|
|
3709
|
+
count += 1;
|
|
3710
|
+
} else {
|
|
3711
|
+
count += countLeafColumns(node.columns);
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
return count;
|
|
3715
|
+
}
|
|
2636
3716
|
|
|
2637
3717
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
2638
3718
|
import { Children, isValidElement as isValidElement2 } from "react";
|
|
@@ -2642,6 +3722,7 @@ import { isValidElement } from "react";
|
|
|
2642
3722
|
var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
|
|
2643
3723
|
var TABLE_BODY_DISPLAY_NAME = "Table.Body";
|
|
2644
3724
|
var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
|
|
3725
|
+
var TABLE_COLUMN_GROUP_DISPLAY_NAME = "Table.ColumnGroup";
|
|
2645
3726
|
var TABLE_PAGINATION_DISPLAY_NAME = "Table.Pagination";
|
|
2646
3727
|
function getComponentDisplayName(type) {
|
|
2647
3728
|
if (typeof type === "function" || typeof type === "object" && type !== null) {
|
|
@@ -2658,6 +3739,9 @@ function isTableBodyElement(child) {
|
|
|
2658
3739
|
function isTableColumnElement(child) {
|
|
2659
3740
|
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
|
|
2660
3741
|
}
|
|
3742
|
+
function isTableColumnGroupElement(child) {
|
|
3743
|
+
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
3744
|
+
}
|
|
2661
3745
|
function isTablePaginationElement(child) {
|
|
2662
3746
|
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
|
|
2663
3747
|
}
|
|
@@ -2684,26 +3768,38 @@ function parseTableChildren(children) {
|
|
|
2684
3768
|
}
|
|
2685
3769
|
return slots;
|
|
2686
3770
|
}
|
|
2687
|
-
function
|
|
3771
|
+
function walkColumnTreeNodes(children) {
|
|
2688
3772
|
const result = [];
|
|
2689
3773
|
for (const child of Children.toArray(children)) {
|
|
2690
3774
|
if (isTableColumnElement(child)) {
|
|
2691
|
-
result.push(
|
|
3775
|
+
result.push({
|
|
3776
|
+
type: "leaf",
|
|
3777
|
+
props: child.props
|
|
3778
|
+
});
|
|
3779
|
+
continue;
|
|
3780
|
+
}
|
|
3781
|
+
if (isTableColumnGroupElement(child)) {
|
|
3782
|
+
const groupProps = child.props;
|
|
3783
|
+
result.push({
|
|
3784
|
+
type: "group",
|
|
3785
|
+
props: groupProps,
|
|
3786
|
+
columns: walkColumnTreeNodes(groupProps.children)
|
|
3787
|
+
});
|
|
2692
3788
|
continue;
|
|
2693
3789
|
}
|
|
2694
3790
|
if (isValidElement2(child)) {
|
|
2695
3791
|
const nested = child.props.children;
|
|
2696
3792
|
if (nested != null) {
|
|
2697
|
-
result.push(...
|
|
3793
|
+
result.push(...walkColumnTreeNodes(nested));
|
|
2698
3794
|
}
|
|
2699
3795
|
}
|
|
2700
3796
|
}
|
|
2701
3797
|
return result;
|
|
2702
3798
|
}
|
|
2703
|
-
function
|
|
3799
|
+
function extractColumnTree(header) {
|
|
2704
3800
|
if (!header) return [];
|
|
2705
3801
|
const { children } = header.props;
|
|
2706
|
-
return
|
|
3802
|
+
return walkColumnTreeNodes(children);
|
|
2707
3803
|
}
|
|
2708
3804
|
|
|
2709
3805
|
// src/components/ui/table/components/Table/TableBody.tsx
|
|
@@ -2719,6 +3815,13 @@ function TableColumn(props) {
|
|
|
2719
3815
|
}
|
|
2720
3816
|
TableColumn.displayName = TABLE_COLUMN_DISPLAY_NAME;
|
|
2721
3817
|
|
|
3818
|
+
// src/components/ui/table/components/Table/TableColumnGroup.tsx
|
|
3819
|
+
function TableColumnGroup(props) {
|
|
3820
|
+
void props;
|
|
3821
|
+
return null;
|
|
3822
|
+
}
|
|
3823
|
+
TableColumnGroup.displayName = TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
3824
|
+
|
|
2722
3825
|
// src/components/ui/table/components/Table/tableDataPipeline.ts
|
|
2723
3826
|
function sortTableData(data, sort) {
|
|
2724
3827
|
if (!sort) return data;
|
|
@@ -2756,7 +3859,7 @@ function TableHeader(props) {
|
|
|
2756
3859
|
TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
|
|
2757
3860
|
|
|
2758
3861
|
// src/components/ui/table/components/Table/TablePagination.tsx
|
|
2759
|
-
import { jsx as
|
|
3862
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2760
3863
|
function TablePagination({
|
|
2761
3864
|
page,
|
|
2762
3865
|
pageSize = 10,
|
|
@@ -2768,8 +3871,8 @@ function TablePagination({
|
|
|
2768
3871
|
const safePage = Math.min(Math.max(1, page), totalPages);
|
|
2769
3872
|
const canGoPrev = safePage > 1;
|
|
2770
3873
|
const canGoNext = safePage < totalPages;
|
|
2771
|
-
return /* @__PURE__ */
|
|
2772
|
-
/* @__PURE__ */
|
|
3874
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("TablePaginationJSX", className), children: [
|
|
3875
|
+
/* @__PURE__ */ jsx8(
|
|
2773
3876
|
"button",
|
|
2774
3877
|
{
|
|
2775
3878
|
type: "button",
|
|
@@ -2777,15 +3880,15 @@ function TablePagination({
|
|
|
2777
3880
|
disabled: !canGoPrev,
|
|
2778
3881
|
onClick: () => onChange(safePage - 1),
|
|
2779
3882
|
"aria-label": "Previous page",
|
|
2780
|
-
children: /* @__PURE__ */
|
|
3883
|
+
children: /* @__PURE__ */ jsx8(ChevronLeft, { className: "pagination-button-icon" })
|
|
2781
3884
|
}
|
|
2782
3885
|
),
|
|
2783
|
-
/* @__PURE__ */
|
|
3886
|
+
/* @__PURE__ */ jsxs7("span", { className: "pagination-label", children: [
|
|
2784
3887
|
safePage,
|
|
2785
3888
|
" / ",
|
|
2786
3889
|
totalPages
|
|
2787
3890
|
] }),
|
|
2788
|
-
/* @__PURE__ */
|
|
3891
|
+
/* @__PURE__ */ jsx8(
|
|
2789
3892
|
"button",
|
|
2790
3893
|
{
|
|
2791
3894
|
type: "button",
|
|
@@ -2793,7 +3896,7 @@ function TablePagination({
|
|
|
2793
3896
|
disabled: !canGoNext,
|
|
2794
3897
|
onClick: () => onChange(safePage + 1),
|
|
2795
3898
|
"aria-label": "Next page",
|
|
2796
|
-
children: /* @__PURE__ */
|
|
3899
|
+
children: /* @__PURE__ */ jsx8(ChevronRight, { className: "pagination-button-icon" })
|
|
2797
3900
|
}
|
|
2798
3901
|
)
|
|
2799
3902
|
] });
|
|
@@ -2801,7 +3904,7 @@ function TablePagination({
|
|
|
2801
3904
|
TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
|
|
2802
3905
|
|
|
2803
3906
|
// src/components/ui/table/components/Table/Table.tsx
|
|
2804
|
-
import { jsx as
|
|
3907
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2805
3908
|
function TableRoot({
|
|
2806
3909
|
data,
|
|
2807
3910
|
children,
|
|
@@ -2810,12 +3913,12 @@ function TableRoot({
|
|
|
2810
3913
|
filteredCount,
|
|
2811
3914
|
...dataTableProps
|
|
2812
3915
|
}) {
|
|
2813
|
-
const { header, pagination: paginationElement } =
|
|
3916
|
+
const { header, pagination: paginationElement } = useMemo5(
|
|
2814
3917
|
() => parseTableChildren(children),
|
|
2815
3918
|
[children]
|
|
2816
3919
|
);
|
|
2817
|
-
const [sort, setSort] =
|
|
2818
|
-
const handleSort =
|
|
3920
|
+
const [sort, setSort] = useState5(null);
|
|
3921
|
+
const handleSort = useCallback5((field) => {
|
|
2819
3922
|
setSort((previous) => {
|
|
2820
3923
|
if (previous?.field !== field) {
|
|
2821
3924
|
return { field, direction: "asc" };
|
|
@@ -2826,25 +3929,25 @@ function TableRoot({
|
|
|
2826
3929
|
return null;
|
|
2827
3930
|
});
|
|
2828
3931
|
}, []);
|
|
2829
|
-
const
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
3932
|
+
const columnTree = useMemo5(() => extractColumnTree(header), [header]);
|
|
3933
|
+
const columns = useMemo5(
|
|
3934
|
+
() => buildColumnDefsFromTree(columnTree, sort, handleSort),
|
|
3935
|
+
[columnTree, sort, handleSort]
|
|
3936
|
+
);
|
|
2834
3937
|
const paginationProps = paginationElement?.props;
|
|
2835
3938
|
const pageSize = paginationProps?.pageSize ?? 10;
|
|
2836
3939
|
const page = paginationProps?.page ?? 1;
|
|
2837
3940
|
const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
|
|
2838
|
-
const tableData =
|
|
3941
|
+
const tableData = useMemo5(() => {
|
|
2839
3942
|
const sortedData = sortTableData(data, sort);
|
|
2840
3943
|
if (!paginationProps) return sortedData;
|
|
2841
3944
|
return paginateTableData(sortedData, page, pageSize);
|
|
2842
3945
|
}, [data, sort, paginationProps, page, pageSize]);
|
|
2843
|
-
if (
|
|
3946
|
+
if (countLeafColumns(columnTree) === 0) {
|
|
2844
3947
|
console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
|
|
2845
3948
|
}
|
|
2846
|
-
return /* @__PURE__ */
|
|
2847
|
-
/* @__PURE__ */
|
|
3949
|
+
return /* @__PURE__ */ jsxs8("div", { className: "TableJSX", children: [
|
|
3950
|
+
/* @__PURE__ */ jsx9(
|
|
2848
3951
|
DataTable,
|
|
2849
3952
|
{
|
|
2850
3953
|
...dataTableProps,
|
|
@@ -2855,7 +3958,7 @@ function TableRoot({
|
|
|
2855
3958
|
className: cn(className, paginationProps && "DataTableJSX--with-pagination")
|
|
2856
3959
|
}
|
|
2857
3960
|
),
|
|
2858
|
-
paginationProps && /* @__PURE__ */
|
|
3961
|
+
paginationProps && /* @__PURE__ */ jsx9(
|
|
2859
3962
|
TablePagination,
|
|
2860
3963
|
{
|
|
2861
3964
|
page,
|
|
@@ -2873,13 +3976,19 @@ function createTable() {
|
|
|
2873
3976
|
return null;
|
|
2874
3977
|
}
|
|
2875
3978
|
Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
|
|
3979
|
+
function ColumnGroup(props) {
|
|
3980
|
+
void props;
|
|
3981
|
+
return null;
|
|
3982
|
+
}
|
|
3983
|
+
ColumnGroup.displayName = TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
2876
3984
|
return Object.assign(
|
|
2877
3985
|
function BoundTable(props) {
|
|
2878
|
-
return /* @__PURE__ */
|
|
3986
|
+
return /* @__PURE__ */ jsx9(TableRoot, { ...props });
|
|
2879
3987
|
},
|
|
2880
3988
|
{
|
|
2881
3989
|
Header: TableHeader,
|
|
2882
3990
|
Column,
|
|
3991
|
+
ColumnGroup,
|
|
2883
3992
|
Body: TableBody,
|
|
2884
3993
|
Pagination: TablePagination
|
|
2885
3994
|
}
|
|
@@ -2888,6 +3997,7 @@ function createTable() {
|
|
|
2888
3997
|
var Table = Object.assign(TableRoot, {
|
|
2889
3998
|
Header: TableHeader,
|
|
2890
3999
|
Column: TableColumn,
|
|
4000
|
+
ColumnGroup: TableColumnGroup,
|
|
2891
4001
|
Body: TableBody,
|
|
2892
4002
|
Pagination: TablePagination
|
|
2893
4003
|
});
|