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.js CHANGED
@@ -36,6 +36,14 @@ import {
36
36
  } from "react";
37
37
 
38
38
  // src/components/ui/table/constants.ts
39
+ var CELL_ALIGN_CLASS = {
40
+ left: "cell-align-left",
41
+ center: "cell-align-center",
42
+ right: "cell-align-right"
43
+ };
44
+ var ROW_HOVER_CLASS = "row-hoverable";
45
+ var ROW_HOVERED_BG_CLASS = "row-hovered";
46
+ var CELL_SELECTION_FILL_CLASS = "cell-selection-fill";
39
47
  var DATA_TABLE_ROW_HEIGHT = 44;
40
48
  var DATA_TABLE_VIRTUAL_OVERSCAN = 8;
41
49
 
@@ -1121,6 +1129,937 @@ function useGlideTable(options) {
1121
1129
  clearHover
1122
1130
  };
1123
1131
  }
1132
+
1133
+ // src/components/ui/table/components/DataTable/DataTable.tsx
1134
+ import { flexRender as flexRender2 } from "@tanstack/react-table";
1135
+
1136
+ // src/components/ui/table/components/DataTable/DataTableRow.tsx
1137
+ import { flexRender } from "@tanstack/react-table";
1138
+ import { useEffect as useEffect5, useRef as useRef4 } from "react";
1139
+
1140
+ // src/components/ui/table/DataTableContext.tsx
1141
+ import { createContext, use } from "react";
1142
+ import { jsx } from "react/jsx-runtime";
1143
+ var DataTableContext = createContext(null);
1144
+ function useDataTableRowContext() {
1145
+ const context = use(DataTableContext);
1146
+ if (!context) {
1147
+ throw new Error("useDataTableRowContext must be used within a DataTableContextProvider");
1148
+ }
1149
+ return context;
1150
+ }
1151
+ function DataTableContextProvider({
1152
+ value,
1153
+ children
1154
+ }) {
1155
+ return /* @__PURE__ */ jsx(DataTableContext, { value, children });
1156
+ }
1157
+
1158
+ // src/components/ui/table/components/icons.tsx
1159
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
1160
+ function ChevronDown({ className, "aria-hidden": ariaHidden = true }) {
1161
+ return /* @__PURE__ */ jsx2(
1162
+ "svg",
1163
+ {
1164
+ className,
1165
+ "aria-hidden": ariaHidden,
1166
+ width: "16",
1167
+ height: "16",
1168
+ viewBox: "0 0 24 24",
1169
+ fill: "none",
1170
+ stroke: "currentColor",
1171
+ strokeWidth: "2",
1172
+ strokeLinecap: "round",
1173
+ strokeLinejoin: "round",
1174
+ children: /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" })
1175
+ }
1176
+ );
1177
+ }
1178
+ function ChevronUp({ className, "aria-hidden": ariaHidden = true }) {
1179
+ return /* @__PURE__ */ jsx2(
1180
+ "svg",
1181
+ {
1182
+ className,
1183
+ "aria-hidden": ariaHidden,
1184
+ width: "16",
1185
+ height: "16",
1186
+ viewBox: "0 0 24 24",
1187
+ fill: "none",
1188
+ stroke: "currentColor",
1189
+ strokeWidth: "2",
1190
+ strokeLinecap: "round",
1191
+ strokeLinejoin: "round",
1192
+ children: /* @__PURE__ */ jsx2("path", { d: "m18 15-6-6-6 6" })
1193
+ }
1194
+ );
1195
+ }
1196
+ function ChevronLeft({ className, "aria-hidden": ariaHidden = true }) {
1197
+ return /* @__PURE__ */ jsx2(
1198
+ "svg",
1199
+ {
1200
+ className,
1201
+ "aria-hidden": ariaHidden,
1202
+ width: "16",
1203
+ height: "16",
1204
+ viewBox: "0 0 24 24",
1205
+ fill: "none",
1206
+ stroke: "currentColor",
1207
+ strokeWidth: "2",
1208
+ strokeLinecap: "round",
1209
+ strokeLinejoin: "round",
1210
+ children: /* @__PURE__ */ jsx2("path", { d: "m15 18-6-6 6-6" })
1211
+ }
1212
+ );
1213
+ }
1214
+ function ChevronRight({ className, "aria-hidden": ariaHidden = true }) {
1215
+ return /* @__PURE__ */ jsx2(
1216
+ "svg",
1217
+ {
1218
+ className,
1219
+ "aria-hidden": ariaHidden,
1220
+ width: "16",
1221
+ height: "16",
1222
+ viewBox: "0 0 24 24",
1223
+ fill: "none",
1224
+ stroke: "currentColor",
1225
+ strokeWidth: "2",
1226
+ strokeLinecap: "round",
1227
+ strokeLinejoin: "round",
1228
+ children: /* @__PURE__ */ jsx2("path", { d: "m9 18 6-6-6-6" })
1229
+ }
1230
+ );
1231
+ }
1232
+ function ArrowUp({ className, "aria-hidden": ariaHidden = true }) {
1233
+ return /* @__PURE__ */ jsxs(
1234
+ "svg",
1235
+ {
1236
+ className,
1237
+ "aria-hidden": ariaHidden,
1238
+ width: "14",
1239
+ height: "14",
1240
+ viewBox: "0 0 24 24",
1241
+ fill: "none",
1242
+ stroke: "currentColor",
1243
+ strokeWidth: "2",
1244
+ strokeLinecap: "round",
1245
+ strokeLinejoin: "round",
1246
+ children: [
1247
+ /* @__PURE__ */ jsx2("path", { d: "m18 15-6-6-6 6" }),
1248
+ /* @__PURE__ */ jsx2("path", { d: "M12 21V9" })
1249
+ ]
1250
+ }
1251
+ );
1252
+ }
1253
+ function ArrowDown({ className, "aria-hidden": ariaHidden = true }) {
1254
+ return /* @__PURE__ */ jsxs(
1255
+ "svg",
1256
+ {
1257
+ className,
1258
+ "aria-hidden": ariaHidden,
1259
+ width: "14",
1260
+ height: "14",
1261
+ viewBox: "0 0 24 24",
1262
+ fill: "none",
1263
+ stroke: "currentColor",
1264
+ strokeWidth: "2",
1265
+ strokeLinecap: "round",
1266
+ strokeLinejoin: "round",
1267
+ children: [
1268
+ /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }),
1269
+ /* @__PURE__ */ jsx2("path", { d: "M12 3v12" })
1270
+ ]
1271
+ }
1272
+ );
1273
+ }
1274
+ function ArrowUpDown({ className, "aria-hidden": ariaHidden = true }) {
1275
+ return /* @__PURE__ */ jsxs(
1276
+ "svg",
1277
+ {
1278
+ className,
1279
+ "aria-hidden": ariaHidden,
1280
+ width: "14",
1281
+ height: "14",
1282
+ viewBox: "0 0 24 24",
1283
+ fill: "none",
1284
+ stroke: "currentColor",
1285
+ strokeWidth: "2",
1286
+ strokeLinecap: "round",
1287
+ strokeLinejoin: "round",
1288
+ children: [
1289
+ /* @__PURE__ */ jsx2("path", { d: "m21 16-4 4-4-4" }),
1290
+ /* @__PURE__ */ jsx2("path", { d: "M17 20V4" }),
1291
+ /* @__PURE__ */ jsx2("path", { d: "m3 8 4-4 4 4" }),
1292
+ /* @__PURE__ */ jsx2("path", { d: "M7 4v16" })
1293
+ ]
1294
+ }
1295
+ );
1296
+ }
1297
+
1298
+ // src/lib/cn.ts
1299
+ function cn(...inputs) {
1300
+ return inputs.filter(Boolean).join(" ");
1301
+ }
1302
+
1303
+ // src/components/ui/table/components/DataTable/DataTableRow.tsx
1304
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1305
+ function resolveExpandCellIndex(cells, toggleField) {
1306
+ if (!toggleField) return 0;
1307
+ const matchedIndex = cells.findIndex(
1308
+ (cell) => cell.column.id === toggleField
1309
+ );
1310
+ if (matchedIndex >= 0) return matchedIndex;
1311
+ const noColumnIndex = cells.findIndex(
1312
+ (cell) => cell.column.id === "no" || cell.column.id === "treeNo"
1313
+ );
1314
+ if (noColumnIndex >= 0 && noColumnIndex + 1 < cells.length) {
1315
+ return noColumnIndex + 1;
1316
+ }
1317
+ return 0;
1318
+ }
1319
+ function DataTableRow({
1320
+ row,
1321
+ onToggleSelect,
1322
+ virtualIndex,
1323
+ measureElement
1324
+ }) {
1325
+ const { rowSpan, selection, cellSelection, cellEdit, expand } = useDataTableRowContext();
1326
+ const {
1327
+ enableRowSpan,
1328
+ primaryRowSpanKey,
1329
+ columnRowSpanMap,
1330
+ hoveredRowIndex,
1331
+ hoveredGroupKey,
1332
+ selectedGroupKeys,
1333
+ onRowHover
1334
+ } = rowSpan;
1335
+ const { rowSelectionMode, selectOnRowClick, onRowClick, getRowClassName } = selection;
1336
+ const {
1337
+ enableCellSelection,
1338
+ activeSelectionBounds,
1339
+ dragState,
1340
+ onCellMouseDown,
1341
+ onCellMouseEnter,
1342
+ onFillHandleMouseDown
1343
+ } = cellSelection;
1344
+ const {
1345
+ editingCell,
1346
+ draftValue,
1347
+ onDraftValueChange,
1348
+ onStartEdit,
1349
+ onCommitEdit,
1350
+ onCancelEdit
1351
+ } = cellEdit;
1352
+ const {
1353
+ enableExpand,
1354
+ toggleField,
1355
+ expandedRows,
1356
+ preventExpand,
1357
+ onToggleExpand,
1358
+ expandRowLabel,
1359
+ collapseRowLabel
1360
+ } = expand;
1361
+ const rowIndex = row.index;
1362
+ const rowData = row.original;
1363
+ const isRowHovered = hoveredRowIndex === rowIndex;
1364
+ const isRowSelected = row.getIsSelected();
1365
+ const rowGroupKey = primaryRowSpanKey !== void 0 && rowData[primaryRowSpanKey] !== null && rowData[primaryRowSpanKey] !== void 0 ? String(rowData[primaryRowSpanKey]) : null;
1366
+ const isGroupHovered = enableRowSpan && hoveredGroupKey !== null && rowGroupKey === hoveredGroupKey;
1367
+ const isGroupSelected = enableRowSpan && rowGroupKey !== null && selectedGroupKeys.has(rowGroupKey);
1368
+ const visibleCells = row.getVisibleCells();
1369
+ const columnIdsByIndex = visibleCells.map((cell) => cell.column.id);
1370
+ const isVisuallySelectedAt = activeSelectionBounds ? (targetRow, targetCol) => {
1371
+ if (targetCol < activeSelectionBounds.startCol || targetCol > activeSelectionBounds.endCol) {
1372
+ return false;
1373
+ }
1374
+ const columnId = columnIdsByIndex[targetCol];
1375
+ const { startRow, rowSpan: span } = resolveRowSpanAt(
1376
+ columnId ? columnRowSpanMap.get(columnId) : void 0,
1377
+ targetRow
1378
+ );
1379
+ return isCellInSelection(
1380
+ startRow,
1381
+ targetCol,
1382
+ activeSelectionBounds,
1383
+ span
1384
+ );
1385
+ } : void 0;
1386
+ const expandCellIndex = enableExpand ? resolveExpandCellIndex(visibleCells, toggleField) : -1;
1387
+ const canExpand = enableExpand && !preventExpand && canExpandRow(rowData);
1388
+ const expandKey = toggleField && rowData[toggleField] !== null && rowData[toggleField] !== void 0 ? String(rowData[toggleField]) : null;
1389
+ const isExpanded = expandKey !== null && Boolean(expandedRows?.has(expandKey));
1390
+ const rowLevel = typeof rowData.level === "number" ? rowData.level : 0;
1391
+ const editInputRef = useRef4(null);
1392
+ const isRowEditing = editingCell?.rowIndex === rowIndex;
1393
+ useEffect5(() => {
1394
+ if (!isRowEditing) return;
1395
+ editInputRef.current?.focus();
1396
+ editInputRef.current?.select();
1397
+ }, [isRowEditing, editingCell?.colIndex]);
1398
+ return /* @__PURE__ */ jsx3(
1399
+ "tr",
1400
+ {
1401
+ ref: measureElement,
1402
+ "data-index": virtualIndex,
1403
+ className: cn(
1404
+ "DataTableRowJSX",
1405
+ !enableRowSpan && ROW_HOVER_CLASS,
1406
+ enableRowSpan && isRowHovered && !isRowSelected && ROW_HOVERED_BG_CLASS,
1407
+ isRowSelected && "is-selected",
1408
+ enableExpand && canExpand && "is-expandable",
1409
+ getRowClassName?.(rowData, rowIndex)
1410
+ ),
1411
+ onMouseEnter: () => onRowHover(rowIndex, rowData),
1412
+ onClick: () => {
1413
+ if (isRowEditing) return;
1414
+ onRowClick?.(rowData, rowIndex);
1415
+ if (rowSelectionMode !== "none" && selectOnRowClick) {
1416
+ onToggleSelect();
1417
+ }
1418
+ },
1419
+ children: visibleCells.map((cell, cellIndex) => {
1420
+ const columnId = cell.column.id;
1421
+ const meta = cell.column.columnDef.meta;
1422
+ const align = meta?.align ?? "center";
1423
+ const cellClassName = meta?.className;
1424
+ const isRowSpanColumn = Boolean(enableRowSpan && meta?.rowSpan);
1425
+ const isExpandCell = cellIndex === expandCellIndex;
1426
+ const editable = isColumnEditable(cell.column.columnDef);
1427
+ const editType = getColumnEditType(cell.column.columnDef);
1428
+ let rowSpanInfo;
1429
+ if (isRowSpanColumn) {
1430
+ rowSpanInfo = columnRowSpanMap.get(columnId)?.[rowIndex];
1431
+ if (rowSpanInfo && rowSpanInfo.rowSpan === 0) {
1432
+ return null;
1433
+ }
1434
+ }
1435
+ const isEditing = editingCell?.rowIndex === rowIndex && editingCell?.colIndex === cellIndex;
1436
+ const showCellHover = isRowSpanColumn ? isGroupHovered : isRowHovered;
1437
+ const showCellSelected = isRowSpanColumn ? isGroupSelected : isRowSelected;
1438
+ const cellRowSpan = rowSpanInfo?.rowSpan ?? 1;
1439
+ const isMerged = cellRowSpan > 1;
1440
+ const showMergedRightEdge = isMerged && (cellIndex === visibleCells.length - 1 || resolveRowSpanAt(
1441
+ columnRowSpanMap.get(columnIdsByIndex[cellIndex + 1]),
1442
+ rowIndex
1443
+ ).rowSpan <= 1);
1444
+ const isCellDragSelected = isCellInSelection(
1445
+ rowIndex,
1446
+ cellIndex,
1447
+ activeSelectionBounds,
1448
+ cellRowSpan
1449
+ );
1450
+ const isBottomRightCell = !isEditing && activeSelectionBounds && !dragState.isSelecting && activeSelectionBounds.endRow >= rowIndex && activeSelectionBounds.endRow <= rowIndex + cellRowSpan - 1 && cellIndex === activeSelectionBounds.endCol;
1451
+ const selectionEdgeStyle = getCellSelectionEdgeStyle(
1452
+ rowIndex,
1453
+ cellIndex,
1454
+ activeSelectionBounds,
1455
+ cellRowSpan,
1456
+ isVisuallySelectedAt
1457
+ );
1458
+ const resolveCellRowIndex = (clientY, element) => getRowIndexInMergedCell(clientY, element, rowIndex, cellRowSpan);
1459
+ return /* @__PURE__ */ jsxs2(
1460
+ "td",
1461
+ {
1462
+ rowSpan: rowSpanInfo && rowSpanInfo.rowSpan > 1 ? rowSpanInfo.rowSpan : void 0,
1463
+ onMouseDown: (event) => {
1464
+ if (isEditing) {
1465
+ event.stopPropagation();
1466
+ return;
1467
+ }
1468
+ if (!enableCellSelection) return;
1469
+ event.preventDefault();
1470
+ onCellMouseDown(
1471
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1472
+ cellIndex
1473
+ );
1474
+ },
1475
+ onMouseEnter: (event) => {
1476
+ if (!enableCellSelection) return;
1477
+ onCellMouseEnter(
1478
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1479
+ cellIndex
1480
+ );
1481
+ },
1482
+ onMouseMove: (event) => {
1483
+ if (!enableCellSelection) return;
1484
+ if (!dragState.isSelecting && !dragState.isFillDragging) return;
1485
+ onCellMouseEnter(
1486
+ resolveCellRowIndex(event.clientY, event.currentTarget),
1487
+ cellIndex
1488
+ );
1489
+ },
1490
+ onDoubleClick: (event) => {
1491
+ if (!editable) return;
1492
+ event.preventDefault();
1493
+ event.stopPropagation();
1494
+ onStartEdit(rowIndex, cellIndex);
1495
+ },
1496
+ style: selectionEdgeStyle,
1497
+ className: cn(
1498
+ "data-table-cell",
1499
+ CELL_ALIGN_CLASS[align],
1500
+ cellClassName,
1501
+ isMerged && cellIndex > 0 && "is-merged",
1502
+ showMergedRightEdge && "is-merged-edge-right",
1503
+ enableRowSpan && showCellSelected && "is-group-selected",
1504
+ enableRowSpan && showCellHover && !showCellSelected && "is-group-hovered",
1505
+ isCellDragSelected && CELL_SELECTION_FILL_CLASS,
1506
+ hasCellSelectionEdges(selectionEdgeStyle) && CELL_SELECTION_EDGES_CLASS,
1507
+ editable && "is-editable"
1508
+ ),
1509
+ children: [
1510
+ isEditing ? /* @__PURE__ */ jsx3(
1511
+ "input",
1512
+ {
1513
+ ref: editInputRef,
1514
+ type: editType === "number" ? "number" : "text",
1515
+ defaultValue: draftValue,
1516
+ className: cn("cell-edit-input", CELL_ALIGN_CLASS[align]),
1517
+ onChange: (event) => onDraftValueChange(event.target.value),
1518
+ onMouseDown: (event) => event.stopPropagation(),
1519
+ onClick: (event) => event.stopPropagation(),
1520
+ onKeyDown: (event) => {
1521
+ if (event.key === "Enter") {
1522
+ event.preventDefault();
1523
+ onCommitEdit(event.currentTarget.value);
1524
+ }
1525
+ if (event.key === "Escape") {
1526
+ event.preventDefault();
1527
+ onCancelEdit();
1528
+ }
1529
+ },
1530
+ onBlur: (event) => {
1531
+ onCommitEdit(event.currentTarget.value);
1532
+ }
1533
+ }
1534
+ ) : isExpandCell && enableExpand ? /* @__PURE__ */ jsxs2("div", { className: "expand-cell", children: [
1535
+ /* @__PURE__ */ jsxs2("div", { className: "expand-cell-content", children: [
1536
+ rowLevel > 0 && /* @__PURE__ */ jsx3("span", { className: "expand-cell-indent", children: "\xB7" }),
1537
+ /* @__PURE__ */ jsx3("div", { className: "expand-cell-value", children: flexRender(cell.column.columnDef.cell, cell.getContext()) })
1538
+ ] }),
1539
+ canExpand && expandKey && /* @__PURE__ */ jsx3(
1540
+ "button",
1541
+ {
1542
+ type: "button",
1543
+ "aria-label": isExpanded ? collapseRowLabel : expandRowLabel,
1544
+ className: "expand-toggle-button",
1545
+ onClick: (event) => {
1546
+ event.stopPropagation();
1547
+ onToggleExpand?.(expandKey);
1548
+ },
1549
+ onMouseDown: (event) => event.stopPropagation(),
1550
+ children: isExpanded ? /* @__PURE__ */ jsx3(ChevronUp, { className: "expand-toggle-icon" }) : /* @__PURE__ */ jsx3(ChevronDown, { className: "expand-toggle-icon" })
1551
+ }
1552
+ )
1553
+ ] }) : flexRender(cell.column.columnDef.cell, cell.getContext()),
1554
+ isBottomRightCell && /* @__PURE__ */ jsx3(
1555
+ "div",
1556
+ {
1557
+ role: "presentation",
1558
+ className: "fill-handle",
1559
+ onMouseDown: (event) => {
1560
+ event.stopPropagation();
1561
+ event.preventDefault();
1562
+ onFillHandleMouseDown(rowIndex, cellIndex);
1563
+ }
1564
+ }
1565
+ )
1566
+ ]
1567
+ },
1568
+ cell.id
1569
+ );
1570
+ })
1571
+ }
1572
+ );
1573
+ }
1574
+
1575
+ // src/components/ui/table/components/DataTable/DataTableToolbar.tsx
1576
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1577
+ function DataTableToolbar({
1578
+ filteredCount,
1579
+ totalCount,
1580
+ summary,
1581
+ selectedCount,
1582
+ selectionLabel,
1583
+ toolbar,
1584
+ className
1585
+ }) {
1586
+ const displayFiltered = filteredCount ?? totalCount;
1587
+ const hasCount = displayFiltered !== void 0 || totalCount !== void 0;
1588
+ const hasLeftContent = hasCount || Boolean(summary);
1589
+ const hasToolbar = Boolean(toolbar);
1590
+ const selectionContent = selectionLabel?.(selectedCount) ?? null;
1591
+ const hasSelectionContent = selectionContent !== null && selectionContent !== false && selectionContent !== void 0 && typeof selectionContent !== "boolean";
1592
+ if (!hasLeftContent && !hasToolbar && !hasSelectionContent) return null;
1593
+ return /* @__PURE__ */ jsxs3("div", { className: cn("DataTableToolbarJSX", className), children: [
1594
+ /* @__PURE__ */ jsxs3("div", { className: "toolbar-left", children: [
1595
+ hasCount && /* @__PURE__ */ jsx4("span", { className: "toolbar-count", children: displayFiltered !== void 0 && totalCount !== void 0 ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1596
+ /* @__PURE__ */ jsx4("span", { className: "toolbar-count-primary", children: displayFiltered }),
1597
+ /* @__PURE__ */ jsxs3("span", { className: "toolbar-count-placeholder", children: [
1598
+ " / ",
1599
+ totalCount
1600
+ ] })
1601
+ ] }) : /* @__PURE__ */ jsx4("span", { className: "toolbar-count-primary", children: displayFiltered ?? totalCount }) }),
1602
+ summary
1603
+ ] }),
1604
+ /* @__PURE__ */ jsxs3("div", { className: "toolbar-right", children: [
1605
+ hasSelectionContent && (typeof selectionContent === "string" || typeof selectionContent === "number" ? /* @__PURE__ */ jsx4("span", { className: "toolbar-selection", children: selectionContent }) : selectionContent),
1606
+ hasToolbar && /* @__PURE__ */ jsx4("div", { className: "toolbar-actions", children: toolbar })
1607
+ ] })
1608
+ ] });
1609
+ }
1610
+
1611
+ // src/components/ui/table/components/DataTable/DataTable.tsx
1612
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1613
+ function DefaultPending({
1614
+ loadingText,
1615
+ className
1616
+ }) {
1617
+ return /* @__PURE__ */ jsx5("div", { className: cn("DataTableJSX", "DataTableJSX--pending", className), children: /* @__PURE__ */ jsx5("span", { className: "data-table-loading-text", children: loadingText }) });
1618
+ }
1619
+ function DefaultEmpty({
1620
+ emptyText,
1621
+ columnCount
1622
+ }) {
1623
+ return /* @__PURE__ */ jsx5("tr", { children: /* @__PURE__ */ jsx5("td", { colSpan: columnCount, className: "data-table-empty-cell", children: emptyText }) });
1624
+ }
1625
+ function DataTable({
1626
+ isPending = false,
1627
+ summary,
1628
+ toolbar,
1629
+ filteredCount,
1630
+ totalCount,
1631
+ className,
1632
+ slots,
1633
+ ...glideOptions
1634
+ }) {
1635
+ const {
1636
+ table,
1637
+ tableData,
1638
+ rows,
1639
+ columnCount,
1640
+ selectedCount,
1641
+ emptyText,
1642
+ loadingText,
1643
+ selectionLabel,
1644
+ enableCellSelection,
1645
+ shouldVirtualize,
1646
+ scrollRef,
1647
+ rowVirtualizer,
1648
+ virtualRows,
1649
+ paddingTop,
1650
+ paddingBottom,
1651
+ rowContextValue,
1652
+ handleToggleSelect,
1653
+ clearHover
1654
+ } = useGlideTable(glideOptions);
1655
+ const ToolbarSlot = slots?.Toolbar ?? DataTableToolbar;
1656
+ const RowSlot = slots?.Row ?? DataTableRow;
1657
+ const PendingSlot = slots?.Pending ?? DefaultPending;
1658
+ const EmptySlot = slots?.Empty ?? DefaultEmpty;
1659
+ if (isPending) {
1660
+ return /* @__PURE__ */ jsx5(PendingSlot, { loadingText, className });
1661
+ }
1662
+ return /* @__PURE__ */ jsxs4(
1663
+ "div",
1664
+ {
1665
+ className: cn(
1666
+ "DataTableJSX",
1667
+ !enableCellSelection && "DataTableJSX--no-cell-selection",
1668
+ className
1669
+ ),
1670
+ children: [
1671
+ /* @__PURE__ */ jsx5(
1672
+ ToolbarSlot,
1673
+ {
1674
+ filteredCount: filteredCount ?? tableData.length,
1675
+ totalCount,
1676
+ summary,
1677
+ selectedCount,
1678
+ selectionLabel,
1679
+ toolbar
1680
+ }
1681
+ ),
1682
+ /* @__PURE__ */ jsx5("div", { ref: scrollRef, className: "data-table-scroll", children: /* @__PURE__ */ jsxs4(
1683
+ "table",
1684
+ {
1685
+ className: "data-table",
1686
+ onDragStart: enableCellSelection ? (event) => event.preventDefault() : void 0,
1687
+ children: [
1688
+ /* @__PURE__ */ jsx5("thead", { className: "data-table-head", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx5("tr", { className: "data-table-head-row", children: headerGroup.headers.map((header) => {
1689
+ const align = header.column.columnDef.meta?.align ?? "center";
1690
+ const headerClassName = header.column.columnDef.meta?.headerClassName;
1691
+ return /* @__PURE__ */ jsx5(
1692
+ "th",
1693
+ {
1694
+ style: { width: header.getSize() !== 150 ? header.getSize() : void 0 },
1695
+ className: cn(
1696
+ "data-table-head-cell",
1697
+ CELL_ALIGN_CLASS[align],
1698
+ headerClassName
1699
+ ),
1700
+ children: header.isPlaceholder ? null : flexRender2(header.column.columnDef.header, header.getContext())
1701
+ },
1702
+ header.id
1703
+ );
1704
+ }) }, headerGroup.id)) }),
1705
+ /* @__PURE__ */ jsx5(DataTableContextProvider, { value: rowContextValue, children: /* @__PURE__ */ jsx5("tbody", { onMouseLeave: clearHover, className: "data-table-body", children: rows.length === 0 ? /* @__PURE__ */ jsx5(EmptySlot, { emptyText, columnCount }) : shouldVirtualize ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
1706
+ paddingTop > 0 && /* @__PURE__ */ jsx5("tr", { "aria-hidden": true, className: "data-table-virtual-spacer", children: /* @__PURE__ */ jsx5(
1707
+ "td",
1708
+ {
1709
+ colSpan: columnCount,
1710
+ style: { height: paddingTop },
1711
+ className: "data-table-virtual-spacer-cell"
1712
+ }
1713
+ ) }),
1714
+ virtualRows.map((virtualRow) => {
1715
+ const row = rows[virtualRow.index];
1716
+ if (!row) return null;
1717
+ return /* @__PURE__ */ jsx5(
1718
+ RowSlot,
1719
+ {
1720
+ row,
1721
+ virtualIndex: virtualRow.index,
1722
+ measureElement: rowVirtualizer.measureElement,
1723
+ onToggleSelect: () => handleToggleSelect(row)
1724
+ },
1725
+ row.id
1726
+ );
1727
+ }),
1728
+ paddingBottom > 0 && /* @__PURE__ */ jsx5("tr", { "aria-hidden": true, className: "data-table-virtual-spacer", children: /* @__PURE__ */ jsx5(
1729
+ "td",
1730
+ {
1731
+ colSpan: columnCount,
1732
+ style: { height: paddingBottom },
1733
+ className: "data-table-virtual-spacer-cell"
1734
+ }
1735
+ ) })
1736
+ ] }) : rows.map((row) => /* @__PURE__ */ jsx5(
1737
+ RowSlot,
1738
+ {
1739
+ row,
1740
+ onToggleSelect: () => handleToggleSelect(row)
1741
+ },
1742
+ row.id
1743
+ )) }) })
1744
+ ]
1745
+ }
1746
+ ) })
1747
+ ]
1748
+ }
1749
+ );
1750
+ }
1751
+
1752
+ // src/components/ui/table/components/Table/Table.tsx
1753
+ import { useCallback as useCallback4, useMemo as useMemo3, useState as useState4 } from "react";
1754
+
1755
+ // src/components/ui/table/components/Table/buildColumnDef.tsx
1756
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1757
+ function SortableHeader({
1758
+ label,
1759
+ field,
1760
+ sort,
1761
+ onSort
1762
+ }) {
1763
+ const isActive = sort?.field === field;
1764
+ const Icon = isActive ? sort.direction === "asc" ? ArrowUp : ArrowDown : ArrowUpDown;
1765
+ return /* @__PURE__ */ jsxs5(
1766
+ "button",
1767
+ {
1768
+ type: "button",
1769
+ className: cn("SortableHeaderJSX", isActive ? "is-active" : "is-inactive"),
1770
+ onClick: () => onSort(field),
1771
+ children: [
1772
+ /* @__PURE__ */ jsx6("span", { children: label }),
1773
+ /* @__PURE__ */ jsx6(Icon, { className: "sortable-header-icon" })
1774
+ ]
1775
+ }
1776
+ );
1777
+ }
1778
+ function buildColumnDef(props, sort, onSort) {
1779
+ const {
1780
+ field,
1781
+ virtual = false,
1782
+ children,
1783
+ sortable = false,
1784
+ width,
1785
+ align,
1786
+ rowSpan,
1787
+ rowSpanKey,
1788
+ editable,
1789
+ editType,
1790
+ className,
1791
+ headerClassName,
1792
+ render
1793
+ } = props;
1794
+ return {
1795
+ id: field,
1796
+ ...!virtual ? { accessorKey: field } : {},
1797
+ size: width ?? 150,
1798
+ header: sortable ? () => /* @__PURE__ */ jsx6(SortableHeader, { label: children, field, sort, onSort }) : (
1799
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1800
+ () => children
1801
+ ),
1802
+ ...render ? {
1803
+ // eslint-disable-next-line @typescript-eslint/promise-function-async
1804
+ cell: ({ row, getValue }) => render(
1805
+ getValue(),
1806
+ row,
1807
+ row.index
1808
+ )
1809
+ } : {},
1810
+ meta: {
1811
+ align,
1812
+ rowSpan,
1813
+ rowSpanKey,
1814
+ editable,
1815
+ editType,
1816
+ className,
1817
+ headerClassName
1818
+ }
1819
+ };
1820
+ }
1821
+
1822
+ // src/components/ui/table/components/Table/parseTableChildren.ts
1823
+ import { Children } from "react";
1824
+
1825
+ // src/components/ui/table/components/Table/tableChildTypes.ts
1826
+ import { isValidElement } from "react";
1827
+ var TABLE_HEADER_DISPLAY_NAME = "Table.Header";
1828
+ var TABLE_BODY_DISPLAY_NAME = "Table.Body";
1829
+ var TABLE_COLUMN_DISPLAY_NAME = "Table.Column";
1830
+ var TABLE_PAGINATION_DISPLAY_NAME = "Table.Pagination";
1831
+ function getComponentDisplayName(type) {
1832
+ if (typeof type === "function" || typeof type === "object" && type !== null) {
1833
+ return type.displayName;
1834
+ }
1835
+ return void 0;
1836
+ }
1837
+ function isTableHeaderElement(child) {
1838
+ return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_HEADER_DISPLAY_NAME;
1839
+ }
1840
+ function isTableBodyElement(child) {
1841
+ return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_BODY_DISPLAY_NAME;
1842
+ }
1843
+ function isTableColumnElement(child) {
1844
+ return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_COLUMN_DISPLAY_NAME;
1845
+ }
1846
+ function isTablePaginationElement(child) {
1847
+ return isValidElement(child) && getComponentDisplayName(child.type) === TABLE_PAGINATION_DISPLAY_NAME;
1848
+ }
1849
+
1850
+ // src/components/ui/table/components/Table/parseTableChildren.ts
1851
+ function parseTableChildren(children) {
1852
+ const slots = {
1853
+ header: null,
1854
+ body: null,
1855
+ pagination: null
1856
+ };
1857
+ for (const child of Children.toArray(children)) {
1858
+ if (isTableHeaderElement(child)) {
1859
+ slots.header = child;
1860
+ continue;
1861
+ }
1862
+ if (isTableBodyElement(child)) {
1863
+ slots.body = child;
1864
+ continue;
1865
+ }
1866
+ if (isTablePaginationElement(child)) {
1867
+ slots.pagination = child;
1868
+ }
1869
+ }
1870
+ return slots;
1871
+ }
1872
+ function extractColumnElements(header) {
1873
+ if (!header) return [];
1874
+ const { children } = header.props;
1875
+ return Children.toArray(children).filter(isTableColumnElement);
1876
+ }
1877
+
1878
+ // src/components/ui/table/components/Table/TableBody.tsx
1879
+ function TableBody() {
1880
+ return null;
1881
+ }
1882
+ TableBody.displayName = TABLE_BODY_DISPLAY_NAME;
1883
+
1884
+ // src/components/ui/table/components/Table/TableColumn.tsx
1885
+ function TableColumn(props) {
1886
+ void props;
1887
+ return null;
1888
+ }
1889
+ TableColumn.displayName = TABLE_COLUMN_DISPLAY_NAME;
1890
+
1891
+ // src/components/ui/table/components/Table/tableDataPipeline.ts
1892
+ function sortTableData(data, sort) {
1893
+ if (!sort) return data;
1894
+ const { field, direction } = sort;
1895
+ const multiplier = direction === "asc" ? 1 : -1;
1896
+ return [...data].sort((left, right) => {
1897
+ const leftValue = left[field];
1898
+ const rightValue = right[field];
1899
+ if ((leftValue === null || leftValue === void 0) && (rightValue === null || rightValue === void 0)) {
1900
+ return 0;
1901
+ }
1902
+ if (leftValue === null || leftValue === void 0) return 1;
1903
+ if (rightValue === null || rightValue === void 0) return -1;
1904
+ if (typeof leftValue === "number" && typeof rightValue === "number") {
1905
+ return (leftValue - rightValue) * multiplier;
1906
+ }
1907
+ return String(leftValue).localeCompare(String(rightValue), "ko") * multiplier;
1908
+ });
1909
+ }
1910
+ function paginateTableData(data, page, pageSize) {
1911
+ const safePage = Math.max(1, page);
1912
+ const start = (safePage - 1) * pageSize;
1913
+ return data.slice(start, start + pageSize);
1914
+ }
1915
+ function getTotalPages(totalCount, pageSize) {
1916
+ if (pageSize <= 0) return 1;
1917
+ return Math.max(1, Math.ceil(totalCount / pageSize));
1918
+ }
1919
+
1920
+ // src/components/ui/table/components/Table/TableHeader.tsx
1921
+ function TableHeader(props) {
1922
+ void props;
1923
+ return null;
1924
+ }
1925
+ TableHeader.displayName = TABLE_HEADER_DISPLAY_NAME;
1926
+
1927
+ // src/components/ui/table/components/Table/TablePagination.tsx
1928
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1929
+ function TablePagination({
1930
+ page,
1931
+ pageSize = 10,
1932
+ totalCount = 0,
1933
+ onChange,
1934
+ className
1935
+ }) {
1936
+ const totalPages = getTotalPages(totalCount, pageSize);
1937
+ const safePage = Math.min(Math.max(1, page), totalPages);
1938
+ const canGoPrev = safePage > 1;
1939
+ const canGoNext = safePage < totalPages;
1940
+ return /* @__PURE__ */ jsxs6("div", { className: cn("TablePaginationJSX", className), children: [
1941
+ /* @__PURE__ */ jsx7(
1942
+ "button",
1943
+ {
1944
+ type: "button",
1945
+ className: "pagination-button",
1946
+ disabled: !canGoPrev,
1947
+ onClick: () => onChange(safePage - 1),
1948
+ "aria-label": "Previous page",
1949
+ children: /* @__PURE__ */ jsx7(ChevronLeft, { className: "pagination-button-icon" })
1950
+ }
1951
+ ),
1952
+ /* @__PURE__ */ jsxs6("span", { className: "pagination-label", children: [
1953
+ safePage,
1954
+ " / ",
1955
+ totalPages
1956
+ ] }),
1957
+ /* @__PURE__ */ jsx7(
1958
+ "button",
1959
+ {
1960
+ type: "button",
1961
+ className: "pagination-button",
1962
+ disabled: !canGoNext,
1963
+ onClick: () => onChange(safePage + 1),
1964
+ "aria-label": "Next page",
1965
+ children: /* @__PURE__ */ jsx7(ChevronRight, { className: "pagination-button-icon" })
1966
+ }
1967
+ )
1968
+ ] });
1969
+ }
1970
+ TablePagination.displayName = TABLE_PAGINATION_DISPLAY_NAME;
1971
+
1972
+ // src/components/ui/table/components/Table/Table.tsx
1973
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1974
+ function TableRoot({
1975
+ data,
1976
+ children,
1977
+ className,
1978
+ totalCount,
1979
+ filteredCount,
1980
+ ...dataTableProps
1981
+ }) {
1982
+ const { header, pagination: paginationElement } = useMemo3(
1983
+ () => parseTableChildren(children),
1984
+ [children]
1985
+ );
1986
+ const [sort, setSort] = useState4(null);
1987
+ const handleSort = useCallback4((field) => {
1988
+ setSort((previous) => {
1989
+ if (previous?.field !== field) {
1990
+ return { field, direction: "asc" };
1991
+ }
1992
+ if (previous.direction === "asc") {
1993
+ return { field, direction: "desc" };
1994
+ }
1995
+ return null;
1996
+ });
1997
+ }, []);
1998
+ const columns = useMemo3(() => {
1999
+ return extractColumnElements(header).map(
2000
+ (columnElement) => buildColumnDef(columnElement.props, sort, handleSort)
2001
+ );
2002
+ }, [header, sort, handleSort]);
2003
+ const paginationProps = paginationElement?.props;
2004
+ const pageSize = paginationProps?.pageSize ?? 10;
2005
+ const page = paginationProps?.page ?? 1;
2006
+ const resolvedTotalCount = paginationProps?.totalCount ?? totalCount ?? data.length;
2007
+ const tableData = useMemo3(() => {
2008
+ const sortedData = sortTableData(data, sort);
2009
+ if (!paginationProps) return sortedData;
2010
+ return paginateTableData(sortedData, page, pageSize);
2011
+ }, [data, sort, paginationProps, page, pageSize]);
2012
+ if (columns.length === 0) {
2013
+ console.warn("[Table] Declare at least one Table.Column inside Table.Header.");
2014
+ }
2015
+ return /* @__PURE__ */ jsxs7("div", { className: "TableJSX", children: [
2016
+ /* @__PURE__ */ jsx8(
2017
+ DataTable,
2018
+ {
2019
+ ...dataTableProps,
2020
+ data: tableData,
2021
+ columns,
2022
+ totalCount: paginationProps ? resolvedTotalCount : totalCount,
2023
+ filteredCount: filteredCount ?? data.length,
2024
+ className: cn(className, paginationProps && "DataTableJSX--with-pagination")
2025
+ }
2026
+ ),
2027
+ paginationProps && /* @__PURE__ */ jsx8(
2028
+ TablePagination,
2029
+ {
2030
+ page,
2031
+ pageSize,
2032
+ totalCount: resolvedTotalCount,
2033
+ onChange: paginationProps.onChange,
2034
+ className: paginationProps.className
2035
+ }
2036
+ )
2037
+ ] });
2038
+ }
2039
+ function createTable() {
2040
+ function Column(props) {
2041
+ void props;
2042
+ return null;
2043
+ }
2044
+ Column.displayName = TABLE_COLUMN_DISPLAY_NAME;
2045
+ return Object.assign(
2046
+ function BoundTable(props) {
2047
+ return /* @__PURE__ */ jsx8(TableRoot, { ...props });
2048
+ },
2049
+ {
2050
+ Header: TableHeader,
2051
+ Column,
2052
+ Body: TableBody,
2053
+ Pagination: TablePagination
2054
+ }
2055
+ );
2056
+ }
2057
+ var Table = Object.assign(TableRoot, {
2058
+ Header: TableHeader,
2059
+ Column: TableColumn,
2060
+ Body: TableBody,
2061
+ Pagination: TablePagination
2062
+ });
1124
2063
  export {
1125
2064
  CELL_SELECTION_EDGES_CLASS,
1126
2065
  DEFAULT_DATA_TABLE_LABELS,
@@ -1128,6 +2067,8 @@ export {
1128
2067
  DEFAULT_TREE_ID_FIELD,
1129
2068
  DEFAULT_TREE_PARENT_ID_FIELD,
1130
2069
  DEFAULT_TREE_QTY_FIELD,
2070
+ DataTable,
2071
+ Table,
1131
2072
  applyCellEdit,
1132
2073
  applyFillData,
1133
2074
  applySelectionUpdater,
@@ -1135,6 +2076,7 @@ export {
1135
2076
  canExpandRow,
1136
2077
  collectFillChanges,
1137
2078
  collectRowSpanColumns,
2079
+ createTable,
1138
2080
  getCellEditDraftValue,
1139
2081
  getCellSelectionEdgeStyle,
1140
2082
  getColumnEditType,