react-glide-table 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -18,14 +18,16 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
23
  CELL_SELECTION_EDGES_CLASS: () => CELL_SELECTION_EDGES_CLASS,
24
24
  DEFAULT_DATA_TABLE_LABELS: () => DEFAULT_DATA_TABLE_LABELS,
25
25
  DEFAULT_TREE_CHILDREN_FIELD: () => DEFAULT_TREE_CHILDREN_FIELD,
26
26
  DEFAULT_TREE_ID_FIELD: () => DEFAULT_TREE_ID_FIELD,
27
27
  DEFAULT_TREE_PARENT_ID_FIELD: () => DEFAULT_TREE_PARENT_ID_FIELD,
28
28
  DEFAULT_TREE_QTY_FIELD: () => DEFAULT_TREE_QTY_FIELD,
29
+ DataTable: () => DataTable,
30
+ Table: () => Table,
29
31
  applyCellEdit: () => applyCellEdit,
30
32
  applyFillData: () => applyFillData,
31
33
  applySelectionUpdater: () => applySelectionUpdater,
@@ -33,6 +35,7 @@ __export(index_exports, {
33
35
  canExpandRow: () => canExpandRow,
34
36
  collectFillChanges: () => collectFillChanges,
35
37
  collectRowSpanColumns: () => collectRowSpanColumns,
38
+ createTable: () => createTable,
36
39
  getCellEditDraftValue: () => getCellEditDraftValue,
37
40
  getCellSelectionEdgeStyle: () => getCellSelectionEdgeStyle,
38
41
  getColumnEditType: () => getColumnEditType,
@@ -50,7 +53,7 @@ __export(index_exports, {
50
53
  useConvertTreeData: () => useConvertTreeData,
51
54
  useGlideTable: () => useGlideTable
52
55
  });
53
- module.exports = __toCommonJS(index_exports);
56
+ module.exports = __toCommonJS(src_exports);
54
57
 
55
58
  // src/core/labels.ts
56
59
  var DEFAULT_DATA_TABLE_LABELS = {
@@ -79,6 +82,14 @@ var import_react_virtual = require("@tanstack/react-virtual");
79
82
  var import_react4 = require("react");
80
83
 
81
84
  // src/components/ui/table/constants.ts
85
+ var CELL_ALIGN_CLASS = {
86
+ left: "cell-align-left",
87
+ center: "cell-align-center",
88
+ right: "cell-align-right"
89
+ };
90
+ var ROW_HOVER_CLASS = "row-hoverable";
91
+ var ROW_HOVERED_BG_CLASS = "row-hovered";
92
+ var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
82
93
  var DATA_TABLE_ROW_HEIGHT = 44;
83
94
  var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
84
95
 
@@ -1164,6 +1175,937 @@ function useGlideTable(options) {
1164
1175
  clearHover
1165
1176
  };
1166
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
1380
+ } = rowSpan;
1381
+ const { rowSelectionMode, selectOnRowClick, onRowClick, getRowClassName } = selection;
1382
+ const {
1383
+ enableCellSelection,
1384
+ activeSelectionBounds,
1385
+ dragState,
1386
+ onCellMouseDown,
1387
+ onCellMouseEnter,
1388
+ onFillHandleMouseDown
1389
+ } = cellSelection;
1390
+ const {
1391
+ editingCell,
1392
+ draftValue,
1393
+ onDraftValueChange,
1394
+ onStartEdit,
1395
+ onCommitEdit,
1396
+ onCancelEdit
1397
+ } = cellEdit;
1398
+ const {
1399
+ enableExpand,
1400
+ toggleField,
1401
+ expandedRows,
1402
+ preventExpand,
1403
+ onToggleExpand,
1404
+ expandRowLabel,
1405
+ collapseRowLabel
1406
+ } = expand;
1407
+ const rowIndex = row.index;
1408
+ const rowData = row.original;
1409
+ const isRowHovered = hoveredRowIndex === rowIndex;
1410
+ const isRowSelected = row.getIsSelected();
1411
+ const rowGroupKey = primaryRowSpanKey !== void 0 && rowData[primaryRowSpanKey] !== null && rowData[primaryRowSpanKey] !== void 0 ? String(rowData[primaryRowSpanKey]) : null;
1412
+ const isGroupHovered = enableRowSpan && hoveredGroupKey !== null && rowGroupKey === hoveredGroupKey;
1413
+ const isGroupSelected = enableRowSpan && rowGroupKey !== null && selectedGroupKeys.has(rowGroupKey);
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;
1432
+ const expandCellIndex = enableExpand ? resolveExpandCellIndex(visibleCells, toggleField) : -1;
1433
+ const canExpand = enableExpand && !preventExpand && canExpandRow(rowData);
1434
+ const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
1435
+ const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
1436
+ const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
1437
+ const editInputRef = (0, import_react6.useRef)(null);
1438
+ const isRowEditing = editingCell?.rowIndex === rowIndex;
1439
+ (0, import_react6.useEffect)(() => {
1440
+ if (!isRowEditing) return;
1441
+ editInputRef.current?.focus();
1442
+ editInputRef.current?.select();
1443
+ }, [isRowEditing, editingCell?.colIndex]);
1444
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1445
+ "tr",
1446
+ {
1447
+ ref: measureElement,
1448
+ "data-index": virtualIndex,
1449
+ className: cn(
1450
+ "DataTableRowJSX",
1451
+ !enableRowSpan && ROW_HOVER_CLASS,
1452
+ enableRowSpan && isRowHovered && !isRowSelected && ROW_HOVERED_BG_CLASS,
1453
+ isRowSelected && "is-selected",
1454
+ enableExpand && canExpand && "is-expandable",
1455
+ getRowClassName?.(rowData, rowIndex)
1456
+ ),
1457
+ onMouseEnter: () => onRowHover(rowIndex, rowData),
1458
+ onClick: () => {
1459
+ if (isRowEditing) return;
1460
+ onRowClick?.(rowData, rowIndex);
1461
+ if (rowSelectionMode !== "none" && selectOnRowClick) {
1462
+ onToggleSelect();
1463
+ }
1464
+ },
1465
+ children: visibleCells.map((cell, cellIndex) => {
1466
+ const columnId = cell.column.id;
1467
+ const meta = cell.column.columnDef.meta;
1468
+ const align = meta?.align ?? "center";
1469
+ const cellClassName = meta?.className;
1470
+ const isRowSpanColumn = Boolean(enableRowSpan && meta?.rowSpan);
1471
+ const isExpandCell = cellIndex === expandCellIndex;
1472
+ const editable = isColumnEditable(cell.column.columnDef);
1473
+ const editType = getColumnEditType(cell.column.columnDef);
1474
+ let rowSpanInfo;
1475
+ if (isRowSpanColumn) {
1476
+ rowSpanInfo = columnRowSpanMap.get(columnId)?.[rowIndex];
1477
+ if (rowSpanInfo && rowSpanInfo.rowSpan === 0) {
1478
+ return null;
1479
+ }
1480
+ }
1481
+ const isEditing = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === cellIndex;
1482
+ const showCellHover = isRowSpanColumn ? isGroupHovered : isRowHovered;
1483
+ const showCellSelected = isRowSpanColumn ? isGroupSelected : isRowSelected;
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);
1490
+ const isCellDragSelected = isCellInSelection(
1491
+ rowIndex,
1492
+ cellIndex,
1493
+ activeSelectionBounds,
1494
+ cellRowSpan
1495
+ );
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
+ );
1504
+ const resolveCellRowIndex = (clientY, element) => getRowIndexInMergedCell(clientY, element, rowIndex, cellRowSpan);
1505
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1506
+ "td",
1507
+ {
1508
+ rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
1509
+ onMouseDown: (event) => {
1510
+ if (isEditing) {
1511
+ event.stopPropagation();
1512
+ return;
1513
+ }
1514
+ if (!enableCellSelection) return;
1515
+ event.preventDefault();
1516
+ onCellMouseDown(
1517
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1518
+ cellIndex
1519
+ );
1520
+ },
1521
+ onMouseEnter: (event) => {
1522
+ if (!enableCellSelection) return;
1523
+ onCellMouseEnter(
1524
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1525
+ cellIndex
1526
+ );
1527
+ },
1528
+ onMouseMove: (event) => {
1529
+ if (!enableCellSelection) return;
1530
+ if (!dragState.isSelecting && !dragState.isFillDragging) return;
1531
+ onCellMouseEnter(
1532
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1533
+ cellIndex
1534
+ );
1535
+ },
1536
+ onDoubleClick: (event) => {
1537
+ if (!editable) return;
1538
+ event.preventDefault();
1539
+ event.stopPropagation();
1540
+ onStartEdit(rowIndex, cellIndex);
1541
+ },
1542
+ style: selectionEdgeStyle,
1543
+ className: cn(
1544
+ "data-table-cell",
1545
+ CELL_ALIGN_CLASS[align],
1546
+ cellClassName,
1547
+ isMerged && cellIndex > 0 && "is-merged",
1548
+ showMergedRightEdge && "is-merged-edge-right",
1549
+ enableRowSpan && showCellSelected && "is-group-selected",
1550
+ enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
1551
+ isCellDragSelected && CELL_SELECTION_FILL_CLASS,
1552
+ hasCellSelectionEdges(selectionEdgeStyle) && CELL_SELECTION_EDGES_CLASS,
1553
+ editable && "is-editable"
1554
+ ),
1555
+ children: [
1556
+ isEditing ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1557
+ "input",
1558
+ {
1559
+ ref: editInputRef,
1560
+ type: editType === "number" ? "number" : "text",
1561
+ defaultValue: draftValue,
1562
+ className: cn("cell-edit-input", CELL_ALIGN_CLASS[align]),
1563
+ onChange: (event) => onDraftValueChange(event.target.value),
1564
+ onMouseDown: (event) => event.stopPropagation(),
1565
+ onClick: (event) => event.stopPropagation(),
1566
+ onKeyDown: (event) => {
1567
+ if (event.key === "Enter") {
1568
+ event.preventDefault();
1569
+ onCommitEdit(event.currentTarget.value);
1570
+ }
1571
+ if (event.key === "Escape") {
1572
+ event.preventDefault();
1573
+ onCancelEdit();
1574
+ }
1575
+ },
1576
+ onBlur: (event) => {
1577
+ onCommitEdit(event.currentTarget.value);
1578
+ }
1579
+ }
1580
+ ) : isExpandCell && enableExpand ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "expand-cell", children: [
1581
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "expand-cell-content", children: [
1582
+ rowLevel > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "expand-cell-indent", children: "\xB7" }),
1583
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "expand-cell-value", children: (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext()) })
1584
+ ] }),
1585
+ canExpand && expandKey && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1586
+ "button",
1587
+ {
1588
+ type: "button",
1589
+ "aria-label": isExpanded ? collapseRowLabel : expandRowLabel,
1590
+ className: "expand-toggle-button",
1591
+ onClick: (event) => {
1592
+ event.stopPropagation();
1593
+ onToggleExpand?.(expandKey);
1594
+ },
1595
+ onMouseDown: (event) => event.stopPropagation(),
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" })
1597
+ }
1598
+ )
1599
+ ] }) : (0, import_react_table2.flexRender)(cell.column.columnDef.cell, cell.getContext()),
1600
+ isBottomRightCell && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1601
+ "div",
1602
+ {
1603
+ role: "presentation",
1604
+ className: "fill-handle",
1605
+ onMouseDown: (event) => {
1606
+ event.stopPropagation();
1607
+ event.preventDefault();
1608
+ onFillHandleMouseDown(rowIndex, cellIndex);
1609
+ }
1610
+ }
1611
+ )
1612
+ ]
1613
+ },
1614
+ cell.id
1615
+ );
1616
+ })
1617
+ }
1618
+ );
1619
+ }
1620
+
1621
+ // src/components/ui/table/components/DataTable/DataTableToolbar.tsx
1622
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1623
+ function DataTableToolbar({
1624
+ filteredCount,
1625
+ totalCount,
1626
+ summary,
1627
+ selectedCount,
1628
+ selectionLabel,
1629
+ toolbar,
1630
+ className
1631
+ }) {
1632
+ const displayFiltered = filteredCount ?? totalCount;
1633
+ const hasCount = displayFiltered !== void 0 || totalCount !== void 0;
1634
+ const hasLeftContent = hasCount || Boolean(summary);
1635
+ const hasToolbar = Boolean(toolbar);
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
+ ] });
1655
+ }
1656
+
1657
+ // src/components/ui/table/components/DataTable/DataTable.tsx
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
+ }
1671
+ function DataTable({
1672
+ isPending = false,
1673
+ summary,
1674
+ toolbar,
1675
+ filteredCount,
1676
+ totalCount,
1677
+ className,
1678
+ slots,
1679
+ ...glideOptions
1680
+ }) {
1681
+ const {
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;
1705
+ if (isPending) {
1706
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PendingSlot, { loadingText, className });
1707
+ }
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,
1784
+ {
1785
+ row,
1786
+ onToggleSelect: () => handleToggleSelect(row)
1787
+ },
1788
+ row.id
1789
+ )) }) })
1790
+ ]
1791
+ }
1792
+ ) })
1793
+ ]
1794
+ }
1795
+ );
1796
+ }
1797
+
1798
+ // src/components/ui/table/components/Table/Table.tsx
1799
+ var import_react9 = require("react");
1800
+
1801
+ // src/components/ui/table/components/Table/buildColumnDef.tsx
1802
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1803
+ function SortableHeader({
1804
+ label,
1805
+ field,
1806
+ sort,
1807
+ onSort
1808
+ }) {
1809
+ const isActive = sort?.field === field;
1810
+ const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
1811
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1812
+ "button",
1813
+ {
1814
+ type: "button",
1815
+ className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
1816
+ onClick: () => onSort(field),
1817
+ children: [
1818
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: label }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { className: "sortable-header-icon" })
1820
+ ]
1821
+ }
1822
+ );
1823
+ }
1824
+ function buildColumnDef(props, sort, onSort) {
1825
+ const {
1826
+ field,
1827
+ virtual = false,
1828
+ children,
1829
+ sortable = false,
1830
+ width,
1831
+ align,
1832
+ rowSpan,
1833
+ rowSpanKey,
1834
+ editable,
1835
+ editType,
1836
+ className,
1837
+ headerClassName,
1838
+ render
1839
+ } = props;
1840
+ return {
1841
+ id: field,
1842
+ ...!virtual ? { accessorKey: field } : {},
1843
+ size: width ?? 150,
1844
+ header: sortable ? () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SortableHeader, { label: children, field, sort, onSort }) : (
1845
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1846
+ () => children
1847
+ ),
1848
+ ...render ? {
1849
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1850
+ cell: ({ row, getValue }) => render(
1851
+ getValue(),
1852
+ row,
1853
+ row.index
1854
+ )
1855
+ } : {},
1856
+ meta: {
1857
+ align,
1858
+ rowSpan,
1859
+ rowSpanKey,
1860
+ editable,
1861
+ editType,
1862
+ className,
1863
+ headerClassName
1864
+ }
1865
+ };
1866
+ }
1867
+
1868
+ // src/components/ui/table/components/Table/parseTableChildren.ts
1869
+ var import_react8 = require("react");
1870
+
1871
+ // src/components/ui/table/components/Table/tableChildTypes.ts
1872
+ var import_react7 = require("react");
1873
+ var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
1874
+ var TABLE_BODY_DISPLAY_NAME = "Table.Body";
1875
+ var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
1876
+ var TABLE_PAGINATION_DISPLAY_NAME = "Table.Pagination";
1877
+ function getComponentDisplayName(type) {
1878
+ if (typeof type === "function" || typeof type === "object" && type !== null) {
1879
+ return type.displayName;
1880
+ }
1881
+ return void 0;
1882
+ }
1883
+ function isTableHeaderElement(child) {
1884
+ return (0, import_react7.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
1885
+ }
1886
+ function isTableBodyElement(child) {
1887
+ return (0, import_react7.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
1888
+ }
1889
+ function isTableColumnElement(child) {
1890
+ return (0, import_react7.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
1891
+ }
1892
+ function isTablePaginationElement(child) {
1893
+ return (0, import_react7.isValidElement)(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
1894
+ }
1895
+
1896
+ // src/components/ui/table/components/Table/parseTableChildren.ts
1897
+ function parseTableChildren(children) {
1898
+ const slots = {
1899
+ header: null,
1900
+ body: null,
1901
+ pagination: null
1902
+ };
1903
+ for (const child of import_react8.Children.toArray(children)) {
1904
+ if (isTableHeaderElement(child)) {
1905
+ slots.header = child;
1906
+ continue;
1907
+ }
1908
+ if (isTableBodyElement(child)) {
1909
+ slots.body = child;
1910
+ continue;
1911
+ }
1912
+ if (isTablePaginationElement(child)) {
1913
+ slots.pagination = child;
1914
+ }
1915
+ }
1916
+ return slots;
1917
+ }
1918
+ function extractColumnElements(header) {
1919
+ if (!header) return [];
1920
+ const { children } = header.props;
1921
+ return import_react8.Children.toArray(children).filter(isTableColumnElement);
1922
+ }
1923
+
1924
+ // src/components/ui/table/components/Table/TableBody.tsx
1925
+ function TableBody() {
1926
+ return null;
1927
+ }
1928
+ TableBody.displayName = TABLE_BODY_DISPLAY_NAME;
1929
+
1930
+ // src/components/ui/table/components/Table/TableColumn.tsx
1931
+ function TableColumn(props) {
1932
+ void props;
1933
+ return null;
1934
+ }
1935
+ TableColumn.displayName = TABLE_COLUMN_DISPLAY_NAME;
1936
+
1937
+ // src/components/ui/table/components/Table/tableDataPipeline.ts
1938
+ function sortTableData(data, sort) {
1939
+ if (!sort) return data;
1940
+ const { field, direction } = sort;
1941
+ const multiplier = direction === "asc" ? 1 : -1;
1942
+ return [...data].sort((left, right) => {
1943
+ const leftValue = left[field];
1944
+ const rightValue = right[field];
1945
+ if ((leftValue === null || leftValue === void 0) && (rightValue === null || rightValue === void 0)) {
1946
+ return 0;
1947
+ }
1948
+ if (leftValue === null || leftValue === void 0) return 1;
1949
+ if (rightValue === null || rightValue === void 0) return -1;
1950
+ if (typeof leftValue === "number" && typeof rightValue === "number") {
1951
+ return (leftValue - rightValue) * multiplier;
1952
+ }
1953
+ return String(leftValue).localeCompare(String(rightValue), "ko") * multiplier;
1954
+ });
1955
+ }
1956
+ function paginateTableData(data, page, pageSize) {
1957
+ const safePage = Math.max(1, page);
1958
+ const start = (safePage - 1) * pageSize;
1959
+ return data.slice(start, start + pageSize);
1960
+ }
1961
+ function getTotalPages(totalCount, pageSize) {
1962
+ if (pageSize <= 0) return 1;
1963
+ return Math.max(1, Math.ceil(totalCount / pageSize));
1964
+ }
1965
+
1966
+ // src/components/ui/table/components/Table/TableHeader.tsx
1967
+ function TableHeader(props) {
1968
+ void props;
1969
+ return null;
1970
+ }
1971
+ TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
1972
+
1973
+ // src/components/ui/table/components/Table/TablePagination.tsx
1974
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1975
+ function TablePagination({
1976
+ page,
1977
+ pageSize = 10,
1978
+ totalCount = 0,
1979
+ onChange,
1980
+ className
1981
+ }) {
1982
+ const totalPages = getTotalPages(totalCount, pageSize);
1983
+ const safePage = Math.min(Math.max(1, page), totalPages);
1984
+ const canGoPrev = safePage > 1;
1985
+ const canGoNext = safePage < totalPages;
1986
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: cn("TablePaginationJSX", className), children: [
1987
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1988
+ "button",
1989
+ {
1990
+ type: "button",
1991
+ className: "pagination-button",
1992
+ disabled: !canGoPrev,
1993
+ onClick: () => onChange(safePage - 1),
1994
+ "aria-label": "Previous page",
1995
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeft, { className: "pagination-button-icon" })
1996
+ }
1997
+ ),
1998
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "pagination-label", children: [
1999
+ safePage,
2000
+ " / ",
2001
+ totalPages
2002
+ ] }),
2003
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2004
+ "button",
2005
+ {
2006
+ type: "button",
2007
+ className: "pagination-button",
2008
+ disabled: !canGoNext,
2009
+ onClick: () => onChange(safePage + 1),
2010
+ "aria-label": "Next page",
2011
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronRight, { className: "pagination-button-icon" })
2012
+ }
2013
+ )
2014
+ ] });
2015
+ }
2016
+ TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
2017
+
2018
+ // src/components/ui/table/components/Table/Table.tsx
2019
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2020
+ function TableRoot({
2021
+ data,
2022
+ children,
2023
+ className,
2024
+ totalCount,
2025
+ filteredCount,
2026
+ ...dataTableProps
2027
+ }) {
2028
+ const { header, pagination: paginationElement } = (0, import_react9.useMemo)(
2029
+ () => parseTableChildren(children),
2030
+ [children]
2031
+ );
2032
+ const [sort, setSort] = (0, import_react9.useState)(null);
2033
+ const handleSort = (0, import_react9.useCallback)((field) => {
2034
+ setSort((previous) => {
2035
+ if (previous?.field !== field) {
2036
+ return { field, direction: "asc" };
2037
+ }
2038
+ if (previous.direction === "asc") {
2039
+ return { field, direction: "desc" };
2040
+ }
2041
+ return null;
2042
+ });
2043
+ }, []);
2044
+ const columns = (0, import_react9.useMemo)(() => {
2045
+ return extractColumnElements(header).map(
2046
+ (columnElement) => buildColumnDef(columnElement.props, sort, handleSort)
2047
+ );
2048
+ }, [header, sort, handleSort]);
2049
+ const paginationProps = paginationElement?.props;
2050
+ const pageSize = paginationProps?.pageSize ?? 10;
2051
+ const page = paginationProps?.page ?? 1;
2052
+ const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
2053
+ const tableData = (0, import_react9.useMemo)(() => {
2054
+ const sortedData = sortTableData(data, sort);
2055
+ if (!paginationProps) return sortedData;
2056
+ return paginateTableData(sortedData, page, pageSize);
2057
+ }, [data, sort, paginationProps, page, pageSize]);
2058
+ if (columns.length === 0) {
2059
+ console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
2060
+ }
2061
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "TableJSX", children: [
2062
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2063
+ DataTable,
2064
+ {
2065
+ ...dataTableProps,
2066
+ data: tableData,
2067
+ columns,
2068
+ totalCount: paginationProps ? resolvedTotalCount : totalCount,
2069
+ filteredCount: filteredCount ?? data.length,
2070
+ className: cn(className, paginationProps && "DataTableJSX--with-pagination")
2071
+ }
2072
+ ),
2073
+ paginationProps && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2074
+ TablePagination,
2075
+ {
2076
+ page,
2077
+ pageSize,
2078
+ totalCount: resolvedTotalCount,
2079
+ onChange: paginationProps.onChange,
2080
+ className: paginationProps.className
2081
+ }
2082
+ )
2083
+ ] });
2084
+ }
2085
+ function createTable() {
2086
+ function Column(props) {
2087
+ void props;
2088
+ return null;
2089
+ }
2090
+ Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
2091
+ return Object.assign(
2092
+ function BoundTable(props) {
2093
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TableRoot, { ...props });
2094
+ },
2095
+ {
2096
+ Header: TableHeader,
2097
+ Column,
2098
+ Body: TableBody,
2099
+ Pagination: TablePagination
2100
+ }
2101
+ );
2102
+ }
2103
+ var Table = Object.assign(TableRoot, {
2104
+ Header: TableHeader,
2105
+ Column: TableColumn,
2106
+ Body: TableBody,
2107
+ Pagination: TablePagination
2108
+ });
1167
2109
  // Annotate the CommonJS export names for ESM import in node:
1168
2110
  0 && (module.exports = {
1169
2111
  CELL_SELECTION_EDGES_CLASS,
@@ -1172,6 +2114,8 @@ function useGlideTable(options) {
1172
2114
  DEFAULT_TREE_ID_FIELD,
1173
2115
  DEFAULT_TREE_PARENT_ID_FIELD,
1174
2116
  DEFAULT_TREE_QTY_FIELD,
2117
+ DataTable,
2118
+ Table,
1175
2119
  applyCellEdit,
1176
2120
  applyFillData,
1177
2121
  applySelectionUpdater,
@@ -1179,6 +2123,7 @@ function useGlideTable(options) {
1179
2123
  canExpandRow,
1180
2124
  collectFillChanges,
1181
2125
  collectRowSpanColumns,
2126
+ createTable,
1182
2127
  getCellEditDraftValue,
1183
2128
  getCellSelectionEdgeStyle,
1184
2129
  getColumnEditType,