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/index.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
|
|
33
|
-
useEffect as
|
|
34
|
-
useMemo as
|
|
35
|
-
useRef as
|
|
36
|
-
useState as
|
|
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
|
|
@@ -46,6 +51,7 @@ var ROW_HOVER_CLASS = "row-hoverable";
|
|
|
46
51
|
var ROW_HOVERED_BG_CLASS = "row-hovered";
|
|
47
52
|
var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
|
|
48
53
|
var DATA_TABLE_ROW_HEIGHT = 44;
|
|
54
|
+
var DATA_TABLE_HEADER_ROW_HEIGHT = 40;
|
|
49
55
|
var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
50
56
|
var DATA_TABLE_COLUMN_SIZE = 150;
|
|
51
57
|
var DATA_TABLE_COLUMN_MIN_SIZE = 40;
|
|
@@ -199,6 +205,36 @@ function getCellSelectionBounds(start, end) {
|
|
|
199
205
|
endCol: Math.max(start.col, end.col)
|
|
200
206
|
};
|
|
201
207
|
}
|
|
208
|
+
function getCellNavigationDelta(key) {
|
|
209
|
+
switch (key) {
|
|
210
|
+
case "ArrowUp":
|
|
211
|
+
case "w":
|
|
212
|
+
case "W":
|
|
213
|
+
return { row: -1, col: 0 };
|
|
214
|
+
case "ArrowDown":
|
|
215
|
+
case "s":
|
|
216
|
+
case "S":
|
|
217
|
+
return { row: 1, col: 0 };
|
|
218
|
+
case "ArrowLeft":
|
|
219
|
+
case "a":
|
|
220
|
+
case "A":
|
|
221
|
+
return { row: 0, col: -1 };
|
|
222
|
+
case "ArrowRight":
|
|
223
|
+
case "d":
|
|
224
|
+
case "D":
|
|
225
|
+
return { row: 0, col: 1 };
|
|
226
|
+
default:
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function clampCellPosition(position, rowCount, columnCount) {
|
|
231
|
+
const maxRow = Math.max(rowCount - 1, 0);
|
|
232
|
+
const maxCol = Math.max(columnCount - 1, 0);
|
|
233
|
+
return {
|
|
234
|
+
row: Math.min(Math.max(position.row, 0), maxRow),
|
|
235
|
+
col: Math.min(Math.max(position.col, 0), maxCol)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
202
238
|
function measureMergedSpanRowHeights(rowIndex, rowSpan, cellElement) {
|
|
203
239
|
if (rowSpan <= 1) return void 0;
|
|
204
240
|
const tbody = cellElement?.closest("tbody") ?? (typeof document !== "undefined" ? document.querySelector("tbody.data-table-body") : null);
|
|
@@ -722,26 +758,44 @@ function useCellSelection({
|
|
|
722
758
|
data,
|
|
723
759
|
rows,
|
|
724
760
|
enabled = true,
|
|
761
|
+
columnCount = 0,
|
|
725
762
|
enableSubtreeCopy = false,
|
|
726
763
|
enableInsertPaste = true,
|
|
727
764
|
onDataChange,
|
|
728
765
|
onBatchChange,
|
|
729
|
-
onRowsPaste
|
|
766
|
+
onRowsPaste,
|
|
767
|
+
onCellNavigate
|
|
730
768
|
}) {
|
|
731
769
|
const [dragState, setDragState] = useState2(INITIAL_DRAG_STATE);
|
|
732
770
|
const pendingPasteModeRef = useRef2(null);
|
|
771
|
+
const dragStateRef = useRef2(dragState);
|
|
772
|
+
const onCellNavigateRef = useRef2(onCellNavigate);
|
|
773
|
+
dragStateRef.current = dragState;
|
|
774
|
+
onCellNavigateRef.current = onCellNavigate;
|
|
733
775
|
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
734
776
|
const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
|
|
735
777
|
const handleCellMouseDown = useCallback2(
|
|
736
|
-
(rowIndex, colIndex) => {
|
|
778
|
+
(rowIndex, colIndex, options) => {
|
|
737
779
|
if (!enabled) return;
|
|
738
|
-
setDragState({
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
780
|
+
setDragState((prev) => {
|
|
781
|
+
if (options?.shiftKey && prev.start) {
|
|
782
|
+
return {
|
|
783
|
+
...prev,
|
|
784
|
+
isSelecting: true,
|
|
785
|
+
isFillDragging: false,
|
|
786
|
+
end: { row: rowIndex, col: colIndex },
|
|
787
|
+
fillAnchor: null,
|
|
788
|
+
fillEnd: null
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
isSelecting: true,
|
|
793
|
+
isFillDragging: false,
|
|
794
|
+
start: { row: rowIndex, col: colIndex },
|
|
795
|
+
end: { row: rowIndex, col: colIndex },
|
|
796
|
+
fillAnchor: null,
|
|
797
|
+
fillEnd: null
|
|
798
|
+
};
|
|
745
799
|
});
|
|
746
800
|
},
|
|
747
801
|
[enabled]
|
|
@@ -783,6 +837,53 @@ function useCellSelection({
|
|
|
783
837
|
setDragState(INITIAL_DRAG_STATE);
|
|
784
838
|
}
|
|
785
839
|
}, [enabled]);
|
|
840
|
+
useEffect2(() => {
|
|
841
|
+
if (!enabled) return;
|
|
842
|
+
const handleKeyDown = (e) => {
|
|
843
|
+
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
844
|
+
if (isEditablePasteTarget(e.target) || isEditablePasteTarget(document.activeElement)) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
const delta = getCellNavigationDelta(e.key);
|
|
848
|
+
if (!delta) return;
|
|
849
|
+
const prev = dragStateRef.current;
|
|
850
|
+
if (!prev.start || !prev.end) return;
|
|
851
|
+
if (prev.isSelecting || prev.isFillDragging) return;
|
|
852
|
+
const rowCount = rows.length;
|
|
853
|
+
const resolvedColumnCount = columnCount > 0 ? columnCount : rows[0]?.getVisibleCells().length ?? 0;
|
|
854
|
+
if (rowCount <= 0 || resolvedColumnCount <= 0) return;
|
|
855
|
+
const nextEnd = clampCellPosition(
|
|
856
|
+
{
|
|
857
|
+
row: prev.end.row + delta.row,
|
|
858
|
+
col: prev.end.col + delta.col
|
|
859
|
+
},
|
|
860
|
+
rowCount,
|
|
861
|
+
resolvedColumnCount
|
|
862
|
+
);
|
|
863
|
+
if (nextEnd.row === prev.end.row && nextEnd.col === prev.end.col) return;
|
|
864
|
+
e.preventDefault();
|
|
865
|
+
const nextState = e.shiftKey ? {
|
|
866
|
+
...prev,
|
|
867
|
+
isSelecting: false,
|
|
868
|
+
isFillDragging: false,
|
|
869
|
+
end: nextEnd,
|
|
870
|
+
fillAnchor: null,
|
|
871
|
+
fillEnd: null
|
|
872
|
+
} : {
|
|
873
|
+
isSelecting: false,
|
|
874
|
+
isFillDragging: false,
|
|
875
|
+
start: nextEnd,
|
|
876
|
+
end: nextEnd,
|
|
877
|
+
fillAnchor: null,
|
|
878
|
+
fillEnd: null
|
|
879
|
+
};
|
|
880
|
+
dragStateRef.current = nextState;
|
|
881
|
+
setDragState(nextState);
|
|
882
|
+
onCellNavigateRef.current?.(nextEnd);
|
|
883
|
+
};
|
|
884
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
885
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
886
|
+
}, [columnCount, enabled, rows]);
|
|
786
887
|
const copySelection = useCallback2(
|
|
787
888
|
async (options) => {
|
|
788
889
|
if (!enabled || !activeSelectionBounds) return false;
|
|
@@ -1019,12 +1120,473 @@ function getColumnFreezeStyle(offset, options) {
|
|
|
1019
1120
|
position: "sticky",
|
|
1020
1121
|
...offset.side === "left" ? { left: offset.offset } : { right: offset.offset },
|
|
1021
1122
|
zIndex: zBase + offset.stack,
|
|
1022
|
-
...options?.isHeader ? { top: 0 } : {}
|
|
1123
|
+
...options?.isHeader ? { top: options.headerTop ?? 0 } : {}
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// src/components/ui/table/features/inline-search/inlineSearch.ts
|
|
1128
|
+
var INLINE_SEARCH_MAX_RESULTS = 1e3;
|
|
1129
|
+
var INLINE_SEARCH_TARGET_TICK_MS = 10;
|
|
1130
|
+
var INLINE_SEARCH_INITIAL_STRIDE = 10;
|
|
1131
|
+
function escapeSearchRegex(value) {
|
|
1132
|
+
return value.replace(/([$()*+.?[\\\]^{|}-])/g, "\\$1");
|
|
1133
|
+
}
|
|
1134
|
+
function createSearchRegex(query) {
|
|
1135
|
+
const trimmed = query.trim();
|
|
1136
|
+
if (!trimmed) return null;
|
|
1137
|
+
return new RegExp(escapeSearchRegex(trimmed), "i");
|
|
1138
|
+
}
|
|
1139
|
+
function cellValueToSearchText(value) {
|
|
1140
|
+
if (value == null) return void 0;
|
|
1141
|
+
if (typeof value === "string") return value;
|
|
1142
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
1143
|
+
return String(value);
|
|
1144
|
+
}
|
|
1145
|
+
if (Array.isArray(value)) {
|
|
1146
|
+
return value.map((item) => cellValueToSearchText(item) ?? "").join(" ");
|
|
1147
|
+
}
|
|
1148
|
+
if (typeof value === "object") {
|
|
1149
|
+
try {
|
|
1150
|
+
return JSON.stringify(value);
|
|
1151
|
+
} catch {
|
|
1152
|
+
return String(value);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return String(value);
|
|
1156
|
+
}
|
|
1157
|
+
function formatSearchResultLabel(status) {
|
|
1158
|
+
const countLabel = status.results >= INLINE_SEARCH_MAX_RESULTS ? `over ${INLINE_SEARCH_MAX_RESULTS}` : `${status.results} result${status.results !== 1 ? "s" : ""}`;
|
|
1159
|
+
if (status.selectedIndex >= 0 && status.results > 0) {
|
|
1160
|
+
return `${status.selectedIndex + 1} of ${countLabel}`;
|
|
1161
|
+
}
|
|
1162
|
+
return countLabel;
|
|
1163
|
+
}
|
|
1164
|
+
function nextSearchIndex(selectedIndex, results) {
|
|
1165
|
+
if (results <= 0) return -1;
|
|
1166
|
+
if (selectedIndex < 0) return 0;
|
|
1167
|
+
return (selectedIndex + 1) % results;
|
|
1168
|
+
}
|
|
1169
|
+
function previousSearchIndex(selectedIndex, results) {
|
|
1170
|
+
if (results <= 0) return -1;
|
|
1171
|
+
if (selectedIndex < 0) return results - 1;
|
|
1172
|
+
let next = (selectedIndex - 1) % results;
|
|
1173
|
+
if (next < 0) next += results;
|
|
1174
|
+
return next;
|
|
1175
|
+
}
|
|
1176
|
+
function buildSearchMatchKey(colIndex, rowIndex) {
|
|
1177
|
+
return `${colIndex}:${rowIndex}`;
|
|
1178
|
+
}
|
|
1179
|
+
function buildSearchMatchKeys(results) {
|
|
1180
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1181
|
+
for (const [colIndex, rowIndex] of results) {
|
|
1182
|
+
keys.add(buildSearchMatchKey(colIndex, rowIndex));
|
|
1183
|
+
}
|
|
1184
|
+
return keys;
|
|
1185
|
+
}
|
|
1186
|
+
function collectSearchMatchesInRange(options) {
|
|
1187
|
+
const {
|
|
1188
|
+
query,
|
|
1189
|
+
startRow,
|
|
1190
|
+
rowCount,
|
|
1191
|
+
columnCount,
|
|
1192
|
+
getCellValue,
|
|
1193
|
+
maxResults = INLINE_SEARCH_MAX_RESULTS
|
|
1194
|
+
} = options;
|
|
1195
|
+
const regex = createSearchRegex(query);
|
|
1196
|
+
if (!regex || rowCount <= 0 || columnCount <= 0) return [];
|
|
1197
|
+
const matches = [];
|
|
1198
|
+
for (let rowOffset = 0; rowOffset < rowCount; rowOffset += 1) {
|
|
1199
|
+
const rowIndex = startRow + rowOffset;
|
|
1200
|
+
for (let colIndex = 0; colIndex < columnCount; colIndex += 1) {
|
|
1201
|
+
const text = cellValueToSearchText(getCellValue(rowIndex, colIndex));
|
|
1202
|
+
if (text !== void 0 && regex.test(text)) {
|
|
1203
|
+
matches.push([colIndex, rowIndex]);
|
|
1204
|
+
if (matches.length >= maxResults) {
|
|
1205
|
+
return matches;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return matches;
|
|
1211
|
+
}
|
|
1212
|
+
function nextSearchStride(currentStride, elapsedMs, targetMs = INLINE_SEARCH_TARGET_TICK_MS) {
|
|
1213
|
+
const rounded = Math.max(elapsedMs, 1);
|
|
1214
|
+
const scalar = targetMs / rounded;
|
|
1215
|
+
return Math.max(1, Math.ceil(currentStride * scalar));
|
|
1216
|
+
}
|
|
1217
|
+
function buildFlatSearchCorpus(rows, getRowId) {
|
|
1218
|
+
return rows.map((data, index) => ({
|
|
1219
|
+
id: getRowId(data, index),
|
|
1220
|
+
data,
|
|
1221
|
+
ancestorToggleKeys: []
|
|
1222
|
+
}));
|
|
1223
|
+
}
|
|
1224
|
+
function buildTreeSearchCorpus(visibleRows, options) {
|
|
1225
|
+
const { toggleField, getRowId } = options;
|
|
1226
|
+
const corpus = [];
|
|
1227
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1228
|
+
const walk = (node, ancestorToggleKeys) => {
|
|
1229
|
+
const id = getRowId(node, corpus.length);
|
|
1230
|
+
if (seen.has(id)) return;
|
|
1231
|
+
seen.add(id);
|
|
1232
|
+
corpus.push({
|
|
1233
|
+
id,
|
|
1234
|
+
data: node,
|
|
1235
|
+
ancestorToggleKeys
|
|
1236
|
+
});
|
|
1237
|
+
const children = node.children;
|
|
1238
|
+
if (!Array.isArray(children) || children.length === 0) return;
|
|
1239
|
+
const toggleValue = node[toggleField];
|
|
1240
|
+
const childAncestors = typeof toggleValue === "string" && toggleValue.length > 0 ? [...ancestorToggleKeys, toggleValue] : ancestorToggleKeys;
|
|
1241
|
+
for (const child of children) {
|
|
1242
|
+
if (child && typeof child === "object") {
|
|
1243
|
+
walk(child, childAncestors);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
for (const row of visibleRows) {
|
|
1248
|
+
const level = row.level;
|
|
1249
|
+
if (level === 0 || level === void 0) {
|
|
1250
|
+
walk(row, []);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
for (const row of visibleRows) {
|
|
1254
|
+
const id = getRowId(row, corpus.length);
|
|
1255
|
+
if (seen.has(id)) continue;
|
|
1256
|
+
walk(row, []);
|
|
1257
|
+
}
|
|
1258
|
+
return corpus;
|
|
1259
|
+
}
|
|
1260
|
+
function mapSearchResultsToVisibleKeys(results, corpus, visibleRowIndexById) {
|
|
1261
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1262
|
+
for (const [colIndex, corpusRowIndex] of results) {
|
|
1263
|
+
const corpusRow = corpus[corpusRowIndex];
|
|
1264
|
+
if (!corpusRow) continue;
|
|
1265
|
+
const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
|
|
1266
|
+
if (visibleRowIndex === void 0) continue;
|
|
1267
|
+
keys.add(buildSearchMatchKey(colIndex, visibleRowIndex));
|
|
1268
|
+
}
|
|
1269
|
+
return keys;
|
|
1270
|
+
}
|
|
1271
|
+
function mapSearchResultToVisibleItem(item, corpus, visibleRowIndexById) {
|
|
1272
|
+
const [colIndex, corpusRowIndex] = item;
|
|
1273
|
+
const corpusRow = corpus[corpusRowIndex];
|
|
1274
|
+
if (!corpusRow) return null;
|
|
1275
|
+
const visibleRowIndex = visibleRowIndexById.get(corpusRow.id);
|
|
1276
|
+
if (visibleRowIndex === void 0) return null;
|
|
1277
|
+
return [colIndex, visibleRowIndex];
|
|
1278
|
+
}
|
|
1279
|
+
function collectAncestorKeysToExpand(corpusRow, expandedRows) {
|
|
1280
|
+
return corpusRow.ancestorToggleKeys.filter((key) => !expandedRows.has(key));
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
// src/components/ui/table/features/inline-search/useInlineSearch.ts
|
|
1284
|
+
import {
|
|
1285
|
+
useCallback as useCallback3,
|
|
1286
|
+
useEffect as useEffect3,
|
|
1287
|
+
useId,
|
|
1288
|
+
useMemo,
|
|
1289
|
+
useRef as useRef3,
|
|
1290
|
+
useState as useState3
|
|
1291
|
+
} from "react";
|
|
1292
|
+
var EMPTY_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
1293
|
+
function useInlineSearch({
|
|
1294
|
+
enabled = false,
|
|
1295
|
+
rowCount,
|
|
1296
|
+
columnCount,
|
|
1297
|
+
getCellValue,
|
|
1298
|
+
initialStartRow = 0,
|
|
1299
|
+
showSearch: controlledShowSearch,
|
|
1300
|
+
searchValue: controlledSearchValue,
|
|
1301
|
+
searchResults: controlledSearchResults,
|
|
1302
|
+
onSearchValueChange,
|
|
1303
|
+
onSearchClose,
|
|
1304
|
+
onSearchResultsChanged,
|
|
1305
|
+
onNavigateToResult,
|
|
1306
|
+
rootRef
|
|
1307
|
+
}) {
|
|
1308
|
+
const searchInputId = useId();
|
|
1309
|
+
const searchInputRef = useRef3(null);
|
|
1310
|
+
const [internalShowSearch, setInternalShowSearch] = useState3(false);
|
|
1311
|
+
const [internalSearchValue, setInternalSearchValue] = useState3("");
|
|
1312
|
+
const [internalResults, setInternalResults] = useState3(
|
|
1313
|
+
[]
|
|
1314
|
+
);
|
|
1315
|
+
const [searchStatus, setSearchStatus] = useState3();
|
|
1316
|
+
const searchStatusRef = useRef3(searchStatus);
|
|
1317
|
+
searchStatusRef.current = searchStatus;
|
|
1318
|
+
const abortControllerRef = useRef3(null);
|
|
1319
|
+
const searchHandleRef = useRef3(void 0);
|
|
1320
|
+
const initialStartRowRef = useRef3(initialStartRow);
|
|
1321
|
+
initialStartRowRef.current = initialStartRow;
|
|
1322
|
+
const getCellValueRef = useRef3(getCellValue);
|
|
1323
|
+
getCellValueRef.current = getCellValue;
|
|
1324
|
+
const showSearch = controlledShowSearch ?? internalShowSearch;
|
|
1325
|
+
const searchValue = controlledSearchValue ?? internalSearchValue;
|
|
1326
|
+
const searchResults = controlledSearchResults ?? internalResults;
|
|
1327
|
+
const setSearchValue = useCallback3(
|
|
1328
|
+
(value) => {
|
|
1329
|
+
setInternalSearchValue(value);
|
|
1330
|
+
onSearchValueChange?.(value);
|
|
1331
|
+
},
|
|
1332
|
+
[onSearchValueChange]
|
|
1333
|
+
);
|
|
1334
|
+
const cancelSearch = useCallback3(() => {
|
|
1335
|
+
if (searchHandleRef.current !== void 0) {
|
|
1336
|
+
window.cancelAnimationFrame(searchHandleRef.current);
|
|
1337
|
+
searchHandleRef.current = void 0;
|
|
1338
|
+
}
|
|
1339
|
+
abortControllerRef.current?.abort();
|
|
1340
|
+
}, []);
|
|
1341
|
+
const emitResultsChanged = useCallback3(
|
|
1342
|
+
(results, navIndex) => {
|
|
1343
|
+
onSearchResultsChanged?.(results, navIndex);
|
|
1344
|
+
},
|
|
1345
|
+
[onSearchResultsChanged]
|
|
1346
|
+
);
|
|
1347
|
+
const navigateToIndex = useCallback3(
|
|
1348
|
+
(results, navIndex) => {
|
|
1349
|
+
if (onSearchResultsChanged) return;
|
|
1350
|
+
if (navIndex < 0 || navIndex >= results.length) return;
|
|
1351
|
+
const item = results[navIndex];
|
|
1352
|
+
if (!item) return;
|
|
1353
|
+
onNavigateToResult?.(item);
|
|
1354
|
+
},
|
|
1355
|
+
[onNavigateToResult, onSearchResultsChanged]
|
|
1356
|
+
);
|
|
1357
|
+
const beginSearch = useCallback3(
|
|
1358
|
+
(query) => {
|
|
1359
|
+
if (controlledSearchResults !== void 0) return;
|
|
1360
|
+
const totalRows = rowCount;
|
|
1361
|
+
if (totalRows === 0 || columnCount === 0) {
|
|
1362
|
+
setSearchStatus(void 0);
|
|
1363
|
+
setInternalResults([]);
|
|
1364
|
+
emitResultsChanged([], -1);
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
let startY = Math.min(
|
|
1368
|
+
Math.max(0, initialStartRowRef.current),
|
|
1369
|
+
totalRows - 1
|
|
1370
|
+
);
|
|
1371
|
+
let searchStride = Math.min(INLINE_SEARCH_INITIAL_STRIDE, totalRows);
|
|
1372
|
+
let rowsSearched = 0;
|
|
1373
|
+
const runningResult = [];
|
|
1374
|
+
setSearchStatus(void 0);
|
|
1375
|
+
setInternalResults([]);
|
|
1376
|
+
const tick = () => {
|
|
1377
|
+
if (abortControllerRef.current?.signal.aborted) return;
|
|
1378
|
+
const tStart = performance.now();
|
|
1379
|
+
const rowsLeft = totalRows - rowsSearched;
|
|
1380
|
+
const height = Math.min(searchStride, rowsLeft, totalRows - startY);
|
|
1381
|
+
if (height <= 0) {
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
const chunk = collectSearchMatchesInRange({
|
|
1385
|
+
query,
|
|
1386
|
+
startRow: startY,
|
|
1387
|
+
rowCount: height,
|
|
1388
|
+
columnCount,
|
|
1389
|
+
getCellValue: (rowIndex, colIndex) => getCellValueRef.current(rowIndex, colIndex),
|
|
1390
|
+
maxResults: INLINE_SEARCH_MAX_RESULTS - runningResult.length
|
|
1391
|
+
});
|
|
1392
|
+
if (chunk.length > 0) {
|
|
1393
|
+
runningResult.push(...chunk);
|
|
1394
|
+
setInternalResults([...runningResult]);
|
|
1395
|
+
}
|
|
1396
|
+
rowsSearched += height;
|
|
1397
|
+
const selectedIndex = searchStatusRef.current?.selectedIndex ?? -1;
|
|
1398
|
+
setSearchStatus({
|
|
1399
|
+
results: runningResult.length,
|
|
1400
|
+
rowsSearched,
|
|
1401
|
+
selectedIndex
|
|
1402
|
+
});
|
|
1403
|
+
emitResultsChanged(runningResult, selectedIndex);
|
|
1404
|
+
if (startY + height >= totalRows) {
|
|
1405
|
+
startY = 0;
|
|
1406
|
+
} else {
|
|
1407
|
+
startY += height;
|
|
1408
|
+
}
|
|
1409
|
+
searchStride = nextSearchStride(
|
|
1410
|
+
searchStride,
|
|
1411
|
+
performance.now() - tStart
|
|
1412
|
+
);
|
|
1413
|
+
if (rowsSearched < totalRows && runningResult.length < INLINE_SEARCH_MAX_RESULTS) {
|
|
1414
|
+
searchHandleRef.current = window.requestAnimationFrame(tick);
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
cancelSearch();
|
|
1418
|
+
abortControllerRef.current = new AbortController();
|
|
1419
|
+
searchHandleRef.current = window.requestAnimationFrame(tick);
|
|
1420
|
+
},
|
|
1421
|
+
[
|
|
1422
|
+
cancelSearch,
|
|
1423
|
+
columnCount,
|
|
1424
|
+
controlledSearchResults,
|
|
1425
|
+
emitResultsChanged,
|
|
1426
|
+
rowCount
|
|
1427
|
+
]
|
|
1428
|
+
);
|
|
1429
|
+
const openSearch = useCallback3(() => {
|
|
1430
|
+
if (controlledShowSearch === void 0) {
|
|
1431
|
+
setInternalShowSearch(true);
|
|
1432
|
+
}
|
|
1433
|
+
}, [controlledShowSearch]);
|
|
1434
|
+
const closeSearch = useCallback3(() => {
|
|
1435
|
+
if (controlledShowSearch === void 0) {
|
|
1436
|
+
setInternalShowSearch(false);
|
|
1437
|
+
}
|
|
1438
|
+
onSearchClose?.();
|
|
1439
|
+
setSearchStatus(void 0);
|
|
1440
|
+
setInternalResults([]);
|
|
1441
|
+
emitResultsChanged([], -1);
|
|
1442
|
+
cancelSearch();
|
|
1443
|
+
}, [
|
|
1444
|
+
cancelSearch,
|
|
1445
|
+
controlledShowSearch,
|
|
1446
|
+
emitResultsChanged,
|
|
1447
|
+
onSearchClose
|
|
1448
|
+
]);
|
|
1449
|
+
const goToNext = useCallback3(() => {
|
|
1450
|
+
if (!searchStatus || searchStatus.results === 0) return;
|
|
1451
|
+
const newIndex = nextSearchIndex(
|
|
1452
|
+
searchStatus.selectedIndex,
|
|
1453
|
+
searchStatus.results
|
|
1454
|
+
);
|
|
1455
|
+
setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
|
|
1456
|
+
emitResultsChanged(searchResults, newIndex);
|
|
1457
|
+
navigateToIndex(searchResults, newIndex);
|
|
1458
|
+
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
1459
|
+
const goToPrevious = useCallback3(() => {
|
|
1460
|
+
if (!searchStatus || searchStatus.results === 0) return;
|
|
1461
|
+
const newIndex = previousSearchIndex(
|
|
1462
|
+
searchStatus.selectedIndex,
|
|
1463
|
+
searchStatus.results
|
|
1464
|
+
);
|
|
1465
|
+
setSearchStatus({ ...searchStatus, selectedIndex: newIndex });
|
|
1466
|
+
emitResultsChanged(searchResults, newIndex);
|
|
1467
|
+
navigateToIndex(searchResults, newIndex);
|
|
1468
|
+
}, [emitResultsChanged, navigateToIndex, searchResults, searchStatus]);
|
|
1469
|
+
useEffect3(() => {
|
|
1470
|
+
if (controlledSearchResults === void 0) return;
|
|
1471
|
+
if (controlledSearchResults.length > 0) {
|
|
1472
|
+
setSearchStatus((current) => ({
|
|
1473
|
+
rowsSearched: rowCount,
|
|
1474
|
+
results: controlledSearchResults.length,
|
|
1475
|
+
selectedIndex: current?.selectedIndex ?? -1
|
|
1476
|
+
}));
|
|
1477
|
+
} else {
|
|
1478
|
+
setSearchStatus(void 0);
|
|
1479
|
+
}
|
|
1480
|
+
}, [controlledSearchResults, rowCount]);
|
|
1481
|
+
useEffect3(() => {
|
|
1482
|
+
if (!enabled) return;
|
|
1483
|
+
setSearchStatus(void 0);
|
|
1484
|
+
setInternalResults([]);
|
|
1485
|
+
emitResultsChanged([], -1);
|
|
1486
|
+
if (showSearch) {
|
|
1487
|
+
queueMicrotask(() => {
|
|
1488
|
+
searchInputRef.current?.focus({ preventScroll: true });
|
|
1489
|
+
});
|
|
1490
|
+
} else {
|
|
1491
|
+
cancelSearch();
|
|
1492
|
+
}
|
|
1493
|
+
}, [enabled, showSearch]);
|
|
1494
|
+
useEffect3(() => {
|
|
1495
|
+
if (!enabled || !showSearch) return;
|
|
1496
|
+
if (controlledSearchResults !== void 0) return;
|
|
1497
|
+
if (searchValue.trim() === "") {
|
|
1498
|
+
setSearchStatus(void 0);
|
|
1499
|
+
setInternalResults([]);
|
|
1500
|
+
cancelSearch();
|
|
1501
|
+
emitResultsChanged([], -1);
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
beginSearch(searchValue);
|
|
1505
|
+
}, [
|
|
1506
|
+
beginSearch,
|
|
1507
|
+
cancelSearch,
|
|
1508
|
+
controlledSearchResults,
|
|
1509
|
+
emitResultsChanged,
|
|
1510
|
+
enabled,
|
|
1511
|
+
searchValue,
|
|
1512
|
+
showSearch
|
|
1513
|
+
]);
|
|
1514
|
+
useEffect3(() => {
|
|
1515
|
+
if (!enabled) return;
|
|
1516
|
+
const handleKeyDown = (event) => {
|
|
1517
|
+
if (!(event.ctrlKey || event.metaKey)) return;
|
|
1518
|
+
if (event.key.toLowerCase() !== "f") return;
|
|
1519
|
+
const root = rootRef?.current;
|
|
1520
|
+
if (root) {
|
|
1521
|
+
const active = document.activeElement;
|
|
1522
|
+
const focusInside = active === root || active instanceof Node && root.contains(active);
|
|
1523
|
+
if (!focusInside && active !== document.body) {
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
event.preventDefault();
|
|
1528
|
+
event.stopPropagation();
|
|
1529
|
+
if (showSearch) {
|
|
1530
|
+
searchInputRef.current?.focus({ preventScroll: true });
|
|
1531
|
+
searchInputRef.current?.select();
|
|
1532
|
+
return;
|
|
1533
|
+
}
|
|
1534
|
+
if (controlledShowSearch === void 0) {
|
|
1535
|
+
setInternalShowSearch(true);
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
window.addEventListener("keydown", handleKeyDown, true);
|
|
1539
|
+
return () => window.removeEventListener("keydown", handleKeyDown, true);
|
|
1540
|
+
}, [controlledShowSearch, enabled, rootRef, showSearch]);
|
|
1541
|
+
useEffect3(() => () => cancelSearch(), [cancelSearch]);
|
|
1542
|
+
const searchMatchKeys = useMemo(
|
|
1543
|
+
() => buildSearchMatchKeys(searchResults),
|
|
1544
|
+
[searchResults]
|
|
1545
|
+
);
|
|
1546
|
+
const activeMatch = useMemo(() => {
|
|
1547
|
+
if (!searchStatus || searchStatus.selectedIndex < 0) return null;
|
|
1548
|
+
return searchResults[searchStatus.selectedIndex] ?? null;
|
|
1549
|
+
}, [searchResults, searchStatus]);
|
|
1550
|
+
if (!enabled) {
|
|
1551
|
+
return {
|
|
1552
|
+
enabled: false,
|
|
1553
|
+
showSearch: false,
|
|
1554
|
+
searchValue: "",
|
|
1555
|
+
searchResults: [],
|
|
1556
|
+
searchStatus: void 0,
|
|
1557
|
+
searchMatchKeys: EMPTY_MATCH_KEYS,
|
|
1558
|
+
activeMatch: null,
|
|
1559
|
+
searchInputRef,
|
|
1560
|
+
searchInputId,
|
|
1561
|
+
canClose: false,
|
|
1562
|
+
openSearch,
|
|
1563
|
+
closeSearch,
|
|
1564
|
+
setSearchValue,
|
|
1565
|
+
goToNext,
|
|
1566
|
+
goToPrevious
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
return {
|
|
1570
|
+
enabled: true,
|
|
1571
|
+
showSearch,
|
|
1572
|
+
searchValue,
|
|
1573
|
+
searchResults,
|
|
1574
|
+
searchStatus,
|
|
1575
|
+
searchMatchKeys,
|
|
1576
|
+
activeMatch,
|
|
1577
|
+
searchInputRef,
|
|
1578
|
+
searchInputId,
|
|
1579
|
+
canClose: controlledShowSearch === void 0 || onSearchClose !== void 0,
|
|
1580
|
+
openSearch,
|
|
1581
|
+
closeSearch,
|
|
1582
|
+
setSearchValue,
|
|
1583
|
+
goToNext,
|
|
1584
|
+
goToPrevious
|
|
1023
1585
|
};
|
|
1024
1586
|
}
|
|
1025
1587
|
|
|
1026
1588
|
// src/components/ui/table/features/row-expand/row-expand.ts
|
|
1027
|
-
import { useEffect as
|
|
1589
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4 } from "react";
|
|
1028
1590
|
function getFieldValue(row, key) {
|
|
1029
1591
|
return row[key];
|
|
1030
1592
|
}
|
|
@@ -1054,12 +1616,12 @@ var useConvertTreeData = ({
|
|
|
1054
1616
|
expandedRows,
|
|
1055
1617
|
onExpandedRowsChange
|
|
1056
1618
|
}) => {
|
|
1057
|
-
const onExpandedRowsChangeRef =
|
|
1058
|
-
const hasInitializedRef =
|
|
1059
|
-
|
|
1619
|
+
const onExpandedRowsChangeRef = useRef4(onExpandedRowsChange);
|
|
1620
|
+
const hasInitializedRef = useRef4(false);
|
|
1621
|
+
useEffect4(() => {
|
|
1060
1622
|
onExpandedRowsChangeRef.current = onExpandedRowsChange;
|
|
1061
1623
|
}, [onExpandedRowsChange]);
|
|
1062
|
-
|
|
1624
|
+
useEffect4(() => {
|
|
1063
1625
|
if (!data || data.length === 0) {
|
|
1064
1626
|
hasInitializedRef.current = false;
|
|
1065
1627
|
return;
|
|
@@ -1069,7 +1631,7 @@ var useConvertTreeData = ({
|
|
|
1069
1631
|
onExpandedRowsChangeRef.current?.(new Set(ids));
|
|
1070
1632
|
hasInitializedRef.current = true;
|
|
1071
1633
|
}, [enabled, data, toggleField]);
|
|
1072
|
-
const processedData =
|
|
1634
|
+
const processedData = useMemo2(() => {
|
|
1073
1635
|
if (!enabled || !data || data.length === 0) return [];
|
|
1074
1636
|
const flattenedData = [];
|
|
1075
1637
|
const flattenItems = (items) => {
|
|
@@ -1133,7 +1695,7 @@ var useConvertTreeData = ({
|
|
|
1133
1695
|
});
|
|
1134
1696
|
return rootItems;
|
|
1135
1697
|
}, [enabled, data, toggleField, childField, flattenField]);
|
|
1136
|
-
const flattenTree =
|
|
1698
|
+
const flattenTree = useMemo2(() => {
|
|
1137
1699
|
if (!enabled) return [];
|
|
1138
1700
|
const flatten = (nodes, result = [], level = 0) => {
|
|
1139
1701
|
nodes.forEach((node, index) => {
|
|
@@ -1183,7 +1745,7 @@ var useConvertTreeData = ({
|
|
|
1183
1745
|
preventExpand,
|
|
1184
1746
|
expandedRows
|
|
1185
1747
|
]);
|
|
1186
|
-
const sortedData =
|
|
1748
|
+
const sortedData = useMemo2(() => {
|
|
1187
1749
|
if (!enabled) {
|
|
1188
1750
|
return data ?? [];
|
|
1189
1751
|
}
|
|
@@ -1289,6 +1851,7 @@ function collectRowSpanColumns(columns) {
|
|
|
1289
1851
|
|
|
1290
1852
|
// src/core/useGlideTable.ts
|
|
1291
1853
|
var EMPTY_COLUMN_FREEZE_OFFSETS = /* @__PURE__ */ new Map();
|
|
1854
|
+
var EMPTY_SEARCH_MATCH_KEYS = /* @__PURE__ */ new Set();
|
|
1292
1855
|
function useGlideTable(options) {
|
|
1293
1856
|
const {
|
|
1294
1857
|
data,
|
|
@@ -1329,9 +1892,16 @@ function useGlideTable(options) {
|
|
|
1329
1892
|
columnSizing: controlledColumnSizing,
|
|
1330
1893
|
onColumnSizingChange,
|
|
1331
1894
|
columnResizeMode = "onChange",
|
|
1332
|
-
enableColumnFreeze = false
|
|
1895
|
+
enableColumnFreeze = false,
|
|
1896
|
+
enableInlineSearch = false,
|
|
1897
|
+
showSearch,
|
|
1898
|
+
searchValue,
|
|
1899
|
+
onSearchValueChange,
|
|
1900
|
+
onSearchClose,
|
|
1901
|
+
searchResults,
|
|
1902
|
+
onSearchResultsChanged
|
|
1333
1903
|
} = options;
|
|
1334
|
-
const labels =
|
|
1904
|
+
const labels = useMemo3(() => {
|
|
1335
1905
|
const resolved = resolveDataTableLabels(labelsProp);
|
|
1336
1906
|
return {
|
|
1337
1907
|
...resolved,
|
|
@@ -1342,15 +1912,16 @@ function useGlideTable(options) {
|
|
|
1342
1912
|
}, [labelsProp, emptyText, loadingText, selectionLabel]);
|
|
1343
1913
|
const enableExpand = Boolean(toggleField);
|
|
1344
1914
|
const resolvedEnableSubtreeCopy = enableSubtreeCopy ?? enableExpand;
|
|
1345
|
-
const [internalRowSelection, setInternalRowSelection] =
|
|
1346
|
-
const [internalColumnSizing, setInternalColumnSizing] =
|
|
1347
|
-
const [internalExpandedRows, setInternalExpandedRows] =
|
|
1915
|
+
const [internalRowSelection, setInternalRowSelection] = useState4({});
|
|
1916
|
+
const [internalColumnSizing, setInternalColumnSizing] = useState4({});
|
|
1917
|
+
const [internalExpandedRows, setInternalExpandedRows] = useState4(
|
|
1348
1918
|
() => /* @__PURE__ */ new Set()
|
|
1349
1919
|
);
|
|
1350
|
-
const [hoveredRowIndex, setHoveredRowIndex] =
|
|
1351
|
-
const scrollRef =
|
|
1920
|
+
const [hoveredRowIndex, setHoveredRowIndex] = useState4(null);
|
|
1921
|
+
const scrollRef = useRef5(null);
|
|
1922
|
+
const rootRef = useRef5(null);
|
|
1352
1923
|
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
1353
|
-
|
|
1924
|
+
useEffect5(() => {
|
|
1354
1925
|
if (enableVirtualization && enableRowSpan) {
|
|
1355
1926
|
console.warn(
|
|
1356
1927
|
"[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
|
|
@@ -1364,7 +1935,7 @@ function useGlideTable(options) {
|
|
|
1364
1935
|
);
|
|
1365
1936
|
const columnSizing = controlledColumnSizing ?? internalColumnSizing;
|
|
1366
1937
|
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
1367
|
-
const handleExpandedRowsChange =
|
|
1938
|
+
const handleExpandedRowsChange = useCallback4(
|
|
1368
1939
|
(next) => {
|
|
1369
1940
|
if (onExpandedRowsChange) {
|
|
1370
1941
|
onExpandedRowsChange(next);
|
|
@@ -1425,13 +1996,13 @@ function useGlideTable(options) {
|
|
|
1425
1996
|
getCoreRowModel: getCoreRowModel(),
|
|
1426
1997
|
getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
|
|
1427
1998
|
});
|
|
1428
|
-
const rowSpanColumnKeys =
|
|
1999
|
+
const rowSpanColumnKeys = useMemo3(() => {
|
|
1429
2000
|
if (!enableRowSpan) return [];
|
|
1430
2001
|
return collectRowSpanColumns(columns);
|
|
1431
2002
|
}, [enableRowSpan, columns]);
|
|
1432
2003
|
const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
|
|
1433
2004
|
const primaryRowSpanColumnId = rowSpanColumnKeys[0]?.columnId;
|
|
1434
|
-
const columnRowSpanMap =
|
|
2005
|
+
const columnRowSpanMap = useMemo3(
|
|
1435
2006
|
() => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
|
|
1436
2007
|
[tableData, rowSpanColumnKeys]
|
|
1437
2008
|
);
|
|
@@ -1440,7 +2011,7 @@ function useGlideTable(options) {
|
|
|
1440
2011
|
const rows = table.getRowModel().rows;
|
|
1441
2012
|
const columnCount = table.getAllLeafColumns().length || 1;
|
|
1442
2013
|
const visibleLeafColumns = table.getVisibleLeafColumns();
|
|
1443
|
-
const columnFreezeOffsets =
|
|
2014
|
+
const columnFreezeOffsets = useMemo3(() => {
|
|
1444
2015
|
if (!enableColumnFreeze) return EMPTY_COLUMN_FREEZE_OFFSETS;
|
|
1445
2016
|
return buildColumnFreezeOffsets(
|
|
1446
2017
|
visibleLeafColumns.map((column) => ({
|
|
@@ -1460,13 +2031,46 @@ function useGlideTable(options) {
|
|
|
1460
2031
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
1461
2032
|
const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
1462
2033
|
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
|
|
1463
|
-
const selectedRowIndices =
|
|
2034
|
+
const selectedRowIndices = useMemo3(() => {
|
|
1464
2035
|
const indices = /* @__PURE__ */ new Set();
|
|
1465
2036
|
for (const selectedRow of selectedRows) {
|
|
1466
2037
|
indices.add(selectedRow.index);
|
|
1467
2038
|
}
|
|
1468
2039
|
return indices;
|
|
1469
2040
|
}, [selectedRows]);
|
|
2041
|
+
const scrollCellIntoView = useCallback4(
|
|
2042
|
+
(rowIndex, colIndex, options2) => {
|
|
2043
|
+
const align = options2?.align ?? "nearest";
|
|
2044
|
+
const blockAlign = align === "center" ? "center" : "nearest";
|
|
2045
|
+
if (shouldVirtualize) {
|
|
2046
|
+
rowVirtualizer.scrollToIndex(rowIndex, {
|
|
2047
|
+
align: align === "nearest" ? "auto" : align
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
const scrollElement = scrollRef.current;
|
|
2051
|
+
if (!scrollElement) return;
|
|
2052
|
+
const scrollToMatchedCell = () => {
|
|
2053
|
+
const cell = scrollElement.querySelector(
|
|
2054
|
+
`[data-row-index="${rowIndex}"][data-col-index="${colIndex}"]`
|
|
2055
|
+
);
|
|
2056
|
+
if (cell instanceof HTMLElement) {
|
|
2057
|
+
cell.scrollIntoView({ block: blockAlign, inline: "nearest" });
|
|
2058
|
+
}
|
|
2059
|
+
};
|
|
2060
|
+
if (shouldVirtualize) {
|
|
2061
|
+
requestAnimationFrame(scrollToMatchedCell);
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
scrollToMatchedCell();
|
|
2065
|
+
},
|
|
2066
|
+
[rowVirtualizer, shouldVirtualize]
|
|
2067
|
+
);
|
|
2068
|
+
const handleCellNavigate = useCallback4(
|
|
2069
|
+
(position) => {
|
|
2070
|
+
scrollCellIntoView(position.row, position.col, { align: "nearest" });
|
|
2071
|
+
},
|
|
2072
|
+
[scrollCellIntoView]
|
|
2073
|
+
);
|
|
1470
2074
|
const {
|
|
1471
2075
|
dragState,
|
|
1472
2076
|
activeSelectionBounds,
|
|
@@ -1478,11 +2082,13 @@ function useGlideTable(options) {
|
|
|
1478
2082
|
data: tableData,
|
|
1479
2083
|
rows,
|
|
1480
2084
|
enabled: enableCellSelection,
|
|
2085
|
+
columnCount: visibleLeafColumns.length,
|
|
1481
2086
|
enableSubtreeCopy: resolvedEnableSubtreeCopy,
|
|
1482
2087
|
enableInsertPaste: enableInsertPaste ?? true,
|
|
1483
2088
|
onDataChange,
|
|
1484
2089
|
onBatchChange,
|
|
1485
|
-
onRowsPaste
|
|
2090
|
+
onRowsPaste,
|
|
2091
|
+
onCellNavigate: handleCellNavigate
|
|
1486
2092
|
});
|
|
1487
2093
|
const {
|
|
1488
2094
|
editingCell,
|
|
@@ -1492,23 +2098,193 @@ function useGlideTable(options) {
|
|
|
1492
2098
|
commitEdit,
|
|
1493
2099
|
cancelEdit
|
|
1494
2100
|
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
1495
|
-
const handleCellMouseDownWithCommit =
|
|
1496
|
-
(rowIndex, colIndex) => {
|
|
2101
|
+
const handleCellMouseDownWithCommit = useCallback4(
|
|
2102
|
+
(rowIndex, colIndex, options2) => {
|
|
1497
2103
|
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
1498
2104
|
if (editingCell && !isSameEditingCell && !commitEdit()) {
|
|
1499
2105
|
return;
|
|
1500
2106
|
}
|
|
1501
|
-
handleCellMouseDown(rowIndex, colIndex);
|
|
2107
|
+
handleCellMouseDown(rowIndex, colIndex, options2);
|
|
1502
2108
|
},
|
|
1503
2109
|
[commitEdit, editingCell, handleCellMouseDown]
|
|
1504
2110
|
);
|
|
1505
|
-
const
|
|
2111
|
+
const navigateToSearchResult = useCallback4(
|
|
2112
|
+
(item) => {
|
|
2113
|
+
const [colIndex, rowIndex] = item;
|
|
2114
|
+
handleCellMouseDownWithCommit(rowIndex, colIndex);
|
|
2115
|
+
scrollCellIntoView(rowIndex, colIndex, { align: "center" });
|
|
2116
|
+
},
|
|
2117
|
+
[handleCellMouseDownWithCommit, scrollCellIntoView]
|
|
2118
|
+
);
|
|
2119
|
+
const resolveSearchRowId = useCallback4(
|
|
2120
|
+
(row, index) => {
|
|
2121
|
+
if (getRowId) return getRowId(row, index);
|
|
2122
|
+
if (enableExpand) {
|
|
2123
|
+
const record = row;
|
|
2124
|
+
const idValue = record.id;
|
|
2125
|
+
if (idValue != null && String(idValue).length > 0) {
|
|
2126
|
+
return String(idValue);
|
|
2127
|
+
}
|
|
2128
|
+
const uniqueId = record.uniqueId;
|
|
2129
|
+
if (uniqueId != null && String(uniqueId).length > 0) {
|
|
2130
|
+
return String(uniqueId);
|
|
2131
|
+
}
|
|
2132
|
+
if (toggleField) {
|
|
2133
|
+
const toggleValue = record[toggleField];
|
|
2134
|
+
if (toggleValue != null && String(toggleValue).length > 0) {
|
|
2135
|
+
return String(toggleValue);
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
return String(index);
|
|
2140
|
+
},
|
|
2141
|
+
[enableExpand, getRowId, toggleField]
|
|
2142
|
+
);
|
|
2143
|
+
const searchCorpus = useMemo3(() => {
|
|
2144
|
+
if (!enableInlineSearch) return [];
|
|
2145
|
+
if (enableExpand && toggleField) {
|
|
2146
|
+
return buildTreeSearchCorpus(tableData, {
|
|
2147
|
+
toggleField,
|
|
2148
|
+
getRowId: resolveSearchRowId
|
|
2149
|
+
});
|
|
2150
|
+
}
|
|
2151
|
+
return buildFlatSearchCorpus(tableData, resolveSearchRowId);
|
|
2152
|
+
}, [
|
|
2153
|
+
enableExpand,
|
|
2154
|
+
enableInlineSearch,
|
|
2155
|
+
resolveSearchRowId,
|
|
2156
|
+
tableData,
|
|
2157
|
+
toggleField
|
|
2158
|
+
]);
|
|
2159
|
+
const searchCorpusRef = useRef5(searchCorpus);
|
|
2160
|
+
searchCorpusRef.current = searchCorpus;
|
|
2161
|
+
const visibleRowIndexById = useMemo3(() => {
|
|
2162
|
+
const map = /* @__PURE__ */ new Map();
|
|
2163
|
+
for (const row of rows) {
|
|
2164
|
+
map.set(resolveSearchRowId(row.original, row.index), row.index);
|
|
2165
|
+
}
|
|
2166
|
+
return map;
|
|
2167
|
+
}, [resolveSearchRowId, rows]);
|
|
2168
|
+
const getSearchCellValue = useCallback4(
|
|
2169
|
+
(rowIndex, colIndex) => {
|
|
2170
|
+
const corpusRow = searchCorpusRef.current[rowIndex];
|
|
2171
|
+
const column = visibleLeafColumns[colIndex];
|
|
2172
|
+
if (!corpusRow || !column) return void 0;
|
|
2173
|
+
const visibleIndex = visibleRowIndexById.get(corpusRow.id);
|
|
2174
|
+
if (visibleIndex !== void 0) {
|
|
2175
|
+
const visibleRow = rows[visibleIndex];
|
|
2176
|
+
if (visibleRow) {
|
|
2177
|
+
return visibleRow.getValue(column.id);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
const columnDef = column.columnDef;
|
|
2181
|
+
if ("accessorFn" in columnDef && typeof columnDef.accessorFn === "function") {
|
|
2182
|
+
return columnDef.accessorFn(corpusRow.data, rowIndex);
|
|
2183
|
+
}
|
|
2184
|
+
if ("accessorKey" in columnDef && columnDef.accessorKey != null && columnDef.accessorKey !== "") {
|
|
2185
|
+
return corpusRow.data[String(columnDef.accessorKey)];
|
|
2186
|
+
}
|
|
2187
|
+
return corpusRow.data[column.id];
|
|
2188
|
+
},
|
|
2189
|
+
[rows, visibleLeafColumns, visibleRowIndexById]
|
|
2190
|
+
);
|
|
2191
|
+
const pendingSearchNavRef = useRef5(null);
|
|
2192
|
+
const focusSearchResult = useCallback4(
|
|
2193
|
+
(colIndex, visibleRowIndex) => {
|
|
2194
|
+
navigateToSearchResult([colIndex, visibleRowIndex]);
|
|
2195
|
+
},
|
|
2196
|
+
[navigateToSearchResult]
|
|
2197
|
+
);
|
|
2198
|
+
const navigateToCorpusSearchResult = useCallback4(
|
|
2199
|
+
(item) => {
|
|
2200
|
+
const [colIndex, corpusRowIndex] = item;
|
|
2201
|
+
const corpusRow = searchCorpusRef.current[corpusRowIndex];
|
|
2202
|
+
if (!corpusRow) return;
|
|
2203
|
+
const missingKeys = collectAncestorKeysToExpand(corpusRow, expandedRows);
|
|
2204
|
+
if (missingKeys.length > 0) {
|
|
2205
|
+
pendingSearchNavRef.current = {
|
|
2206
|
+
colIndex,
|
|
2207
|
+
rowId: corpusRow.id
|
|
2208
|
+
};
|
|
2209
|
+
const next = new Set(expandedRows);
|
|
2210
|
+
for (const key of corpusRow.ancestorToggleKeys) {
|
|
2211
|
+
next.add(key);
|
|
2212
|
+
}
|
|
2213
|
+
handleExpandedRowsChange(next);
|
|
2214
|
+
return;
|
|
2215
|
+
}
|
|
2216
|
+
const visibleItem = mapSearchResultToVisibleItem(
|
|
2217
|
+
item,
|
|
2218
|
+
searchCorpusRef.current,
|
|
2219
|
+
visibleRowIndexById
|
|
2220
|
+
);
|
|
2221
|
+
if (!visibleItem) return;
|
|
2222
|
+
focusSearchResult(visibleItem[0], visibleItem[1]);
|
|
2223
|
+
},
|
|
2224
|
+
[
|
|
2225
|
+
expandedRows,
|
|
2226
|
+
focusSearchResult,
|
|
2227
|
+
handleExpandedRowsChange,
|
|
2228
|
+
visibleRowIndexById
|
|
2229
|
+
]
|
|
2230
|
+
);
|
|
2231
|
+
useEffect5(() => {
|
|
2232
|
+
const pending = pendingSearchNavRef.current;
|
|
2233
|
+
if (!pending) return;
|
|
2234
|
+
const visibleRowIndex = visibleRowIndexById.get(pending.rowId);
|
|
2235
|
+
if (visibleRowIndex === void 0) return;
|
|
2236
|
+
pendingSearchNavRef.current = null;
|
|
2237
|
+
focusSearchResult(pending.colIndex, visibleRowIndex);
|
|
2238
|
+
}, [focusSearchResult, rows, visibleRowIndexById]);
|
|
2239
|
+
const initialSearchStartRow = virtualRows[0]?.index ?? 0;
|
|
2240
|
+
const inlineSearch = useInlineSearch({
|
|
2241
|
+
enabled: enableInlineSearch,
|
|
2242
|
+
rowCount: searchCorpus.length,
|
|
2243
|
+
columnCount: visibleLeafColumns.length,
|
|
2244
|
+
getCellValue: getSearchCellValue,
|
|
2245
|
+
initialStartRow: initialSearchStartRow,
|
|
2246
|
+
showSearch,
|
|
2247
|
+
searchValue,
|
|
2248
|
+
searchResults,
|
|
2249
|
+
onSearchValueChange,
|
|
2250
|
+
onSearchClose,
|
|
2251
|
+
onSearchResultsChanged,
|
|
2252
|
+
onNavigateToResult: navigateToCorpusSearchResult,
|
|
2253
|
+
rootRef
|
|
2254
|
+
});
|
|
2255
|
+
const visibleSearchMatchKeys = useMemo3(() => {
|
|
2256
|
+
if (!enableInlineSearch) return EMPTY_SEARCH_MATCH_KEYS;
|
|
2257
|
+
return mapSearchResultsToVisibleKeys(
|
|
2258
|
+
inlineSearch.searchResults,
|
|
2259
|
+
searchCorpus,
|
|
2260
|
+
visibleRowIndexById
|
|
2261
|
+
);
|
|
2262
|
+
}, [
|
|
2263
|
+
enableInlineSearch,
|
|
2264
|
+
inlineSearch.searchResults,
|
|
2265
|
+
searchCorpus,
|
|
2266
|
+
visibleRowIndexById
|
|
2267
|
+
]);
|
|
2268
|
+
const visibleActiveMatch = useMemo3(() => {
|
|
2269
|
+
if (!enableInlineSearch || !inlineSearch.activeMatch) return null;
|
|
2270
|
+
return mapSearchResultToVisibleItem(
|
|
2271
|
+
inlineSearch.activeMatch,
|
|
2272
|
+
searchCorpus,
|
|
2273
|
+
visibleRowIndexById
|
|
2274
|
+
);
|
|
2275
|
+
}, [
|
|
2276
|
+
enableInlineSearch,
|
|
2277
|
+
inlineSearch.activeMatch,
|
|
2278
|
+
searchCorpus,
|
|
2279
|
+
visibleRowIndexById
|
|
2280
|
+
]);
|
|
2281
|
+
const clearHover = useCallback4(() => {
|
|
1506
2282
|
setHoveredRowIndex(null);
|
|
1507
2283
|
}, []);
|
|
1508
|
-
const handleRowHover =
|
|
2284
|
+
const handleRowHover = useCallback4((rowIndex, _rowData) => {
|
|
1509
2285
|
setHoveredRowIndex(rowIndex);
|
|
1510
2286
|
}, []);
|
|
1511
|
-
const handleToggleSelect =
|
|
2287
|
+
const handleToggleSelect = useCallback4(
|
|
1512
2288
|
(row) => {
|
|
1513
2289
|
if (!row.getCanSelect()) return;
|
|
1514
2290
|
if (preserveRowSelection && row.getIsSelected()) {
|
|
@@ -1518,14 +2294,14 @@ function useGlideTable(options) {
|
|
|
1518
2294
|
},
|
|
1519
2295
|
[preserveRowSelection]
|
|
1520
2296
|
);
|
|
1521
|
-
const handleToggleExpand =
|
|
2297
|
+
const handleToggleExpand = useCallback4(
|
|
1522
2298
|
(rowKey) => {
|
|
1523
2299
|
if (preventExpand) return;
|
|
1524
2300
|
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
1525
2301
|
},
|
|
1526
2302
|
[preventExpand, handleExpandedRowsChange, expandedRows]
|
|
1527
2303
|
);
|
|
1528
|
-
const rowContextValue =
|
|
2304
|
+
const rowContextValue = useMemo3(() => {
|
|
1529
2305
|
return {
|
|
1530
2306
|
rowSpan: {
|
|
1531
2307
|
enableRowSpan,
|
|
@@ -1573,6 +2349,11 @@ function useGlideTable(options) {
|
|
|
1573
2349
|
columnFreeze: {
|
|
1574
2350
|
enableColumnFreeze,
|
|
1575
2351
|
offsets: columnFreezeOffsets
|
|
2352
|
+
},
|
|
2353
|
+
inlineSearch: {
|
|
2354
|
+
enabled: enableInlineSearch,
|
|
2355
|
+
matchKeys: visibleSearchMatchKeys,
|
|
2356
|
+
activeMatch: visibleActiveMatch
|
|
1576
2357
|
}
|
|
1577
2358
|
};
|
|
1578
2359
|
}, [
|
|
@@ -1608,14 +2389,17 @@ function useGlideTable(options) {
|
|
|
1608
2389
|
labels.collapseRow,
|
|
1609
2390
|
enableColumnResize,
|
|
1610
2391
|
enableColumnFreeze,
|
|
1611
|
-
columnFreezeOffsets
|
|
2392
|
+
columnFreezeOffsets,
|
|
2393
|
+
enableInlineSearch,
|
|
2394
|
+
visibleSearchMatchKeys,
|
|
2395
|
+
visibleActiveMatch
|
|
1612
2396
|
]);
|
|
1613
|
-
const copySelectionRef =
|
|
1614
|
-
|
|
2397
|
+
const copySelectionRef = useRef5(copySelection);
|
|
2398
|
+
useEffect5(() => {
|
|
1615
2399
|
copySelectionRef.current = copySelection;
|
|
1616
2400
|
}, [copySelection]);
|
|
1617
|
-
const stableCopySelection =
|
|
1618
|
-
|
|
2401
|
+
const stableCopySelection = useCallback4((options2) => copySelectionRef.current(options2), []);
|
|
2402
|
+
useEffect5(() => {
|
|
1619
2403
|
onCopyActionsReady?.({ copySelection: stableCopySelection });
|
|
1620
2404
|
}, [onCopyActionsReady, stableCopySelection]);
|
|
1621
2405
|
return {
|
|
@@ -1631,8 +2415,10 @@ function useGlideTable(options) {
|
|
|
1631
2415
|
enableCellSelection,
|
|
1632
2416
|
enableColumnResize,
|
|
1633
2417
|
enableColumnFreeze,
|
|
2418
|
+
enableInlineSearch,
|
|
1634
2419
|
shouldVirtualize,
|
|
1635
2420
|
scrollRef,
|
|
2421
|
+
rootRef,
|
|
1636
2422
|
rowVirtualizer,
|
|
1637
2423
|
virtualRows,
|
|
1638
2424
|
paddingTop,
|
|
@@ -1640,7 +2426,21 @@ function useGlideTable(options) {
|
|
|
1640
2426
|
rowContextValue,
|
|
1641
2427
|
handleToggleSelect,
|
|
1642
2428
|
clearHover,
|
|
1643
|
-
copySelection: stableCopySelection
|
|
2429
|
+
copySelection: stableCopySelection,
|
|
2430
|
+
inlineSearch: {
|
|
2431
|
+
showSearch: inlineSearch.showSearch,
|
|
2432
|
+
searchValue: inlineSearch.searchValue,
|
|
2433
|
+
searchStatus: inlineSearch.searchStatus,
|
|
2434
|
+
searchInputRef: inlineSearch.searchInputRef,
|
|
2435
|
+
searchInputId: inlineSearch.searchInputId,
|
|
2436
|
+
canClose: inlineSearch.canClose,
|
|
2437
|
+
searchRowCount: searchCorpus.length,
|
|
2438
|
+
setSearchValue: inlineSearch.setSearchValue,
|
|
2439
|
+
closeSearch: inlineSearch.closeSearch,
|
|
2440
|
+
goToNext: inlineSearch.goToNext,
|
|
2441
|
+
goToPrevious: inlineSearch.goToPrevious,
|
|
2442
|
+
openSearch: inlineSearch.openSearch
|
|
2443
|
+
}
|
|
1644
2444
|
};
|
|
1645
2445
|
}
|
|
1646
2446
|
|
|
@@ -1659,11 +2459,11 @@ function getColumnSizeStyle(size, options) {
|
|
|
1659
2459
|
|
|
1660
2460
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
1661
2461
|
import { flexRender as flexRender2 } from "@tanstack/react-table";
|
|
1662
|
-
import { useMemo as
|
|
2462
|
+
import { useMemo as useMemo4 } from "react";
|
|
1663
2463
|
|
|
1664
2464
|
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
1665
2465
|
import { flexRender } from "@tanstack/react-table";
|
|
1666
|
-
import { useEffect as
|
|
2466
|
+
import { useEffect as useEffect6, useRef as useRef6 } from "react";
|
|
1667
2467
|
|
|
1668
2468
|
// src/components/ui/table/DataTableContext.tsx
|
|
1669
2469
|
import { createContext, use } from "react";
|
|
@@ -1871,10 +2671,16 @@ function DataTableRow({
|
|
|
1871
2671
|
cellEdit,
|
|
1872
2672
|
expand,
|
|
1873
2673
|
columnResize,
|
|
1874
|
-
columnFreeze
|
|
2674
|
+
columnFreeze,
|
|
2675
|
+
inlineSearch
|
|
1875
2676
|
} = useDataTableRowContext();
|
|
1876
2677
|
const { enableColumnResize } = columnResize;
|
|
1877
2678
|
const { enableColumnFreeze, offsets: freezeOffsets } = columnFreeze;
|
|
2679
|
+
const {
|
|
2680
|
+
enabled: enableInlineSearch,
|
|
2681
|
+
matchKeys: searchMatchKeys,
|
|
2682
|
+
activeMatch
|
|
2683
|
+
} = inlineSearch;
|
|
1878
2684
|
const {
|
|
1879
2685
|
enableRowSpan,
|
|
1880
2686
|
primaryRowSpanColumnId,
|
|
@@ -1968,9 +2774,9 @@ function DataTableRow({
|
|
|
1968
2774
|
const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
|
|
1969
2775
|
const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
|
|
1970
2776
|
const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
|
|
1971
|
-
const editInputRef =
|
|
2777
|
+
const editInputRef = useRef6(null);
|
|
1972
2778
|
const isRowEditing = editingCell?.rowIndex === rowIndex;
|
|
1973
|
-
|
|
2779
|
+
useEffect6(() => {
|
|
1974
2780
|
if (!isRowEditing) return;
|
|
1975
2781
|
editInputRef.current?.focus();
|
|
1976
2782
|
editInputRef.current?.select();
|
|
@@ -2066,9 +2872,14 @@ function DataTableRow({
|
|
|
2066
2872
|
...freezeStyle,
|
|
2067
2873
|
...selectionEdgeStyle
|
|
2068
2874
|
};
|
|
2875
|
+
const searchMatchKey = buildSearchMatchKey(cellIndex, rowIndex);
|
|
2876
|
+
const isSearchMatch = enableInlineSearch && searchMatchKeys.has(searchMatchKey);
|
|
2877
|
+
const isSearchActive = isSearchMatch && activeMatch !== null && activeMatch[0] === cellIndex && activeMatch[1] === rowIndex;
|
|
2069
2878
|
return /* @__PURE__ */ jsxs2(
|
|
2070
2879
|
"td",
|
|
2071
2880
|
{
|
|
2881
|
+
"data-row-index": rowIndex,
|
|
2882
|
+
"data-col-index": cellIndex,
|
|
2072
2883
|
rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
|
|
2073
2884
|
"data-merged": isMerged && cellIndex > 0 ? "" : void 0,
|
|
2074
2885
|
"data-merged-edge-right": showMergedRightEdge ? "" : void 0,
|
|
@@ -2078,6 +2889,8 @@ function DataTableRow({
|
|
|
2078
2889
|
"data-group-hovered": enableRowSpan && showCellHover && !showCellSelected ? "" : void 0,
|
|
2079
2890
|
"data-selection-fill": isCellDragSelected ? "" : void 0,
|
|
2080
2891
|
"data-selection-edges": hasSelectionEdges ? "" : void 0,
|
|
2892
|
+
"data-search-match": isSearchMatch ? "" : void 0,
|
|
2893
|
+
"data-search-active": isSearchActive ? "" : void 0,
|
|
2081
2894
|
"data-editable": editable ? "" : void 0,
|
|
2082
2895
|
"data-editing": isEditing ? "" : void 0,
|
|
2083
2896
|
"data-frozen": freezeOffset?.side,
|
|
@@ -2092,7 +2905,8 @@ function DataTableRow({
|
|
|
2092
2905
|
event.preventDefault();
|
|
2093
2906
|
onCellMouseDown(
|
|
2094
2907
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
2095
|
-
cellIndex
|
|
2908
|
+
cellIndex,
|
|
2909
|
+
{ shiftKey: event.shiftKey }
|
|
2096
2910
|
);
|
|
2097
2911
|
},
|
|
2098
2912
|
onMouseEnter: (event) => {
|
|
@@ -2129,6 +2943,8 @@ function DataTableRow({
|
|
|
2129
2943
|
enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
|
|
2130
2944
|
isCellDragSelected && CELL_SELECTION_FILL_CLASS,
|
|
2131
2945
|
hasSelectionEdges && CELL_SELECTION_EDGES_CLASS,
|
|
2946
|
+
isSearchMatch && "is-search-match",
|
|
2947
|
+
isSearchActive && "is-search-active",
|
|
2132
2948
|
editable && "is-editable",
|
|
2133
2949
|
classNames?.cell
|
|
2134
2950
|
),
|
|
@@ -2263,8 +3079,169 @@ function DataTableRow({
|
|
|
2263
3079
|
);
|
|
2264
3080
|
}
|
|
2265
3081
|
|
|
3082
|
+
// src/components/ui/table/components/DataTable/DataTableSearch.tsx
|
|
3083
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3084
|
+
function SearchCloseIcon({ className }) {
|
|
3085
|
+
return /* @__PURE__ */ jsxs3(
|
|
3086
|
+
"svg",
|
|
3087
|
+
{
|
|
3088
|
+
className,
|
|
3089
|
+
"aria-hidden": true,
|
|
3090
|
+
width: "16",
|
|
3091
|
+
height: "16",
|
|
3092
|
+
viewBox: "0 0 24 24",
|
|
3093
|
+
fill: "none",
|
|
3094
|
+
stroke: "currentColor",
|
|
3095
|
+
strokeWidth: "2",
|
|
3096
|
+
strokeLinecap: "round",
|
|
3097
|
+
strokeLinejoin: "round",
|
|
3098
|
+
children: [
|
|
3099
|
+
/* @__PURE__ */ jsx4("path", { d: "M18 6 6 18" }),
|
|
3100
|
+
/* @__PURE__ */ jsx4("path", { d: "m6 6 12 12" })
|
|
3101
|
+
]
|
|
3102
|
+
}
|
|
3103
|
+
);
|
|
3104
|
+
}
|
|
3105
|
+
function DataTableSearch({
|
|
3106
|
+
showSearch,
|
|
3107
|
+
searchValue,
|
|
3108
|
+
searchStatus,
|
|
3109
|
+
searchInputId,
|
|
3110
|
+
searchInputRef,
|
|
3111
|
+
canClose,
|
|
3112
|
+
placeholder,
|
|
3113
|
+
resultHint,
|
|
3114
|
+
previousLabel,
|
|
3115
|
+
nextLabel,
|
|
3116
|
+
closeLabel,
|
|
3117
|
+
rowsTotal,
|
|
3118
|
+
classNames,
|
|
3119
|
+
onSearchValueChange,
|
|
3120
|
+
onClose,
|
|
3121
|
+
onNext,
|
|
3122
|
+
onPrevious
|
|
3123
|
+
}) {
|
|
3124
|
+
if (!showSearch) return null;
|
|
3125
|
+
const resultString = searchStatus ? formatSearchResultLabel(searchStatus) : resultHint;
|
|
3126
|
+
const progress = rowsTotal > 0 ? Math.floor((searchStatus?.rowsSearched ?? 0) / rowsTotal * 100) : 0;
|
|
3127
|
+
const handleKeyDown = (event) => {
|
|
3128
|
+
if ((event.ctrlKey || event.metaKey) && event.code === "KeyF" || event.key === "Escape") {
|
|
3129
|
+
event.preventDefault();
|
|
3130
|
+
event.stopPropagation();
|
|
3131
|
+
if (canClose) {
|
|
3132
|
+
onClose();
|
|
3133
|
+
}
|
|
3134
|
+
return;
|
|
3135
|
+
}
|
|
3136
|
+
if (event.key === "ArrowDown" || event.key === "Enter" && !event.shiftKey) {
|
|
3137
|
+
event.preventDefault();
|
|
3138
|
+
onNext();
|
|
3139
|
+
return;
|
|
3140
|
+
}
|
|
3141
|
+
if (event.key === "ArrowUp" || event.key === "Enter" && event.shiftKey) {
|
|
3142
|
+
event.preventDefault();
|
|
3143
|
+
onPrevious();
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
return /* @__PURE__ */ jsxs3(
|
|
3147
|
+
"div",
|
|
3148
|
+
{
|
|
3149
|
+
className: cn("data-table-search", classNames?.search),
|
|
3150
|
+
role: "search",
|
|
3151
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
3152
|
+
children: [
|
|
3153
|
+
/* @__PURE__ */ jsxs3("div", { className: "data-table-search-row", children: [
|
|
3154
|
+
/* @__PURE__ */ jsx4(
|
|
3155
|
+
"input",
|
|
3156
|
+
{
|
|
3157
|
+
ref: searchInputRef,
|
|
3158
|
+
id: searchInputId,
|
|
3159
|
+
type: "search",
|
|
3160
|
+
value: searchValue,
|
|
3161
|
+
placeholder,
|
|
3162
|
+
autoComplete: "off",
|
|
3163
|
+
spellCheck: false,
|
|
3164
|
+
"aria-label": placeholder,
|
|
3165
|
+
className: cn("data-table-search-input", classNames?.searchInput),
|
|
3166
|
+
onChange: (event) => onSearchValueChange(event.target.value),
|
|
3167
|
+
onKeyDown: handleKeyDown
|
|
3168
|
+
}
|
|
3169
|
+
),
|
|
3170
|
+
/* @__PURE__ */ jsx4(
|
|
3171
|
+
"button",
|
|
3172
|
+
{
|
|
3173
|
+
type: "button",
|
|
3174
|
+
"aria-label": previousLabel,
|
|
3175
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
3176
|
+
onClick: (event) => {
|
|
3177
|
+
event.stopPropagation();
|
|
3178
|
+
onPrevious();
|
|
3179
|
+
},
|
|
3180
|
+
children: /* @__PURE__ */ jsx4(ChevronUp, { className: "data-table-search-icon" })
|
|
3181
|
+
}
|
|
3182
|
+
),
|
|
3183
|
+
/* @__PURE__ */ jsx4(
|
|
3184
|
+
"button",
|
|
3185
|
+
{
|
|
3186
|
+
type: "button",
|
|
3187
|
+
"aria-label": nextLabel,
|
|
3188
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
3189
|
+
onClick: (event) => {
|
|
3190
|
+
event.stopPropagation();
|
|
3191
|
+
onNext();
|
|
3192
|
+
},
|
|
3193
|
+
children: /* @__PURE__ */ jsx4(ChevronDown, { className: "data-table-search-icon" })
|
|
3194
|
+
}
|
|
3195
|
+
),
|
|
3196
|
+
canClose ? /* @__PURE__ */ jsx4(
|
|
3197
|
+
"button",
|
|
3198
|
+
{
|
|
3199
|
+
type: "button",
|
|
3200
|
+
"aria-label": closeLabel,
|
|
3201
|
+
className: cn("data-table-search-button", classNames?.searchButton),
|
|
3202
|
+
onClick: (event) => {
|
|
3203
|
+
event.stopPropagation();
|
|
3204
|
+
onClose();
|
|
3205
|
+
},
|
|
3206
|
+
children: /* @__PURE__ */ jsx4(SearchCloseIcon, { className: "data-table-search-icon" })
|
|
3207
|
+
}
|
|
3208
|
+
) : null
|
|
3209
|
+
] }),
|
|
3210
|
+
/* @__PURE__ */ jsx4(
|
|
3211
|
+
"div",
|
|
3212
|
+
{
|
|
3213
|
+
className: cn("data-table-search-status", classNames?.searchStatus),
|
|
3214
|
+
"aria-live": "polite",
|
|
3215
|
+
children: resultString
|
|
3216
|
+
}
|
|
3217
|
+
),
|
|
3218
|
+
searchStatus !== void 0 ? /* @__PURE__ */ jsx4(
|
|
3219
|
+
"div",
|
|
3220
|
+
{
|
|
3221
|
+
className: cn(
|
|
3222
|
+
"data-table-search-progress",
|
|
3223
|
+
classNames?.searchProgress
|
|
3224
|
+
),
|
|
3225
|
+
role: "progressbar",
|
|
3226
|
+
"aria-valuemin": 0,
|
|
3227
|
+
"aria-valuemax": 100,
|
|
3228
|
+
"aria-valuenow": progress,
|
|
3229
|
+
children: /* @__PURE__ */ jsx4(
|
|
3230
|
+
"div",
|
|
3231
|
+
{
|
|
3232
|
+
className: "data-table-search-progress-bar",
|
|
3233
|
+
style: { width: `${progress}%` }
|
|
3234
|
+
}
|
|
3235
|
+
)
|
|
3236
|
+
}
|
|
3237
|
+
) : null
|
|
3238
|
+
]
|
|
3239
|
+
}
|
|
3240
|
+
);
|
|
3241
|
+
}
|
|
3242
|
+
|
|
2266
3243
|
// src/components/ui/table/components/DataTable/DataTableToolbar.tsx
|
|
2267
|
-
import { Fragment, jsx as
|
|
3244
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2268
3245
|
function DataTableToolbar({
|
|
2269
3246
|
filteredCount,
|
|
2270
3247
|
totalCount,
|
|
@@ -2282,39 +3259,71 @@ function DataTableToolbar({
|
|
|
2282
3259
|
const selectionContent = selectionLabel?.(selectedCount) ?? null;
|
|
2283
3260
|
const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
|
|
2284
3261
|
if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
|
|
2285
|
-
return /* @__PURE__ */
|
|
2286
|
-
/* @__PURE__ */
|
|
2287
|
-
hasCount && /* @__PURE__ */
|
|
2288
|
-
/* @__PURE__ */
|
|
2289
|
-
/* @__PURE__ */
|
|
3262
|
+
return /* @__PURE__ */ jsxs4("div", { className: cn("DataTableToolbarJSX", classNames?.toolbar, className), children: [
|
|
3263
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("toolbar-left", classNames?.toolbarLeft), children: [
|
|
3264
|
+
hasCount && /* @__PURE__ */ jsx5("span", { className: cn("toolbar-count", classNames?.toolbarCount), children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
3265
|
+
/* @__PURE__ */ jsx5("span", { className: "toolbar-count-primary", children: displayFiltered }),
|
|
3266
|
+
/* @__PURE__ */ jsxs4("span", { className: "toolbar-count-placeholder", children: [
|
|
2290
3267
|
" / ",
|
|
2291
3268
|
totalCount
|
|
2292
3269
|
] })
|
|
2293
|
-
] }) : /* @__PURE__ */
|
|
3270
|
+
] }) : /* @__PURE__ */ jsx5("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
|
|
2294
3271
|
summary
|
|
2295
3272
|
] }),
|
|
2296
|
-
/* @__PURE__ */
|
|
2297
|
-
hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */
|
|
2298
|
-
hasToolbar && /* @__PURE__ */
|
|
3273
|
+
/* @__PURE__ */ jsxs4("div", { className: cn("toolbar-right", classNames?.toolbarRight), children: [
|
|
3274
|
+
hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ jsx5("span", { className: cn("toolbar-selection", classNames?.toolbarSelection), children: selectionContent }) : selectionContent),
|
|
3275
|
+
hasToolbar && /* @__PURE__ */ jsx5("div", { className: cn("toolbar-actions", classNames?.toolbarActions), children: toolbar })
|
|
2299
3276
|
] })
|
|
2300
3277
|
] });
|
|
2301
3278
|
}
|
|
2302
3279
|
|
|
3280
|
+
// src/components/ui/table/features/column-groups/mergeHeaderGroups.ts
|
|
3281
|
+
function getMergedHeaderGroups(headerGroups) {
|
|
3282
|
+
if (headerGroups.length <= 1) {
|
|
3283
|
+
return headerGroups.map((group) => ({
|
|
3284
|
+
...group,
|
|
3285
|
+
headers: group.headers.map((header) => ({
|
|
3286
|
+
...header,
|
|
3287
|
+
mergedRowSpan: 1
|
|
3288
|
+
}))
|
|
3289
|
+
}));
|
|
3290
|
+
}
|
|
3291
|
+
const seenColumnIds = /* @__PURE__ */ new Set();
|
|
3292
|
+
const fullDepth = headerGroups.length;
|
|
3293
|
+
return headerGroups.map((group, depth) => ({
|
|
3294
|
+
...group,
|
|
3295
|
+
headers: group.headers.filter((header) => !seenColumnIds.has(header.column.id)).map((header) => {
|
|
3296
|
+
seenColumnIds.add(header.column.id);
|
|
3297
|
+
if (header.isPlaceholder) {
|
|
3298
|
+
return {
|
|
3299
|
+
...header,
|
|
3300
|
+
isPlaceholder: false,
|
|
3301
|
+
mergedRowSpan: fullDepth - depth
|
|
3302
|
+
};
|
|
3303
|
+
}
|
|
3304
|
+
return {
|
|
3305
|
+
...header,
|
|
3306
|
+
mergedRowSpan: 1
|
|
3307
|
+
};
|
|
3308
|
+
})
|
|
3309
|
+
}));
|
|
3310
|
+
}
|
|
3311
|
+
|
|
2303
3312
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
2304
|
-
import { Fragment as Fragment2, jsx as
|
|
3313
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2305
3314
|
function DefaultScroll({
|
|
2306
3315
|
scrollRef,
|
|
2307
3316
|
children,
|
|
2308
3317
|
className
|
|
2309
3318
|
}) {
|
|
2310
|
-
return /* @__PURE__ */
|
|
3319
|
+
return /* @__PURE__ */ jsx6("div", { ref: scrollRef, className: cn("data-table-scroll", className), children });
|
|
2311
3320
|
}
|
|
2312
3321
|
function DefaultPending({
|
|
2313
3322
|
loadingText,
|
|
2314
3323
|
className,
|
|
2315
3324
|
classNames
|
|
2316
3325
|
}) {
|
|
2317
|
-
return /* @__PURE__ */
|
|
3326
|
+
return /* @__PURE__ */ jsx6(
|
|
2318
3327
|
"div",
|
|
2319
3328
|
{
|
|
2320
3329
|
className: cn(
|
|
@@ -2324,7 +3333,7 @@ function DefaultPending({
|
|
|
2324
3333
|
classNames?.pending,
|
|
2325
3334
|
className
|
|
2326
3335
|
),
|
|
2327
|
-
children: /* @__PURE__ */
|
|
3336
|
+
children: /* @__PURE__ */ jsx6("span", { className: cn("data-table-loading-text", classNames?.loadingText), children: loadingText })
|
|
2328
3337
|
}
|
|
2329
3338
|
);
|
|
2330
3339
|
}
|
|
@@ -2333,7 +3342,7 @@ function DefaultEmpty({
|
|
|
2333
3342
|
columnCount,
|
|
2334
3343
|
classNames
|
|
2335
3344
|
}) {
|
|
2336
|
-
return /* @__PURE__ */
|
|
3345
|
+
return /* @__PURE__ */ jsx6("tr", { children: /* @__PURE__ */ jsx6(
|
|
2337
3346
|
"td",
|
|
2338
3347
|
{
|
|
2339
3348
|
colSpan: columnCount,
|
|
@@ -2366,15 +3375,18 @@ function DataTable({
|
|
|
2366
3375
|
enableCellSelection,
|
|
2367
3376
|
enableColumnResize,
|
|
2368
3377
|
enableColumnFreeze,
|
|
3378
|
+
enableInlineSearch,
|
|
2369
3379
|
shouldVirtualize,
|
|
2370
3380
|
scrollRef,
|
|
3381
|
+
rootRef,
|
|
2371
3382
|
rowVirtualizer,
|
|
2372
3383
|
virtualRows,
|
|
2373
3384
|
paddingTop,
|
|
2374
3385
|
paddingBottom,
|
|
2375
3386
|
rowContextValue,
|
|
2376
3387
|
handleToggleSelect,
|
|
2377
|
-
clearHover
|
|
3388
|
+
clearHover,
|
|
3389
|
+
inlineSearch
|
|
2378
3390
|
} = useGlideTable(glideOptions);
|
|
2379
3391
|
const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
|
|
2380
3392
|
const ScrollSlot = slots?.Scroll ?? DefaultScroll;
|
|
@@ -2382,12 +3394,13 @@ function DataTable({
|
|
|
2382
3394
|
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
2383
3395
|
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
2384
3396
|
const freezeOffsets = rowContextValue.columnFreeze.offsets;
|
|
2385
|
-
const
|
|
3397
|
+
const headerGroups = getMergedHeaderGroups(table.getHeaderGroups());
|
|
3398
|
+
const contextValue = useMemo4(
|
|
2386
3399
|
() => ({ ...rowContextValue, classNames }),
|
|
2387
3400
|
[rowContextValue, classNames]
|
|
2388
3401
|
);
|
|
2389
3402
|
if (isPending) {
|
|
2390
|
-
return /* @__PURE__ */
|
|
3403
|
+
return /* @__PURE__ */ jsx6(
|
|
2391
3404
|
PendingSlot,
|
|
2392
3405
|
{
|
|
2393
3406
|
loadingText,
|
|
@@ -2396,19 +3409,21 @@ function DataTable({
|
|
|
2396
3409
|
}
|
|
2397
3410
|
);
|
|
2398
3411
|
}
|
|
2399
|
-
return /* @__PURE__ */
|
|
3412
|
+
return /* @__PURE__ */ jsxs5(
|
|
2400
3413
|
"div",
|
|
2401
3414
|
{
|
|
3415
|
+
ref: rootRef,
|
|
2402
3416
|
className: cn(
|
|
2403
3417
|
"DataTableJSX",
|
|
2404
3418
|
!enableCellSelection && "DataTableJSX--no-cell-selection",
|
|
2405
3419
|
enableColumnResize && "DataTableJSX--column-resize",
|
|
2406
3420
|
enableColumnFreeze && "DataTableJSX--column-freeze",
|
|
3421
|
+
enableInlineSearch && "DataTableJSX--inline-search",
|
|
2407
3422
|
classNames?.root,
|
|
2408
3423
|
className
|
|
2409
3424
|
),
|
|
2410
3425
|
children: [
|
|
2411
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsx6(
|
|
2412
3427
|
ToolbarSlot,
|
|
2413
3428
|
{
|
|
2414
3429
|
filteredCount: filteredCount ?? tableData.length,
|
|
@@ -2420,14 +3435,36 @@ function DataTable({
|
|
|
2420
3435
|
classNames
|
|
2421
3436
|
}
|
|
2422
3437
|
),
|
|
2423
|
-
|
|
3438
|
+
enableInlineSearch ? /* @__PURE__ */ jsx6(
|
|
3439
|
+
DataTableSearch,
|
|
3440
|
+
{
|
|
3441
|
+
showSearch: inlineSearch.showSearch,
|
|
3442
|
+
searchValue: inlineSearch.searchValue,
|
|
3443
|
+
searchStatus: inlineSearch.searchStatus,
|
|
3444
|
+
searchInputId: inlineSearch.searchInputId,
|
|
3445
|
+
searchInputRef: inlineSearch.searchInputRef,
|
|
3446
|
+
canClose: inlineSearch.canClose,
|
|
3447
|
+
placeholder: labels.searchPlaceholder,
|
|
3448
|
+
resultHint: labels.searchResultHint,
|
|
3449
|
+
previousLabel: labels.searchPrevious,
|
|
3450
|
+
nextLabel: labels.searchNext,
|
|
3451
|
+
closeLabel: labels.searchClose,
|
|
3452
|
+
rowsTotal: inlineSearch.searchRowCount,
|
|
3453
|
+
classNames,
|
|
3454
|
+
onSearchValueChange: inlineSearch.setSearchValue,
|
|
3455
|
+
onClose: inlineSearch.closeSearch,
|
|
3456
|
+
onNext: inlineSearch.goToNext,
|
|
3457
|
+
onPrevious: inlineSearch.goToPrevious
|
|
3458
|
+
}
|
|
3459
|
+
) : null,
|
|
3460
|
+
/* @__PURE__ */ jsx6(ScrollSlot, { scrollRef, className: classNames?.scroll, children: /* @__PURE__ */ jsxs5(
|
|
2424
3461
|
"table",
|
|
2425
3462
|
{
|
|
2426
3463
|
className: cn("data-table", classNames?.table),
|
|
2427
3464
|
style: enableColumnResize ? { width: table.getTotalSize() } : void 0,
|
|
2428
3465
|
onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
|
|
2429
3466
|
children: [
|
|
2430
|
-
/* @__PURE__ */
|
|
3467
|
+
/* @__PURE__ */ jsx6("thead", { className: cn("data-table-head", classNames?.head), children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx6(
|
|
2431
3468
|
"tr",
|
|
2432
3469
|
{
|
|
2433
3470
|
className: cn("data-table-head-row", classNames?.headRow),
|
|
@@ -2441,15 +3478,18 @@ function DataTable({
|
|
|
2441
3478
|
});
|
|
2442
3479
|
const freezeOffset = enableColumnFreeze ? freezeOffsets.get(header.column.id) : void 0;
|
|
2443
3480
|
const freezeStyle = getColumnFreezeStyle(freezeOffset, {
|
|
2444
|
-
isHeader: true
|
|
3481
|
+
isHeader: true,
|
|
3482
|
+
headerTop: header.depth * DATA_TABLE_HEADER_ROW_HEIGHT
|
|
2445
3483
|
});
|
|
2446
3484
|
const headerStyle = {
|
|
2447
3485
|
...sizeStyle,
|
|
2448
3486
|
...freezeStyle
|
|
2449
3487
|
};
|
|
2450
|
-
return /* @__PURE__ */
|
|
3488
|
+
return /* @__PURE__ */ jsxs5(
|
|
2451
3489
|
"th",
|
|
2452
3490
|
{
|
|
3491
|
+
colSpan: header.colSpan,
|
|
3492
|
+
rowSpan: header.mergedRowSpan,
|
|
2453
3493
|
"data-resizing": header.column.getIsResizing() ? "" : void 0,
|
|
2454
3494
|
"data-frozen": freezeOffset?.side,
|
|
2455
3495
|
"data-freeze-edge": getColumnFreezeEdgeAttr(freezeOffset),
|
|
@@ -2463,7 +3503,7 @@ function DataTable({
|
|
|
2463
3503
|
),
|
|
2464
3504
|
children: [
|
|
2465
3505
|
header.isPlaceholder ? null : flexRender2(header.column.columnDef.header, header.getContext()),
|
|
2466
|
-
canResize ? /* @__PURE__ */
|
|
3506
|
+
canResize ? /* @__PURE__ */ jsx6(
|
|
2467
3507
|
"div",
|
|
2468
3508
|
{
|
|
2469
3509
|
role: "separator",
|
|
@@ -2489,20 +3529,20 @@ function DataTable({
|
|
|
2489
3529
|
},
|
|
2490
3530
|
headerGroup.id
|
|
2491
3531
|
)) }),
|
|
2492
|
-
/* @__PURE__ */
|
|
3532
|
+
/* @__PURE__ */ jsx6(DataTableContextProvider, { value: contextValue, children: /* @__PURE__ */ jsx6(
|
|
2493
3533
|
"tbody",
|
|
2494
3534
|
{
|
|
2495
3535
|
onMouseLeave: clearHover,
|
|
2496
3536
|
className: cn("data-table-body", classNames?.body),
|
|
2497
|
-
children: rows.length === 0 ? /* @__PURE__ */
|
|
3537
|
+
children: rows.length === 0 ? /* @__PURE__ */ jsx6(
|
|
2498
3538
|
EmptySlot,
|
|
2499
3539
|
{
|
|
2500
3540
|
emptyText,
|
|
2501
3541
|
columnCount,
|
|
2502
3542
|
classNames
|
|
2503
3543
|
}
|
|
2504
|
-
) : shouldVirtualize ? /* @__PURE__ */
|
|
2505
|
-
paddingTop > 0 && /* @__PURE__ */
|
|
3544
|
+
) : shouldVirtualize ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
3545
|
+
paddingTop > 0 && /* @__PURE__ */ jsx6(
|
|
2506
3546
|
"tr",
|
|
2507
3547
|
{
|
|
2508
3548
|
"aria-hidden": true,
|
|
@@ -2510,7 +3550,7 @@ function DataTable({
|
|
|
2510
3550
|
"data-table-virtual-spacer",
|
|
2511
3551
|
classNames?.virtualSpacer
|
|
2512
3552
|
),
|
|
2513
|
-
children: /* @__PURE__ */
|
|
3553
|
+
children: /* @__PURE__ */ jsx6(
|
|
2514
3554
|
"td",
|
|
2515
3555
|
{
|
|
2516
3556
|
colSpan: columnCount,
|
|
@@ -2526,7 +3566,7 @@ function DataTable({
|
|
|
2526
3566
|
virtualRows.map((virtualRow) => {
|
|
2527
3567
|
const row = rows[virtualRow.index];
|
|
2528
3568
|
if (!row) return null;
|
|
2529
|
-
return /* @__PURE__ */
|
|
3569
|
+
return /* @__PURE__ */ jsx6(
|
|
2530
3570
|
RowSlot,
|
|
2531
3571
|
{
|
|
2532
3572
|
row,
|
|
@@ -2537,7 +3577,7 @@ function DataTable({
|
|
|
2537
3577
|
row.id
|
|
2538
3578
|
);
|
|
2539
3579
|
}),
|
|
2540
|
-
paddingBottom > 0 && /* @__PURE__ */
|
|
3580
|
+
paddingBottom > 0 && /* @__PURE__ */ jsx6(
|
|
2541
3581
|
"tr",
|
|
2542
3582
|
{
|
|
2543
3583
|
"aria-hidden": true,
|
|
@@ -2545,7 +3585,7 @@ function DataTable({
|
|
|
2545
3585
|
"data-table-virtual-spacer",
|
|
2546
3586
|
classNames?.virtualSpacer
|
|
2547
3587
|
),
|
|
2548
|
-
children: /* @__PURE__ */
|
|
3588
|
+
children: /* @__PURE__ */ jsx6(
|
|
2549
3589
|
"td",
|
|
2550
3590
|
{
|
|
2551
3591
|
colSpan: columnCount,
|
|
@@ -2558,7 +3598,7 @@ function DataTable({
|
|
|
2558
3598
|
)
|
|
2559
3599
|
}
|
|
2560
3600
|
)
|
|
2561
|
-
] }) : rows.map((row) => /* @__PURE__ */
|
|
3601
|
+
] }) : rows.map((row) => /* @__PURE__ */ jsx6(
|
|
2562
3602
|
RowSlot,
|
|
2563
3603
|
{
|
|
2564
3604
|
row,
|
|
@@ -2577,10 +3617,10 @@ function DataTable({
|
|
|
2577
3617
|
}
|
|
2578
3618
|
|
|
2579
3619
|
// src/components/ui/table/components/Table/Table.tsx
|
|
2580
|
-
import { useCallback as
|
|
3620
|
+
import { useCallback as useCallback5, useMemo as useMemo5, useState as useState5 } from "react";
|
|
2581
3621
|
|
|
2582
3622
|
// src/components/ui/table/components/Table/buildColumnDef.tsx
|
|
2583
|
-
import { jsx as
|
|
3623
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2584
3624
|
function SortableHeader({
|
|
2585
3625
|
label,
|
|
2586
3626
|
field,
|
|
@@ -2589,15 +3629,15 @@ function SortableHeader({
|
|
|
2589
3629
|
}) {
|
|
2590
3630
|
const isActive = sort?.field === field;
|
|
2591
3631
|
const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
|
|
2592
|
-
return /* @__PURE__ */
|
|
3632
|
+
return /* @__PURE__ */ jsxs6(
|
|
2593
3633
|
"button",
|
|
2594
3634
|
{
|
|
2595
3635
|
type: "button",
|
|
2596
3636
|
className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
|
|
2597
3637
|
onClick: () => onSort(field),
|
|
2598
3638
|
children: [
|
|
2599
|
-
/* @__PURE__ */
|
|
2600
|
-
/* @__PURE__ */
|
|
3639
|
+
/* @__PURE__ */ jsx7("span", { children: label }),
|
|
3640
|
+
/* @__PURE__ */ jsx7(Icon, { className: "sortable-header-icon" })
|
|
2601
3641
|
]
|
|
2602
3642
|
}
|
|
2603
3643
|
);
|
|
@@ -2630,7 +3670,7 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
2630
3670
|
...minWidth != null ? { minSize: minWidth } : {},
|
|
2631
3671
|
...maxWidth != null ? { maxSize: maxWidth } : {},
|
|
2632
3672
|
...resizable === false ? { enableResizing: false } : {},
|
|
2633
|
-
header: sortable ? () => /* @__PURE__ */
|
|
3673
|
+
header: sortable ? () => /* @__PURE__ */ jsx7(SortableHeader, { label: children, field, sort, onSort }) : (
|
|
2634
3674
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
2635
3675
|
() => children
|
|
2636
3676
|
),
|
|
@@ -2655,6 +3695,46 @@ function buildColumnDef(props, sort, onSort) {
|
|
|
2655
3695
|
}
|
|
2656
3696
|
};
|
|
2657
3697
|
}
|
|
3698
|
+
function resolveGroupId(props, index) {
|
|
3699
|
+
if (props.id) return props.id;
|
|
3700
|
+
if (typeof props.header === "string" || typeof props.header === "number") {
|
|
3701
|
+
return `group:${props.header}:${index}`;
|
|
3702
|
+
}
|
|
3703
|
+
return `group:${index}`;
|
|
3704
|
+
}
|
|
3705
|
+
function buildColumnDefsFromTree(nodes, sort, onSort) {
|
|
3706
|
+
return nodes.map((node, index) => {
|
|
3707
|
+
if (node.type === "leaf") {
|
|
3708
|
+
return buildColumnDef(node.props, sort, onSort);
|
|
3709
|
+
}
|
|
3710
|
+
const childDefs = buildColumnDefsFromTree(node.columns, sort, onSort);
|
|
3711
|
+
const { header, align, headerClassName } = node.props;
|
|
3712
|
+
return {
|
|
3713
|
+
id: resolveGroupId(node.props, index),
|
|
3714
|
+
header: (
|
|
3715
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
3716
|
+
() => header
|
|
3717
|
+
),
|
|
3718
|
+
columns: childDefs,
|
|
3719
|
+
enableResizing: false,
|
|
3720
|
+
meta: {
|
|
3721
|
+
align,
|
|
3722
|
+
headerClassName
|
|
3723
|
+
}
|
|
3724
|
+
};
|
|
3725
|
+
});
|
|
3726
|
+
}
|
|
3727
|
+
function countLeafColumns(nodes) {
|
|
3728
|
+
let count = 0;
|
|
3729
|
+
for (const node of nodes) {
|
|
3730
|
+
if (node.type === "leaf") {
|
|
3731
|
+
count += 1;
|
|
3732
|
+
} else {
|
|
3733
|
+
count += countLeafColumns(node.columns);
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
return count;
|
|
3737
|
+
}
|
|
2658
3738
|
|
|
2659
3739
|
// src/components/ui/table/components/Table/parseTableChildren.ts
|
|
2660
3740
|
import { Children, isValidElement as isValidElement2 } from "react";
|
|
@@ -2664,6 +3744,7 @@ import { isValidElement } from "react";
|
|
|
2664
3744
|
var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
|
|
2665
3745
|
var TABLE_BODY_DISPLAY_NAME = "Table.Body";
|
|
2666
3746
|
var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
|
|
3747
|
+
var TABLE_COLUMN_GROUP_DISPLAY_NAME = "Table.ColumnGroup";
|
|
2667
3748
|
var TABLE_PAGINATION_DISPLAY_NAME = "Table.Pagination";
|
|
2668
3749
|
function getComponentDisplayName(type) {
|
|
2669
3750
|
if (typeof type === "function" || typeof type === "object" && type !== null) {
|
|
@@ -2680,6 +3761,9 @@ function isTableBodyElement(child) {
|
|
|
2680
3761
|
function isTableColumnElement(child) {
|
|
2681
3762
|
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
|
|
2682
3763
|
}
|
|
3764
|
+
function isTableColumnGroupElement(child) {
|
|
3765
|
+
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
3766
|
+
}
|
|
2683
3767
|
function isTablePaginationElement(child) {
|
|
2684
3768
|
return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
|
|
2685
3769
|
}
|
|
@@ -2706,26 +3790,38 @@ function parseTableChildren(children) {
|
|
|
2706
3790
|
}
|
|
2707
3791
|
return slots;
|
|
2708
3792
|
}
|
|
2709
|
-
function
|
|
3793
|
+
function walkColumnTreeNodes(children) {
|
|
2710
3794
|
const result = [];
|
|
2711
3795
|
for (const child of Children.toArray(children)) {
|
|
2712
3796
|
if (isTableColumnElement(child)) {
|
|
2713
|
-
result.push(
|
|
3797
|
+
result.push({
|
|
3798
|
+
type: "leaf",
|
|
3799
|
+
props: child.props
|
|
3800
|
+
});
|
|
3801
|
+
continue;
|
|
3802
|
+
}
|
|
3803
|
+
if (isTableColumnGroupElement(child)) {
|
|
3804
|
+
const groupProps = child.props;
|
|
3805
|
+
result.push({
|
|
3806
|
+
type: "group",
|
|
3807
|
+
props: groupProps,
|
|
3808
|
+
columns: walkColumnTreeNodes(groupProps.children)
|
|
3809
|
+
});
|
|
2714
3810
|
continue;
|
|
2715
3811
|
}
|
|
2716
3812
|
if (isValidElement2(child)) {
|
|
2717
3813
|
const nested = child.props.children;
|
|
2718
3814
|
if (nested != null) {
|
|
2719
|
-
result.push(...
|
|
3815
|
+
result.push(...walkColumnTreeNodes(nested));
|
|
2720
3816
|
}
|
|
2721
3817
|
}
|
|
2722
3818
|
}
|
|
2723
3819
|
return result;
|
|
2724
3820
|
}
|
|
2725
|
-
function
|
|
3821
|
+
function extractColumnTree(header) {
|
|
2726
3822
|
if (!header) return [];
|
|
2727
3823
|
const { children } = header.props;
|
|
2728
|
-
return
|
|
3824
|
+
return walkColumnTreeNodes(children);
|
|
2729
3825
|
}
|
|
2730
3826
|
|
|
2731
3827
|
// src/components/ui/table/components/Table/TableBody.tsx
|
|
@@ -2741,6 +3837,13 @@ function TableColumn(props) {
|
|
|
2741
3837
|
}
|
|
2742
3838
|
TableColumn.displayName = TABLE_COLUMN_DISPLAY_NAME;
|
|
2743
3839
|
|
|
3840
|
+
// src/components/ui/table/components/Table/TableColumnGroup.tsx
|
|
3841
|
+
function TableColumnGroup(props) {
|
|
3842
|
+
void props;
|
|
3843
|
+
return null;
|
|
3844
|
+
}
|
|
3845
|
+
TableColumnGroup.displayName = TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
3846
|
+
|
|
2744
3847
|
// src/components/ui/table/components/Table/tableDataPipeline.ts
|
|
2745
3848
|
function sortTableData(data, sort) {
|
|
2746
3849
|
if (!sort) return data;
|
|
@@ -2778,7 +3881,7 @@ function TableHeader(props) {
|
|
|
2778
3881
|
TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
|
|
2779
3882
|
|
|
2780
3883
|
// src/components/ui/table/components/Table/TablePagination.tsx
|
|
2781
|
-
import { jsx as
|
|
3884
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2782
3885
|
function TablePagination({
|
|
2783
3886
|
page,
|
|
2784
3887
|
pageSize = 10,
|
|
@@ -2790,8 +3893,8 @@ function TablePagination({
|
|
|
2790
3893
|
const safePage = Math.min(Math.max(1, page), totalPages);
|
|
2791
3894
|
const canGoPrev = safePage > 1;
|
|
2792
3895
|
const canGoNext = safePage < totalPages;
|
|
2793
|
-
return /* @__PURE__ */
|
|
2794
|
-
/* @__PURE__ */
|
|
3896
|
+
return /* @__PURE__ */ jsxs7("div", { className: cn("TablePaginationJSX", className), children: [
|
|
3897
|
+
/* @__PURE__ */ jsx8(
|
|
2795
3898
|
"button",
|
|
2796
3899
|
{
|
|
2797
3900
|
type: "button",
|
|
@@ -2799,15 +3902,15 @@ function TablePagination({
|
|
|
2799
3902
|
disabled: !canGoPrev,
|
|
2800
3903
|
onClick: () => onChange(safePage - 1),
|
|
2801
3904
|
"aria-label": "Previous page",
|
|
2802
|
-
children: /* @__PURE__ */
|
|
3905
|
+
children: /* @__PURE__ */ jsx8(ChevronLeft, { className: "pagination-button-icon" })
|
|
2803
3906
|
}
|
|
2804
3907
|
),
|
|
2805
|
-
/* @__PURE__ */
|
|
3908
|
+
/* @__PURE__ */ jsxs7("span", { className: "pagination-label", children: [
|
|
2806
3909
|
safePage,
|
|
2807
3910
|
" / ",
|
|
2808
3911
|
totalPages
|
|
2809
3912
|
] }),
|
|
2810
|
-
/* @__PURE__ */
|
|
3913
|
+
/* @__PURE__ */ jsx8(
|
|
2811
3914
|
"button",
|
|
2812
3915
|
{
|
|
2813
3916
|
type: "button",
|
|
@@ -2815,7 +3918,7 @@ function TablePagination({
|
|
|
2815
3918
|
disabled: !canGoNext,
|
|
2816
3919
|
onClick: () => onChange(safePage + 1),
|
|
2817
3920
|
"aria-label": "Next page",
|
|
2818
|
-
children: /* @__PURE__ */
|
|
3921
|
+
children: /* @__PURE__ */ jsx8(ChevronRight, { className: "pagination-button-icon" })
|
|
2819
3922
|
}
|
|
2820
3923
|
)
|
|
2821
3924
|
] });
|
|
@@ -2823,7 +3926,7 @@ function TablePagination({
|
|
|
2823
3926
|
TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
|
|
2824
3927
|
|
|
2825
3928
|
// src/components/ui/table/components/Table/Table.tsx
|
|
2826
|
-
import { jsx as
|
|
3929
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2827
3930
|
function TableRoot({
|
|
2828
3931
|
data,
|
|
2829
3932
|
children,
|
|
@@ -2832,12 +3935,12 @@ function TableRoot({
|
|
|
2832
3935
|
filteredCount,
|
|
2833
3936
|
...dataTableProps
|
|
2834
3937
|
}) {
|
|
2835
|
-
const { header, pagination: paginationElement } =
|
|
3938
|
+
const { header, pagination: paginationElement } = useMemo5(
|
|
2836
3939
|
() => parseTableChildren(children),
|
|
2837
3940
|
[children]
|
|
2838
3941
|
);
|
|
2839
|
-
const [sort, setSort] =
|
|
2840
|
-
const handleSort =
|
|
3942
|
+
const [sort, setSort] = useState5(null);
|
|
3943
|
+
const handleSort = useCallback5((field) => {
|
|
2841
3944
|
setSort((previous) => {
|
|
2842
3945
|
if (previous?.field !== field) {
|
|
2843
3946
|
return { field, direction: "asc" };
|
|
@@ -2848,25 +3951,25 @@ function TableRoot({
|
|
|
2848
3951
|
return null;
|
|
2849
3952
|
});
|
|
2850
3953
|
}, []);
|
|
2851
|
-
const
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
3954
|
+
const columnTree = useMemo5(() => extractColumnTree(header), [header]);
|
|
3955
|
+
const columns = useMemo5(
|
|
3956
|
+
() => buildColumnDefsFromTree(columnTree, sort, handleSort),
|
|
3957
|
+
[columnTree, sort, handleSort]
|
|
3958
|
+
);
|
|
2856
3959
|
const paginationProps = paginationElement?.props;
|
|
2857
3960
|
const pageSize = paginationProps?.pageSize ?? 10;
|
|
2858
3961
|
const page = paginationProps?.page ?? 1;
|
|
2859
3962
|
const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
|
|
2860
|
-
const tableData =
|
|
3963
|
+
const tableData = useMemo5(() => {
|
|
2861
3964
|
const sortedData = sortTableData(data, sort);
|
|
2862
3965
|
if (!paginationProps) return sortedData;
|
|
2863
3966
|
return paginateTableData(sortedData, page, pageSize);
|
|
2864
3967
|
}, [data, sort, paginationProps, page, pageSize]);
|
|
2865
|
-
if (
|
|
3968
|
+
if (countLeafColumns(columnTree) === 0) {
|
|
2866
3969
|
console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
|
|
2867
3970
|
}
|
|
2868
|
-
return /* @__PURE__ */
|
|
2869
|
-
/* @__PURE__ */
|
|
3971
|
+
return /* @__PURE__ */ jsxs8("div", { className: "TableJSX", children: [
|
|
3972
|
+
/* @__PURE__ */ jsx9(
|
|
2870
3973
|
DataTable,
|
|
2871
3974
|
{
|
|
2872
3975
|
...dataTableProps,
|
|
@@ -2877,7 +3980,7 @@ function TableRoot({
|
|
|
2877
3980
|
className: cn(className, paginationProps && "DataTableJSX--with-pagination")
|
|
2878
3981
|
}
|
|
2879
3982
|
),
|
|
2880
|
-
paginationProps && /* @__PURE__ */
|
|
3983
|
+
paginationProps && /* @__PURE__ */ jsx9(
|
|
2881
3984
|
TablePagination,
|
|
2882
3985
|
{
|
|
2883
3986
|
page,
|
|
@@ -2895,13 +3998,19 @@ function createTable() {
|
|
|
2895
3998
|
return null;
|
|
2896
3999
|
}
|
|
2897
4000
|
Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
|
|
4001
|
+
function ColumnGroup(props) {
|
|
4002
|
+
void props;
|
|
4003
|
+
return null;
|
|
4004
|
+
}
|
|
4005
|
+
ColumnGroup.displayName = TABLE_COLUMN_GROUP_DISPLAY_NAME;
|
|
2898
4006
|
return Object.assign(
|
|
2899
4007
|
function BoundTable(props) {
|
|
2900
|
-
return /* @__PURE__ */
|
|
4008
|
+
return /* @__PURE__ */ jsx9(TableRoot, { ...props });
|
|
2901
4009
|
},
|
|
2902
4010
|
{
|
|
2903
4011
|
Header: TableHeader,
|
|
2904
4012
|
Column,
|
|
4013
|
+
ColumnGroup,
|
|
2905
4014
|
Body: TableBody,
|
|
2906
4015
|
Pagination: TablePagination
|
|
2907
4016
|
}
|
|
@@ -2910,6 +4019,7 @@ function createTable() {
|
|
|
2910
4019
|
var Table = Object.assign(TableRoot, {
|
|
2911
4020
|
Header: TableHeader,
|
|
2912
4021
|
Column: TableColumn,
|
|
4022
|
+
ColumnGroup: TableColumnGroup,
|
|
2913
4023
|
Body: TableBody,
|
|
2914
4024
|
Pagination: TablePagination
|
|
2915
4025
|
});
|
|
@@ -2921,20 +4031,31 @@ export {
|
|
|
2921
4031
|
DEFAULT_TREE_PARENT_ID_FIELD,
|
|
2922
4032
|
DEFAULT_TREE_QTY_FIELD,
|
|
2923
4033
|
DataTable,
|
|
4034
|
+
INLINE_SEARCH_MAX_RESULTS,
|
|
2924
4035
|
Table,
|
|
2925
4036
|
applyCellEdit,
|
|
2926
4037
|
applyFillData,
|
|
2927
4038
|
applySelectionUpdater,
|
|
2928
4039
|
buildColumnFreezeOffsets,
|
|
2929
4040
|
buildColumnRowSpanMap,
|
|
4041
|
+
buildFlatSearchCorpus,
|
|
2930
4042
|
buildRowsPastePayload,
|
|
4043
|
+
buildSearchMatchKey,
|
|
4044
|
+
buildSearchMatchKeys,
|
|
4045
|
+
buildTreeSearchCorpus,
|
|
2931
4046
|
canExpandRow,
|
|
4047
|
+
cellValueToSearchText,
|
|
4048
|
+
collectAncestorKeysToExpand,
|
|
2932
4049
|
collectCopyRowEntries,
|
|
2933
4050
|
collectCopyRows,
|
|
2934
4051
|
collectFillChanges,
|
|
2935
4052
|
collectRowSpanColumns,
|
|
4053
|
+
collectSearchMatchesInRange,
|
|
4054
|
+
createSearchRegex,
|
|
2936
4055
|
createTable,
|
|
4056
|
+
escapeSearchRegex,
|
|
2937
4057
|
flattenSubtreeRows,
|
|
4058
|
+
formatSearchResultLabel,
|
|
2938
4059
|
getCellEditDraftValue,
|
|
2939
4060
|
getCellSelectionEdgeStyle,
|
|
2940
4061
|
getColumnEditType,
|
|
@@ -2946,10 +4067,15 @@ export {
|
|
|
2946
4067
|
isCellInSelection,
|
|
2947
4068
|
isColumnEditable,
|
|
2948
4069
|
isEditablePasteTarget,
|
|
4070
|
+
mapSearchResultToVisibleItem,
|
|
4071
|
+
mapSearchResultsToVisibleKeys,
|
|
2949
4072
|
measureMergedSpanRowHeights,
|
|
4073
|
+
nextSearchIndex,
|
|
4074
|
+
nextSearchStride,
|
|
2950
4075
|
parseCellEditValue,
|
|
2951
4076
|
parseClipboardTSV,
|
|
2952
4077
|
parseClipboardTSVWithDepths,
|
|
4078
|
+
previousSearchIndex,
|
|
2953
4079
|
resolveColumnFreezeSide,
|
|
2954
4080
|
resolveDataTableLabels,
|
|
2955
4081
|
resolvePasteColumnIds,
|
|
@@ -2963,5 +4089,6 @@ export {
|
|
|
2963
4089
|
useCellSelection,
|
|
2964
4090
|
useConvertTreeData,
|
|
2965
4091
|
useGlideTable,
|
|
4092
|
+
useInlineSearch,
|
|
2966
4093
|
writeSelectionToClipboard
|
|
2967
4094
|
};
|