react-glide-table 1.0.2 → 1.1.1
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 +89 -470
- package/dist/index.cjs +1293 -841
- package/dist/index.d.cts +367 -31
- package/dist/index.d.ts +367 -31
- package/dist/index.js +1248 -818
- package/package.json +10 -4
- package/dist/style.css +0 -404
package/dist/index.cjs
CHANGED
|
@@ -20,20 +20,66 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
CELL_SELECTION_EDGES_CLASS: () => CELL_SELECTION_EDGES_CLASS,
|
|
24
|
+
DEFAULT_DATA_TABLE_LABELS: () => DEFAULT_DATA_TABLE_LABELS,
|
|
25
|
+
DEFAULT_TREE_CHILDREN_FIELD: () => DEFAULT_TREE_CHILDREN_FIELD,
|
|
26
|
+
DEFAULT_TREE_ID_FIELD: () => DEFAULT_TREE_ID_FIELD,
|
|
27
|
+
DEFAULT_TREE_PARENT_ID_FIELD: () => DEFAULT_TREE_PARENT_ID_FIELD,
|
|
28
|
+
DEFAULT_TREE_QTY_FIELD: () => DEFAULT_TREE_QTY_FIELD,
|
|
23
29
|
DataTable: () => DataTable,
|
|
24
30
|
Table: () => Table,
|
|
25
|
-
|
|
31
|
+
applyCellEdit: () => applyCellEdit,
|
|
32
|
+
applyFillData: () => applyFillData,
|
|
33
|
+
applySelectionUpdater: () => applySelectionUpdater,
|
|
34
|
+
buildColumnRowSpanMap: () => buildColumnRowSpanMap,
|
|
35
|
+
canExpandRow: () => canExpandRow,
|
|
36
|
+
collectFillChanges: () => collectFillChanges,
|
|
37
|
+
collectRowSpanColumns: () => collectRowSpanColumns,
|
|
38
|
+
createTable: () => createTable,
|
|
39
|
+
getCellEditDraftValue: () => getCellEditDraftValue,
|
|
40
|
+
getCellSelectionEdgeStyle: () => getCellSelectionEdgeStyle,
|
|
41
|
+
getColumnEditType: () => getColumnEditType,
|
|
42
|
+
getRowIndexInMergedCell: () => getRowIndexInMergedCell,
|
|
43
|
+
hasCellSelectionEdges: () => hasCellSelectionEdges,
|
|
44
|
+
isCellInSelection: () => isCellInSelection,
|
|
45
|
+
isColumnEditable: () => isColumnEditable,
|
|
46
|
+
parseCellEditValue: () => parseCellEditValue,
|
|
47
|
+
resolveDataTableLabels: () => resolveDataTableLabels,
|
|
48
|
+
resolveRowSelection: () => resolveRowSelection,
|
|
49
|
+
resolveRowSpanAt: () => resolveRowSpanAt,
|
|
50
|
+
toggleExpandedRowId: () => toggleExpandedRowId,
|
|
51
|
+
useCellEdit: () => useCellEdit,
|
|
52
|
+
useCellSelection: () => useCellSelection,
|
|
53
|
+
useConvertTreeData: () => useConvertTreeData,
|
|
54
|
+
useGlideTable: () => useGlideTable
|
|
26
55
|
});
|
|
27
56
|
module.exports = __toCommonJS(index_exports);
|
|
28
57
|
|
|
29
|
-
// src/
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
58
|
+
// src/core/labels.ts
|
|
59
|
+
var DEFAULT_DATA_TABLE_LABELS = {
|
|
60
|
+
empty: "No data",
|
|
61
|
+
loading: "Loading...",
|
|
62
|
+
selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
|
|
63
|
+
expandRow: "Expand row",
|
|
64
|
+
collapseRow: "Collapse row"
|
|
65
|
+
};
|
|
66
|
+
function resolveDataTableLabels(partial) {
|
|
67
|
+
return {
|
|
68
|
+
...DEFAULT_DATA_TABLE_LABELS,
|
|
69
|
+
...partial
|
|
70
|
+
};
|
|
71
|
+
}
|
|
33
72
|
|
|
34
|
-
// src/
|
|
73
|
+
// src/core/treeDefaults.ts
|
|
74
|
+
var DEFAULT_TREE_ID_FIELD = "id";
|
|
75
|
+
var DEFAULT_TREE_PARENT_ID_FIELD = "parentId";
|
|
76
|
+
var DEFAULT_TREE_CHILDREN_FIELD = "children";
|
|
77
|
+
var DEFAULT_TREE_QTY_FIELD = "qty";
|
|
78
|
+
|
|
79
|
+
// src/core/useGlideTable.ts
|
|
35
80
|
var import_react_table = require("@tanstack/react-table");
|
|
36
|
-
var
|
|
81
|
+
var import_react_virtual = require("@tanstack/react-virtual");
|
|
82
|
+
var import_react4 = require("react");
|
|
37
83
|
|
|
38
84
|
// src/components/ui/table/constants.ts
|
|
39
85
|
var CELL_ALIGN_CLASS = {
|
|
@@ -47,23 +93,8 @@ var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
|
|
|
47
93
|
var DATA_TABLE_ROW_HEIGHT = 44;
|
|
48
94
|
var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
|
|
49
95
|
|
|
50
|
-
// src/components/ui/table/
|
|
96
|
+
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
51
97
|
var import_react = require("react");
|
|
52
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
53
|
-
var DataTableContext = (0, import_react.createContext)(null);
|
|
54
|
-
function useDataTableRowContext() {
|
|
55
|
-
const context = (0, import_react.use)(DataTableContext);
|
|
56
|
-
if (!context) {
|
|
57
|
-
throw new Error("useDataTableRowContext must be used within a DataTableContextProvider");
|
|
58
|
-
}
|
|
59
|
-
return context;
|
|
60
|
-
}
|
|
61
|
-
function DataTableContextProvider({
|
|
62
|
-
value,
|
|
63
|
-
children
|
|
64
|
-
}) {
|
|
65
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataTableContext, { value, children });
|
|
66
|
-
}
|
|
67
98
|
|
|
68
99
|
// src/components/ui/table/features/cell-edit/cellEdit.ts
|
|
69
100
|
function getColumnAccessorKey(columnDef) {
|
|
@@ -111,6 +142,87 @@ function applyCellEdit(data, rows, rowIndex, colIndex, raw) {
|
|
|
111
142
|
return newData;
|
|
112
143
|
}
|
|
113
144
|
|
|
145
|
+
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
146
|
+
function useCellEdit({
|
|
147
|
+
data,
|
|
148
|
+
rows,
|
|
149
|
+
onDataChange,
|
|
150
|
+
onCellChange
|
|
151
|
+
}) {
|
|
152
|
+
const [editingCell, setEditingCell] = (0, import_react.useState)(null);
|
|
153
|
+
const [draftValue, setDraftValue] = (0, import_react.useState)("");
|
|
154
|
+
const draftValueRef = (0, import_react.useRef)(draftValue);
|
|
155
|
+
const editingCellRef = (0, import_react.useRef)(editingCell);
|
|
156
|
+
(0, import_react.useEffect)(() => {
|
|
157
|
+
draftValueRef.current = draftValue;
|
|
158
|
+
}, [draftValue]);
|
|
159
|
+
(0, import_react.useEffect)(() => {
|
|
160
|
+
editingCellRef.current = editingCell;
|
|
161
|
+
}, [editingCell]);
|
|
162
|
+
const cancelEdit = (0, import_react.useCallback)(() => {
|
|
163
|
+
setEditingCell(null);
|
|
164
|
+
setDraftValue("");
|
|
165
|
+
}, []);
|
|
166
|
+
const commitEdit = (0, import_react.useCallback)(
|
|
167
|
+
(raw) => {
|
|
168
|
+
const current = editingCellRef.current;
|
|
169
|
+
if (!current) return true;
|
|
170
|
+
if (!onCellChange && !onDataChange) {
|
|
171
|
+
cancelEdit();
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
const row = rows[current.rowIndex];
|
|
175
|
+
const cell = row?.getVisibleCells()[current.colIndex];
|
|
176
|
+
if (!row || !cell) {
|
|
177
|
+
cancelEdit();
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
const value = raw ?? draftValueRef.current;
|
|
181
|
+
if (!isColumnEditable(cell.column.columnDef)) {
|
|
182
|
+
cancelEdit();
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
const parsed = parseCellEditValue(value, getColumnEditType(cell.column.columnDef));
|
|
186
|
+
if (!parsed.ok) return false;
|
|
187
|
+
if (onCellChange) {
|
|
188
|
+
onCellChange(row.id, cell.column.id, parsed.value);
|
|
189
|
+
cancelEdit();
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
const next = applyCellEdit(data, rows, current.rowIndex, current.colIndex, value);
|
|
193
|
+
if (!next) return false;
|
|
194
|
+
onDataChange?.(next);
|
|
195
|
+
cancelEdit();
|
|
196
|
+
return true;
|
|
197
|
+
},
|
|
198
|
+
[cancelEdit, data, onCellChange, onDataChange, rows]
|
|
199
|
+
);
|
|
200
|
+
const startEdit = (0, import_react.useCallback)(
|
|
201
|
+
(rowIndex, colIndex) => {
|
|
202
|
+
const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
|
|
203
|
+
if (!cell || !isColumnEditable(cell.column.columnDef)) return;
|
|
204
|
+
const current = editingCellRef.current;
|
|
205
|
+
if (current && (current.rowIndex !== rowIndex || current.colIndex !== colIndex) && !commitEdit()) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
setEditingCell({ rowIndex, colIndex });
|
|
209
|
+
setDraftValue(getCellEditDraftValue(cell.getValue()));
|
|
210
|
+
},
|
|
211
|
+
[commitEdit, rows]
|
|
212
|
+
);
|
|
213
|
+
return {
|
|
214
|
+
editingCell,
|
|
215
|
+
draftValue,
|
|
216
|
+
setDraftValue,
|
|
217
|
+
startEdit,
|
|
218
|
+
commitEdit,
|
|
219
|
+
cancelEdit
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
224
|
+
var import_react2 = require("react");
|
|
225
|
+
|
|
114
226
|
// src/components/ui/table/features/cell-selection/cellSelection.ts
|
|
115
227
|
var INITIAL_DRAG_STATE = {
|
|
116
228
|
isSelecting: false,
|
|
@@ -134,7 +246,10 @@ function getRowIndexInMergedCell(clientY, cellElement, rowIndex, rowSpan) {
|
|
|
134
246
|
const rect = cellElement.getBoundingClientRect();
|
|
135
247
|
const relativeY = clientY - rect.top;
|
|
136
248
|
const rowHeight = rect.height / rowSpan;
|
|
137
|
-
const offset = Math.min(
|
|
249
|
+
const offset = Math.min(
|
|
250
|
+
Math.max(Math.floor(relativeY / rowHeight), 0),
|
|
251
|
+
rowSpan - 1
|
|
252
|
+
);
|
|
138
253
|
return rowIndex + offset;
|
|
139
254
|
}
|
|
140
255
|
function isCellInSelection(rowIndex, colIndex, bounds, rowSpan = 1) {
|
|
@@ -150,31 +265,348 @@ function getActiveSelectionBounds(dragState, selectionBounds) {
|
|
|
150
265
|
}
|
|
151
266
|
var SELECTION_EDGE_WIDTH_PX = 2;
|
|
152
267
|
var SELECTION_EDGE_COLOR = "var(--color-brand-primary)";
|
|
153
|
-
|
|
154
|
-
|
|
268
|
+
var CELL_SELECTION_EDGES_CLASS = "cell-selection-edges";
|
|
269
|
+
function getMergedCellStepEdges(rowIndex, colIndex, bounds, rowSpan, isVisuallySelectedAt) {
|
|
270
|
+
const cellEndRow = rowIndex + rowSpan - 1;
|
|
271
|
+
const span = cellEndRow - rowIndex + 1;
|
|
272
|
+
if (span <= 1) return [];
|
|
273
|
+
const edges = [];
|
|
274
|
+
const isNeighborSelected = (row, neighborCol) => {
|
|
275
|
+
if (isVisuallySelectedAt) {
|
|
276
|
+
return isVisuallySelectedAt(row, neighborCol);
|
|
277
|
+
}
|
|
278
|
+
return row >= bounds.startRow && row <= bounds.endRow && neighborCol >= bounds.startCol && neighborCol <= bounds.endCol;
|
|
279
|
+
};
|
|
280
|
+
const pushUnselectedRuns = (side, neighborCol, fromRow, toRowExclusive) => {
|
|
281
|
+
let runStart = null;
|
|
282
|
+
for (let row = fromRow; row < toRowExclusive; row++) {
|
|
283
|
+
if (!isNeighborSelected(row, neighborCol)) {
|
|
284
|
+
if (runStart === null) runStart = row;
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
if (runStart !== null) {
|
|
288
|
+
edges.push({
|
|
289
|
+
side,
|
|
290
|
+
offsetRatio: (runStart - rowIndex) / span,
|
|
291
|
+
heightRatio: (row - runStart) / span
|
|
292
|
+
});
|
|
293
|
+
runStart = null;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
if (runStart !== null) {
|
|
297
|
+
edges.push({
|
|
298
|
+
side,
|
|
299
|
+
offsetRatio: (runStart - rowIndex) / span,
|
|
300
|
+
heightRatio: (toRowExclusive - runStart) / span
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const collectSide = (side, neighborCol) => {
|
|
305
|
+
if (bounds.startRow > rowIndex) {
|
|
306
|
+
pushUnselectedRuns(
|
|
307
|
+
side,
|
|
308
|
+
neighborCol,
|
|
309
|
+
rowIndex,
|
|
310
|
+
Math.min(bounds.startRow, cellEndRow + 1)
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
if (bounds.endRow < cellEndRow) {
|
|
314
|
+
pushUnselectedRuns(
|
|
315
|
+
side,
|
|
316
|
+
neighborCol,
|
|
317
|
+
Math.max(bounds.endRow + 1, rowIndex),
|
|
318
|
+
cellEndRow + 1
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
if (colIndex < bounds.endCol) {
|
|
323
|
+
collectSide("right", colIndex + 1);
|
|
324
|
+
}
|
|
325
|
+
if (colIndex > bounds.startCol) {
|
|
326
|
+
collectSide("left", colIndex - 1);
|
|
327
|
+
}
|
|
328
|
+
return edges;
|
|
329
|
+
}
|
|
330
|
+
function buildPartialVerticalGradient(edge) {
|
|
331
|
+
const startPct = edge.offsetRatio * 100;
|
|
332
|
+
const endPct = (edge.offsetRatio + edge.heightRatio) * 100;
|
|
333
|
+
const overlapPx = SELECTION_EDGE_WIDTH_PX + 1;
|
|
334
|
+
const isTopProtrusion = edge.offsetRatio === 0 && edge.heightRatio < 1;
|
|
335
|
+
const isBottomProtrusion = edge.offsetRatio > 0;
|
|
336
|
+
const startStop = isBottomProtrusion ? `calc(${startPct}% - ${overlapPx}px)` : `${startPct}%`;
|
|
337
|
+
const endStop = isTopProtrusion ? `calc(${endPct}% + ${overlapPx}px)` : `${endPct}%`;
|
|
338
|
+
const xPos = edge.side === "left" ? "0" : "100%";
|
|
339
|
+
const layers = [
|
|
340
|
+
{
|
|
341
|
+
image: `linear-gradient(to bottom, transparent 0%, transparent ${startStop}, ${SELECTION_EDGE_COLOR} ${startStop}, ${SELECTION_EDGE_COLOR} ${endStop}, transparent ${endStop}, transparent 100%)`,
|
|
342
|
+
size: `${SELECTION_EDGE_WIDTH_PX}px 100%`,
|
|
343
|
+
position: `${xPos} 0`
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
if (isTopProtrusion || isBottomProtrusion) {
|
|
347
|
+
const capTop = isTopProtrusion ? `calc(${endPct}% - ${SELECTION_EDGE_WIDTH_PX}px)` : `calc(${startPct}% - ${SELECTION_EDGE_WIDTH_PX}px)`;
|
|
348
|
+
layers.push({
|
|
349
|
+
image: `linear-gradient(${SELECTION_EDGE_COLOR}, ${SELECTION_EDGE_COLOR})`,
|
|
350
|
+
size: `${SELECTION_EDGE_WIDTH_PX}px ${SELECTION_EDGE_WIDTH_PX}px`,
|
|
351
|
+
position: `${xPos} ${capTop}`
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return layers;
|
|
355
|
+
}
|
|
356
|
+
function getCellSelectionEdgeStyle(rowIndex, colIndex, bounds, rowSpan = 1, isVisuallySelectedAt) {
|
|
357
|
+
if (!isCellInSelection(rowIndex, colIndex, bounds, rowSpan) || !bounds)
|
|
358
|
+
return void 0;
|
|
155
359
|
const cellEndRow = rowIndex + rowSpan - 1;
|
|
156
360
|
const isTopEdge = bounds.startRow >= rowIndex && bounds.startRow <= cellEndRow;
|
|
157
361
|
const isBottomEdge = bounds.endRow >= rowIndex && bounds.endRow <= cellEndRow;
|
|
158
362
|
const isLeftEdge = colIndex === bounds.startCol;
|
|
159
363
|
const isRightEdge = colIndex === bounds.endCol;
|
|
364
|
+
const selectionContinuesBelow = cellEndRow < bounds.endRow;
|
|
160
365
|
const shadows = [];
|
|
161
366
|
if (isTopEdge) {
|
|
162
|
-
shadows.push(
|
|
367
|
+
shadows.push(
|
|
368
|
+
`inset 0 ${SELECTION_EDGE_WIDTH_PX}px 0 0 ${SELECTION_EDGE_COLOR}`
|
|
369
|
+
);
|
|
163
370
|
}
|
|
164
371
|
if (isBottomEdge) {
|
|
165
|
-
shadows.push(
|
|
372
|
+
shadows.push(
|
|
373
|
+
`inset 0 -${SELECTION_EDGE_WIDTH_PX}px 0 0 ${SELECTION_EDGE_COLOR}`
|
|
374
|
+
);
|
|
166
375
|
}
|
|
167
376
|
if (isLeftEdge) {
|
|
168
|
-
shadows.push(
|
|
377
|
+
shadows.push(
|
|
378
|
+
`inset ${SELECTION_EDGE_WIDTH_PX}px 0 0 0 ${SELECTION_EDGE_COLOR}`
|
|
379
|
+
);
|
|
169
380
|
}
|
|
170
381
|
if (isRightEdge) {
|
|
171
|
-
shadows.push(
|
|
382
|
+
shadows.push(
|
|
383
|
+
`inset -${SELECTION_EDGE_WIDTH_PX}px 0 0 0 ${SELECTION_EDGE_COLOR}`
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
const stepEdges = getMergedCellStepEdges(
|
|
387
|
+
rowIndex,
|
|
388
|
+
colIndex,
|
|
389
|
+
bounds,
|
|
390
|
+
rowSpan,
|
|
391
|
+
isVisuallySelectedAt
|
|
392
|
+
);
|
|
393
|
+
const gradients = [];
|
|
394
|
+
const sizes = [];
|
|
395
|
+
const positions = [];
|
|
396
|
+
for (const edge of stepEdges) {
|
|
397
|
+
for (const partial of buildPartialVerticalGradient(edge)) {
|
|
398
|
+
gradients.push(partial.image);
|
|
399
|
+
sizes.push(partial.size);
|
|
400
|
+
positions.push(partial.position);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (shadows.length === 0 && gradients.length === 0 && !selectionContinuesBelow) {
|
|
404
|
+
return void 0;
|
|
405
|
+
}
|
|
406
|
+
const style = {};
|
|
407
|
+
if (shadows.length > 0) {
|
|
408
|
+
style["--selection-edge-shadows"] = shadows.join(", ");
|
|
409
|
+
}
|
|
410
|
+
if (gradients.length > 0) {
|
|
411
|
+
style["--selection-edge-gradients"] = gradients.join(", ");
|
|
412
|
+
style["--selection-edge-sizes"] = sizes.join(", ");
|
|
413
|
+
style["--selection-edge-positions"] = positions.join(", ");
|
|
414
|
+
}
|
|
415
|
+
if (selectionContinuesBelow) {
|
|
416
|
+
style.borderBottomColor = "var(--color-brand-surface)";
|
|
417
|
+
}
|
|
418
|
+
return style;
|
|
419
|
+
}
|
|
420
|
+
function hasCellSelectionEdges(style) {
|
|
421
|
+
return Boolean(
|
|
422
|
+
style?.["--selection-edge-shadows"] || style?.["--selection-edge-gradients"]
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/components/ui/table/features/cell-selection/fillData.ts
|
|
427
|
+
function getColumnAccessorKey2(columnDef) {
|
|
428
|
+
if ("accessorKey" in columnDef && columnDef.accessorKey) {
|
|
429
|
+
return String(columnDef.accessorKey);
|
|
430
|
+
}
|
|
431
|
+
return columnDef.id;
|
|
432
|
+
}
|
|
433
|
+
function collectFillTargets(rows, sourceBounds, fillBounds) {
|
|
434
|
+
const targets = [];
|
|
435
|
+
const sourceHeight = sourceBounds.endRow - sourceBounds.startRow + 1;
|
|
436
|
+
const sourceWidth = sourceBounds.endCol - sourceBounds.startCol + 1;
|
|
437
|
+
for (let rowIndex = fillBounds.startRow; rowIndex <= fillBounds.endRow; rowIndex += 1) {
|
|
438
|
+
for (let colIndex = fillBounds.startCol; colIndex <= fillBounds.endCol; colIndex += 1) {
|
|
439
|
+
if (isCellInSelection(rowIndex, colIndex, sourceBounds)) continue;
|
|
440
|
+
const offsetRow = rowIndex - sourceBounds.startRow;
|
|
441
|
+
const offsetCol = colIndex - sourceBounds.startCol;
|
|
442
|
+
const sourceRowIndex = sourceBounds.startRow + (offsetRow % sourceHeight + sourceHeight) % sourceHeight;
|
|
443
|
+
const sourceColIndex = sourceBounds.startCol + (offsetCol % sourceWidth + sourceWidth) % sourceWidth;
|
|
444
|
+
const targetRow = rows[rowIndex];
|
|
445
|
+
const targetCell = targetRow?.getVisibleCells()[colIndex];
|
|
446
|
+
const sourceCell = rows[sourceRowIndex]?.getVisibleCells()[sourceColIndex];
|
|
447
|
+
if (!targetRow || !targetCell || !sourceCell) continue;
|
|
448
|
+
const accessorKey = getColumnAccessorKey2(
|
|
449
|
+
targetCell.column.columnDef
|
|
450
|
+
);
|
|
451
|
+
if (!accessorKey) continue;
|
|
452
|
+
targets.push({
|
|
453
|
+
rowIndex,
|
|
454
|
+
accessorKey,
|
|
455
|
+
columnId: targetCell.column.id,
|
|
456
|
+
value: sourceCell.getValue(),
|
|
457
|
+
rowId: targetRow.id
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
return targets;
|
|
462
|
+
}
|
|
463
|
+
function collectFillChanges(rows, sourceBounds, fillBounds) {
|
|
464
|
+
return collectFillTargets(rows, sourceBounds, fillBounds).map(
|
|
465
|
+
({ rowId, columnId, value }) => ({ rowId, columnId, value })
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
function applyFillData(data, rows, sourceBounds, fillBounds) {
|
|
469
|
+
const newData = data.map((row) => ({ ...row }));
|
|
470
|
+
const targets = collectFillTargets(rows, sourceBounds, fillBounds);
|
|
471
|
+
for (const target of targets) {
|
|
472
|
+
if (!newData[target.rowIndex]) continue;
|
|
473
|
+
newData[target.rowIndex][target.accessorKey] = target.value;
|
|
172
474
|
}
|
|
173
|
-
return
|
|
475
|
+
return newData;
|
|
476
|
+
}
|
|
477
|
+
function hasFillExtension(sourceBounds, fillBounds) {
|
|
478
|
+
if (!sourceBounds) return false;
|
|
479
|
+
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
483
|
+
function useCellSelection({
|
|
484
|
+
data,
|
|
485
|
+
rows,
|
|
486
|
+
enabled = true,
|
|
487
|
+
onDataChange,
|
|
488
|
+
onBatchChange
|
|
489
|
+
}) {
|
|
490
|
+
const [dragState, setDragState] = (0, import_react2.useState)(INITIAL_DRAG_STATE);
|
|
491
|
+
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
492
|
+
const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
|
|
493
|
+
const handleCellMouseDown = (0, import_react2.useCallback)(
|
|
494
|
+
(rowIndex, colIndex) => {
|
|
495
|
+
if (!enabled) return;
|
|
496
|
+
setDragState({
|
|
497
|
+
isSelecting: true,
|
|
498
|
+
isFillDragging: false,
|
|
499
|
+
start: { row: rowIndex, col: colIndex },
|
|
500
|
+
end: { row: rowIndex, col: colIndex },
|
|
501
|
+
fillAnchor: null,
|
|
502
|
+
fillEnd: null
|
|
503
|
+
});
|
|
504
|
+
},
|
|
505
|
+
[enabled]
|
|
506
|
+
);
|
|
507
|
+
const handleCellMouseEnter = (0, import_react2.useCallback)(
|
|
508
|
+
(rowIndex, colIndex) => {
|
|
509
|
+
if (!enabled) return;
|
|
510
|
+
setDragState((prev) => {
|
|
511
|
+
if (prev.isSelecting) {
|
|
512
|
+
return { ...prev, end: { row: rowIndex, col: colIndex } };
|
|
513
|
+
}
|
|
514
|
+
if (prev.isFillDragging) {
|
|
515
|
+
return { ...prev, fillEnd: { row: rowIndex, col: colIndex } };
|
|
516
|
+
}
|
|
517
|
+
return prev;
|
|
518
|
+
});
|
|
519
|
+
},
|
|
520
|
+
[enabled]
|
|
521
|
+
);
|
|
522
|
+
const handleFillHandleMouseDown = (0, import_react2.useCallback)(
|
|
523
|
+
(rowIndex, colIndex) => {
|
|
524
|
+
if (!enabled) return;
|
|
525
|
+
setDragState((prev) => {
|
|
526
|
+
const bounds = getCellSelectionBounds(prev.start, prev.end);
|
|
527
|
+
if (!bounds) return prev;
|
|
528
|
+
return {
|
|
529
|
+
...prev,
|
|
530
|
+
isSelecting: false,
|
|
531
|
+
isFillDragging: true,
|
|
532
|
+
fillAnchor: { row: bounds.startRow, col: bounds.startCol },
|
|
533
|
+
fillEnd: { row: rowIndex, col: colIndex }
|
|
534
|
+
};
|
|
535
|
+
});
|
|
536
|
+
},
|
|
537
|
+
[enabled]
|
|
538
|
+
);
|
|
539
|
+
(0, import_react2.useEffect)(() => {
|
|
540
|
+
if (!enabled) {
|
|
541
|
+
setDragState(INITIAL_DRAG_STATE);
|
|
542
|
+
}
|
|
543
|
+
}, [enabled]);
|
|
544
|
+
(0, import_react2.useEffect)(() => {
|
|
545
|
+
if (!enabled) return;
|
|
546
|
+
const handleKeyDown = (e) => {
|
|
547
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "c" && activeSelectionBounds) {
|
|
548
|
+
const { startRow, endRow, startCol, endCol } = activeSelectionBounds;
|
|
549
|
+
const selectedData = rows.slice(startRow, endRow + 1).map((row) => {
|
|
550
|
+
const cells = row.getVisibleCells();
|
|
551
|
+
return cells.slice(startCol, endCol + 1).map((cell) => cell.getValue()).join(" ");
|
|
552
|
+
}).join("\n");
|
|
553
|
+
navigator.clipboard.writeText(selectedData);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
557
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
558
|
+
}, [activeSelectionBounds, enabled, rows]);
|
|
559
|
+
(0, import_react2.useEffect)(() => {
|
|
560
|
+
if (!enabled) return;
|
|
561
|
+
const handleMouseUp = () => {
|
|
562
|
+
setDragState((prev) => {
|
|
563
|
+
if (prev.isFillDragging && prev.fillAnchor && prev.fillEnd) {
|
|
564
|
+
const sourceBounds = getCellSelectionBounds(prev.start, prev.end);
|
|
565
|
+
const newBounds = getCellSelectionBounds(prev.fillAnchor, prev.fillEnd);
|
|
566
|
+
if (newBounds) {
|
|
567
|
+
if (hasFillExtension(sourceBounds, newBounds) && sourceBounds) {
|
|
568
|
+
if (onBatchChange) {
|
|
569
|
+
const changes = collectFillChanges(rows, sourceBounds, newBounds);
|
|
570
|
+
if (changes.length > 0) {
|
|
571
|
+
onBatchChange(changes);
|
|
572
|
+
}
|
|
573
|
+
} else if (onDataChange) {
|
|
574
|
+
onDataChange(applyFillData(data, rows, sourceBounds, newBounds));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
isSelecting: false,
|
|
579
|
+
isFillDragging: false,
|
|
580
|
+
start: { row: newBounds.startRow, col: newBounds.startCol },
|
|
581
|
+
end: { row: newBounds.endRow, col: newBounds.endCol },
|
|
582
|
+
fillAnchor: null,
|
|
583
|
+
fillEnd: null
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (prev.isSelecting) {
|
|
588
|
+
return { ...prev, isSelecting: false };
|
|
589
|
+
}
|
|
590
|
+
if (prev.isFillDragging) {
|
|
591
|
+
return { ...prev, isFillDragging: false, fillAnchor: null, fillEnd: null };
|
|
592
|
+
}
|
|
593
|
+
return prev;
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
window.addEventListener("mouseup", handleMouseUp);
|
|
597
|
+
return () => window.removeEventListener("mouseup", handleMouseUp);
|
|
598
|
+
}, [data, enabled, onBatchChange, onDataChange, rows]);
|
|
599
|
+
return {
|
|
600
|
+
dragState: enabled ? dragState : INITIAL_DRAG_STATE,
|
|
601
|
+
activeSelectionBounds,
|
|
602
|
+
handleCellMouseDown,
|
|
603
|
+
handleCellMouseEnter,
|
|
604
|
+
handleFillHandleMouseDown
|
|
605
|
+
};
|
|
174
606
|
}
|
|
175
607
|
|
|
176
608
|
// src/components/ui/table/features/row-expand/row-expand.ts
|
|
177
|
-
var
|
|
609
|
+
var import_react3 = require("react");
|
|
178
610
|
function getFieldValue(row, key) {
|
|
179
611
|
return row[key];
|
|
180
612
|
}
|
|
@@ -195,20 +627,21 @@ function toggleExpandedRowId(rowId, previous) {
|
|
|
195
627
|
var useConvertTreeData = ({
|
|
196
628
|
data,
|
|
197
629
|
enabled = true,
|
|
198
|
-
toggleField =
|
|
199
|
-
childField =
|
|
200
|
-
flattenField =
|
|
630
|
+
toggleField = DEFAULT_TREE_ID_FIELD,
|
|
631
|
+
childField = DEFAULT_TREE_PARENT_ID_FIELD,
|
|
632
|
+
flattenField = DEFAULT_TREE_CHILDREN_FIELD,
|
|
633
|
+
qtyField = DEFAULT_TREE_QTY_FIELD,
|
|
201
634
|
preventExpand = false,
|
|
202
635
|
startIndex = 1,
|
|
203
636
|
expandedRows,
|
|
204
637
|
onExpandedRowsChange
|
|
205
638
|
}) => {
|
|
206
|
-
const onExpandedRowsChangeRef = (0,
|
|
207
|
-
const hasInitializedRef = (0,
|
|
208
|
-
(0,
|
|
639
|
+
const onExpandedRowsChangeRef = (0, import_react3.useRef)(onExpandedRowsChange);
|
|
640
|
+
const hasInitializedRef = (0, import_react3.useRef)(false);
|
|
641
|
+
(0, import_react3.useEffect)(() => {
|
|
209
642
|
onExpandedRowsChangeRef.current = onExpandedRowsChange;
|
|
210
643
|
}, [onExpandedRowsChange]);
|
|
211
|
-
(0,
|
|
644
|
+
(0, import_react3.useEffect)(() => {
|
|
212
645
|
if (!data || data.length === 0) {
|
|
213
646
|
hasInitializedRef.current = false;
|
|
214
647
|
return;
|
|
@@ -218,7 +651,7 @@ var useConvertTreeData = ({
|
|
|
218
651
|
onExpandedRowsChangeRef.current?.(new Set(ids));
|
|
219
652
|
hasInitializedRef.current = true;
|
|
220
653
|
}, [enabled, data, toggleField]);
|
|
221
|
-
const processedData = (0,
|
|
654
|
+
const processedData = (0, import_react3.useMemo)(() => {
|
|
222
655
|
if (!enabled || !data || data.length === 0) return [];
|
|
223
656
|
const flattenedData = [];
|
|
224
657
|
const flattenItems = (items) => {
|
|
@@ -292,7 +725,7 @@ var useConvertTreeData = ({
|
|
|
292
725
|
});
|
|
293
726
|
return rootItems;
|
|
294
727
|
}, [enabled, data, toggleField, childField, flattenField]);
|
|
295
|
-
const flattenTree = (0,
|
|
728
|
+
const flattenTree = (0, import_react3.useMemo)(() => {
|
|
296
729
|
if (!enabled) return [];
|
|
297
730
|
const flatten = (nodes, result = [], level = 0) => {
|
|
298
731
|
nodes.forEach((node, index) => {
|
|
@@ -318,19 +751,28 @@ var useConvertTreeData = ({
|
|
|
318
751
|
const parentItem = flattenedData.find(
|
|
319
752
|
(parent) => getFieldValue(parent, toggleField) === getFieldValue(item, childField)
|
|
320
753
|
);
|
|
321
|
-
const parentAmount = parentItem ? Number(getFieldValue(parentItem,
|
|
754
|
+
const parentAmount = parentItem ? Number(getFieldValue(parentItem, qtyField) ?? 1) : 1;
|
|
322
755
|
item.parentCount = parentAmount || 1;
|
|
323
756
|
} else {
|
|
324
757
|
item.parentCount = 1;
|
|
325
758
|
}
|
|
326
759
|
});
|
|
327
760
|
return flattenedData;
|
|
328
|
-
}, [
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
761
|
+
}, [
|
|
762
|
+
enabled,
|
|
763
|
+
processedData,
|
|
764
|
+
startIndex,
|
|
765
|
+
toggleField,
|
|
766
|
+
childField,
|
|
767
|
+
qtyField,
|
|
768
|
+
preventExpand,
|
|
769
|
+
expandedRows
|
|
770
|
+
]);
|
|
771
|
+
const sortedData = (0, import_react3.useMemo)(() => {
|
|
772
|
+
if (!enabled) {
|
|
773
|
+
return data ?? [];
|
|
774
|
+
}
|
|
775
|
+
return [...flattenTree].sort((a, b) => {
|
|
334
776
|
const aParts = String(a.treeNo ?? "").split("-").map(Number);
|
|
335
777
|
const bParts = String(b.treeNo ?? "").split("-").map(Number);
|
|
336
778
|
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
|
|
@@ -346,185 +788,599 @@ var useConvertTreeData = ({
|
|
|
346
788
|
return sortedData;
|
|
347
789
|
};
|
|
348
790
|
|
|
349
|
-
// src/components/ui/table/
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return
|
|
353
|
-
"svg",
|
|
354
|
-
{
|
|
355
|
-
className,
|
|
356
|
-
"aria-hidden": ariaHidden,
|
|
357
|
-
width: "16",
|
|
358
|
-
height: "16",
|
|
359
|
-
viewBox: "0 0 24 24",
|
|
360
|
-
fill: "none",
|
|
361
|
-
stroke: "currentColor",
|
|
362
|
-
strokeWidth: "2",
|
|
363
|
-
strokeLinecap: "round",
|
|
364
|
-
strokeLinejoin: "round",
|
|
365
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
366
|
-
}
|
|
367
|
-
);
|
|
791
|
+
// src/components/ui/table/features/row-selection/rowSelection.ts
|
|
792
|
+
function resolveRowSelection(mode, controlledSelection, internalSelection) {
|
|
793
|
+
if (mode === "none") return {};
|
|
794
|
+
return controlledSelection ?? internalSelection;
|
|
368
795
|
}
|
|
369
|
-
function
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
className,
|
|
374
|
-
"aria-hidden": ariaHidden,
|
|
375
|
-
width: "16",
|
|
376
|
-
height: "16",
|
|
377
|
-
viewBox: "0 0 24 24",
|
|
378
|
-
fill: "none",
|
|
379
|
-
stroke: "currentColor",
|
|
380
|
-
strokeWidth: "2",
|
|
381
|
-
strokeLinecap: "round",
|
|
382
|
-
strokeLinejoin: "round",
|
|
383
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" })
|
|
384
|
-
}
|
|
385
|
-
);
|
|
796
|
+
function normalizeSingleSelection(next) {
|
|
797
|
+
const selectedIds = Object.keys(next).filter((id) => next[id]);
|
|
798
|
+
if (selectedIds.length <= 1) return next;
|
|
799
|
+
return { [selectedIds[selectedIds.length - 1]]: true };
|
|
386
800
|
}
|
|
387
|
-
function
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
{
|
|
391
|
-
className,
|
|
392
|
-
"aria-hidden": ariaHidden,
|
|
393
|
-
width: "16",
|
|
394
|
-
height: "16",
|
|
395
|
-
viewBox: "0 0 24 24",
|
|
396
|
-
fill: "none",
|
|
397
|
-
stroke: "currentColor",
|
|
398
|
-
strokeWidth: "2",
|
|
399
|
-
strokeLinecap: "round",
|
|
400
|
-
strokeLinejoin: "round",
|
|
401
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" })
|
|
402
|
-
}
|
|
403
|
-
);
|
|
801
|
+
function applySelectionUpdater(mode, updater, previous) {
|
|
802
|
+
const next = typeof updater === "function" ? updater(previous) : updater;
|
|
803
|
+
return mode === "single" ? normalizeSingleSelection(next) : next;
|
|
404
804
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
className,
|
|
410
|
-
"aria-hidden": ariaHidden,
|
|
411
|
-
width: "16",
|
|
412
|
-
height: "16",
|
|
413
|
-
viewBox: "0 0 24 24",
|
|
414
|
-
fill: "none",
|
|
415
|
-
stroke: "currentColor",
|
|
416
|
-
strokeWidth: "2",
|
|
417
|
-
strokeLinecap: "round",
|
|
418
|
-
strokeLinejoin: "round",
|
|
419
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 18 6-6-6-6" })
|
|
420
|
-
}
|
|
421
|
-
);
|
|
805
|
+
|
|
806
|
+
// src/components/ui/table/features/row-span/rowSpan.ts
|
|
807
|
+
function getRowFieldValue(row, key) {
|
|
808
|
+
return row[key];
|
|
422
809
|
}
|
|
423
|
-
function
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
fill: "none",
|
|
433
|
-
stroke: "currentColor",
|
|
434
|
-
strokeWidth: "2",
|
|
435
|
-
strokeLinecap: "round",
|
|
436
|
-
strokeLinejoin: "round",
|
|
437
|
-
children: [
|
|
438
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" }),
|
|
439
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 21V9" })
|
|
440
|
-
]
|
|
810
|
+
function computeRowSpans(data, rowSpanKey) {
|
|
811
|
+
if (data.length === 0) return [];
|
|
812
|
+
const result = [];
|
|
813
|
+
for (let index = 0; index < data.length; index++) {
|
|
814
|
+
const currentValue = getRowFieldValue(data[index], rowSpanKey);
|
|
815
|
+
const previousValue = index > 0 ? getRowFieldValue(data[index - 1], rowSpanKey) : void 0;
|
|
816
|
+
if (index > 0 && currentValue === previousValue) {
|
|
817
|
+
result.push({ rowSpan: 0, isFirstInGroup: false });
|
|
818
|
+
continue;
|
|
441
819
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
"aria-hidden": ariaHidden,
|
|
450
|
-
width: "14",
|
|
451
|
-
height: "14",
|
|
452
|
-
viewBox: "0 0 24 24",
|
|
453
|
-
fill: "none",
|
|
454
|
-
stroke: "currentColor",
|
|
455
|
-
strokeWidth: "2",
|
|
456
|
-
strokeLinecap: "round",
|
|
457
|
-
strokeLinejoin: "round",
|
|
458
|
-
children: [
|
|
459
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }),
|
|
460
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 3v12" })
|
|
461
|
-
]
|
|
820
|
+
let span = 1;
|
|
821
|
+
for (let nextIndex = index + 1; nextIndex < data.length; nextIndex++) {
|
|
822
|
+
if (getRowFieldValue(data[nextIndex], rowSpanKey) === currentValue) {
|
|
823
|
+
span++;
|
|
824
|
+
} else {
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
462
827
|
}
|
|
463
|
-
|
|
828
|
+
result.push({ rowSpan: span, isFirstInGroup: true });
|
|
829
|
+
}
|
|
830
|
+
return result;
|
|
464
831
|
}
|
|
465
|
-
function
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
strokeLinecap: "round",
|
|
478
|
-
strokeLinejoin: "round",
|
|
479
|
-
children: [
|
|
480
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 16-4 4-4-4" }),
|
|
481
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 20V4" }),
|
|
482
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m3 8 4-4 4 4" }),
|
|
483
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 4v16" })
|
|
484
|
-
]
|
|
832
|
+
function resolveRowSpanAt(rowSpans, rowIndex) {
|
|
833
|
+
if (!rowSpans?.[rowIndex]) {
|
|
834
|
+
return { startRow: rowIndex, rowSpan: 1 };
|
|
835
|
+
}
|
|
836
|
+
const current = rowSpans[rowIndex];
|
|
837
|
+
if (current.rowSpan > 0) {
|
|
838
|
+
return { startRow: rowIndex, rowSpan: current.rowSpan };
|
|
839
|
+
}
|
|
840
|
+
for (let row = rowIndex - 1; row >= 0; row--) {
|
|
841
|
+
const info = rowSpans[row];
|
|
842
|
+
if (info && info.rowSpan > 0) {
|
|
843
|
+
return { startRow: row, rowSpan: info.rowSpan };
|
|
485
844
|
}
|
|
486
|
-
|
|
845
|
+
}
|
|
846
|
+
return { startRow: rowIndex, rowSpan: 1 };
|
|
487
847
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
848
|
+
function buildColumnRowSpanMap(data, columnKeys) {
|
|
849
|
+
const map = /* @__PURE__ */ new Map();
|
|
850
|
+
for (const { columnId, rowSpanKey } of columnKeys) {
|
|
851
|
+
map.set(columnId, computeRowSpans(data, rowSpanKey));
|
|
852
|
+
}
|
|
853
|
+
return map;
|
|
854
|
+
}
|
|
855
|
+
function collectRowSpanColumns(columns) {
|
|
856
|
+
const result = [];
|
|
857
|
+
const visit = (defs) => {
|
|
858
|
+
for (const columnDef of defs) {
|
|
859
|
+
if ("columns" in columnDef && columnDef.columns?.length) {
|
|
860
|
+
visit(columnDef.columns);
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
const columnId = columnDef.id ?? ("accessorKey" in columnDef && columnDef.accessorKey ? String(columnDef.accessorKey) : void 0);
|
|
864
|
+
if (!columnId || !columnDef.meta?.rowSpan) continue;
|
|
865
|
+
result.push({
|
|
866
|
+
columnId,
|
|
867
|
+
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
};
|
|
871
|
+
visit(columns);
|
|
872
|
+
return result;
|
|
492
873
|
}
|
|
493
874
|
|
|
494
|
-
// src/
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
875
|
+
// src/core/useGlideTable.ts
|
|
876
|
+
function useGlideTable(options) {
|
|
877
|
+
const {
|
|
878
|
+
data,
|
|
879
|
+
columns,
|
|
880
|
+
rowSelectionMode = "none",
|
|
881
|
+
rowSelection: controlledRowSelection,
|
|
882
|
+
onRowSelectionChange,
|
|
883
|
+
selectionLabel,
|
|
884
|
+
emptyText,
|
|
885
|
+
loadingText,
|
|
886
|
+
labels: labelsProp,
|
|
887
|
+
enableRowSpan = false,
|
|
888
|
+
getRowId,
|
|
889
|
+
onRowClick,
|
|
890
|
+
getRowClassName,
|
|
891
|
+
getRowCanSelect,
|
|
892
|
+
selectOnRowClick = true,
|
|
893
|
+
enableCellSelection = true,
|
|
894
|
+
onDataChange,
|
|
895
|
+
onCellChange,
|
|
896
|
+
onBatchChange,
|
|
897
|
+
preserveRowSelection = false,
|
|
898
|
+
toggleField,
|
|
899
|
+
childField,
|
|
900
|
+
flattenField,
|
|
901
|
+
qtyField,
|
|
902
|
+
expandedRows: controlledExpandedRows,
|
|
903
|
+
onExpandedRowsChange,
|
|
904
|
+
preventExpand = false,
|
|
905
|
+
enableVirtualization = true,
|
|
906
|
+
estimateRowHeight = DATA_TABLE_ROW_HEIGHT,
|
|
907
|
+
virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN
|
|
908
|
+
} = options;
|
|
909
|
+
const labels = (0, import_react4.useMemo)(() => {
|
|
910
|
+
const resolved = resolveDataTableLabels(labelsProp);
|
|
911
|
+
return {
|
|
912
|
+
...resolved,
|
|
913
|
+
empty: labelsProp?.empty ?? emptyText ?? resolved.empty,
|
|
914
|
+
loading: labelsProp?.loading ?? loadingText ?? resolved.loading,
|
|
915
|
+
selection: labelsProp?.selection ?? selectionLabel ?? resolved.selection
|
|
916
|
+
};
|
|
917
|
+
}, [labelsProp, emptyText, loadingText, selectionLabel]);
|
|
918
|
+
const enableExpand = Boolean(toggleField);
|
|
919
|
+
const [internalRowSelection, setInternalRowSelection] = (0, import_react4.useState)({});
|
|
920
|
+
const [internalExpandedRows, setInternalExpandedRows] = (0, import_react4.useState)(
|
|
921
|
+
() => /* @__PURE__ */ new Set()
|
|
500
922
|
);
|
|
501
|
-
|
|
502
|
-
const
|
|
503
|
-
|
|
923
|
+
const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react4.useState)(null);
|
|
924
|
+
const [hoveredGroupKey, setHoveredGroupKey] = (0, import_react4.useState)(null);
|
|
925
|
+
const scrollRef = (0, import_react4.useRef)(null);
|
|
926
|
+
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
927
|
+
(0, import_react4.useEffect)(() => {
|
|
928
|
+
if (enableVirtualization && enableRowSpan) {
|
|
929
|
+
console.warn(
|
|
930
|
+
"[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
|
|
931
|
+
);
|
|
932
|
+
}
|
|
933
|
+
}, [enableVirtualization, enableRowSpan]);
|
|
934
|
+
const rowSelection = resolveRowSelection(
|
|
935
|
+
rowSelectionMode,
|
|
936
|
+
controlledRowSelection,
|
|
937
|
+
internalRowSelection
|
|
504
938
|
);
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
const
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
939
|
+
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
940
|
+
const handleExpandedRowsChange = (0, import_react4.useCallback)(
|
|
941
|
+
(next) => {
|
|
942
|
+
if (onExpandedRowsChange) {
|
|
943
|
+
onExpandedRowsChange(next);
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
setInternalExpandedRows(next);
|
|
947
|
+
},
|
|
948
|
+
[onExpandedRowsChange]
|
|
949
|
+
);
|
|
950
|
+
const tableData = useConvertTreeData({
|
|
951
|
+
data,
|
|
952
|
+
enabled: enableExpand,
|
|
953
|
+
toggleField,
|
|
954
|
+
childField,
|
|
955
|
+
flattenField,
|
|
956
|
+
qtyField,
|
|
957
|
+
expandedRows,
|
|
958
|
+
onExpandedRowsChange: enableExpand ? handleExpandedRowsChange : void 0,
|
|
959
|
+
preventExpand
|
|
960
|
+
});
|
|
961
|
+
const table = (0, import_react_table.useReactTable)({
|
|
962
|
+
data: tableData,
|
|
963
|
+
columns,
|
|
964
|
+
state: {
|
|
965
|
+
rowSelection: rowSelectionMode === "none" ? {} : rowSelection
|
|
966
|
+
},
|
|
967
|
+
enableRowSelection: rowSelectionMode === "none" ? false : getRowCanSelect ? (row) => getRowCanSelect(row.original, row.index) : true,
|
|
968
|
+
enableMultiRowSelection: rowSelectionMode === "multi",
|
|
969
|
+
onRowSelectionChange: (updater) => {
|
|
970
|
+
if (onRowSelectionChange) {
|
|
971
|
+
onRowSelectionChange(
|
|
972
|
+
(previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
|
|
973
|
+
);
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
setInternalRowSelection(
|
|
977
|
+
(previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
|
|
978
|
+
);
|
|
979
|
+
},
|
|
980
|
+
getCoreRowModel: (0, import_react_table.getCoreRowModel)(),
|
|
981
|
+
getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
|
|
982
|
+
});
|
|
983
|
+
const rowSpanColumnKeys = (0, import_react4.useMemo)(() => {
|
|
984
|
+
if (!enableRowSpan) return [];
|
|
985
|
+
return collectRowSpanColumns(columns);
|
|
986
|
+
}, [enableRowSpan, columns]);
|
|
987
|
+
const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
|
|
988
|
+
const columnRowSpanMap = (0, import_react4.useMemo)(
|
|
989
|
+
() => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
|
|
990
|
+
[tableData, rowSpanColumnKeys]
|
|
991
|
+
);
|
|
992
|
+
const selectedRows = table.getSelectedRowModel().rows;
|
|
993
|
+
const selectedCount = selectedRows.length;
|
|
994
|
+
const rows = table.getRowModel().rows;
|
|
995
|
+
const columnCount = table.getAllLeafColumns().length || 1;
|
|
996
|
+
const rowVirtualizer = (0, import_react_virtual.useVirtualizer)({
|
|
997
|
+
count: shouldVirtualize ? rows.length : 0,
|
|
998
|
+
getScrollElement: () => scrollRef.current,
|
|
999
|
+
estimateSize: () => estimateRowHeight,
|
|
1000
|
+
overscan: virtualOverscan
|
|
1001
|
+
});
|
|
1002
|
+
const virtualRows = rowVirtualizer.getVirtualItems();
|
|
1003
|
+
const totalSize = rowVirtualizer.getTotalSize();
|
|
1004
|
+
const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
1005
|
+
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
|
|
1006
|
+
const selectedGroupKeys = (0, import_react4.useMemo)(() => {
|
|
1007
|
+
if (!enableRowSpan || !primaryRowSpanKey) return /* @__PURE__ */ new Set();
|
|
1008
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1009
|
+
for (const selectedRow of selectedRows) {
|
|
1010
|
+
const value = selectedRow.original[primaryRowSpanKey];
|
|
1011
|
+
if (value !== null && value !== void 0) keys.add(String(value));
|
|
1012
|
+
}
|
|
1013
|
+
return keys;
|
|
1014
|
+
}, [enableRowSpan, primaryRowSpanKey, selectedRows]);
|
|
1015
|
+
const {
|
|
1016
|
+
dragState,
|
|
1017
|
+
activeSelectionBounds,
|
|
1018
|
+
handleCellMouseDown,
|
|
1019
|
+
handleCellMouseEnter,
|
|
1020
|
+
handleFillHandleMouseDown
|
|
1021
|
+
} = useCellSelection({
|
|
1022
|
+
data: tableData,
|
|
1023
|
+
rows,
|
|
1024
|
+
enabled: enableCellSelection,
|
|
1025
|
+
onDataChange,
|
|
1026
|
+
onBatchChange
|
|
1027
|
+
});
|
|
1028
|
+
const {
|
|
1029
|
+
editingCell,
|
|
1030
|
+
draftValue,
|
|
1031
|
+
setDraftValue,
|
|
1032
|
+
startEdit,
|
|
1033
|
+
commitEdit,
|
|
1034
|
+
cancelEdit
|
|
1035
|
+
} = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
|
|
1036
|
+
const handleCellMouseDownWithCommit = (0, import_react4.useCallback)(
|
|
1037
|
+
(rowIndex, colIndex) => {
|
|
1038
|
+
const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
|
|
1039
|
+
if (editingCell && !isSameEditingCell && !commitEdit()) {
|
|
1040
|
+
return;
|
|
1041
|
+
}
|
|
1042
|
+
handleCellMouseDown(rowIndex, colIndex);
|
|
1043
|
+
},
|
|
1044
|
+
[commitEdit, editingCell, handleCellMouseDown]
|
|
1045
|
+
);
|
|
1046
|
+
const clearHover = (0, import_react4.useCallback)(() => {
|
|
1047
|
+
setHoveredRowIndex(null);
|
|
1048
|
+
setHoveredGroupKey(null);
|
|
1049
|
+
}, []);
|
|
1050
|
+
const handleRowHover = (0, import_react4.useCallback)(
|
|
1051
|
+
(rowIndex, rowData) => {
|
|
1052
|
+
setHoveredRowIndex(rowIndex);
|
|
1053
|
+
if (!primaryRowSpanKey) {
|
|
1054
|
+
setHoveredGroupKey(null);
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
const groupValue = rowData[primaryRowSpanKey];
|
|
1058
|
+
setHoveredGroupKey(
|
|
1059
|
+
groupValue === null || groupValue === void 0 ? null : String(groupValue)
|
|
1060
|
+
);
|
|
1061
|
+
},
|
|
1062
|
+
[primaryRowSpanKey]
|
|
1063
|
+
);
|
|
1064
|
+
const handleToggleSelect = (0, import_react4.useCallback)(
|
|
1065
|
+
(row) => {
|
|
1066
|
+
if (!row.getCanSelect()) return;
|
|
1067
|
+
if (preserveRowSelection && row.getIsSelected()) {
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
row.toggleSelected();
|
|
1071
|
+
},
|
|
1072
|
+
[preserveRowSelection]
|
|
1073
|
+
);
|
|
1074
|
+
const handleToggleExpand = (0, import_react4.useCallback)(
|
|
1075
|
+
(rowKey) => {
|
|
1076
|
+
if (preventExpand) return;
|
|
1077
|
+
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
1078
|
+
},
|
|
1079
|
+
[preventExpand, handleExpandedRowsChange, expandedRows]
|
|
1080
|
+
);
|
|
1081
|
+
const rowContextValue = (0, import_react4.useMemo)(() => {
|
|
1082
|
+
return {
|
|
1083
|
+
rowSpan: {
|
|
1084
|
+
enableRowSpan,
|
|
1085
|
+
primaryRowSpanKey,
|
|
1086
|
+
columnRowSpanMap,
|
|
1087
|
+
hoveredRowIndex,
|
|
1088
|
+
hoveredGroupKey,
|
|
1089
|
+
selectedGroupKeys,
|
|
1090
|
+
onRowHover: handleRowHover
|
|
1091
|
+
},
|
|
1092
|
+
selection: {
|
|
1093
|
+
rowSelectionMode,
|
|
1094
|
+
selectOnRowClick,
|
|
1095
|
+
onRowClick,
|
|
1096
|
+
getRowClassName
|
|
1097
|
+
},
|
|
1098
|
+
cellSelection: {
|
|
1099
|
+
enableCellSelection,
|
|
1100
|
+
activeSelectionBounds,
|
|
1101
|
+
dragState,
|
|
1102
|
+
onCellMouseDown: handleCellMouseDownWithCommit,
|
|
1103
|
+
onCellMouseEnter: handleCellMouseEnter,
|
|
1104
|
+
onFillHandleMouseDown: handleFillHandleMouseDown
|
|
1105
|
+
},
|
|
1106
|
+
cellEdit: {
|
|
1107
|
+
editingCell,
|
|
1108
|
+
draftValue,
|
|
1109
|
+
onDraftValueChange: setDraftValue,
|
|
1110
|
+
onStartEdit: startEdit,
|
|
1111
|
+
onCommitEdit: commitEdit,
|
|
1112
|
+
onCancelEdit: cancelEdit
|
|
1113
|
+
},
|
|
1114
|
+
expand: {
|
|
1115
|
+
enableExpand,
|
|
1116
|
+
toggleField,
|
|
1117
|
+
expandedRows,
|
|
1118
|
+
preventExpand,
|
|
1119
|
+
onToggleExpand: handleToggleExpand,
|
|
1120
|
+
expandRowLabel: labels.expandRow,
|
|
1121
|
+
collapseRowLabel: labels.collapseRow
|
|
1122
|
+
}
|
|
1123
|
+
};
|
|
1124
|
+
}, [
|
|
1125
|
+
enableRowSpan,
|
|
1126
|
+
primaryRowSpanKey,
|
|
1127
|
+
columnRowSpanMap,
|
|
1128
|
+
hoveredRowIndex,
|
|
1129
|
+
hoveredGroupKey,
|
|
1130
|
+
selectedGroupKeys,
|
|
1131
|
+
handleRowHover,
|
|
1132
|
+
rowSelectionMode,
|
|
1133
|
+
selectOnRowClick,
|
|
1134
|
+
onRowClick,
|
|
1135
|
+
getRowClassName,
|
|
1136
|
+
enableCellSelection,
|
|
1137
|
+
activeSelectionBounds,
|
|
1138
|
+
dragState,
|
|
1139
|
+
handleCellMouseDownWithCommit,
|
|
1140
|
+
handleCellMouseEnter,
|
|
1141
|
+
handleFillHandleMouseDown,
|
|
1142
|
+
editingCell,
|
|
1143
|
+
draftValue,
|
|
1144
|
+
setDraftValue,
|
|
1145
|
+
startEdit,
|
|
1146
|
+
commitEdit,
|
|
1147
|
+
cancelEdit,
|
|
1148
|
+
enableExpand,
|
|
1149
|
+
toggleField,
|
|
1150
|
+
expandedRows,
|
|
1151
|
+
preventExpand,
|
|
1152
|
+
handleToggleExpand,
|
|
1153
|
+
labels.expandRow,
|
|
1154
|
+
labels.collapseRow
|
|
1155
|
+
]);
|
|
1156
|
+
return {
|
|
1157
|
+
table,
|
|
1158
|
+
tableData,
|
|
1159
|
+
rows,
|
|
1160
|
+
columnCount,
|
|
1161
|
+
selectedCount,
|
|
1162
|
+
labels,
|
|
1163
|
+
emptyText: labels.empty,
|
|
1164
|
+
loadingText: labels.loading,
|
|
1165
|
+
selectionLabel: labels.selection,
|
|
1166
|
+
enableCellSelection,
|
|
1167
|
+
shouldVirtualize,
|
|
1168
|
+
scrollRef,
|
|
1169
|
+
rowVirtualizer,
|
|
1170
|
+
virtualRows,
|
|
1171
|
+
paddingTop,
|
|
1172
|
+
paddingBottom,
|
|
1173
|
+
rowContextValue,
|
|
1174
|
+
handleToggleSelect,
|
|
1175
|
+
clearHover
|
|
1176
|
+
};
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
1180
|
+
var import_react_table3 = require("@tanstack/react-table");
|
|
1181
|
+
|
|
1182
|
+
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
1183
|
+
var import_react_table2 = require("@tanstack/react-table");
|
|
1184
|
+
var import_react6 = require("react");
|
|
1185
|
+
|
|
1186
|
+
// src/components/ui/table/DataTableContext.tsx
|
|
1187
|
+
var import_react5 = require("react");
|
|
1188
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
1189
|
+
var DataTableContext = (0, import_react5.createContext)(null);
|
|
1190
|
+
function useDataTableRowContext() {
|
|
1191
|
+
const context = (0, import_react5.use)(DataTableContext);
|
|
1192
|
+
if (!context) {
|
|
1193
|
+
throw new Error("useDataTableRowContext must be used within a DataTableContextProvider");
|
|
1194
|
+
}
|
|
1195
|
+
return context;
|
|
1196
|
+
}
|
|
1197
|
+
function DataTableContextProvider({
|
|
1198
|
+
value,
|
|
1199
|
+
children
|
|
1200
|
+
}) {
|
|
1201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataTableContext, { value, children });
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// src/components/ui/table/components/icons.tsx
|
|
1205
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1206
|
+
function ChevronDown({ className, "aria-hidden": ariaHidden = true }) {
|
|
1207
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1208
|
+
"svg",
|
|
1209
|
+
{
|
|
1210
|
+
className,
|
|
1211
|
+
"aria-hidden": ariaHidden,
|
|
1212
|
+
width: "16",
|
|
1213
|
+
height: "16",
|
|
1214
|
+
viewBox: "0 0 24 24",
|
|
1215
|
+
fill: "none",
|
|
1216
|
+
stroke: "currentColor",
|
|
1217
|
+
strokeWidth: "2",
|
|
1218
|
+
strokeLinecap: "round",
|
|
1219
|
+
strokeLinejoin: "round",
|
|
1220
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" })
|
|
1221
|
+
}
|
|
1222
|
+
);
|
|
1223
|
+
}
|
|
1224
|
+
function ChevronUp({ className, "aria-hidden": ariaHidden = true }) {
|
|
1225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1226
|
+
"svg",
|
|
1227
|
+
{
|
|
1228
|
+
className,
|
|
1229
|
+
"aria-hidden": ariaHidden,
|
|
1230
|
+
width: "16",
|
|
1231
|
+
height: "16",
|
|
1232
|
+
viewBox: "0 0 24 24",
|
|
1233
|
+
fill: "none",
|
|
1234
|
+
stroke: "currentColor",
|
|
1235
|
+
strokeWidth: "2",
|
|
1236
|
+
strokeLinecap: "round",
|
|
1237
|
+
strokeLinejoin: "round",
|
|
1238
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" })
|
|
1239
|
+
}
|
|
1240
|
+
);
|
|
1241
|
+
}
|
|
1242
|
+
function ChevronLeft({ className, "aria-hidden": ariaHidden = true }) {
|
|
1243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1244
|
+
"svg",
|
|
1245
|
+
{
|
|
1246
|
+
className,
|
|
1247
|
+
"aria-hidden": ariaHidden,
|
|
1248
|
+
width: "16",
|
|
1249
|
+
height: "16",
|
|
1250
|
+
viewBox: "0 0 24 24",
|
|
1251
|
+
fill: "none",
|
|
1252
|
+
stroke: "currentColor",
|
|
1253
|
+
strokeWidth: "2",
|
|
1254
|
+
strokeLinecap: "round",
|
|
1255
|
+
strokeLinejoin: "round",
|
|
1256
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" })
|
|
1257
|
+
}
|
|
1258
|
+
);
|
|
1259
|
+
}
|
|
1260
|
+
function ChevronRight({ className, "aria-hidden": ariaHidden = true }) {
|
|
1261
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1262
|
+
"svg",
|
|
1263
|
+
{
|
|
1264
|
+
className,
|
|
1265
|
+
"aria-hidden": ariaHidden,
|
|
1266
|
+
width: "16",
|
|
1267
|
+
height: "16",
|
|
1268
|
+
viewBox: "0 0 24 24",
|
|
1269
|
+
fill: "none",
|
|
1270
|
+
stroke: "currentColor",
|
|
1271
|
+
strokeWidth: "2",
|
|
1272
|
+
strokeLinecap: "round",
|
|
1273
|
+
strokeLinejoin: "round",
|
|
1274
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 18 6-6-6-6" })
|
|
1275
|
+
}
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
function ArrowUp({ className, "aria-hidden": ariaHidden = true }) {
|
|
1279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1280
|
+
"svg",
|
|
1281
|
+
{
|
|
1282
|
+
className,
|
|
1283
|
+
"aria-hidden": ariaHidden,
|
|
1284
|
+
width: "14",
|
|
1285
|
+
height: "14",
|
|
1286
|
+
viewBox: "0 0 24 24",
|
|
1287
|
+
fill: "none",
|
|
1288
|
+
stroke: "currentColor",
|
|
1289
|
+
strokeWidth: "2",
|
|
1290
|
+
strokeLinecap: "round",
|
|
1291
|
+
strokeLinejoin: "round",
|
|
1292
|
+
children: [
|
|
1293
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" }),
|
|
1294
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 21V9" })
|
|
1295
|
+
]
|
|
1296
|
+
}
|
|
1297
|
+
);
|
|
1298
|
+
}
|
|
1299
|
+
function ArrowDown({ className, "aria-hidden": ariaHidden = true }) {
|
|
1300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1301
|
+
"svg",
|
|
1302
|
+
{
|
|
1303
|
+
className,
|
|
1304
|
+
"aria-hidden": ariaHidden,
|
|
1305
|
+
width: "14",
|
|
1306
|
+
height: "14",
|
|
1307
|
+
viewBox: "0 0 24 24",
|
|
1308
|
+
fill: "none",
|
|
1309
|
+
stroke: "currentColor",
|
|
1310
|
+
strokeWidth: "2",
|
|
1311
|
+
strokeLinecap: "round",
|
|
1312
|
+
strokeLinejoin: "round",
|
|
1313
|
+
children: [
|
|
1314
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }),
|
|
1315
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 3v12" })
|
|
1316
|
+
]
|
|
1317
|
+
}
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
function ArrowUpDown({ className, "aria-hidden": ariaHidden = true }) {
|
|
1321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1322
|
+
"svg",
|
|
1323
|
+
{
|
|
1324
|
+
className,
|
|
1325
|
+
"aria-hidden": ariaHidden,
|
|
1326
|
+
width: "14",
|
|
1327
|
+
height: "14",
|
|
1328
|
+
viewBox: "0 0 24 24",
|
|
1329
|
+
fill: "none",
|
|
1330
|
+
stroke: "currentColor",
|
|
1331
|
+
strokeWidth: "2",
|
|
1332
|
+
strokeLinecap: "round",
|
|
1333
|
+
strokeLinejoin: "round",
|
|
1334
|
+
children: [
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 16-4 4-4-4" }),
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 20V4" }),
|
|
1337
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m3 8 4-4 4 4" }),
|
|
1338
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 4v16" })
|
|
1339
|
+
]
|
|
1340
|
+
}
|
|
1341
|
+
);
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// src/lib/cn.ts
|
|
1345
|
+
function cn(...inputs) {
|
|
1346
|
+
return inputs.filter(Boolean).join(" ");
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
// src/components/ui/table/components/DataTable/DataTableRow.tsx
|
|
1350
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1351
|
+
function resolveExpandCellIndex(cells, toggleField) {
|
|
1352
|
+
if (!toggleField) return 0;
|
|
1353
|
+
const matchedIndex = cells.findIndex(
|
|
1354
|
+
(cell) => cell.column.id === toggleField
|
|
1355
|
+
);
|
|
1356
|
+
if (matchedIndex >= 0) return matchedIndex;
|
|
1357
|
+
const noColumnIndex = cells.findIndex(
|
|
1358
|
+
(cell) => cell.column.id === "no" || cell.column.id === "treeNo"
|
|
1359
|
+
);
|
|
1360
|
+
if (noColumnIndex >= 0 && noColumnIndex + 1 < cells.length) {
|
|
1361
|
+
return noColumnIndex + 1;
|
|
1362
|
+
}
|
|
1363
|
+
return 0;
|
|
1364
|
+
}
|
|
1365
|
+
function DataTableRow({
|
|
1366
|
+
row,
|
|
1367
|
+
onToggleSelect,
|
|
1368
|
+
virtualIndex,
|
|
1369
|
+
measureElement
|
|
1370
|
+
}) {
|
|
1371
|
+
const { rowSpan, selection, cellSelection, cellEdit, expand } = useDataTableRowContext();
|
|
1372
|
+
const {
|
|
1373
|
+
enableRowSpan,
|
|
1374
|
+
primaryRowSpanKey,
|
|
1375
|
+
columnRowSpanMap,
|
|
1376
|
+
hoveredRowIndex,
|
|
1377
|
+
hoveredGroupKey,
|
|
1378
|
+
selectedGroupKeys,
|
|
1379
|
+
onRowHover
|
|
525
1380
|
} = rowSpan;
|
|
526
1381
|
const { rowSelectionMode, selectOnRowClick, onRowClick, getRowClassName } = selection;
|
|
527
1382
|
const {
|
|
1383
|
+
enableCellSelection,
|
|
528
1384
|
activeSelectionBounds,
|
|
529
1385
|
dragState,
|
|
530
1386
|
onCellMouseDown,
|
|
@@ -544,7 +1400,9 @@ function DataTableRow({
|
|
|
544
1400
|
toggleField,
|
|
545
1401
|
expandedRows,
|
|
546
1402
|
preventExpand,
|
|
547
|
-
onToggleExpand
|
|
1403
|
+
onToggleExpand,
|
|
1404
|
+
expandRowLabel,
|
|
1405
|
+
collapseRowLabel
|
|
548
1406
|
} = expand;
|
|
549
1407
|
const rowIndex = row.index;
|
|
550
1408
|
const rowData = row.original;
|
|
@@ -554,14 +1412,31 @@ function DataTableRow({
|
|
|
554
1412
|
const isGroupHovered = enableRowSpan && hoveredGroupKey !== null && rowGroupKey === hoveredGroupKey;
|
|
555
1413
|
const isGroupSelected = enableRowSpan && rowGroupKey !== null && selectedGroupKeys.has(rowGroupKey);
|
|
556
1414
|
const visibleCells = row.getVisibleCells();
|
|
1415
|
+
const columnIdsByIndex = visibleCells.map((cell) => cell.column.id);
|
|
1416
|
+
const isVisuallySelectedAt = activeSelectionBounds ? (targetRow, targetCol) => {
|
|
1417
|
+
if (targetCol < activeSelectionBounds.startCol || targetCol > activeSelectionBounds.endCol) {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
const columnId = columnIdsByIndex[targetCol];
|
|
1421
|
+
const { startRow, rowSpan: span } = resolveRowSpanAt(
|
|
1422
|
+
columnId ? columnRowSpanMap.get(columnId) : void 0,
|
|
1423
|
+
targetRow
|
|
1424
|
+
);
|
|
1425
|
+
return isCellInSelection(
|
|
1426
|
+
startRow,
|
|
1427
|
+
targetCol,
|
|
1428
|
+
activeSelectionBounds,
|
|
1429
|
+
span
|
|
1430
|
+
);
|
|
1431
|
+
} : void 0;
|
|
557
1432
|
const expandCellIndex = enableExpand ? resolveExpandCellIndex(visibleCells, toggleField) : -1;
|
|
558
1433
|
const canExpand = enableExpand && !preventExpand && canExpandRow(rowData);
|
|
559
1434
|
const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
|
|
560
1435
|
const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
|
|
561
1436
|
const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
|
|
562
|
-
const editInputRef = (0,
|
|
1437
|
+
const editInputRef = (0, import_react6.useRef)(null);
|
|
563
1438
|
const isRowEditing = editingCell?.rowIndex === rowIndex;
|
|
564
|
-
(0,
|
|
1439
|
+
(0, import_react6.useEffect)(() => {
|
|
565
1440
|
if (!isRowEditing) return;
|
|
566
1441
|
editInputRef.current?.focus();
|
|
567
1442
|
editInputRef.current?.select();
|
|
@@ -607,6 +1482,11 @@ function DataTableRow({
|
|
|
607
1482
|
const showCellHover = isRowSpanColumn ? isGroupHovered : isRowHovered;
|
|
608
1483
|
const showCellSelected = isRowSpanColumn ? isGroupSelected : isRowSelected;
|
|
609
1484
|
const cellRowSpan = rowSpanInfo?.rowSpan ?? 1;
|
|
1485
|
+
const isMerged = cellRowSpan > 1;
|
|
1486
|
+
const showMergedRightEdge = isMerged && (cellIndex === visibleCells.length - 1 || resolveRowSpanAt(
|
|
1487
|
+
columnRowSpanMap.get(columnIdsByIndex[cellIndex + 1]),
|
|
1488
|
+
rowIndex
|
|
1489
|
+
).rowSpan <= 1);
|
|
610
1490
|
const isCellDragSelected = isCellInSelection(
|
|
611
1491
|
rowIndex,
|
|
612
1492
|
cellIndex,
|
|
@@ -614,6 +1494,13 @@ function DataTableRow({
|
|
|
614
1494
|
cellRowSpan
|
|
615
1495
|
);
|
|
616
1496
|
const isBottomRightCell = !isEditing && activeSelectionBounds && !dragState.isSelecting && activeSelectionBounds.endRow >= rowIndex && activeSelectionBounds.endRow <= rowIndex + cellRowSpan - 1 && cellIndex === activeSelectionBounds.endCol;
|
|
1497
|
+
const selectionEdgeStyle = getCellSelectionEdgeStyle(
|
|
1498
|
+
rowIndex,
|
|
1499
|
+
cellIndex,
|
|
1500
|
+
activeSelectionBounds,
|
|
1501
|
+
cellRowSpan,
|
|
1502
|
+
isVisuallySelectedAt
|
|
1503
|
+
);
|
|
617
1504
|
const resolveCellRowIndex = (clientY, element) => getRowIndexInMergedCell(clientY, element, rowIndex, cellRowSpan);
|
|
618
1505
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
619
1506
|
"td",
|
|
@@ -624,17 +1511,22 @@ function DataTableRow({
|
|
|
624
1511
|
event.stopPropagation();
|
|
625
1512
|
return;
|
|
626
1513
|
}
|
|
1514
|
+
if (!enableCellSelection) return;
|
|
627
1515
|
event.preventDefault();
|
|
628
1516
|
onCellMouseDown(
|
|
629
1517
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
630
1518
|
cellIndex
|
|
631
1519
|
);
|
|
632
1520
|
},
|
|
633
|
-
onMouseEnter: (event) =>
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
1521
|
+
onMouseEnter: (event) => {
|
|
1522
|
+
if (!enableCellSelection) return;
|
|
1523
|
+
onCellMouseEnter(
|
|
1524
|
+
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
1525
|
+
cellIndex
|
|
1526
|
+
);
|
|
1527
|
+
},
|
|
637
1528
|
onMouseMove: (event) => {
|
|
1529
|
+
if (!enableCellSelection) return;
|
|
638
1530
|
if (!dragState.isSelecting && !dragState.isFillDragging) return;
|
|
639
1531
|
onCellMouseEnter(
|
|
640
1532
|
resolveCellRowIndex(event.clientY, event.currentTarget),
|
|
@@ -647,19 +1539,17 @@ function DataTableRow({
|
|
|
647
1539
|
event.stopPropagation();
|
|
648
1540
|
onStartEdit(rowIndex, cellIndex);
|
|
649
1541
|
},
|
|
650
|
-
style:
|
|
651
|
-
rowIndex,
|
|
652
|
-
cellIndex,
|
|
653
|
-
activeSelectionBounds,
|
|
654
|
-
cellRowSpan
|
|
655
|
-
),
|
|
1542
|
+
style: selectionEdgeStyle,
|
|
656
1543
|
className: cn(
|
|
657
1544
|
"data-table-cell",
|
|
658
1545
|
CELL_ALIGN_CLASS[align],
|
|
659
1546
|
cellClassName,
|
|
1547
|
+
isMerged && cellIndex > 0 && "is-merged",
|
|
1548
|
+
showMergedRightEdge && "is-merged-edge-right",
|
|
660
1549
|
enableRowSpan && showCellSelected && "is-group-selected",
|
|
661
1550
|
enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
|
|
662
1551
|
isCellDragSelected && CELL_SELECTION_FILL_CLASS,
|
|
1552
|
+
hasCellSelectionEdges(selectionEdgeStyle) && CELL_SELECTION_EDGES_CLASS,
|
|
663
1553
|
editable && "is-editable"
|
|
664
1554
|
),
|
|
665
1555
|
children: [
|
|
@@ -690,13 +1580,13 @@ function DataTableRow({
|
|
|
690
1580
|
) : isExpandCell && enableExpand ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "expand-cell", children: [
|
|
691
1581
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "expand-cell-content", children: [
|
|
692
1582
|
rowLevel > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "expand-cell-indent", children: "\xB7" }),
|
|
693
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "expand-cell-value", children: (0,
|
|
1583
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "expand-cell-value", children: (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext()) })
|
|
694
1584
|
] }),
|
|
695
1585
|
canExpand && expandKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
696
1586
|
"button",
|
|
697
1587
|
{
|
|
698
1588
|
type: "button",
|
|
699
|
-
"aria-label": isExpanded ?
|
|
1589
|
+
"aria-label": isExpanded ? collapseRowLabel : expandRowLabel,
|
|
700
1590
|
className: "expand-toggle-button",
|
|
701
1591
|
onClick: (event) => {
|
|
702
1592
|
event.stopPropagation();
|
|
@@ -706,7 +1596,7 @@ function DataTableRow({
|
|
|
706
1596
|
children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChevronUp, { className: "expand-toggle-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChevronDown, { className: "expand-toggle-icon" })
|
|
707
1597
|
}
|
|
708
1598
|
)
|
|
709
|
-
] }) : (0,
|
|
1599
|
+
] }) : (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext()),
|
|
710
1600
|
isBottomRightCell && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
711
1601
|
"div",
|
|
712
1602
|
{
|
|
@@ -730,14 +1620,6 @@ function DataTableRow({
|
|
|
730
1620
|
|
|
731
1621
|
// src/components/ui/table/components/DataTable/DataTableToolbar.tsx
|
|
732
1622
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
733
|
-
function DefaultSelectionLabel({ selectedCount }) {
|
|
734
|
-
if (selectedCount <= 0) return null;
|
|
735
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "toolbar-selection", children: [
|
|
736
|
-
"\u2713 ",
|
|
737
|
-
selectedCount,
|
|
738
|
-
"\uAC1C \uC120\uD0DD\uB428"
|
|
739
|
-
] });
|
|
740
|
-
}
|
|
741
1623
|
function DataTableToolbar({
|
|
742
1624
|
filteredCount,
|
|
743
1625
|
totalCount,
|
|
@@ -751,625 +1633,166 @@ function DataTableToolbar({
|
|
|
751
1633
|
const hasCount = displayFiltered !== void 0 || totalCount !== void 0;
|
|
752
1634
|
const hasLeftContent = hasCount || Boolean(summary);
|
|
753
1635
|
const hasToolbar = Boolean(toolbar);
|
|
754
|
-
const selectionContent = selectionLabel
|
|
755
|
-
const hasSelectionContent = selectionContent !== null && selectionContent !== false;
|
|
756
|
-
if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
|
|
757
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("DataTableToolbarJSX", className), children: [
|
|
758
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "toolbar-left", children: [
|
|
759
|
-
hasCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count", children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
760
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered }),
|
|
761
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "toolbar-count-placeholder", children: [
|
|
762
|
-
" / ",
|
|
763
|
-
totalCount
|
|
764
|
-
] })
|
|
765
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
|
|
766
|
-
summary
|
|
767
|
-
] }),
|
|
768
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "toolbar-right", children: [
|
|
769
|
-
selectionContent,
|
|
770
|
-
hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "toolbar-actions", children: toolbar })
|
|
771
|
-
] })
|
|
772
|
-
] });
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
// src/components/ui/table/features/cell-edit/useCellEdit.ts
|
|
776
|
-
var import_react4 = require("react");
|
|
777
|
-
function useCellEdit({
|
|
778
|
-
data,
|
|
779
|
-
rows,
|
|
780
|
-
onDataChange
|
|
781
|
-
}) {
|
|
782
|
-
const [editingCell, setEditingCell] = (0, import_react4.useState)(null);
|
|
783
|
-
const [draftValue, setDraftValue] = (0, import_react4.useState)("");
|
|
784
|
-
const draftValueRef = (0, import_react4.useRef)(draftValue);
|
|
785
|
-
const editingCellRef = (0, import_react4.useRef)(editingCell);
|
|
786
|
-
(0, import_react4.useEffect)(() => {
|
|
787
|
-
draftValueRef.current = draftValue;
|
|
788
|
-
}, [draftValue]);
|
|
789
|
-
(0, import_react4.useEffect)(() => {
|
|
790
|
-
editingCellRef.current = editingCell;
|
|
791
|
-
}, [editingCell]);
|
|
792
|
-
const cancelEdit = (0, import_react4.useCallback)(() => {
|
|
793
|
-
setEditingCell(null);
|
|
794
|
-
setDraftValue("");
|
|
795
|
-
}, []);
|
|
796
|
-
const commitEdit = (0, import_react4.useCallback)(
|
|
797
|
-
(raw) => {
|
|
798
|
-
const current = editingCellRef.current;
|
|
799
|
-
if (!current) return true;
|
|
800
|
-
if (!onDataChange) {
|
|
801
|
-
cancelEdit();
|
|
802
|
-
return true;
|
|
803
|
-
}
|
|
804
|
-
const value = raw ?? draftValueRef.current;
|
|
805
|
-
const next = applyCellEdit(data, rows, current.rowIndex, current.colIndex, value);
|
|
806
|
-
if (!next) return false;
|
|
807
|
-
onDataChange(next);
|
|
808
|
-
cancelEdit();
|
|
809
|
-
return true;
|
|
810
|
-
},
|
|
811
|
-
[cancelEdit, data, onDataChange, rows]
|
|
812
|
-
);
|
|
813
|
-
const startEdit = (0, import_react4.useCallback)(
|
|
814
|
-
(rowIndex, colIndex) => {
|
|
815
|
-
const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
|
|
816
|
-
if (!cell || !isColumnEditable(cell.column.columnDef)) return;
|
|
817
|
-
const current = editingCellRef.current;
|
|
818
|
-
if (current && (current.rowIndex !== rowIndex || current.colIndex !== colIndex) && !commitEdit()) {
|
|
819
|
-
return;
|
|
820
|
-
}
|
|
821
|
-
setEditingCell({ rowIndex, colIndex });
|
|
822
|
-
setDraftValue(getCellEditDraftValue(cell.getValue()));
|
|
823
|
-
},
|
|
824
|
-
[commitEdit, rows]
|
|
825
|
-
);
|
|
826
|
-
return {
|
|
827
|
-
editingCell,
|
|
828
|
-
draftValue,
|
|
829
|
-
setDraftValue,
|
|
830
|
-
startEdit,
|
|
831
|
-
commitEdit,
|
|
832
|
-
cancelEdit
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
837
|
-
var import_react5 = require("react");
|
|
838
|
-
|
|
839
|
-
// src/components/ui/table/features/cell-selection/fillData.ts
|
|
840
|
-
function getColumnAccessorKey2(columnDef) {
|
|
841
|
-
if ("accessorKey" in columnDef && columnDef.accessorKey) {
|
|
842
|
-
return String(columnDef.accessorKey);
|
|
843
|
-
}
|
|
844
|
-
return columnDef.id;
|
|
845
|
-
}
|
|
846
|
-
function applyFillData(data, rows, sourceBounds, fillBounds) {
|
|
847
|
-
const newData = data.map((row) => ({ ...row }));
|
|
848
|
-
const sourceHeight = sourceBounds.endRow - sourceBounds.startRow + 1;
|
|
849
|
-
const sourceWidth = sourceBounds.endCol - sourceBounds.startCol + 1;
|
|
850
|
-
for (let rowIndex = fillBounds.startRow; rowIndex <= fillBounds.endRow; rowIndex += 1) {
|
|
851
|
-
for (let colIndex = fillBounds.startCol; colIndex <= fillBounds.endCol; colIndex += 1) {
|
|
852
|
-
if (isCellInSelection(rowIndex, colIndex, sourceBounds)) continue;
|
|
853
|
-
const offsetRow = rowIndex - sourceBounds.startRow;
|
|
854
|
-
const offsetCol = colIndex - sourceBounds.startCol;
|
|
855
|
-
const sourceRowIndex = sourceBounds.startRow + (offsetRow % sourceHeight + sourceHeight) % sourceHeight;
|
|
856
|
-
const sourceColIndex = sourceBounds.startCol + (offsetCol % sourceWidth + sourceWidth) % sourceWidth;
|
|
857
|
-
const targetCell = rows[rowIndex]?.getVisibleCells()[colIndex];
|
|
858
|
-
const sourceCell = rows[sourceRowIndex]?.getVisibleCells()[sourceColIndex];
|
|
859
|
-
if (!targetCell || !sourceCell) continue;
|
|
860
|
-
const accessorKey = getColumnAccessorKey2(
|
|
861
|
-
targetCell.column.columnDef
|
|
862
|
-
);
|
|
863
|
-
if (!accessorKey) continue;
|
|
864
|
-
newData[rowIndex][accessorKey] = sourceCell.getValue();
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
return newData;
|
|
868
|
-
}
|
|
869
|
-
function hasFillExtension(sourceBounds, fillBounds) {
|
|
870
|
-
if (!sourceBounds) return false;
|
|
871
|
-
return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
// src/components/ui/table/features/cell-selection/useCellSelection.ts
|
|
875
|
-
function useCellSelection({
|
|
876
|
-
data,
|
|
877
|
-
rows,
|
|
878
|
-
onDataChange
|
|
879
|
-
}) {
|
|
880
|
-
const [dragState, setDragState] = (0, import_react5.useState)(INITIAL_DRAG_STATE);
|
|
881
|
-
const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
|
|
882
|
-
const activeSelectionBounds = getActiveSelectionBounds(dragState, cellSelectionBounds);
|
|
883
|
-
const handleCellMouseDown = (0, import_react5.useCallback)((rowIndex, colIndex) => {
|
|
884
|
-
setDragState({
|
|
885
|
-
isSelecting: true,
|
|
886
|
-
isFillDragging: false,
|
|
887
|
-
start: { row: rowIndex, col: colIndex },
|
|
888
|
-
end: { row: rowIndex, col: colIndex },
|
|
889
|
-
fillAnchor: null,
|
|
890
|
-
fillEnd: null
|
|
891
|
-
});
|
|
892
|
-
}, []);
|
|
893
|
-
const handleCellMouseEnter = (0, import_react5.useCallback)((rowIndex, colIndex) => {
|
|
894
|
-
setDragState((prev) => {
|
|
895
|
-
if (prev.isSelecting) {
|
|
896
|
-
return { ...prev, end: { row: rowIndex, col: colIndex } };
|
|
897
|
-
}
|
|
898
|
-
if (prev.isFillDragging) {
|
|
899
|
-
return { ...prev, fillEnd: { row: rowIndex, col: colIndex } };
|
|
900
|
-
}
|
|
901
|
-
return prev;
|
|
902
|
-
});
|
|
903
|
-
}, []);
|
|
904
|
-
const handleFillHandleMouseDown = (0, import_react5.useCallback)((rowIndex, colIndex) => {
|
|
905
|
-
setDragState((prev) => {
|
|
906
|
-
const bounds = getCellSelectionBounds(prev.start, prev.end);
|
|
907
|
-
if (!bounds) return prev;
|
|
908
|
-
return {
|
|
909
|
-
...prev,
|
|
910
|
-
isSelecting: false,
|
|
911
|
-
isFillDragging: true,
|
|
912
|
-
fillAnchor: { row: bounds.startRow, col: bounds.startCol },
|
|
913
|
-
fillEnd: { row: rowIndex, col: colIndex }
|
|
914
|
-
};
|
|
915
|
-
});
|
|
916
|
-
}, []);
|
|
917
|
-
(0, import_react5.useEffect)(() => {
|
|
918
|
-
const handleKeyDown = (e) => {
|
|
919
|
-
if ((e.ctrlKey || e.metaKey) && e.key === "c" && activeSelectionBounds) {
|
|
920
|
-
const { startRow, endRow, startCol, endCol } = activeSelectionBounds;
|
|
921
|
-
const selectedData = rows.slice(startRow, endRow + 1).map((row) => {
|
|
922
|
-
const cells = row.getVisibleCells();
|
|
923
|
-
return cells.slice(startCol, endCol + 1).map((cell) => cell.getValue()).join(" ");
|
|
924
|
-
}).join("\n");
|
|
925
|
-
navigator.clipboard.writeText(selectedData);
|
|
926
|
-
}
|
|
927
|
-
};
|
|
928
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
929
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
930
|
-
}, [activeSelectionBounds, rows]);
|
|
931
|
-
(0, import_react5.useEffect)(() => {
|
|
932
|
-
const handleMouseUp = () => {
|
|
933
|
-
setDragState((prev) => {
|
|
934
|
-
if (prev.isFillDragging && prev.fillAnchor && prev.fillEnd) {
|
|
935
|
-
const sourceBounds = getCellSelectionBounds(prev.start, prev.end);
|
|
936
|
-
const newBounds = getCellSelectionBounds(prev.fillAnchor, prev.fillEnd);
|
|
937
|
-
if (newBounds) {
|
|
938
|
-
if (hasFillExtension(sourceBounds, newBounds) && sourceBounds && onDataChange) {
|
|
939
|
-
onDataChange(applyFillData(data, rows, sourceBounds, newBounds));
|
|
940
|
-
}
|
|
941
|
-
return {
|
|
942
|
-
isSelecting: false,
|
|
943
|
-
isFillDragging: false,
|
|
944
|
-
start: { row: newBounds.startRow, col: newBounds.startCol },
|
|
945
|
-
end: { row: newBounds.endRow, col: newBounds.endCol },
|
|
946
|
-
fillAnchor: null,
|
|
947
|
-
fillEnd: null
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
if (prev.isSelecting) {
|
|
952
|
-
return { ...prev, isSelecting: false };
|
|
953
|
-
}
|
|
954
|
-
if (prev.isFillDragging) {
|
|
955
|
-
return { ...prev, isFillDragging: false, fillAnchor: null, fillEnd: null };
|
|
956
|
-
}
|
|
957
|
-
return prev;
|
|
958
|
-
});
|
|
959
|
-
};
|
|
960
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
961
|
-
return () => window.removeEventListener("mouseup", handleMouseUp);
|
|
962
|
-
}, [data, onDataChange, rows]);
|
|
963
|
-
return {
|
|
964
|
-
dragState,
|
|
965
|
-
activeSelectionBounds,
|
|
966
|
-
handleCellMouseDown,
|
|
967
|
-
handleCellMouseEnter,
|
|
968
|
-
handleFillHandleMouseDown
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
// src/components/ui/table/features/row-selection/rowSelection.ts
|
|
973
|
-
function resolveRowSelection(mode, controlledSelection, internalSelection) {
|
|
974
|
-
if (mode === "none") return {};
|
|
975
|
-
return controlledSelection ?? internalSelection;
|
|
976
|
-
}
|
|
977
|
-
function normalizeSingleSelection(next) {
|
|
978
|
-
const selectedIds = Object.keys(next).filter((id) => next[id]);
|
|
979
|
-
if (selectedIds.length <= 1) return next;
|
|
980
|
-
return { [selectedIds[selectedIds.length - 1]]: true };
|
|
981
|
-
}
|
|
982
|
-
function applySelectionUpdater(mode, updater, previous) {
|
|
983
|
-
const next = typeof updater === "function" ? updater(previous) : updater;
|
|
984
|
-
return mode === "single" ? normalizeSingleSelection(next) : next;
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
// src/components/ui/table/features/row-span/rowSpan.ts
|
|
988
|
-
function getRowFieldValue(row, key) {
|
|
989
|
-
return row[key];
|
|
990
|
-
}
|
|
991
|
-
function computeRowSpans(data, rowSpanKey) {
|
|
992
|
-
if (data.length === 0) return [];
|
|
993
|
-
const result = [];
|
|
994
|
-
for (let index = 0; index < data.length; index++) {
|
|
995
|
-
const currentValue = getRowFieldValue(data[index], rowSpanKey);
|
|
996
|
-
const previousValue = index > 0 ? getRowFieldValue(data[index - 1], rowSpanKey) : void 0;
|
|
997
|
-
if (index > 0 && currentValue === previousValue) {
|
|
998
|
-
result.push({ rowSpan: 0, isFirstInGroup: false });
|
|
999
|
-
continue;
|
|
1000
|
-
}
|
|
1001
|
-
let span = 1;
|
|
1002
|
-
for (let nextIndex = index + 1; nextIndex < data.length; nextIndex++) {
|
|
1003
|
-
if (getRowFieldValue(data[nextIndex], rowSpanKey) === currentValue) {
|
|
1004
|
-
span++;
|
|
1005
|
-
} else {
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
result.push({ rowSpan: span, isFirstInGroup: true });
|
|
1010
|
-
}
|
|
1011
|
-
return result;
|
|
1012
|
-
}
|
|
1013
|
-
function buildColumnRowSpanMap(data, columnKeys) {
|
|
1014
|
-
const map = /* @__PURE__ */ new Map();
|
|
1015
|
-
for (const { columnId, rowSpanKey } of columnKeys) {
|
|
1016
|
-
map.set(columnId, computeRowSpans(data, rowSpanKey));
|
|
1017
|
-
}
|
|
1018
|
-
return map;
|
|
1019
|
-
}
|
|
1020
|
-
function collectRowSpanColumns(columns) {
|
|
1021
|
-
const result = [];
|
|
1022
|
-
const visit = (defs) => {
|
|
1023
|
-
for (const columnDef of defs) {
|
|
1024
|
-
if ("columns" in columnDef && columnDef.columns?.length) {
|
|
1025
|
-
visit(columnDef.columns);
|
|
1026
|
-
continue;
|
|
1027
|
-
}
|
|
1028
|
-
const columnId = columnDef.id ?? ("accessorKey" in columnDef && columnDef.accessorKey ? String(columnDef.accessorKey) : void 0);
|
|
1029
|
-
if (!columnId || !columnDef.meta?.rowSpan) continue;
|
|
1030
|
-
result.push({
|
|
1031
|
-
columnId,
|
|
1032
|
-
rowSpanKey: columnDef.meta.rowSpanKey ?? columnId
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
};
|
|
1036
|
-
visit(columns);
|
|
1037
|
-
return result;
|
|
1636
|
+
const selectionContent = selectionLabel?.(selectedCount) ?? null;
|
|
1637
|
+
const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
|
|
1638
|
+
if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
|
|
1639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("DataTableToolbarJSX", className), children: [
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "toolbar-left", children: [
|
|
1641
|
+
hasCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count", children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1642
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered }),
|
|
1643
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "toolbar-count-placeholder", children: [
|
|
1644
|
+
" / ",
|
|
1645
|
+
totalCount
|
|
1646
|
+
] })
|
|
1647
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
|
|
1648
|
+
summary
|
|
1649
|
+
] }),
|
|
1650
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "toolbar-right", children: [
|
|
1651
|
+
hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-selection", children: selectionContent }) : selectionContent),
|
|
1652
|
+
hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "toolbar-actions", children: toolbar })
|
|
1653
|
+
] })
|
|
1654
|
+
] });
|
|
1038
1655
|
}
|
|
1039
1656
|
|
|
1040
1657
|
// src/components/ui/table/components/DataTable/DataTable.tsx
|
|
1041
1658
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1659
|
+
function DefaultPending({
|
|
1660
|
+
loadingText,
|
|
1661
|
+
className
|
|
1662
|
+
}) {
|
|
1663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("DataTableJSX", "DataTableJSX--pending", className), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "data-table-loading-text", children: loadingText }) });
|
|
1664
|
+
}
|
|
1665
|
+
function DefaultEmpty({
|
|
1666
|
+
emptyText,
|
|
1667
|
+
columnCount
|
|
1668
|
+
}) {
|
|
1669
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("td", { colSpan: columnCount, className: "data-table-empty-cell", children: emptyText }) });
|
|
1670
|
+
}
|
|
1042
1671
|
function DataTable({
|
|
1043
|
-
|
|
1044
|
-
columns,
|
|
1045
|
-
rowSelectionMode = "none",
|
|
1046
|
-
rowSelection: controlledRowSelection,
|
|
1047
|
-
onRowSelectionChange,
|
|
1048
|
-
totalCount,
|
|
1049
|
-
filteredCount,
|
|
1672
|
+
isPending = false,
|
|
1050
1673
|
summary,
|
|
1051
1674
|
toolbar,
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
emptyText = "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
1055
|
-
enableRowSpan = false,
|
|
1056
|
-
getRowId,
|
|
1057
|
-
onRowClick,
|
|
1058
|
-
getRowClassName,
|
|
1059
|
-
getRowCanSelect,
|
|
1060
|
-
selectOnRowClick = true,
|
|
1061
|
-
onDataChange,
|
|
1675
|
+
filteredCount,
|
|
1676
|
+
totalCount,
|
|
1062
1677
|
className,
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
childField,
|
|
1066
|
-
flattenField,
|
|
1067
|
-
expandedRows: controlledExpandedRows,
|
|
1068
|
-
onExpandedRowsChange,
|
|
1069
|
-
preventExpand = false,
|
|
1070
|
-
enableVirtualization = true,
|
|
1071
|
-
estimateRowHeight = DATA_TABLE_ROW_HEIGHT,
|
|
1072
|
-
virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN
|
|
1678
|
+
slots,
|
|
1679
|
+
...glideOptions
|
|
1073
1680
|
}) {
|
|
1074
|
-
const enableExpand = Boolean(toggleField);
|
|
1075
|
-
const [internalRowSelection, setInternalRowSelection] = (0, import_react6.useState)({});
|
|
1076
|
-
const [internalExpandedRows, setInternalExpandedRows] = (0, import_react6.useState)(() => /* @__PURE__ */ new Set());
|
|
1077
|
-
const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react6.useState)(null);
|
|
1078
|
-
const [hoveredGroupKey, setHoveredGroupKey] = (0, import_react6.useState)(null);
|
|
1079
|
-
const scrollRef = (0, import_react6.useRef)(null);
|
|
1080
|
-
const shouldVirtualize = enableVirtualization && !enableRowSpan;
|
|
1081
|
-
(0, import_react6.useEffect)(() => {
|
|
1082
|
-
if (enableVirtualization && enableRowSpan) {
|
|
1083
|
-
console.warn(
|
|
1084
|
-
"[DataTable] enableRowSpan\uC774 \uCF1C\uC838 \uC788\uC73C\uBA74 \uC140 \uBCD1\uD569 \uC720\uC9C0\uB97C \uC704\uD574 \uAC00\uC0C1\uD654\uB97C \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4."
|
|
1085
|
-
);
|
|
1086
|
-
}
|
|
1087
|
-
}, [enableVirtualization, enableRowSpan]);
|
|
1088
|
-
const rowSelection = resolveRowSelection(
|
|
1089
|
-
rowSelectionMode,
|
|
1090
|
-
controlledRowSelection,
|
|
1091
|
-
internalRowSelection
|
|
1092
|
-
);
|
|
1093
|
-
const expandedRows = controlledExpandedRows ?? internalExpandedRows;
|
|
1094
|
-
const handleExpandedRowsChange = (0, import_react6.useCallback)(
|
|
1095
|
-
(next) => {
|
|
1096
|
-
if (onExpandedRowsChange) {
|
|
1097
|
-
onExpandedRowsChange(next);
|
|
1098
|
-
return;
|
|
1099
|
-
}
|
|
1100
|
-
setInternalExpandedRows(next);
|
|
1101
|
-
},
|
|
1102
|
-
[onExpandedRowsChange]
|
|
1103
|
-
);
|
|
1104
|
-
const tableData = useConvertTreeData({
|
|
1105
|
-
data,
|
|
1106
|
-
enabled: enableExpand,
|
|
1107
|
-
toggleField,
|
|
1108
|
-
childField,
|
|
1109
|
-
flattenField,
|
|
1110
|
-
expandedRows,
|
|
1111
|
-
onExpandedRowsChange: enableExpand ? handleExpandedRowsChange : void 0,
|
|
1112
|
-
preventExpand
|
|
1113
|
-
});
|
|
1114
|
-
const table = (0, import_react_table2.useReactTable)({
|
|
1115
|
-
data: tableData,
|
|
1116
|
-
columns,
|
|
1117
|
-
state: {
|
|
1118
|
-
rowSelection: rowSelectionMode === "none" ? {} : rowSelection
|
|
1119
|
-
},
|
|
1120
|
-
enableRowSelection: rowSelectionMode === "none" ? false : getRowCanSelect ? (row) => getRowCanSelect(row.original, row.index) : true,
|
|
1121
|
-
enableMultiRowSelection: rowSelectionMode === "multi",
|
|
1122
|
-
onRowSelectionChange: (updater) => {
|
|
1123
|
-
if (onRowSelectionChange) {
|
|
1124
|
-
onRowSelectionChange(
|
|
1125
|
-
(previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
|
|
1126
|
-
);
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
setInternalRowSelection(
|
|
1130
|
-
(previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
|
|
1131
|
-
);
|
|
1132
|
-
},
|
|
1133
|
-
getCoreRowModel: (0, import_react_table2.getCoreRowModel)(),
|
|
1134
|
-
getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
|
|
1135
|
-
});
|
|
1136
|
-
const rowSpanColumnKeys = (0, import_react6.useMemo)(() => {
|
|
1137
|
-
if (!enableRowSpan) return [];
|
|
1138
|
-
return collectRowSpanColumns(columns);
|
|
1139
|
-
}, [enableRowSpan, columns]);
|
|
1140
|
-
const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
|
|
1141
|
-
const columnRowSpanMap = (0, import_react6.useMemo)(
|
|
1142
|
-
() => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
|
|
1143
|
-
[tableData, rowSpanColumnKeys]
|
|
1144
|
-
);
|
|
1145
|
-
const selectedRows = table.getSelectedRowModel().rows;
|
|
1146
|
-
const selectedCount = selectedRows.length;
|
|
1147
|
-
const rows = table.getRowModel().rows;
|
|
1148
|
-
const columnCount = table.getAllLeafColumns().length || 1;
|
|
1149
|
-
const rowVirtualizer = (0, import_react_virtual.useVirtualizer)({
|
|
1150
|
-
count: shouldVirtualize ? rows.length : 0,
|
|
1151
|
-
getScrollElement: () => scrollRef.current,
|
|
1152
|
-
estimateSize: () => estimateRowHeight,
|
|
1153
|
-
overscan: virtualOverscan
|
|
1154
|
-
});
|
|
1155
|
-
const virtualRows = rowVirtualizer.getVirtualItems();
|
|
1156
|
-
const totalSize = rowVirtualizer.getTotalSize();
|
|
1157
|
-
const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
|
|
1158
|
-
const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
|
|
1159
|
-
const selectedGroupKeys = (0, import_react6.useMemo)(() => {
|
|
1160
|
-
if (!enableRowSpan || !primaryRowSpanKey) return /* @__PURE__ */ new Set();
|
|
1161
|
-
const keys = /* @__PURE__ */ new Set();
|
|
1162
|
-
for (const selectedRow of selectedRows) {
|
|
1163
|
-
const value = selectedRow.original[primaryRowSpanKey];
|
|
1164
|
-
if (value !== null && value !== void 0) keys.add(String(value));
|
|
1165
|
-
}
|
|
1166
|
-
return keys;
|
|
1167
|
-
}, [enableRowSpan, primaryRowSpanKey, selectedRows]);
|
|
1168
1681
|
const {
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
);
|
|
1188
|
-
const
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
const handleRowHover = (0, import_react6.useCallback)(
|
|
1193
|
-
(rowIndex, rowData) => {
|
|
1194
|
-
setHoveredRowIndex(rowIndex);
|
|
1195
|
-
if (!primaryRowSpanKey) {
|
|
1196
|
-
setHoveredGroupKey(null);
|
|
1197
|
-
return;
|
|
1198
|
-
}
|
|
1199
|
-
const groupValue = rowData[primaryRowSpanKey];
|
|
1200
|
-
setHoveredGroupKey(
|
|
1201
|
-
groupValue === null || groupValue === void 0 ? null : String(groupValue)
|
|
1202
|
-
);
|
|
1203
|
-
},
|
|
1204
|
-
[primaryRowSpanKey]
|
|
1205
|
-
);
|
|
1206
|
-
const handleToggleSelect = (0, import_react6.useCallback)(
|
|
1207
|
-
(row) => {
|
|
1208
|
-
if (!row.getCanSelect()) return;
|
|
1209
|
-
if (preserveRowSelection && row.getIsSelected()) {
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
row.toggleSelected();
|
|
1213
|
-
},
|
|
1214
|
-
[preserveRowSelection]
|
|
1215
|
-
);
|
|
1216
|
-
const handleToggleExpand = (0, import_react6.useCallback)(
|
|
1217
|
-
(rowKey) => {
|
|
1218
|
-
if (preventExpand) return;
|
|
1219
|
-
handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
|
|
1220
|
-
},
|
|
1221
|
-
[preventExpand, handleExpandedRowsChange, expandedRows]
|
|
1222
|
-
);
|
|
1223
|
-
const rowContextValue = (0, import_react6.useMemo)(() => {
|
|
1224
|
-
return {
|
|
1225
|
-
rowSpan: {
|
|
1226
|
-
enableRowSpan,
|
|
1227
|
-
primaryRowSpanKey,
|
|
1228
|
-
columnRowSpanMap,
|
|
1229
|
-
hoveredRowIndex,
|
|
1230
|
-
hoveredGroupKey,
|
|
1231
|
-
selectedGroupKeys,
|
|
1232
|
-
onRowHover: handleRowHover
|
|
1233
|
-
},
|
|
1234
|
-
selection: {
|
|
1235
|
-
rowSelectionMode,
|
|
1236
|
-
selectOnRowClick,
|
|
1237
|
-
onRowClick,
|
|
1238
|
-
getRowClassName
|
|
1239
|
-
},
|
|
1240
|
-
cellSelection: {
|
|
1241
|
-
activeSelectionBounds,
|
|
1242
|
-
dragState,
|
|
1243
|
-
onCellMouseDown: handleCellMouseDownWithCommit,
|
|
1244
|
-
onCellMouseEnter: handleCellMouseEnter,
|
|
1245
|
-
onFillHandleMouseDown: handleFillHandleMouseDown
|
|
1246
|
-
},
|
|
1247
|
-
cellEdit: {
|
|
1248
|
-
editingCell,
|
|
1249
|
-
draftValue,
|
|
1250
|
-
onDraftValueChange: setDraftValue,
|
|
1251
|
-
onStartEdit: startEdit,
|
|
1252
|
-
onCommitEdit: commitEdit,
|
|
1253
|
-
onCancelEdit: cancelEdit
|
|
1254
|
-
},
|
|
1255
|
-
expand: {
|
|
1256
|
-
enableExpand,
|
|
1257
|
-
toggleField,
|
|
1258
|
-
expandedRows,
|
|
1259
|
-
preventExpand,
|
|
1260
|
-
onToggleExpand: handleToggleExpand
|
|
1261
|
-
}
|
|
1262
|
-
};
|
|
1263
|
-
}, [
|
|
1264
|
-
enableRowSpan,
|
|
1265
|
-
primaryRowSpanKey,
|
|
1266
|
-
columnRowSpanMap,
|
|
1267
|
-
hoveredRowIndex,
|
|
1268
|
-
hoveredGroupKey,
|
|
1269
|
-
selectedGroupKeys,
|
|
1270
|
-
handleRowHover,
|
|
1271
|
-
rowSelectionMode,
|
|
1272
|
-
selectOnRowClick,
|
|
1273
|
-
onRowClick,
|
|
1274
|
-
getRowClassName,
|
|
1275
|
-
activeSelectionBounds,
|
|
1276
|
-
dragState,
|
|
1277
|
-
handleCellMouseDownWithCommit,
|
|
1278
|
-
handleCellMouseEnter,
|
|
1279
|
-
handleFillHandleMouseDown,
|
|
1280
|
-
editingCell,
|
|
1281
|
-
draftValue,
|
|
1282
|
-
setDraftValue,
|
|
1283
|
-
startEdit,
|
|
1284
|
-
commitEdit,
|
|
1285
|
-
cancelEdit,
|
|
1286
|
-
enableExpand,
|
|
1287
|
-
toggleField,
|
|
1288
|
-
expandedRows,
|
|
1289
|
-
preventExpand,
|
|
1290
|
-
handleToggleExpand
|
|
1291
|
-
]);
|
|
1682
|
+
table,
|
|
1683
|
+
tableData,
|
|
1684
|
+
rows,
|
|
1685
|
+
columnCount,
|
|
1686
|
+
selectedCount,
|
|
1687
|
+
emptyText,
|
|
1688
|
+
loadingText,
|
|
1689
|
+
selectionLabel,
|
|
1690
|
+
enableCellSelection,
|
|
1691
|
+
shouldVirtualize,
|
|
1692
|
+
scrollRef,
|
|
1693
|
+
rowVirtualizer,
|
|
1694
|
+
virtualRows,
|
|
1695
|
+
paddingTop,
|
|
1696
|
+
paddingBottom,
|
|
1697
|
+
rowContextValue,
|
|
1698
|
+
handleToggleSelect,
|
|
1699
|
+
clearHover
|
|
1700
|
+
} = useGlideTable(glideOptions);
|
|
1701
|
+
const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
|
|
1702
|
+
const RowSlot = slots?.Row ?? DataTableRow;
|
|
1703
|
+
const PendingSlot = slots?.Pending ?? DefaultPending;
|
|
1704
|
+
const EmptySlot = slots?.Empty ?? DefaultEmpty;
|
|
1292
1705
|
if (isPending) {
|
|
1293
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PendingSlot, { loadingText, className });
|
|
1294
1707
|
}
|
|
1295
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
)
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1709
|
+
"div",
|
|
1710
|
+
{
|
|
1711
|
+
className: cn(
|
|
1712
|
+
"DataTableJSX",
|
|
1713
|
+
!enableCellSelection && "DataTableJSX--no-cell-selection",
|
|
1714
|
+
className
|
|
1715
|
+
),
|
|
1716
|
+
children: [
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1718
|
+
ToolbarSlot,
|
|
1719
|
+
{
|
|
1720
|
+
filteredCount: filteredCount ?? tableData.length,
|
|
1721
|
+
totalCount,
|
|
1722
|
+
summary,
|
|
1723
|
+
selectedCount,
|
|
1724
|
+
selectionLabel,
|
|
1725
|
+
toolbar
|
|
1726
|
+
}
|
|
1727
|
+
),
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: "data-table-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1729
|
+
"table",
|
|
1730
|
+
{
|
|
1731
|
+
className: "data-table",
|
|
1732
|
+
onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
|
|
1733
|
+
children: [
|
|
1734
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { className: "data-table-head", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { className: "data-table-head-row", children: headerGroup.headers.map((header) => {
|
|
1735
|
+
const align = header.column.columnDef.meta?.align ?? "center";
|
|
1736
|
+
const headerClassName = header.column.columnDef.meta?.headerClassName;
|
|
1737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1738
|
+
"th",
|
|
1739
|
+
{
|
|
1740
|
+
style: { width: header.getSize() !== 150 ? header.getSize() : void 0 },
|
|
1741
|
+
className: cn(
|
|
1742
|
+
"data-table-head-cell",
|
|
1743
|
+
CELL_ALIGN_CLASS[align],
|
|
1744
|
+
headerClassName
|
|
1745
|
+
),
|
|
1746
|
+
children: header.isPlaceholder ? null : (0, import_react_table3.flexRender)(header.column.columnDef.header, header.getContext())
|
|
1747
|
+
},
|
|
1748
|
+
header.id
|
|
1749
|
+
);
|
|
1750
|
+
}) }, headerGroup.id)) }),
|
|
1751
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DataTableContextProvider, { value: rowContextValue, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tbody", { onMouseLeave: clearHover, className: "data-table-body", children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EmptySlot, { emptyText, columnCount }) : shouldVirtualize ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1752
|
+
paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { "aria-hidden": true, className: "data-table-virtual-spacer", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1753
|
+
"td",
|
|
1754
|
+
{
|
|
1755
|
+
colSpan: columnCount,
|
|
1756
|
+
style: { height: paddingTop },
|
|
1757
|
+
className: "data-table-virtual-spacer-cell"
|
|
1758
|
+
}
|
|
1759
|
+
) }),
|
|
1760
|
+
virtualRows.map((virtualRow) => {
|
|
1761
|
+
const row = rows[virtualRow.index];
|
|
1762
|
+
if (!row) return null;
|
|
1763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1764
|
+
RowSlot,
|
|
1765
|
+
{
|
|
1766
|
+
row,
|
|
1767
|
+
virtualIndex: virtualRow.index,
|
|
1768
|
+
measureElement: rowVirtualizer.measureElement,
|
|
1769
|
+
onToggleSelect: () => handleToggleSelect(row)
|
|
1770
|
+
},
|
|
1771
|
+
row.id
|
|
1772
|
+
);
|
|
1773
|
+
}),
|
|
1774
|
+
paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { "aria-hidden": true, className: "data-table-virtual-spacer", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1775
|
+
"td",
|
|
1776
|
+
{
|
|
1777
|
+
colSpan: columnCount,
|
|
1778
|
+
style: { height: paddingBottom },
|
|
1779
|
+
className: "data-table-virtual-spacer-cell"
|
|
1780
|
+
}
|
|
1781
|
+
) })
|
|
1782
|
+
] }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1783
|
+
RowSlot,
|
|
1344
1784
|
{
|
|
1345
1785
|
row,
|
|
1346
|
-
virtualIndex: virtualRow.index,
|
|
1347
|
-
measureElement: rowVirtualizer.measureElement,
|
|
1348
1786
|
onToggleSelect: () => handleToggleSelect(row)
|
|
1349
1787
|
},
|
|
1350
1788
|
row.id
|
|
1351
|
-
)
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
className: "data-table-virtual-spacer-cell"
|
|
1359
|
-
}
|
|
1360
|
-
) })
|
|
1361
|
-
] }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1362
|
-
DataTableRow,
|
|
1363
|
-
{
|
|
1364
|
-
row,
|
|
1365
|
-
onToggleSelect: () => handleToggleSelect(row)
|
|
1366
|
-
},
|
|
1367
|
-
row.id
|
|
1368
|
-
)) }) })
|
|
1369
|
-
]
|
|
1370
|
-
}
|
|
1371
|
-
) })
|
|
1372
|
-
] });
|
|
1789
|
+
)) }) })
|
|
1790
|
+
]
|
|
1791
|
+
}
|
|
1792
|
+
) })
|
|
1793
|
+
]
|
|
1794
|
+
}
|
|
1795
|
+
);
|
|
1373
1796
|
}
|
|
1374
1797
|
|
|
1375
1798
|
// src/components/ui/table/components/Table/Table.tsx
|
|
@@ -1568,7 +1991,7 @@ function TablePagination({
|
|
|
1568
1991
|
className: "pagination-button",
|
|
1569
1992
|
disabled: !canGoPrev,
|
|
1570
1993
|
onClick: () => onChange(safePage - 1),
|
|
1571
|
-
"aria-label": "
|
|
1994
|
+
"aria-label": "Previous page",
|
|
1572
1995
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeft, { className: "pagination-button-icon" })
|
|
1573
1996
|
}
|
|
1574
1997
|
),
|
|
@@ -1584,7 +2007,7 @@ function TablePagination({
|
|
|
1584
2007
|
className: "pagination-button",
|
|
1585
2008
|
disabled: !canGoNext,
|
|
1586
2009
|
onClick: () => onChange(safePage + 1),
|
|
1587
|
-
"aria-label": "
|
|
2010
|
+
"aria-label": "Next page",
|
|
1588
2011
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRight, { className: "pagination-button-icon" })
|
|
1589
2012
|
}
|
|
1590
2013
|
)
|
|
@@ -1633,7 +2056,7 @@ function TableRoot({
|
|
|
1633
2056
|
return paginateTableData(sortedData, page, pageSize);
|
|
1634
2057
|
}, [data, sort, paginationProps, page, pageSize]);
|
|
1635
2058
|
if (columns.length === 0) {
|
|
1636
|
-
console.warn("[Table]
|
|
2059
|
+
console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
|
|
1637
2060
|
}
|
|
1638
2061
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "TableJSX", children: [
|
|
1639
2062
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -1685,7 +2108,36 @@ var Table = Object.assign(TableRoot, {
|
|
|
1685
2108
|
});
|
|
1686
2109
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1687
2110
|
0 && (module.exports = {
|
|
2111
|
+
CELL_SELECTION_EDGES_CLASS,
|
|
2112
|
+
DEFAULT_DATA_TABLE_LABELS,
|
|
2113
|
+
DEFAULT_TREE_CHILDREN_FIELD,
|
|
2114
|
+
DEFAULT_TREE_ID_FIELD,
|
|
2115
|
+
DEFAULT_TREE_PARENT_ID_FIELD,
|
|
2116
|
+
DEFAULT_TREE_QTY_FIELD,
|
|
1688
2117
|
DataTable,
|
|
1689
2118
|
Table,
|
|
1690
|
-
|
|
2119
|
+
applyCellEdit,
|
|
2120
|
+
applyFillData,
|
|
2121
|
+
applySelectionUpdater,
|
|
2122
|
+
buildColumnRowSpanMap,
|
|
2123
|
+
canExpandRow,
|
|
2124
|
+
collectFillChanges,
|
|
2125
|
+
collectRowSpanColumns,
|
|
2126
|
+
createTable,
|
|
2127
|
+
getCellEditDraftValue,
|
|
2128
|
+
getCellSelectionEdgeStyle,
|
|
2129
|
+
getColumnEditType,
|
|
2130
|
+
getRowIndexInMergedCell,
|
|
2131
|
+
hasCellSelectionEdges,
|
|
2132
|
+
isCellInSelection,
|
|
2133
|
+
isColumnEditable,
|
|
2134
|
+
parseCellEditValue,
|
|
2135
|
+
resolveDataTableLabels,
|
|
2136
|
+
resolveRowSelection,
|
|
2137
|
+
resolveRowSpanAt,
|
|
2138
|
+
toggleExpandedRowId,
|
|
2139
|
+
useCellEdit,
|
|
2140
|
+
useCellSelection,
|
|
2141
|
+
useConvertTreeData,
|
|
2142
|
+
useGlideTable
|
|
1691
2143
|
});
|