react-glide-table 1.1.1 → 1.1.3

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.
@@ -0,0 +1,2235 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/compound/index.ts
21
+ var compound_exports = {};
22
+ __export(compound_exports, {
23
+ DataTable: () => DataTable,
24
+ Table: () => Table,
25
+ createTable: () => createTable
26
+ });
27
+ module.exports = __toCommonJS(compound_exports);
28
+
29
+ // src/components/ui/table/components/DataTable/DataTable.tsx
30
+ var import_react_table3 = require("@tanstack/react-table");
31
+ var import_react7 = require("react");
32
+
33
+ // src/components/ui/table/components/DataTable/DataTableRow.tsx
34
+ var import_react_table = require("@tanstack/react-table");
35
+ var import_react3 = require("react");
36
+
37
+ // src/components/ui/table/constants.ts
38
+ var CELL_ALIGN_CLASS = {
39
+ left: "cell-align-left",
40
+ center: "cell-align-center",
41
+ right: "cell-align-right"
42
+ };
43
+ var ROW_HOVER_CLASS = "row-hoverable";
44
+ var ROW_HOVERED_BG_CLASS = "row-hovered";
45
+ var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
46
+ var DATA_TABLE_ROW_HEIGHT = 44;
47
+ var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
48
+
49
+ // src/components/ui/table/DataTableContext.tsx
50
+ var import_react = require("react");
51
+ var import_jsx_runtime = require("react/jsx-runtime");
52
+ var DataTableContext = (0, import_react.createContext)(null);
53
+ function useDataTableRowContext() {
54
+ const context = (0, import_react.use)(DataTableContext);
55
+ if (!context) {
56
+ throw new Error("useDataTableRowContext must be used within a DataTableContextProvider");
57
+ }
58
+ return context;
59
+ }
60
+ function DataTableContextProvider({
61
+ value,
62
+ children
63
+ }) {
64
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataTableContext, { value, children });
65
+ }
66
+
67
+ // src/components/ui/table/features/cell-edit/cellEdit.ts
68
+ function getColumnAccessorKey(columnDef) {
69
+ if (columnDef.accessorKey !== void 0 && columnDef.accessorKey !== null) {
70
+ return String(columnDef.accessorKey);
71
+ }
72
+ return columnDef.id;
73
+ }
74
+ function isColumnEditable(columnDef) {
75
+ return Boolean(columnDef.meta?.editable);
76
+ }
77
+ function getColumnEditType(columnDef) {
78
+ return columnDef.meta?.editType ?? "text";
79
+ }
80
+ function parseCellEditValue(raw, editType) {
81
+ if (editType === "text") {
82
+ return { ok: true, value: raw };
83
+ }
84
+ const trimmed = raw.trim();
85
+ if (trimmed === "") {
86
+ return { ok: true, value: null };
87
+ }
88
+ const parsed = Number(trimmed);
89
+ if (Number.isNaN(parsed)) {
90
+ return { ok: false };
91
+ }
92
+ return { ok: true, value: parsed };
93
+ }
94
+ function getCellEditDraftValue(value) {
95
+ if (value === null || value === void 0) return "";
96
+ return String(value);
97
+ }
98
+ function applyCellEdit(data, rows, rowIndex, colIndex, raw) {
99
+ const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
100
+ if (!cell) return null;
101
+ const columnDef = cell.column.columnDef;
102
+ if (!isColumnEditable(columnDef)) return null;
103
+ const accessorKey = getColumnAccessorKey(columnDef);
104
+ if (!accessorKey) return null;
105
+ const parsed = parseCellEditValue(raw, getColumnEditType(columnDef));
106
+ if (!parsed.ok) return null;
107
+ const newData = data.map((row) => ({ ...row }));
108
+ if (!newData[rowIndex]) return null;
109
+ newData[rowIndex][accessorKey] = parsed.value;
110
+ return newData;
111
+ }
112
+
113
+ // src/components/ui/table/features/cell-selection/cellSelection.ts
114
+ var INITIAL_DRAG_STATE = {
115
+ isSelecting: false,
116
+ isFillDragging: false,
117
+ start: null,
118
+ end: null,
119
+ fillAnchor: null,
120
+ fillEnd: null
121
+ };
122
+ function getCellSelectionBounds(start, end) {
123
+ if (!start || !end) return null;
124
+ return {
125
+ startRow: Math.min(start.row, end.row),
126
+ endRow: Math.max(start.row, end.row),
127
+ startCol: Math.min(start.col, end.col),
128
+ endCol: Math.max(start.col, end.col)
129
+ };
130
+ }
131
+ function getRowIndexInMergedCell(clientY, cellElement, rowIndex, rowSpan) {
132
+ if (rowSpan <= 1) return rowIndex;
133
+ const rect = cellElement.getBoundingClientRect();
134
+ const relativeY = clientY - rect.top;
135
+ const rowHeight = rect.height / rowSpan;
136
+ const offset = Math.min(
137
+ Math.max(Math.floor(relativeY / rowHeight), 0),
138
+ rowSpan - 1
139
+ );
140
+ return rowIndex + offset;
141
+ }
142
+ function isCellInSelection(rowIndex, colIndex, bounds, rowSpan = 1) {
143
+ if (!bounds) return false;
144
+ const cellEndRow = rowIndex + rowSpan - 1;
145
+ return cellEndRow >= bounds.startRow && rowIndex <= bounds.endRow && colIndex >= bounds.startCol && colIndex <= bounds.endCol;
146
+ }
147
+ function getActiveSelectionBounds(dragState, selectionBounds) {
148
+ if (dragState.isFillDragging && dragState.fillAnchor && dragState.fillEnd) {
149
+ return getCellSelectionBounds(dragState.fillAnchor, dragState.fillEnd);
150
+ }
151
+ return selectionBounds;
152
+ }
153
+ var SELECTION_EDGE_WIDTH_PX = 2;
154
+ var SELECTION_EDGE_COLOR = "var(--color-brand-primary)";
155
+ var CELL_SELECTION_EDGES_CLASS = "cell-selection-edges";
156
+ function getMergedCellStepEdges(rowIndex, colIndex, bounds, rowSpan, isVisuallySelectedAt) {
157
+ const cellEndRow = rowIndex + rowSpan - 1;
158
+ const span = cellEndRow - rowIndex + 1;
159
+ if (span <= 1) return [];
160
+ const edges = [];
161
+ const isNeighborSelected = (row, neighborCol) => {
162
+ if (isVisuallySelectedAt) {
163
+ return isVisuallySelectedAt(row, neighborCol);
164
+ }
165
+ return row >= bounds.startRow && row <= bounds.endRow && neighborCol >= bounds.startCol && neighborCol <= bounds.endCol;
166
+ };
167
+ const pushUnselectedRuns = (side, neighborCol, fromRow, toRowExclusive) => {
168
+ let runStart = null;
169
+ for (let row = fromRow; row < toRowExclusive; row++) {
170
+ if (!isNeighborSelected(row, neighborCol)) {
171
+ if (runStart === null) runStart = row;
172
+ continue;
173
+ }
174
+ if (runStart !== null) {
175
+ edges.push({
176
+ side,
177
+ offsetRatio: (runStart - rowIndex) / span,
178
+ heightRatio: (row - runStart) / span
179
+ });
180
+ runStart = null;
181
+ }
182
+ }
183
+ if (runStart !== null) {
184
+ edges.push({
185
+ side,
186
+ offsetRatio: (runStart - rowIndex) / span,
187
+ heightRatio: (toRowExclusive - runStart) / span
188
+ });
189
+ }
190
+ };
191
+ const collectSide = (side, neighborCol) => {
192
+ if (bounds.startRow > rowIndex) {
193
+ pushUnselectedRuns(
194
+ side,
195
+ neighborCol,
196
+ rowIndex,
197
+ Math.min(bounds.startRow, cellEndRow + 1)
198
+ );
199
+ }
200
+ if (bounds.endRow < cellEndRow) {
201
+ pushUnselectedRuns(
202
+ side,
203
+ neighborCol,
204
+ Math.max(bounds.endRow + 1, rowIndex),
205
+ cellEndRow + 1
206
+ );
207
+ }
208
+ };
209
+ if (colIndex < bounds.endCol) {
210
+ collectSide("right", colIndex + 1);
211
+ }
212
+ if (colIndex > bounds.startCol) {
213
+ collectSide("left", colIndex - 1);
214
+ }
215
+ return edges;
216
+ }
217
+ function buildPartialVerticalGradient(edge) {
218
+ const startPct = edge.offsetRatio * 100;
219
+ const endPct = (edge.offsetRatio + edge.heightRatio) * 100;
220
+ const overlapPx = SELECTION_EDGE_WIDTH_PX + 1;
221
+ const isTopProtrusion = edge.offsetRatio === 0 && edge.heightRatio < 1;
222
+ const isBottomProtrusion = edge.offsetRatio > 0;
223
+ const startStop = isBottomProtrusion ? `calc(${startPct}% - ${overlapPx}px)` : `${startPct}%`;
224
+ const endStop = isTopProtrusion ? `calc(${endPct}% + ${overlapPx}px)` : `${endPct}%`;
225
+ const xPos = edge.side === "left" ? "0" : "100%";
226
+ const layers = [
227
+ {
228
+ image: `linear-gradient(to bottom, transparent 0%, transparent ${startStop}, ${SELECTION_EDGE_COLOR} ${startStop}, ${SELECTION_EDGE_COLOR} ${endStop}, transparent ${endStop}, transparent 100%)`,
229
+ size: `${SELECTION_EDGE_WIDTH_PX}px 100%`,
230
+ position: `${xPos} 0`
231
+ }
232
+ ];
233
+ if (isTopProtrusion || isBottomProtrusion) {
234
+ const capTop = isTopProtrusion ? `calc(${endPct}% - ${SELECTION_EDGE_WIDTH_PX}px)` : `calc(${startPct}% - ${SELECTION_EDGE_WIDTH_PX}px)`;
235
+ layers.push({
236
+ image: `linear-gradient(${SELECTION_EDGE_COLOR}, ${SELECTION_EDGE_COLOR})`,
237
+ size: `${SELECTION_EDGE_WIDTH_PX}px ${SELECTION_EDGE_WIDTH_PX}px`,
238
+ position: `${xPos} ${capTop}`
239
+ });
240
+ }
241
+ return layers;
242
+ }
243
+ function getCellSelectionEdgeStyle(rowIndex, colIndex, bounds, rowSpan = 1, isVisuallySelectedAt) {
244
+ if (!isCellInSelection(rowIndex, colIndex, bounds, rowSpan) || !bounds)
245
+ return void 0;
246
+ const cellEndRow = rowIndex + rowSpan - 1;
247
+ const isTopEdge = bounds.startRow >= rowIndex && bounds.startRow <= cellEndRow;
248
+ const isBottomEdge = bounds.endRow >= rowIndex && bounds.endRow <= cellEndRow;
249
+ const isLeftEdge = colIndex === bounds.startCol;
250
+ const isRightEdge = colIndex === bounds.endCol;
251
+ const selectionContinuesBelow = cellEndRow < bounds.endRow;
252
+ const shadows = [];
253
+ if (isTopEdge) {
254
+ shadows.push(
255
+ `inset 0 ${SELECTION_EDGE_WIDTH_PX}px 0 0 ${SELECTION_EDGE_COLOR}`
256
+ );
257
+ }
258
+ if (isBottomEdge) {
259
+ shadows.push(
260
+ `inset 0 -${SELECTION_EDGE_WIDTH_PX}px 0 0 ${SELECTION_EDGE_COLOR}`
261
+ );
262
+ }
263
+ if (isLeftEdge) {
264
+ shadows.push(
265
+ `inset ${SELECTION_EDGE_WIDTH_PX}px 0 0 0 ${SELECTION_EDGE_COLOR}`
266
+ );
267
+ }
268
+ if (isRightEdge) {
269
+ shadows.push(
270
+ `inset -${SELECTION_EDGE_WIDTH_PX}px 0 0 0 ${SELECTION_EDGE_COLOR}`
271
+ );
272
+ }
273
+ const stepEdges = getMergedCellStepEdges(
274
+ rowIndex,
275
+ colIndex,
276
+ bounds,
277
+ rowSpan,
278
+ isVisuallySelectedAt
279
+ );
280
+ const gradients = [];
281
+ const sizes = [];
282
+ const positions = [];
283
+ for (const edge of stepEdges) {
284
+ for (const partial of buildPartialVerticalGradient(edge)) {
285
+ gradients.push(partial.image);
286
+ sizes.push(partial.size);
287
+ positions.push(partial.position);
288
+ }
289
+ }
290
+ if (shadows.length === 0 && gradients.length === 0 && !selectionContinuesBelow) {
291
+ return void 0;
292
+ }
293
+ const style = {};
294
+ if (shadows.length > 0) {
295
+ style["--selection-edge-shadows"] = shadows.join(", ");
296
+ }
297
+ if (gradients.length > 0) {
298
+ style["--selection-edge-gradients"] = gradients.join(", ");
299
+ style["--selection-edge-sizes"] = sizes.join(", ");
300
+ style["--selection-edge-positions"] = positions.join(", ");
301
+ }
302
+ if (selectionContinuesBelow) {
303
+ style.borderBottomColor = "var(--color-brand-surface)";
304
+ }
305
+ return style;
306
+ }
307
+ function hasCellSelectionEdges(style) {
308
+ return Boolean(
309
+ style?.["--selection-edge-shadows"] || style?.["--selection-edge-gradients"]
310
+ );
311
+ }
312
+
313
+ // src/components/ui/table/features/row-expand/row-expand.ts
314
+ var import_react2 = require("react");
315
+
316
+ // src/core/treeDefaults.ts
317
+ var DEFAULT_TREE_ID_FIELD = "id";
318
+ var DEFAULT_TREE_PARENT_ID_FIELD = "parentId";
319
+ var DEFAULT_TREE_CHILDREN_FIELD = "children";
320
+ var DEFAULT_TREE_QTY_FIELD = "qty";
321
+
322
+ // src/components/ui/table/features/row-expand/row-expand.ts
323
+ function getFieldValue(row, key) {
324
+ return row[key];
325
+ }
326
+ function canExpandRow(row) {
327
+ const children = row.children;
328
+ const level = row.level;
329
+ return Array.isArray(children) && children.length > 0 && (level === 0 || level === void 0);
330
+ }
331
+ function toggleExpandedRowId(rowId, previous) {
332
+ const next = new Set(previous);
333
+ if (next.has(rowId)) {
334
+ next.delete(rowId);
335
+ } else {
336
+ next.add(rowId);
337
+ }
338
+ return next;
339
+ }
340
+ var useConvertTreeData = ({
341
+ data,
342
+ enabled = true,
343
+ toggleField = DEFAULT_TREE_ID_FIELD,
344
+ childField = DEFAULT_TREE_PARENT_ID_FIELD,
345
+ flattenField = DEFAULT_TREE_CHILDREN_FIELD,
346
+ qtyField = DEFAULT_TREE_QTY_FIELD,
347
+ preventExpand = false,
348
+ startIndex = 1,
349
+ expandedRows,
350
+ onExpandedRowsChange
351
+ }) => {
352
+ const onExpandedRowsChangeRef = (0, import_react2.useRef)(onExpandedRowsChange);
353
+ const hasInitializedRef = (0, import_react2.useRef)(false);
354
+ (0, import_react2.useEffect)(() => {
355
+ onExpandedRowsChangeRef.current = onExpandedRowsChange;
356
+ }, [onExpandedRowsChange]);
357
+ (0, import_react2.useEffect)(() => {
358
+ if (!data || data.length === 0) {
359
+ hasInitializedRef.current = false;
360
+ return;
361
+ }
362
+ if (!enabled || hasInitializedRef.current) return;
363
+ const ids = data.map((item) => getFieldValue(item, toggleField)).filter((value) => typeof value === "string" && value.length > 0);
364
+ onExpandedRowsChangeRef.current?.(new Set(ids));
365
+ hasInitializedRef.current = true;
366
+ }, [enabled, data, toggleField]);
367
+ const processedData = (0, import_react2.useMemo)(() => {
368
+ if (!enabled || !data || data.length === 0) return [];
369
+ const flattenedData = [];
370
+ const flattenItems = (items) => {
371
+ items.forEach((item) => {
372
+ const newItem = { ...item };
373
+ const nested = newItem[flattenField];
374
+ if (Array.isArray(nested)) {
375
+ const children = nested.map(
376
+ (child) => typeof child === "object" && child !== null ? { ...child } : child
377
+ );
378
+ delete newItem[flattenField];
379
+ flattenedData.push(newItem);
380
+ children.forEach((child) => {
381
+ if (typeof child === "object" && child !== null) {
382
+ ;
383
+ child[childField] = newItem[toggleField];
384
+ }
385
+ });
386
+ flattenItems(children);
387
+ } else {
388
+ flattenedData.push(newItem);
389
+ }
390
+ });
391
+ };
392
+ flattenItems(data);
393
+ const dataWithLevels = flattenedData.map((item) => ({
394
+ ...item,
395
+ level: 0,
396
+ children: [],
397
+ processed: false
398
+ }));
399
+ const itemMap = /* @__PURE__ */ new Map();
400
+ dataWithLevels.forEach((item) => {
401
+ const key = getFieldValue(item, toggleField);
402
+ if (typeof key !== "string" || !key) return;
403
+ if (!itemMap.has(key)) {
404
+ itemMap.set(key, []);
405
+ }
406
+ itemMap.get(key)?.push(item);
407
+ });
408
+ const rootItems = [];
409
+ dataWithLevels.forEach((item) => {
410
+ if (!getFieldValue(item, childField)) {
411
+ rootItems.push(item);
412
+ item.processed = true;
413
+ }
414
+ });
415
+ dataWithLevels.forEach((item) => {
416
+ const parentKey = getFieldValue(item, childField);
417
+ if (!parentKey || item.processed) return;
418
+ const parentItems = dataWithLevels.filter(
419
+ (parent) => getFieldValue(parent, toggleField) === parentKey && !getFieldValue(parent, childField)
420
+ );
421
+ if (parentItems.length > 0) {
422
+ const parent = parentItems[0];
423
+ item.level = parent.level + 1;
424
+ parent.children.push(item);
425
+ item.processed = true;
426
+ } else {
427
+ const otherParents = itemMap.get(String(parentKey)) || [];
428
+ if (otherParents.length > 0) {
429
+ const parent = otherParents[0];
430
+ item.level = parent.level + 1;
431
+ parent.children.push(item);
432
+ item.processed = true;
433
+ } else {
434
+ rootItems.push(item);
435
+ item.processed = true;
436
+ }
437
+ }
438
+ });
439
+ return rootItems;
440
+ }, [enabled, data, toggleField, childField, flattenField]);
441
+ const flattenTree = (0, import_react2.useMemo)(() => {
442
+ if (!enabled) return [];
443
+ const flatten = (nodes, result = [], level = 0) => {
444
+ nodes.forEach((node, index) => {
445
+ const currentIndex = level === 0 ? `${index + startIndex}` : `${level}-${index + 1}`;
446
+ const toggleValue = getFieldValue(node, toggleField);
447
+ const uniqueId = `${index}-${String(toggleValue ?? "")}`;
448
+ result.push({
449
+ ...node,
450
+ treeNo: currentIndex,
451
+ uniqueId,
452
+ processed: true
453
+ });
454
+ const shouldExpandChildren = node.children.length > 0 && (preventExpand || typeof toggleValue === "string" && expandedRows?.has(toggleValue));
455
+ if (shouldExpandChildren) {
456
+ flatten(node.children, result, index + startIndex);
457
+ }
458
+ });
459
+ return result;
460
+ };
461
+ const flattenedData = flatten(processedData, [], 0);
462
+ flattenedData.forEach((item) => {
463
+ if (getFieldValue(item, childField)) {
464
+ const parentItem = flattenedData.find(
465
+ (parent) => getFieldValue(parent, toggleField) === getFieldValue(item, childField)
466
+ );
467
+ const parentAmount = parentItem ? Number(getFieldValue(parentItem, qtyField) ?? 1) : 1;
468
+ item.parentCount = parentAmount || 1;
469
+ } else {
470
+ item.parentCount = 1;
471
+ }
472
+ });
473
+ return flattenedData;
474
+ }, [
475
+ enabled,
476
+ processedData,
477
+ startIndex,
478
+ toggleField,
479
+ childField,
480
+ qtyField,
481
+ preventExpand,
482
+ expandedRows
483
+ ]);
484
+ const sortedData = (0, import_react2.useMemo)(() => {
485
+ if (!enabled) {
486
+ return data ?? [];
487
+ }
488
+ return [...flattenTree].sort((a, b) => {
489
+ const aParts = String(a.treeNo ?? "").split("-").map(Number);
490
+ const bParts = String(b.treeNo ?? "").split("-").map(Number);
491
+ for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
492
+ const aVal = aParts[i] || 0;
493
+ const bVal = bParts[i] || 0;
494
+ if (aVal !== bVal) {
495
+ return aVal - bVal;
496
+ }
497
+ }
498
+ return 0;
499
+ });
500
+ }, [enabled, data, flattenTree]);
501
+ return sortedData;
502
+ };
503
+
504
+ // src/components/ui/table/features/row-span/rowSpan.ts
505
+ function getRowFieldValue(row, key) {
506
+ return row[key];
507
+ }
508
+ function computeRowSpans(data, rowSpanKey) {
509
+ if (data.length === 0) return [];
510
+ const result = [];
511
+ for (let index = 0; index < data.length; index++) {
512
+ const currentValue = getRowFieldValue(data[index], rowSpanKey);
513
+ const previousValue = index > 0 ? getRowFieldValue(data[index - 1], rowSpanKey) : void 0;
514
+ if (index > 0 && currentValue === previousValue) {
515
+ result.push({ rowSpan: 0, isFirstInGroup: false });
516
+ continue;
517
+ }
518
+ let span = 1;
519
+ for (let nextIndex = index + 1; nextIndex < data.length; nextIndex++) {
520
+ if (getRowFieldValue(data[nextIndex], rowSpanKey) === currentValue) {
521
+ span++;
522
+ } else {
523
+ break;
524
+ }
525
+ }
526
+ result.push({ rowSpan: span, isFirstInGroup: true });
527
+ }
528
+ return result;
529
+ }
530
+ function resolveRowSpanAt(rowSpans, rowIndex) {
531
+ if (!rowSpans?.[rowIndex]) {
532
+ return { startRow: rowIndex, rowSpan: 1 };
533
+ }
534
+ const current = rowSpans[rowIndex];
535
+ if (current.rowSpan > 0) {
536
+ return { startRow: rowIndex, rowSpan: current.rowSpan };
537
+ }
538
+ for (let row = rowIndex - 1; row >= 0; row--) {
539
+ const info = rowSpans[row];
540
+ if (info && info.rowSpan > 0) {
541
+ return { startRow: row, rowSpan: info.rowSpan };
542
+ }
543
+ }
544
+ return { startRow: rowIndex, rowSpan: 1 };
545
+ }
546
+ function buildColumnRowSpanMap(data, columnKeys) {
547
+ const map = /* @__PURE__ */ new Map();
548
+ for (const { columnId, rowSpanKey } of columnKeys) {
549
+ map.set(columnId, computeRowSpans(data, rowSpanKey));
550
+ }
551
+ return map;
552
+ }
553
+ function collectRowSpanColumns(columns) {
554
+ const result = [];
555
+ const visit = (defs) => {
556
+ for (const columnDef of defs) {
557
+ if ("columns" in columnDef && columnDef.columns?.length) {
558
+ visit(columnDef.columns);
559
+ continue;
560
+ }
561
+ const columnId = columnDef.id ?? ("accessorKey" in columnDef && columnDef.accessorKey ? String(columnDef.accessorKey) : void 0);
562
+ if (!columnId || !columnDef.meta?.rowSpan) continue;
563
+ result.push({
564
+ columnId,
565
+ rowSpanKey: columnDef.meta.rowSpanKey ?? columnId
566
+ });
567
+ }
568
+ };
569
+ visit(columns);
570
+ return result;
571
+ }
572
+
573
+ // src/components/ui/table/components/icons.tsx
574
+ var import_jsx_runtime2 = require("react/jsx-runtime");
575
+ function ChevronDown({ className, "aria-hidden": ariaHidden = true }) {
576
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
577
+ "svg",
578
+ {
579
+ className,
580
+ "aria-hidden": ariaHidden,
581
+ width: "16",
582
+ height: "16",
583
+ viewBox: "0 0 24 24",
584
+ fill: "none",
585
+ stroke: "currentColor",
586
+ strokeWidth: "2",
587
+ strokeLinecap: "round",
588
+ strokeLinejoin: "round",
589
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" })
590
+ }
591
+ );
592
+ }
593
+ function ChevronUp({ className, "aria-hidden": ariaHidden = true }) {
594
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
595
+ "svg",
596
+ {
597
+ className,
598
+ "aria-hidden": ariaHidden,
599
+ width: "16",
600
+ height: "16",
601
+ viewBox: "0 0 24 24",
602
+ fill: "none",
603
+ stroke: "currentColor",
604
+ strokeWidth: "2",
605
+ strokeLinecap: "round",
606
+ strokeLinejoin: "round",
607
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" })
608
+ }
609
+ );
610
+ }
611
+ function ChevronLeft({ className, "aria-hidden": ariaHidden = true }) {
612
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
613
+ "svg",
614
+ {
615
+ className,
616
+ "aria-hidden": ariaHidden,
617
+ width: "16",
618
+ height: "16",
619
+ viewBox: "0 0 24 24",
620
+ fill: "none",
621
+ stroke: "currentColor",
622
+ strokeWidth: "2",
623
+ strokeLinecap: "round",
624
+ strokeLinejoin: "round",
625
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" })
626
+ }
627
+ );
628
+ }
629
+ function ChevronRight({ className, "aria-hidden": ariaHidden = true }) {
630
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
631
+ "svg",
632
+ {
633
+ className,
634
+ "aria-hidden": ariaHidden,
635
+ width: "16",
636
+ height: "16",
637
+ viewBox: "0 0 24 24",
638
+ fill: "none",
639
+ stroke: "currentColor",
640
+ strokeWidth: "2",
641
+ strokeLinecap: "round",
642
+ strokeLinejoin: "round",
643
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m9 18 6-6-6-6" })
644
+ }
645
+ );
646
+ }
647
+ function ArrowUp({ className, "aria-hidden": ariaHidden = true }) {
648
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
649
+ "svg",
650
+ {
651
+ className,
652
+ "aria-hidden": ariaHidden,
653
+ width: "14",
654
+ height: "14",
655
+ viewBox: "0 0 24 24",
656
+ fill: "none",
657
+ stroke: "currentColor",
658
+ strokeWidth: "2",
659
+ strokeLinecap: "round",
660
+ strokeLinejoin: "round",
661
+ children: [
662
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m18 15-6-6-6 6" }),
663
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 21V9" })
664
+ ]
665
+ }
666
+ );
667
+ }
668
+ function ArrowDown({ className, "aria-hidden": ariaHidden = true }) {
669
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
670
+ "svg",
671
+ {
672
+ className,
673
+ "aria-hidden": ariaHidden,
674
+ width: "14",
675
+ height: "14",
676
+ viewBox: "0 0 24 24",
677
+ fill: "none",
678
+ stroke: "currentColor",
679
+ strokeWidth: "2",
680
+ strokeLinecap: "round",
681
+ strokeLinejoin: "round",
682
+ children: [
683
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }),
684
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 3v12" })
685
+ ]
686
+ }
687
+ );
688
+ }
689
+ function ArrowUpDown({ className, "aria-hidden": ariaHidden = true }) {
690
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
691
+ "svg",
692
+ {
693
+ className,
694
+ "aria-hidden": ariaHidden,
695
+ width: "14",
696
+ height: "14",
697
+ viewBox: "0 0 24 24",
698
+ fill: "none",
699
+ stroke: "currentColor",
700
+ strokeWidth: "2",
701
+ strokeLinecap: "round",
702
+ strokeLinejoin: "round",
703
+ children: [
704
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 16-4 4-4-4" }),
705
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 20V4" }),
706
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m3 8 4-4 4 4" }),
707
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M7 4v16" })
708
+ ]
709
+ }
710
+ );
711
+ }
712
+
713
+ // src/lib/cn.ts
714
+ function cn(...inputs) {
715
+ return inputs.filter(Boolean).join(" ");
716
+ }
717
+
718
+ // src/components/ui/table/components/DataTable/DataTableRow.tsx
719
+ var import_jsx_runtime3 = require("react/jsx-runtime");
720
+ function resolveExpandCellIndex(cells, toggleField) {
721
+ if (!toggleField) return 0;
722
+ const matchedIndex = cells.findIndex(
723
+ (cell) => cell.column.id === toggleField
724
+ );
725
+ if (matchedIndex >= 0) return matchedIndex;
726
+ const noColumnIndex = cells.findIndex(
727
+ (cell) => cell.column.id === "no" || cell.column.id === "treeNo"
728
+ );
729
+ if (noColumnIndex >= 0 && noColumnIndex + 1 < cells.length) {
730
+ return noColumnIndex + 1;
731
+ }
732
+ return 0;
733
+ }
734
+ function DataTableRow({
735
+ row,
736
+ onToggleSelect,
737
+ virtualIndex,
738
+ measureElement
739
+ }) {
740
+ const { classNames, rowSpan, selection, cellSelection, cellEdit, expand } = useDataTableRowContext();
741
+ const {
742
+ enableRowSpan,
743
+ primaryRowSpanKey,
744
+ columnRowSpanMap,
745
+ hoveredRowIndex,
746
+ hoveredGroupKey,
747
+ selectedGroupKeys,
748
+ onRowHover
749
+ } = rowSpan;
750
+ const { rowSelectionMode, selectOnRowClick, onRowClick, getRowClassName } = selection;
751
+ const {
752
+ enableCellSelection,
753
+ activeSelectionBounds,
754
+ dragState,
755
+ onCellMouseDown,
756
+ onCellMouseEnter,
757
+ onFillHandleMouseDown
758
+ } = cellSelection;
759
+ const {
760
+ editingCell,
761
+ draftValue,
762
+ onDraftValueChange,
763
+ onStartEdit,
764
+ onCommitEdit,
765
+ onCancelEdit
766
+ } = cellEdit;
767
+ const {
768
+ enableExpand,
769
+ toggleField,
770
+ expandedRows,
771
+ preventExpand,
772
+ onToggleExpand,
773
+ expandRowLabel,
774
+ collapseRowLabel
775
+ } = expand;
776
+ const rowIndex = row.index;
777
+ const rowData = row.original;
778
+ const isRowHovered = hoveredRowIndex === rowIndex;
779
+ const isRowSelected = row.getIsSelected();
780
+ const rowGroupKey = primaryRowSpanKey !== void 0 && rowData[primaryRowSpanKey] !== null && rowData[primaryRowSpanKey] !== void 0 ? String(rowData[primaryRowSpanKey]) : null;
781
+ const isGroupHovered = enableRowSpan && hoveredGroupKey !== null && rowGroupKey === hoveredGroupKey;
782
+ const isGroupSelected = enableRowSpan && rowGroupKey !== null && selectedGroupKeys.has(rowGroupKey);
783
+ const visibleCells = row.getVisibleCells();
784
+ const columnIdsByIndex = visibleCells.map((cell) => cell.column.id);
785
+ const isVisuallySelectedAt = activeSelectionBounds ? (targetRow, targetCol) => {
786
+ if (targetCol < activeSelectionBounds.startCol || targetCol > activeSelectionBounds.endCol) {
787
+ return false;
788
+ }
789
+ const columnId = columnIdsByIndex[targetCol];
790
+ const { startRow, rowSpan: span } = resolveRowSpanAt(
791
+ columnId ? columnRowSpanMap.get(columnId) : void 0,
792
+ targetRow
793
+ );
794
+ return isCellInSelection(
795
+ startRow,
796
+ targetCol,
797
+ activeSelectionBounds,
798
+ span
799
+ );
800
+ } : void 0;
801
+ const expandCellIndex = enableExpand ? resolveExpandCellIndex(visibleCells, toggleField) : -1;
802
+ const canExpand = enableExpand && !preventExpand && canExpandRow(rowData);
803
+ const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
804
+ const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
805
+ const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
806
+ const editInputRef = (0, import_react3.useRef)(null);
807
+ const isRowEditing = editingCell?.rowIndex === rowIndex;
808
+ (0, import_react3.useEffect)(() => {
809
+ if (!isRowEditing) return;
810
+ editInputRef.current?.focus();
811
+ editInputRef.current?.select();
812
+ }, [isRowEditing, editingCell?.colIndex]);
813
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
814
+ "tr",
815
+ {
816
+ ref: measureElement,
817
+ "data-index": virtualIndex,
818
+ "data-selected": isRowSelected ? "" : void 0,
819
+ "data-hovered": isRowHovered || isGroupHovered ? "" : void 0,
820
+ "data-expandable": enableExpand && canExpand ? "" : void 0,
821
+ "data-expanded": isExpanded ? "" : void 0,
822
+ className: cn(
823
+ "DataTableRowJSX",
824
+ !enableRowSpan && ROW_HOVER_CLASS,
825
+ enableRowSpan && isRowHovered && !isRowSelected && ROW_HOVERED_BG_CLASS,
826
+ isRowSelected && "is-selected",
827
+ enableExpand && canExpand && "is-expandable",
828
+ classNames?.row,
829
+ getRowClassName?.(rowData, rowIndex)
830
+ ),
831
+ onMouseEnter: () => onRowHover(rowIndex, rowData),
832
+ onClick: () => {
833
+ if (isRowEditing) return;
834
+ onRowClick?.(rowData, rowIndex);
835
+ if (rowSelectionMode !== "none" && selectOnRowClick) {
836
+ onToggleSelect();
837
+ }
838
+ },
839
+ children: visibleCells.map((cell, cellIndex) => {
840
+ const columnId = cell.column.id;
841
+ const meta = cell.column.columnDef.meta;
842
+ const align = meta?.align ?? "center";
843
+ const cellClassName = meta?.className;
844
+ const isRowSpanColumn = Boolean(enableRowSpan && meta?.rowSpan);
845
+ const isExpandCell = cellIndex === expandCellIndex;
846
+ const editable = isColumnEditable(cell.column.columnDef);
847
+ const editType = getColumnEditType(cell.column.columnDef);
848
+ let rowSpanInfo;
849
+ if (isRowSpanColumn) {
850
+ rowSpanInfo = columnRowSpanMap.get(columnId)?.[rowIndex];
851
+ if (rowSpanInfo && rowSpanInfo.rowSpan === 0) {
852
+ return null;
853
+ }
854
+ }
855
+ const isEditing = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === cellIndex;
856
+ const showCellHover = isRowSpanColumn ? isGroupHovered : isRowHovered;
857
+ const showCellSelected = isRowSpanColumn ? isGroupSelected : isRowSelected;
858
+ const cellRowSpan = rowSpanInfo?.rowSpan ?? 1;
859
+ const isMerged = cellRowSpan > 1;
860
+ const showMergedRightEdge = isMerged && (cellIndex === visibleCells.length - 1 || resolveRowSpanAt(
861
+ columnRowSpanMap.get(columnIdsByIndex[cellIndex + 1]),
862
+ rowIndex
863
+ ).rowSpan <= 1);
864
+ const isCellDragSelected = isCellInSelection(
865
+ rowIndex,
866
+ cellIndex,
867
+ activeSelectionBounds,
868
+ cellRowSpan
869
+ );
870
+ const isBottomRightCell = !isEditing && activeSelectionBounds && !dragState.isSelecting && activeSelectionBounds.endRow >= rowIndex && activeSelectionBounds.endRow <= rowIndex + cellRowSpan - 1 && cellIndex === activeSelectionBounds.endCol;
871
+ const selectionEdgeStyle = getCellSelectionEdgeStyle(
872
+ rowIndex,
873
+ cellIndex,
874
+ activeSelectionBounds,
875
+ cellRowSpan,
876
+ isVisuallySelectedAt
877
+ );
878
+ const resolveCellRowIndex = (clientY, element) => getRowIndexInMergedCell(clientY, element, rowIndex, cellRowSpan);
879
+ const hasSelectionEdges = hasCellSelectionEdges(selectionEdgeStyle);
880
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
881
+ "td",
882
+ {
883
+ rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
884
+ "data-merged": isMerged && cellIndex > 0 ? "" : void 0,
885
+ "data-merged-edge-right": showMergedRightEdge ? "" : void 0,
886
+ "data-group-selected": enableRowSpan && showCellSelected ? "" : void 0,
887
+ "data-group-hovered": enableRowSpan && showCellHover && !showCellSelected ? "" : void 0,
888
+ "data-selection-fill": isCellDragSelected ? "" : void 0,
889
+ "data-selection-edges": hasSelectionEdges ? "" : void 0,
890
+ "data-editable": editable ? "" : void 0,
891
+ "data-editing": isEditing ? "" : void 0,
892
+ onMouseDown: (event) => {
893
+ if (isEditing) {
894
+ event.stopPropagation();
895
+ return;
896
+ }
897
+ if (!enableCellSelection) return;
898
+ event.preventDefault();
899
+ onCellMouseDown(
900
+ resolveCellRowIndex(event.clientY, event.currentTarget),
901
+ cellIndex
902
+ );
903
+ },
904
+ onMouseEnter: (event) => {
905
+ if (!enableCellSelection) return;
906
+ onCellMouseEnter(
907
+ resolveCellRowIndex(event.clientY, event.currentTarget),
908
+ cellIndex
909
+ );
910
+ },
911
+ onMouseMove: (event) => {
912
+ if (!enableCellSelection) return;
913
+ if (!dragState.isSelecting && !dragState.isFillDragging) return;
914
+ onCellMouseEnter(
915
+ resolveCellRowIndex(event.clientY, event.currentTarget),
916
+ cellIndex
917
+ );
918
+ },
919
+ onDoubleClick: (event) => {
920
+ if (!editable) return;
921
+ event.preventDefault();
922
+ event.stopPropagation();
923
+ onStartEdit(rowIndex, cellIndex);
924
+ },
925
+ style: selectionEdgeStyle,
926
+ className: cn(
927
+ "data-table-cell",
928
+ CELL_ALIGN_CLASS[align],
929
+ cellClassName,
930
+ isMerged && cellIndex > 0 && "is-merged",
931
+ showMergedRightEdge && "is-merged-edge-right",
932
+ enableRowSpan && showCellSelected && "is-group-selected",
933
+ enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
934
+ isCellDragSelected && CELL_SELECTION_FILL_CLASS,
935
+ hasSelectionEdges && CELL_SELECTION_EDGES_CLASS,
936
+ editable && "is-editable",
937
+ classNames?.cell
938
+ ),
939
+ children: [
940
+ isEditing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
941
+ "input",
942
+ {
943
+ ref: editInputRef,
944
+ type: editType === "number" ? "number" : "text",
945
+ defaultValue: draftValue,
946
+ className: cn(
947
+ "cell-edit-input",
948
+ CELL_ALIGN_CLASS[align],
949
+ classNames?.cellEditInput
950
+ ),
951
+ onChange: (event) => onDraftValueChange(event.target.value),
952
+ onMouseDown: (event) => event.stopPropagation(),
953
+ onClick: (event) => event.stopPropagation(),
954
+ onKeyDown: (event) => {
955
+ if (event.key === "Enter") {
956
+ event.preventDefault();
957
+ onCommitEdit(event.currentTarget.value);
958
+ }
959
+ if (event.key === "Escape") {
960
+ event.preventDefault();
961
+ onCancelEdit();
962
+ }
963
+ },
964
+ onBlur: (event) => {
965
+ onCommitEdit(event.currentTarget.value);
966
+ }
967
+ }
968
+ ) : isExpandCell && enableExpand ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: cn("expand-cell", classNames?.expandCell), children: [
969
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
970
+ "div",
971
+ {
972
+ className: cn(
973
+ "expand-cell-content",
974
+ classNames?.expandCellContent
975
+ ),
976
+ children: [
977
+ rowLevel > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
978
+ "span",
979
+ {
980
+ className: cn(
981
+ "expand-cell-indent",
982
+ classNames?.expandCellIndent
983
+ ),
984
+ children: "\xB7"
985
+ }
986
+ ),
987
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
988
+ "div",
989
+ {
990
+ className: cn(
991
+ "expand-cell-value",
992
+ classNames?.expandCellValue
993
+ ),
994
+ children: (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext())
995
+ }
996
+ )
997
+ ]
998
+ }
999
+ ),
1000
+ canExpand && expandKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1001
+ "button",
1002
+ {
1003
+ type: "button",
1004
+ "aria-label": isExpanded ? collapseRowLabel : expandRowLabel,
1005
+ className: cn(
1006
+ "expand-toggle-button",
1007
+ classNames?.expandToggle
1008
+ ),
1009
+ onClick: (event) => {
1010
+ event.stopPropagation();
1011
+ onToggleExpand?.(expandKey);
1012
+ },
1013
+ onMouseDown: (event) => event.stopPropagation(),
1014
+ children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1015
+ ChevronUp,
1016
+ {
1017
+ className: cn(
1018
+ "expand-toggle-icon",
1019
+ classNames?.expandToggleIcon
1020
+ )
1021
+ }
1022
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1023
+ ChevronDown,
1024
+ {
1025
+ className: cn(
1026
+ "expand-toggle-icon",
1027
+ classNames?.expandToggleIcon
1028
+ )
1029
+ }
1030
+ )
1031
+ }
1032
+ )
1033
+ ] }) : (0, import_react_table.flexRender)(cell.column.columnDef.cell, cell.getContext()),
1034
+ isBottomRightCell && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1035
+ "div",
1036
+ {
1037
+ role: "presentation",
1038
+ className: cn("fill-handle", classNames?.fillHandle),
1039
+ onMouseDown: (event) => {
1040
+ event.stopPropagation();
1041
+ event.preventDefault();
1042
+ onFillHandleMouseDown(rowIndex, cellIndex);
1043
+ }
1044
+ }
1045
+ )
1046
+ ]
1047
+ },
1048
+ cell.id
1049
+ );
1050
+ })
1051
+ }
1052
+ );
1053
+ }
1054
+
1055
+ // src/components/ui/table/components/DataTable/DataTableToolbar.tsx
1056
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1057
+ function DataTableToolbar({
1058
+ filteredCount,
1059
+ totalCount,
1060
+ summary,
1061
+ selectedCount,
1062
+ selectionLabel,
1063
+ toolbar,
1064
+ className,
1065
+ classNames
1066
+ }) {
1067
+ const displayFiltered = filteredCount ?? totalCount;
1068
+ const hasCount = displayFiltered !== void 0 || totalCount !== void 0;
1069
+ const hasLeftContent = hasCount || Boolean(summary);
1070
+ const hasToolbar = Boolean(toolbar);
1071
+ const selectionContent = selectionLabel?.(selectedCount) ?? null;
1072
+ const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
1073
+ if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
1074
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("DataTableToolbarJSX", classNames?.toolbar, className), children: [
1075
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("toolbar-left", classNames?.toolbarLeft), children: [
1076
+ hasCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn("toolbar-count", classNames?.toolbarCount), children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1077
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered }),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "toolbar-count-placeholder", children: [
1079
+ " / ",
1080
+ totalCount
1081
+ ] })
1082
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
1083
+ summary
1084
+ ] }),
1085
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: cn("toolbar-right", classNames?.toolbarRight), children: [
1086
+ hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: cn("toolbar-selection", classNames?.toolbarSelection), children: selectionContent }) : selectionContent),
1087
+ hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("toolbar-actions", classNames?.toolbarActions), children: toolbar })
1088
+ ] })
1089
+ ] });
1090
+ }
1091
+
1092
+ // src/core/useGlideTable.ts
1093
+ var import_react_table2 = require("@tanstack/react-table");
1094
+ var import_react_virtual = require("@tanstack/react-virtual");
1095
+ var import_react6 = require("react");
1096
+
1097
+ // src/components/ui/table/features/cell-edit/useCellEdit.ts
1098
+ var import_react4 = require("react");
1099
+ function useCellEdit({
1100
+ data,
1101
+ rows,
1102
+ onDataChange,
1103
+ onCellChange
1104
+ }) {
1105
+ const [editingCell, setEditingCell] = (0, import_react4.useState)(null);
1106
+ const [draftValue, setDraftValue] = (0, import_react4.useState)("");
1107
+ const draftValueRef = (0, import_react4.useRef)(draftValue);
1108
+ const editingCellRef = (0, import_react4.useRef)(editingCell);
1109
+ (0, import_react4.useEffect)(() => {
1110
+ draftValueRef.current = draftValue;
1111
+ }, [draftValue]);
1112
+ (0, import_react4.useEffect)(() => {
1113
+ editingCellRef.current = editingCell;
1114
+ }, [editingCell]);
1115
+ const cancelEdit = (0, import_react4.useCallback)(() => {
1116
+ setEditingCell(null);
1117
+ setDraftValue("");
1118
+ }, []);
1119
+ const commitEdit = (0, import_react4.useCallback)(
1120
+ (raw) => {
1121
+ const current = editingCellRef.current;
1122
+ if (!current) return true;
1123
+ if (!onCellChange && !onDataChange) {
1124
+ cancelEdit();
1125
+ return true;
1126
+ }
1127
+ const row = rows[current.rowIndex];
1128
+ const cell = row?.getVisibleCells()[current.colIndex];
1129
+ if (!row || !cell) {
1130
+ cancelEdit();
1131
+ return true;
1132
+ }
1133
+ const value = raw ?? draftValueRef.current;
1134
+ if (!isColumnEditable(cell.column.columnDef)) {
1135
+ cancelEdit();
1136
+ return true;
1137
+ }
1138
+ const parsed = parseCellEditValue(value, getColumnEditType(cell.column.columnDef));
1139
+ if (!parsed.ok) return false;
1140
+ if (onCellChange) {
1141
+ onCellChange(row.id, cell.column.id, parsed.value);
1142
+ cancelEdit();
1143
+ return true;
1144
+ }
1145
+ const next = applyCellEdit(data, rows, current.rowIndex, current.colIndex, value);
1146
+ if (!next) return false;
1147
+ onDataChange?.(next);
1148
+ cancelEdit();
1149
+ return true;
1150
+ },
1151
+ [cancelEdit, data, onCellChange, onDataChange, rows]
1152
+ );
1153
+ const startEdit = (0, import_react4.useCallback)(
1154
+ (rowIndex, colIndex) => {
1155
+ const cell = rows[rowIndex]?.getVisibleCells()[colIndex];
1156
+ if (!cell || !isColumnEditable(cell.column.columnDef)) return;
1157
+ const current = editingCellRef.current;
1158
+ if (current && (current.rowIndex !== rowIndex || current.colIndex !== colIndex) && !commitEdit()) {
1159
+ return;
1160
+ }
1161
+ setEditingCell({ rowIndex, colIndex });
1162
+ setDraftValue(getCellEditDraftValue(cell.getValue()));
1163
+ },
1164
+ [commitEdit, rows]
1165
+ );
1166
+ return {
1167
+ editingCell,
1168
+ draftValue,
1169
+ setDraftValue,
1170
+ startEdit,
1171
+ commitEdit,
1172
+ cancelEdit
1173
+ };
1174
+ }
1175
+
1176
+ // src/components/ui/table/features/cell-selection/useCellSelection.ts
1177
+ var import_react5 = require("react");
1178
+
1179
+ // src/components/ui/table/features/cell-selection/fillData.ts
1180
+ function getColumnAccessorKey2(columnDef) {
1181
+ if ("accessorKey" in columnDef && columnDef.accessorKey) {
1182
+ return String(columnDef.accessorKey);
1183
+ }
1184
+ return columnDef.id;
1185
+ }
1186
+ function collectFillTargets(rows, sourceBounds, fillBounds) {
1187
+ const targets = [];
1188
+ const sourceHeight = sourceBounds.endRow - sourceBounds.startRow + 1;
1189
+ const sourceWidth = sourceBounds.endCol - sourceBounds.startCol + 1;
1190
+ for (let rowIndex = fillBounds.startRow; rowIndex <= fillBounds.endRow; rowIndex += 1) {
1191
+ for (let colIndex = fillBounds.startCol; colIndex <= fillBounds.endCol; colIndex += 1) {
1192
+ if (isCellInSelection(rowIndex, colIndex, sourceBounds)) continue;
1193
+ const offsetRow = rowIndex - sourceBounds.startRow;
1194
+ const offsetCol = colIndex - sourceBounds.startCol;
1195
+ const sourceRowIndex = sourceBounds.startRow + (offsetRow % sourceHeight + sourceHeight) % sourceHeight;
1196
+ const sourceColIndex = sourceBounds.startCol + (offsetCol % sourceWidth + sourceWidth) % sourceWidth;
1197
+ const targetRow = rows[rowIndex];
1198
+ const targetCell = targetRow?.getVisibleCells()[colIndex];
1199
+ const sourceCell = rows[sourceRowIndex]?.getVisibleCells()[sourceColIndex];
1200
+ if (!targetRow || !targetCell || !sourceCell) continue;
1201
+ const accessorKey = getColumnAccessorKey2(
1202
+ targetCell.column.columnDef
1203
+ );
1204
+ if (!accessorKey) continue;
1205
+ targets.push({
1206
+ rowIndex,
1207
+ accessorKey,
1208
+ columnId: targetCell.column.id,
1209
+ value: sourceCell.getValue(),
1210
+ rowId: targetRow.id
1211
+ });
1212
+ }
1213
+ }
1214
+ return targets;
1215
+ }
1216
+ function collectFillChanges(rows, sourceBounds, fillBounds) {
1217
+ return collectFillTargets(rows, sourceBounds, fillBounds).map(
1218
+ ({ rowId, columnId, value }) => ({ rowId, columnId, value })
1219
+ );
1220
+ }
1221
+ function applyFillData(data, rows, sourceBounds, fillBounds) {
1222
+ const newData = data.map((row) => ({ ...row }));
1223
+ const targets = collectFillTargets(rows, sourceBounds, fillBounds);
1224
+ for (const target of targets) {
1225
+ if (!newData[target.rowIndex]) continue;
1226
+ newData[target.rowIndex][target.accessorKey] = target.value;
1227
+ }
1228
+ return newData;
1229
+ }
1230
+ function hasFillExtension(sourceBounds, fillBounds) {
1231
+ if (!sourceBounds) return false;
1232
+ return fillBounds.startRow < sourceBounds.startRow || fillBounds.endRow > sourceBounds.endRow || fillBounds.startCol < sourceBounds.startCol || fillBounds.endCol > sourceBounds.endCol;
1233
+ }
1234
+
1235
+ // src/components/ui/table/features/cell-selection/useCellSelection.ts
1236
+ function useCellSelection({
1237
+ data,
1238
+ rows,
1239
+ enabled = true,
1240
+ onDataChange,
1241
+ onBatchChange
1242
+ }) {
1243
+ const [dragState, setDragState] = (0, import_react5.useState)(INITIAL_DRAG_STATE);
1244
+ const cellSelectionBounds = getCellSelectionBounds(dragState.start, dragState.end);
1245
+ const activeSelectionBounds = enabled ? getActiveSelectionBounds(dragState, cellSelectionBounds) : null;
1246
+ const handleCellMouseDown = (0, import_react5.useCallback)(
1247
+ (rowIndex, colIndex) => {
1248
+ if (!enabled) return;
1249
+ setDragState({
1250
+ isSelecting: true,
1251
+ isFillDragging: false,
1252
+ start: { row: rowIndex, col: colIndex },
1253
+ end: { row: rowIndex, col: colIndex },
1254
+ fillAnchor: null,
1255
+ fillEnd: null
1256
+ });
1257
+ },
1258
+ [enabled]
1259
+ );
1260
+ const handleCellMouseEnter = (0, import_react5.useCallback)(
1261
+ (rowIndex, colIndex) => {
1262
+ if (!enabled) return;
1263
+ setDragState((prev) => {
1264
+ if (prev.isSelecting) {
1265
+ return { ...prev, end: { row: rowIndex, col: colIndex } };
1266
+ }
1267
+ if (prev.isFillDragging) {
1268
+ return { ...prev, fillEnd: { row: rowIndex, col: colIndex } };
1269
+ }
1270
+ return prev;
1271
+ });
1272
+ },
1273
+ [enabled]
1274
+ );
1275
+ const handleFillHandleMouseDown = (0, import_react5.useCallback)(
1276
+ (rowIndex, colIndex) => {
1277
+ if (!enabled) return;
1278
+ setDragState((prev) => {
1279
+ const bounds = getCellSelectionBounds(prev.start, prev.end);
1280
+ if (!bounds) return prev;
1281
+ return {
1282
+ ...prev,
1283
+ isSelecting: false,
1284
+ isFillDragging: true,
1285
+ fillAnchor: { row: bounds.startRow, col: bounds.startCol },
1286
+ fillEnd: { row: rowIndex, col: colIndex }
1287
+ };
1288
+ });
1289
+ },
1290
+ [enabled]
1291
+ );
1292
+ (0, import_react5.useEffect)(() => {
1293
+ if (!enabled) {
1294
+ setDragState(INITIAL_DRAG_STATE);
1295
+ }
1296
+ }, [enabled]);
1297
+ (0, import_react5.useEffect)(() => {
1298
+ if (!enabled) return;
1299
+ const handleKeyDown = (e) => {
1300
+ if ((e.ctrlKey || e.metaKey) && e.key === "c" && activeSelectionBounds) {
1301
+ const { startRow, endRow, startCol, endCol } = activeSelectionBounds;
1302
+ const selectedData = rows.slice(startRow, endRow + 1).map((row) => {
1303
+ const cells = row.getVisibleCells();
1304
+ return cells.slice(startCol, endCol + 1).map((cell) => cell.getValue()).join(" ");
1305
+ }).join("\n");
1306
+ navigator.clipboard.writeText(selectedData);
1307
+ }
1308
+ };
1309
+ window.addEventListener("keydown", handleKeyDown);
1310
+ return () => window.removeEventListener("keydown", handleKeyDown);
1311
+ }, [activeSelectionBounds, enabled, rows]);
1312
+ (0, import_react5.useEffect)(() => {
1313
+ if (!enabled) return;
1314
+ const handleMouseUp = () => {
1315
+ setDragState((prev) => {
1316
+ if (prev.isFillDragging && prev.fillAnchor && prev.fillEnd) {
1317
+ const sourceBounds = getCellSelectionBounds(prev.start, prev.end);
1318
+ const newBounds = getCellSelectionBounds(prev.fillAnchor, prev.fillEnd);
1319
+ if (newBounds) {
1320
+ if (hasFillExtension(sourceBounds, newBounds) && sourceBounds) {
1321
+ if (onBatchChange) {
1322
+ const changes = collectFillChanges(rows, sourceBounds, newBounds);
1323
+ if (changes.length > 0) {
1324
+ onBatchChange(changes);
1325
+ }
1326
+ } else if (onDataChange) {
1327
+ onDataChange(applyFillData(data, rows, sourceBounds, newBounds));
1328
+ }
1329
+ }
1330
+ return {
1331
+ isSelecting: false,
1332
+ isFillDragging: false,
1333
+ start: { row: newBounds.startRow, col: newBounds.startCol },
1334
+ end: { row: newBounds.endRow, col: newBounds.endCol },
1335
+ fillAnchor: null,
1336
+ fillEnd: null
1337
+ };
1338
+ }
1339
+ }
1340
+ if (prev.isSelecting) {
1341
+ return { ...prev, isSelecting: false };
1342
+ }
1343
+ if (prev.isFillDragging) {
1344
+ return { ...prev, isFillDragging: false, fillAnchor: null, fillEnd: null };
1345
+ }
1346
+ return prev;
1347
+ });
1348
+ };
1349
+ window.addEventListener("mouseup", handleMouseUp);
1350
+ return () => window.removeEventListener("mouseup", handleMouseUp);
1351
+ }, [data, enabled, onBatchChange, onDataChange, rows]);
1352
+ return {
1353
+ dragState: enabled ? dragState : INITIAL_DRAG_STATE,
1354
+ activeSelectionBounds,
1355
+ handleCellMouseDown,
1356
+ handleCellMouseEnter,
1357
+ handleFillHandleMouseDown
1358
+ };
1359
+ }
1360
+
1361
+ // src/components/ui/table/features/row-selection/rowSelection.ts
1362
+ function resolveRowSelection(mode, controlledSelection, internalSelection) {
1363
+ if (mode === "none") return {};
1364
+ return controlledSelection ?? internalSelection;
1365
+ }
1366
+ function normalizeSingleSelection(next) {
1367
+ const selectedIds = Object.keys(next).filter((id) => next[id]);
1368
+ if (selectedIds.length <= 1) return next;
1369
+ return { [selectedIds[selectedIds.length - 1]]: true };
1370
+ }
1371
+ function applySelectionUpdater(mode, updater, previous) {
1372
+ const next = typeof updater === "function" ? updater(previous) : updater;
1373
+ return mode === "single" ? normalizeSingleSelection(next) : next;
1374
+ }
1375
+
1376
+ // src/core/labels.ts
1377
+ var DEFAULT_DATA_TABLE_LABELS = {
1378
+ empty: "No data",
1379
+ loading: "Loading...",
1380
+ selection: (selectedCount) => selectedCount > 0 ? `\u2713 ${selectedCount} selected` : null,
1381
+ expandRow: "Expand row",
1382
+ collapseRow: "Collapse row"
1383
+ };
1384
+ function resolveDataTableLabels(partial) {
1385
+ return {
1386
+ ...DEFAULT_DATA_TABLE_LABELS,
1387
+ ...partial
1388
+ };
1389
+ }
1390
+
1391
+ // src/core/useGlideTable.ts
1392
+ function useGlideTable(options) {
1393
+ const {
1394
+ data,
1395
+ columns,
1396
+ rowSelectionMode = "none",
1397
+ rowSelection: controlledRowSelection,
1398
+ onRowSelectionChange,
1399
+ selectionLabel,
1400
+ emptyText,
1401
+ loadingText,
1402
+ labels: labelsProp,
1403
+ enableRowSpan = false,
1404
+ getRowId,
1405
+ onRowClick,
1406
+ getRowClassName,
1407
+ getRowCanSelect,
1408
+ selectOnRowClick = true,
1409
+ enableCellSelection = true,
1410
+ onDataChange,
1411
+ onCellChange,
1412
+ onBatchChange,
1413
+ preserveRowSelection = false,
1414
+ toggleField,
1415
+ childField,
1416
+ flattenField,
1417
+ qtyField,
1418
+ expandedRows: controlledExpandedRows,
1419
+ onExpandedRowsChange,
1420
+ preventExpand = false,
1421
+ enableVirtualization = true,
1422
+ estimateRowHeight = DATA_TABLE_ROW_HEIGHT,
1423
+ virtualOverscan = DATA_TABLE_VIRTUAL_OVERSCAN
1424
+ } = options;
1425
+ const labels = (0, import_react6.useMemo)(() => {
1426
+ const resolved = resolveDataTableLabels(labelsProp);
1427
+ return {
1428
+ ...resolved,
1429
+ empty: labelsProp?.empty ?? emptyText ?? resolved.empty,
1430
+ loading: labelsProp?.loading ?? loadingText ?? resolved.loading,
1431
+ selection: labelsProp?.selection ?? selectionLabel ?? resolved.selection
1432
+ };
1433
+ }, [labelsProp, emptyText, loadingText, selectionLabel]);
1434
+ const enableExpand = Boolean(toggleField);
1435
+ const [internalRowSelection, setInternalRowSelection] = (0, import_react6.useState)({});
1436
+ const [internalExpandedRows, setInternalExpandedRows] = (0, import_react6.useState)(
1437
+ () => /* @__PURE__ */ new Set()
1438
+ );
1439
+ const [hoveredRowIndex, setHoveredRowIndex] = (0, import_react6.useState)(null);
1440
+ const [hoveredGroupKey, setHoveredGroupKey] = (0, import_react6.useState)(null);
1441
+ const scrollRef = (0, import_react6.useRef)(null);
1442
+ const shouldVirtualize = enableVirtualization && !enableRowSpan;
1443
+ (0, import_react6.useEffect)(() => {
1444
+ if (enableVirtualization && enableRowSpan) {
1445
+ console.warn(
1446
+ "[useGlideTable] enableRowSpan is on; virtualization is disabled to preserve cell merges."
1447
+ );
1448
+ }
1449
+ }, [enableVirtualization, enableRowSpan]);
1450
+ const rowSelection = resolveRowSelection(
1451
+ rowSelectionMode,
1452
+ controlledRowSelection,
1453
+ internalRowSelection
1454
+ );
1455
+ const expandedRows = controlledExpandedRows ?? internalExpandedRows;
1456
+ const handleExpandedRowsChange = (0, import_react6.useCallback)(
1457
+ (next) => {
1458
+ if (onExpandedRowsChange) {
1459
+ onExpandedRowsChange(next);
1460
+ return;
1461
+ }
1462
+ setInternalExpandedRows(next);
1463
+ },
1464
+ [onExpandedRowsChange]
1465
+ );
1466
+ const tableData = useConvertTreeData({
1467
+ data,
1468
+ enabled: enableExpand,
1469
+ toggleField,
1470
+ childField,
1471
+ flattenField,
1472
+ qtyField,
1473
+ expandedRows,
1474
+ onExpandedRowsChange: enableExpand ? handleExpandedRowsChange : void 0,
1475
+ preventExpand
1476
+ });
1477
+ const table = (0, import_react_table2.useReactTable)({
1478
+ data: tableData,
1479
+ columns,
1480
+ state: {
1481
+ rowSelection: rowSelectionMode === "none" ? {} : rowSelection
1482
+ },
1483
+ enableRowSelection: rowSelectionMode === "none" ? false : getRowCanSelect ? (row) => getRowCanSelect(row.original, row.index) : true,
1484
+ enableMultiRowSelection: rowSelectionMode === "multi",
1485
+ onRowSelectionChange: (updater) => {
1486
+ if (onRowSelectionChange) {
1487
+ onRowSelectionChange(
1488
+ (previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
1489
+ );
1490
+ return;
1491
+ }
1492
+ setInternalRowSelection(
1493
+ (previous) => applySelectionUpdater(rowSelectionMode, updater, previous)
1494
+ );
1495
+ },
1496
+ getCoreRowModel: (0, import_react_table2.getCoreRowModel)(),
1497
+ getRowId: getRowId ? (originalRow, index) => getRowId(originalRow, index) : (_originalRow, index) => String(index)
1498
+ });
1499
+ const rowSpanColumnKeys = (0, import_react6.useMemo)(() => {
1500
+ if (!enableRowSpan) return [];
1501
+ return collectRowSpanColumns(columns);
1502
+ }, [enableRowSpan, columns]);
1503
+ const primaryRowSpanKey = rowSpanColumnKeys[0]?.rowSpanKey;
1504
+ const columnRowSpanMap = (0, import_react6.useMemo)(
1505
+ () => buildColumnRowSpanMap(tableData, rowSpanColumnKeys),
1506
+ [tableData, rowSpanColumnKeys]
1507
+ );
1508
+ const selectedRows = table.getSelectedRowModel().rows;
1509
+ const selectedCount = selectedRows.length;
1510
+ const rows = table.getRowModel().rows;
1511
+ const columnCount = table.getAllLeafColumns().length || 1;
1512
+ const rowVirtualizer = (0, import_react_virtual.useVirtualizer)({
1513
+ count: shouldVirtualize ? rows.length : 0,
1514
+ getScrollElement: () => scrollRef.current,
1515
+ estimateSize: () => estimateRowHeight,
1516
+ overscan: virtualOverscan
1517
+ });
1518
+ const virtualRows = rowVirtualizer.getVirtualItems();
1519
+ const totalSize = rowVirtualizer.getTotalSize();
1520
+ const paddingTop = virtualRows.length > 0 ? virtualRows[0]?.start ?? 0 : 0;
1521
+ const paddingBottom = virtualRows.length > 0 ? totalSize - (virtualRows[virtualRows.length - 1]?.end ?? 0) : 0;
1522
+ const selectedGroupKeys = (0, import_react6.useMemo)(() => {
1523
+ if (!enableRowSpan || !primaryRowSpanKey) return /* @__PURE__ */ new Set();
1524
+ const keys = /* @__PURE__ */ new Set();
1525
+ for (const selectedRow of selectedRows) {
1526
+ const value = selectedRow.original[primaryRowSpanKey];
1527
+ if (value !== null && value !== void 0) keys.add(String(value));
1528
+ }
1529
+ return keys;
1530
+ }, [enableRowSpan, primaryRowSpanKey, selectedRows]);
1531
+ const {
1532
+ dragState,
1533
+ activeSelectionBounds,
1534
+ handleCellMouseDown,
1535
+ handleCellMouseEnter,
1536
+ handleFillHandleMouseDown
1537
+ } = useCellSelection({
1538
+ data: tableData,
1539
+ rows,
1540
+ enabled: enableCellSelection,
1541
+ onDataChange,
1542
+ onBatchChange
1543
+ });
1544
+ const {
1545
+ editingCell,
1546
+ draftValue,
1547
+ setDraftValue,
1548
+ startEdit,
1549
+ commitEdit,
1550
+ cancelEdit
1551
+ } = useCellEdit({ data: tableData, rows, onDataChange, onCellChange });
1552
+ const handleCellMouseDownWithCommit = (0, import_react6.useCallback)(
1553
+ (rowIndex, colIndex) => {
1554
+ const isSameEditingCell = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === colIndex;
1555
+ if (editingCell && !isSameEditingCell && !commitEdit()) {
1556
+ return;
1557
+ }
1558
+ handleCellMouseDown(rowIndex, colIndex);
1559
+ },
1560
+ [commitEdit, editingCell, handleCellMouseDown]
1561
+ );
1562
+ const clearHover = (0, import_react6.useCallback)(() => {
1563
+ setHoveredRowIndex(null);
1564
+ setHoveredGroupKey(null);
1565
+ }, []);
1566
+ const handleRowHover = (0, import_react6.useCallback)(
1567
+ (rowIndex, rowData) => {
1568
+ setHoveredRowIndex(rowIndex);
1569
+ if (!primaryRowSpanKey) {
1570
+ setHoveredGroupKey(null);
1571
+ return;
1572
+ }
1573
+ const groupValue = rowData[primaryRowSpanKey];
1574
+ setHoveredGroupKey(
1575
+ groupValue === null || groupValue === void 0 ? null : String(groupValue)
1576
+ );
1577
+ },
1578
+ [primaryRowSpanKey]
1579
+ );
1580
+ const handleToggleSelect = (0, import_react6.useCallback)(
1581
+ (row) => {
1582
+ if (!row.getCanSelect()) return;
1583
+ if (preserveRowSelection && row.getIsSelected()) {
1584
+ return;
1585
+ }
1586
+ row.toggleSelected();
1587
+ },
1588
+ [preserveRowSelection]
1589
+ );
1590
+ const handleToggleExpand = (0, import_react6.useCallback)(
1591
+ (rowKey) => {
1592
+ if (preventExpand) return;
1593
+ handleExpandedRowsChange(toggleExpandedRowId(rowKey, expandedRows));
1594
+ },
1595
+ [preventExpand, handleExpandedRowsChange, expandedRows]
1596
+ );
1597
+ const rowContextValue = (0, import_react6.useMemo)(() => {
1598
+ return {
1599
+ rowSpan: {
1600
+ enableRowSpan,
1601
+ primaryRowSpanKey,
1602
+ columnRowSpanMap,
1603
+ hoveredRowIndex,
1604
+ hoveredGroupKey,
1605
+ selectedGroupKeys,
1606
+ onRowHover: handleRowHover
1607
+ },
1608
+ selection: {
1609
+ rowSelectionMode,
1610
+ selectOnRowClick,
1611
+ onRowClick,
1612
+ getRowClassName
1613
+ },
1614
+ cellSelection: {
1615
+ enableCellSelection,
1616
+ activeSelectionBounds,
1617
+ dragState,
1618
+ onCellMouseDown: handleCellMouseDownWithCommit,
1619
+ onCellMouseEnter: handleCellMouseEnter,
1620
+ onFillHandleMouseDown: handleFillHandleMouseDown
1621
+ },
1622
+ cellEdit: {
1623
+ editingCell,
1624
+ draftValue,
1625
+ onDraftValueChange: setDraftValue,
1626
+ onStartEdit: startEdit,
1627
+ onCommitEdit: commitEdit,
1628
+ onCancelEdit: cancelEdit
1629
+ },
1630
+ expand: {
1631
+ enableExpand,
1632
+ toggleField,
1633
+ expandedRows,
1634
+ preventExpand,
1635
+ onToggleExpand: handleToggleExpand,
1636
+ expandRowLabel: labels.expandRow,
1637
+ collapseRowLabel: labels.collapseRow
1638
+ }
1639
+ };
1640
+ }, [
1641
+ enableRowSpan,
1642
+ primaryRowSpanKey,
1643
+ columnRowSpanMap,
1644
+ hoveredRowIndex,
1645
+ hoveredGroupKey,
1646
+ selectedGroupKeys,
1647
+ handleRowHover,
1648
+ rowSelectionMode,
1649
+ selectOnRowClick,
1650
+ onRowClick,
1651
+ getRowClassName,
1652
+ enableCellSelection,
1653
+ activeSelectionBounds,
1654
+ dragState,
1655
+ handleCellMouseDownWithCommit,
1656
+ handleCellMouseEnter,
1657
+ handleFillHandleMouseDown,
1658
+ editingCell,
1659
+ draftValue,
1660
+ setDraftValue,
1661
+ startEdit,
1662
+ commitEdit,
1663
+ cancelEdit,
1664
+ enableExpand,
1665
+ toggleField,
1666
+ expandedRows,
1667
+ preventExpand,
1668
+ handleToggleExpand,
1669
+ labels.expandRow,
1670
+ labels.collapseRow
1671
+ ]);
1672
+ return {
1673
+ table,
1674
+ tableData,
1675
+ rows,
1676
+ columnCount,
1677
+ selectedCount,
1678
+ labels,
1679
+ emptyText: labels.empty,
1680
+ loadingText: labels.loading,
1681
+ selectionLabel: labels.selection,
1682
+ enableCellSelection,
1683
+ shouldVirtualize,
1684
+ scrollRef,
1685
+ rowVirtualizer,
1686
+ virtualRows,
1687
+ paddingTop,
1688
+ paddingBottom,
1689
+ rowContextValue,
1690
+ handleToggleSelect,
1691
+ clearHover
1692
+ };
1693
+ }
1694
+
1695
+ // src/components/ui/table/components/DataTable/DataTable.tsx
1696
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1697
+ function DefaultPending({
1698
+ loadingText,
1699
+ className,
1700
+ classNames
1701
+ }) {
1702
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1703
+ "div",
1704
+ {
1705
+ className: cn(
1706
+ "DataTableJSX",
1707
+ "DataTableJSX--pending",
1708
+ classNames?.root,
1709
+ classNames?.pending,
1710
+ className
1711
+ ),
1712
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: cn("data-table-loading-text", classNames?.loadingText), children: loadingText })
1713
+ }
1714
+ );
1715
+ }
1716
+ function DefaultEmpty({
1717
+ emptyText,
1718
+ columnCount,
1719
+ classNames
1720
+ }) {
1721
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1722
+ "td",
1723
+ {
1724
+ colSpan: columnCount,
1725
+ className: cn("data-table-empty-cell", classNames?.emptyCell),
1726
+ children: emptyText
1727
+ }
1728
+ ) });
1729
+ }
1730
+ function DataTable({
1731
+ isPending = false,
1732
+ summary,
1733
+ toolbar,
1734
+ filteredCount,
1735
+ totalCount,
1736
+ className,
1737
+ classNames,
1738
+ slots,
1739
+ ...glideOptions
1740
+ }) {
1741
+ const {
1742
+ table,
1743
+ tableData,
1744
+ rows,
1745
+ columnCount,
1746
+ selectedCount,
1747
+ emptyText,
1748
+ loadingText,
1749
+ selectionLabel,
1750
+ enableCellSelection,
1751
+ shouldVirtualize,
1752
+ scrollRef,
1753
+ rowVirtualizer,
1754
+ virtualRows,
1755
+ paddingTop,
1756
+ paddingBottom,
1757
+ rowContextValue,
1758
+ handleToggleSelect,
1759
+ clearHover
1760
+ } = useGlideTable(glideOptions);
1761
+ const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
1762
+ const RowSlot = slots?.Row ?? DataTableRow;
1763
+ const PendingSlot = slots?.Pending ?? DefaultPending;
1764
+ const EmptySlot = slots?.Empty ?? DefaultEmpty;
1765
+ const contextValue = (0, import_react7.useMemo)(
1766
+ () => ({ ...rowContextValue, classNames }),
1767
+ [rowContextValue, classNames]
1768
+ );
1769
+ if (isPending) {
1770
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1771
+ PendingSlot,
1772
+ {
1773
+ loadingText,
1774
+ className,
1775
+ classNames
1776
+ }
1777
+ );
1778
+ }
1779
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1780
+ "div",
1781
+ {
1782
+ className: cn(
1783
+ "DataTableJSX",
1784
+ !enableCellSelection && "DataTableJSX--no-cell-selection",
1785
+ classNames?.root,
1786
+ className
1787
+ ),
1788
+ children: [
1789
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1790
+ ToolbarSlot,
1791
+ {
1792
+ filteredCount: filteredCount ?? tableData.length,
1793
+ totalCount,
1794
+ summary,
1795
+ selectedCount,
1796
+ selectionLabel,
1797
+ toolbar,
1798
+ classNames
1799
+ }
1800
+ ),
1801
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { ref: scrollRef, className: cn("data-table-scroll", classNames?.scroll), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1802
+ "table",
1803
+ {
1804
+ className: cn("data-table", classNames?.table),
1805
+ onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
1806
+ children: [
1807
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("thead", { className: cn("data-table-head", classNames?.head), children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1808
+ "tr",
1809
+ {
1810
+ className: cn("data-table-head-row", classNames?.headRow),
1811
+ children: headerGroup.headers.map((header) => {
1812
+ const align = header.column.columnDef.meta?.align ?? "center";
1813
+ const headerClassName = header.column.columnDef.meta?.headerClassName;
1814
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1815
+ "th",
1816
+ {
1817
+ style: { width: header.getSize() !== 150 ? header.getSize() : void 0 },
1818
+ className: cn(
1819
+ "data-table-head-cell",
1820
+ CELL_ALIGN_CLASS[align],
1821
+ classNames?.headCell,
1822
+ headerClassName
1823
+ ),
1824
+ children: header.isPlaceholder ? null : (0, import_react_table3.flexRender)(header.column.columnDef.header, header.getContext())
1825
+ },
1826
+ header.id
1827
+ );
1828
+ })
1829
+ },
1830
+ headerGroup.id
1831
+ )) }),
1832
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DataTableContextProvider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1833
+ "tbody",
1834
+ {
1835
+ onMouseLeave: clearHover,
1836
+ className: cn("data-table-body", classNames?.body),
1837
+ children: rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1838
+ EmptySlot,
1839
+ {
1840
+ emptyText,
1841
+ columnCount,
1842
+ classNames
1843
+ }
1844
+ ) : shouldVirtualize ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1845
+ paddingTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1846
+ "tr",
1847
+ {
1848
+ "aria-hidden": true,
1849
+ className: cn(
1850
+ "data-table-virtual-spacer",
1851
+ classNames?.virtualSpacer
1852
+ ),
1853
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1854
+ "td",
1855
+ {
1856
+ colSpan: columnCount,
1857
+ style: { height: paddingTop },
1858
+ className: cn(
1859
+ "data-table-virtual-spacer-cell",
1860
+ classNames?.virtualSpacerCell
1861
+ )
1862
+ }
1863
+ )
1864
+ }
1865
+ ),
1866
+ virtualRows.map((virtualRow) => {
1867
+ const row = rows[virtualRow.index];
1868
+ if (!row) return null;
1869
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1870
+ RowSlot,
1871
+ {
1872
+ row,
1873
+ virtualIndex: virtualRow.index,
1874
+ measureElement: rowVirtualizer.measureElement,
1875
+ onToggleSelect: () => handleToggleSelect(row)
1876
+ },
1877
+ row.id
1878
+ );
1879
+ }),
1880
+ paddingBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1881
+ "tr",
1882
+ {
1883
+ "aria-hidden": true,
1884
+ className: cn(
1885
+ "data-table-virtual-spacer",
1886
+ classNames?.virtualSpacer
1887
+ ),
1888
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1889
+ "td",
1890
+ {
1891
+ colSpan: columnCount,
1892
+ style: { height: paddingBottom },
1893
+ className: cn(
1894
+ "data-table-virtual-spacer-cell",
1895
+ classNames?.virtualSpacerCell
1896
+ )
1897
+ }
1898
+ )
1899
+ }
1900
+ )
1901
+ ] }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1902
+ RowSlot,
1903
+ {
1904
+ row,
1905
+ onToggleSelect: () => handleToggleSelect(row)
1906
+ },
1907
+ row.id
1908
+ ))
1909
+ }
1910
+ ) })
1911
+ ]
1912
+ }
1913
+ ) })
1914
+ ]
1915
+ }
1916
+ );
1917
+ }
1918
+
1919
+ // src/components/ui/table/components/Table/Table.tsx
1920
+ var import_react10 = require("react");
1921
+
1922
+ // src/components/ui/table/components/Table/buildColumnDef.tsx
1923
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1924
+ function SortableHeader({
1925
+ label,
1926
+ field,
1927
+ sort,
1928
+ onSort
1929
+ }) {
1930
+ const isActive = sort?.field === field;
1931
+ const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
1932
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1933
+ "button",
1934
+ {
1935
+ type: "button",
1936
+ className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
1937
+ onClick: () => onSort(field),
1938
+ children: [
1939
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label }),
1940
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { className: "sortable-header-icon" })
1941
+ ]
1942
+ }
1943
+ );
1944
+ }
1945
+ function buildColumnDef(props, sort, onSort) {
1946
+ const {
1947
+ field,
1948
+ virtual = false,
1949
+ children,
1950
+ sortable = false,
1951
+ width,
1952
+ align,
1953
+ rowSpan,
1954
+ rowSpanKey,
1955
+ editable,
1956
+ editType,
1957
+ className,
1958
+ headerClassName,
1959
+ render
1960
+ } = props;
1961
+ return {
1962
+ id: field,
1963
+ ...!virtual ? { accessorKey: field } : {},
1964
+ size: width ?? 150,
1965
+ header: sortable ? () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SortableHeader, { label: children, field, sort, onSort }) : (
1966
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1967
+ () => children
1968
+ ),
1969
+ ...render ? {
1970
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1971
+ cell: ({ row, getValue }) => render(
1972
+ getValue(),
1973
+ row,
1974
+ row.index
1975
+ )
1976
+ } : {},
1977
+ meta: {
1978
+ align,
1979
+ rowSpan,
1980
+ rowSpanKey,
1981
+ editable,
1982
+ editType,
1983
+ className,
1984
+ headerClassName
1985
+ }
1986
+ };
1987
+ }
1988
+
1989
+ // src/components/ui/table/components/Table/parseTableChildren.ts
1990
+ var import_react9 = require("react");
1991
+
1992
+ // src/components/ui/table/components/Table/tableChildTypes.ts
1993
+ var import_react8 = require("react");
1994
+ var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
1995
+ var TABLE_BODY_DISPLAY_NAME = "Table.Body";
1996
+ var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
1997
+ var TABLE_PAGINATION_DISPLAY_NAME = "Table.Pagination";
1998
+ function getComponentDisplayName(type) {
1999
+ if (typeof type === "function" || typeof type === "object" && type !== null) {
2000
+ return type.displayName;
2001
+ }
2002
+ return void 0;
2003
+ }
2004
+ function isTableHeaderElement(child) {
2005
+ return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
2006
+ }
2007
+ function isTableBodyElement(child) {
2008
+ return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
2009
+ }
2010
+ function isTableColumnElement(child) {
2011
+ return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
2012
+ }
2013
+ function isTablePaginationElement(child) {
2014
+ return (0, import_react8.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
2015
+ }
2016
+
2017
+ // src/components/ui/table/components/Table/parseTableChildren.ts
2018
+ function parseTableChildren(children) {
2019
+ const slots = {
2020
+ header: null,
2021
+ body: null,
2022
+ pagination: null
2023
+ };
2024
+ for (const child of import_react9.Children.toArray(children)) {
2025
+ if (isTableHeaderElement(child)) {
2026
+ slots.header = child;
2027
+ continue;
2028
+ }
2029
+ if (isTableBodyElement(child)) {
2030
+ slots.body = child;
2031
+ continue;
2032
+ }
2033
+ if (isTablePaginationElement(child)) {
2034
+ slots.pagination = child;
2035
+ }
2036
+ }
2037
+ return slots;
2038
+ }
2039
+ function extractColumnElements(header) {
2040
+ if (!header) return [];
2041
+ const { children } = header.props;
2042
+ return import_react9.Children.toArray(children).filter(isTableColumnElement);
2043
+ }
2044
+
2045
+ // src/components/ui/table/components/Table/TableBody.tsx
2046
+ function TableBody() {
2047
+ return null;
2048
+ }
2049
+ TableBody.displayName = TABLE_BODY_DISPLAY_NAME;
2050
+
2051
+ // src/components/ui/table/components/Table/TableColumn.tsx
2052
+ function TableColumn(props) {
2053
+ void props;
2054
+ return null;
2055
+ }
2056
+ TableColumn.displayName = TABLE_COLUMN_DISPLAY_NAME;
2057
+
2058
+ // src/components/ui/table/components/Table/tableDataPipeline.ts
2059
+ function sortTableData(data, sort) {
2060
+ if (!sort) return data;
2061
+ const { field, direction } = sort;
2062
+ const multiplier = direction === "asc" ? 1 : -1;
2063
+ return [...data].sort((left, right) => {
2064
+ const leftValue = left[field];
2065
+ const rightValue = right[field];
2066
+ if ((leftValue === null || leftValue === void 0) && (rightValue === null || rightValue === void 0)) {
2067
+ return 0;
2068
+ }
2069
+ if (leftValue === null || leftValue === void 0) return 1;
2070
+ if (rightValue === null || rightValue === void 0) return -1;
2071
+ if (typeof leftValue === "number" && typeof rightValue === "number") {
2072
+ return (leftValue - rightValue) * multiplier;
2073
+ }
2074
+ return String(leftValue).localeCompare(String(rightValue), "ko") * multiplier;
2075
+ });
2076
+ }
2077
+ function paginateTableData(data, page, pageSize) {
2078
+ const safePage = Math.max(1, page);
2079
+ const start = (safePage - 1) * pageSize;
2080
+ return data.slice(start, start + pageSize);
2081
+ }
2082
+ function getTotalPages(totalCount, pageSize) {
2083
+ if (pageSize <= 0) return 1;
2084
+ return Math.max(1, Math.ceil(totalCount / pageSize));
2085
+ }
2086
+
2087
+ // src/components/ui/table/components/Table/TableHeader.tsx
2088
+ function TableHeader(props) {
2089
+ void props;
2090
+ return null;
2091
+ }
2092
+ TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
2093
+
2094
+ // src/components/ui/table/components/Table/TablePagination.tsx
2095
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2096
+ function TablePagination({
2097
+ page,
2098
+ pageSize = 10,
2099
+ totalCount = 0,
2100
+ onChange,
2101
+ className
2102
+ }) {
2103
+ const totalPages = getTotalPages(totalCount, pageSize);
2104
+ const safePage = Math.min(Math.max(1, page), totalPages);
2105
+ const canGoPrev = safePage > 1;
2106
+ const canGoNext = safePage < totalPages;
2107
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("TablePaginationJSX", className), children: [
2108
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2109
+ "button",
2110
+ {
2111
+ type: "button",
2112
+ className: "pagination-button",
2113
+ disabled: !canGoPrev,
2114
+ onClick: () => onChange(safePage - 1),
2115
+ "aria-label": "Previous page",
2116
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeft, { className: "pagination-button-icon" })
2117
+ }
2118
+ ),
2119
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "pagination-label", children: [
2120
+ safePage,
2121
+ " / ",
2122
+ totalPages
2123
+ ] }),
2124
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2125
+ "button",
2126
+ {
2127
+ type: "button",
2128
+ className: "pagination-button",
2129
+ disabled: !canGoNext,
2130
+ onClick: () => onChange(safePage + 1),
2131
+ "aria-label": "Next page",
2132
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRight, { className: "pagination-button-icon" })
2133
+ }
2134
+ )
2135
+ ] });
2136
+ }
2137
+ TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
2138
+
2139
+ // src/components/ui/table/components/Table/Table.tsx
2140
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2141
+ function TableRoot({
2142
+ data,
2143
+ children,
2144
+ className,
2145
+ totalCount,
2146
+ filteredCount,
2147
+ ...dataTableProps
2148
+ }) {
2149
+ const { header, pagination: paginationElement } = (0, import_react10.useMemo)(
2150
+ () => parseTableChildren(children),
2151
+ [children]
2152
+ );
2153
+ const [sort, setSort] = (0, import_react10.useState)(null);
2154
+ const handleSort = (0, import_react10.useCallback)((field) => {
2155
+ setSort((previous) => {
2156
+ if (previous?.field !== field) {
2157
+ return { field, direction: "asc" };
2158
+ }
2159
+ if (previous.direction === "asc") {
2160
+ return { field, direction: "desc" };
2161
+ }
2162
+ return null;
2163
+ });
2164
+ }, []);
2165
+ const columns = (0, import_react10.useMemo)(() => {
2166
+ return extractColumnElements(header).map(
2167
+ (columnElement) => buildColumnDef(columnElement.props, sort, handleSort)
2168
+ );
2169
+ }, [header, sort, handleSort]);
2170
+ const paginationProps = paginationElement?.props;
2171
+ const pageSize = paginationProps?.pageSize ?? 10;
2172
+ const page = paginationProps?.page ?? 1;
2173
+ const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
2174
+ const tableData = (0, import_react10.useMemo)(() => {
2175
+ const sortedData = sortTableData(data, sort);
2176
+ if (!paginationProps) return sortedData;
2177
+ return paginateTableData(sortedData, page, pageSize);
2178
+ }, [data, sort, paginationProps, page, pageSize]);
2179
+ if (columns.length === 0) {
2180
+ console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
2181
+ }
2182
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "TableJSX", children: [
2183
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2184
+ DataTable,
2185
+ {
2186
+ ...dataTableProps,
2187
+ data: tableData,
2188
+ columns,
2189
+ totalCount: paginationProps ? resolvedTotalCount : totalCount,
2190
+ filteredCount: filteredCount ?? data.length,
2191
+ className: cn(className, paginationProps && "DataTableJSX--with-pagination")
2192
+ }
2193
+ ),
2194
+ paginationProps && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2195
+ TablePagination,
2196
+ {
2197
+ page,
2198
+ pageSize,
2199
+ totalCount: resolvedTotalCount,
2200
+ onChange: paginationProps.onChange,
2201
+ className: paginationProps.className
2202
+ }
2203
+ )
2204
+ ] });
2205
+ }
2206
+ function createTable() {
2207
+ function Column(props) {
2208
+ void props;
2209
+ return null;
2210
+ }
2211
+ Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
2212
+ return Object.assign(
2213
+ function BoundTable(props) {
2214
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TableRoot, { ...props });
2215
+ },
2216
+ {
2217
+ Header: TableHeader,
2218
+ Column,
2219
+ Body: TableBody,
2220
+ Pagination: TablePagination
2221
+ }
2222
+ );
2223
+ }
2224
+ var Table = Object.assign(TableRoot, {
2225
+ Header: TableHeader,
2226
+ Column: TableColumn,
2227
+ Body: TableBody,
2228
+ Pagination: TablePagination
2229
+ });
2230
+ // Annotate the CommonJS export names for ESM import in node:
2231
+ 0 && (module.exports = {
2232
+ DataTable,
2233
+ Table,
2234
+ createTable
2235
+ });