@forgedevstack/grid-table 1.0.2 → 1.0.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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,8 @@
1
+ // src/index.ts
2
+ import "@forgedevstack/bear/styles.css";
3
+
1
4
  // src/components/GridTable/GridTable.tsx
2
- import { useMemo as useMemo12, useCallback as useCallback13 } from "react";
5
+ import { useMemo as useMemo11, useCallback as useCallback13, useState as useState8, useEffect as useEffect6 } from "react";
3
6
 
4
7
  // src/context/TableContext.tsx
5
8
  import {
@@ -175,6 +178,10 @@ function reducer(state, action) {
175
178
  return { ...state, selectedIds: action.payload };
176
179
  case "SET_EXPANDED_IDS":
177
180
  return { ...state, expandedIds: action.payload };
181
+ case "SET_EXPANDED_CELL_IDS":
182
+ return { ...state, expandedCellIds: action.payload };
183
+ case "SET_AUTO_SIZED_COLUMN_IDS":
184
+ return { ...state, autoSizedColumnIds: action.payload };
178
185
  case "SET_COLUMN_STATES":
179
186
  return { ...state, columnStates: action.payload };
180
187
  case "SET_DRAGGING_COLUMN":
@@ -212,9 +219,24 @@ function TableProvider({
212
219
  sortConfig: _sortConfig,
213
220
  enableMultiSort = false,
214
221
  getRowId,
215
- onStateChange
222
+ onStateChange,
223
+ showOverflowTooltip = true,
224
+ enableCellAutoSizeOnDoubleClick = false,
225
+ subCellExpandTrigger = "both",
226
+ expandRowOnDoubleClick = false,
227
+ globalFilterColumns = void 0
216
228
  }) {
217
229
  var _a, _b;
230
+ const tableOptions = useMemo(
231
+ () => ({
232
+ showOverflowTooltip,
233
+ enableCellAutoSizeOnDoubleClick,
234
+ subCellExpandTrigger,
235
+ expandRowOnDoubleClick,
236
+ globalFilterColumns
237
+ }),
238
+ [showOverflowTooltip, enableCellAutoSizeOnDoubleClick, subCellExpandTrigger, expandRowOnDoubleClick, globalFilterColumns]
239
+ );
218
240
  const initialColumnStates = columns.map((col, index) => ({
219
241
  id: col.id,
220
242
  visible: !col.hidden,
@@ -243,6 +265,8 @@ function TableProvider({
243
265
  totalItems: data.length,
244
266
  selectedIds: /* @__PURE__ */ new Set(),
245
267
  expandedIds: /* @__PURE__ */ new Set(),
268
+ expandedCellIds: /* @__PURE__ */ new Set(),
269
+ autoSizedColumnIds: /* @__PURE__ */ new Set(),
246
270
  loading,
247
271
  error,
248
272
  theme: mergedTheme,
@@ -369,6 +393,25 @@ function TableProvider({
369
393
  actions.expandRow(id);
370
394
  }
371
395
  },
396
+ toggleCellExpansion: (rowId, columnId) => {
397
+ const key = `${String(rowId)}-${columnId}`;
398
+ const next = new Set(state.expandedCellIds);
399
+ if (next.has(key)) {
400
+ next.delete(key);
401
+ } else {
402
+ next.add(key);
403
+ }
404
+ dispatch({ type: "SET_EXPANDED_CELL_IDS", payload: next });
405
+ },
406
+ toggleColumnAutoSize: (columnId) => {
407
+ const next = new Set(state.autoSizedColumnIds);
408
+ if (next.has(columnId)) {
409
+ next.delete(columnId);
410
+ } else {
411
+ next.add(columnId);
412
+ }
413
+ dispatch({ type: "SET_AUTO_SIZED_COLUMN_IDS", payload: next });
414
+ },
372
415
  reorderColumn: (sourceId, targetId) => {
373
416
  const newStates = [...state.columnStates];
374
417
  const sourceIndex = newStates.findIndex((c) => c.id === sourceId);
@@ -407,6 +450,8 @@ function TableProvider({
407
450
  page: ONE,
408
451
  selectedIds: /* @__PURE__ */ new Set(),
409
452
  expandedIds: /* @__PURE__ */ new Set(),
453
+ expandedCellIds: /* @__PURE__ */ new Set(),
454
+ autoSizedColumnIds: /* @__PURE__ */ new Set(),
410
455
  columnStates: initialColumnStates
411
456
  }
412
457
  })
@@ -417,11 +462,15 @@ function TableProvider({
417
462
  let filteredData = [...state.data];
418
463
  if (state.globalFilter) {
419
464
  const searchLower = state.globalFilter.toLowerCase();
420
- filteredData = filteredData.filter(
421
- (row) => Object.values(row).some(
422
- (val) => String(val).toLowerCase().includes(searchLower)
423
- )
424
- );
465
+ const columnIds = tableOptions.globalFilterColumns;
466
+ filteredData = filteredData.filter((row) => {
467
+ const colsToSearch = columnIds && columnIds.length > 0 ? state.columns.filter((c) => columnIds.includes(c.id)) : state.columns;
468
+ return colsToSearch.some((col) => {
469
+ const accessor = col.accessor;
470
+ const value = typeof accessor === "function" ? accessor(row) : row[accessor];
471
+ return String(value != null ? value : "").toLowerCase().includes(searchLower);
472
+ });
473
+ });
425
474
  }
426
475
  state.filters.forEach((filter) => {
427
476
  const column = columns.find((c) => c.id === filter.columnId);
@@ -507,10 +556,11 @@ function TableProvider({
507
556
  isTablet,
508
557
  isDesktop
509
558
  };
510
- }, [state, columns]);
559
+ }, [state, columns, tableOptions]);
511
560
  const contextValue = {
512
561
  state,
513
562
  actions,
563
+ tableOptions,
514
564
  computed
515
565
  };
516
566
  return /* @__PURE__ */ jsx(TableContext.Provider, { value: contextValue, children });
@@ -999,6 +1049,7 @@ function useTable() {
999
1049
 
1000
1050
  // src/components/GridHeader/GridHeader.tsx
1001
1051
  import { useMemo as useMemo8, useCallback as useCallback7, useState as useState4, useRef as useRef3 } from "react";
1052
+ import { Checkbox } from "@forgedevstack/bear";
1002
1053
 
1003
1054
  // src/components/FilterPopup/FilterPopup.tsx
1004
1055
  import { useState as useState3, useCallback as useCallback6, useEffect as useEffect3, useRef as useRef2 } from "react";
@@ -1214,6 +1265,7 @@ function HeaderCell({
1214
1265
  hasFilter = false,
1215
1266
  isDragging = false,
1216
1267
  isDragOver = false,
1268
+ isColumnAutoSized = false,
1217
1269
  onSort,
1218
1270
  onFilterOpen,
1219
1271
  onResizeStart,
@@ -1258,23 +1310,33 @@ function HeaderCell({
1258
1310
  }
1259
1311
  return classes.join(" ");
1260
1312
  }, [column.align, isSortable, isDragging, isDragOver]);
1313
+ const cellStyle = useMemo8(() => {
1314
+ const base = {
1315
+ flexShrink: 0,
1316
+ ...column.sticky && {
1317
+ position: "sticky",
1318
+ [column.sticky]: 0,
1319
+ zIndex: 2,
1320
+ backgroundColor: "var(--gt-bg-secondary, #2b2b2b)"
1321
+ },
1322
+ ...column.headerStyle
1323
+ };
1324
+ if (isColumnAutoSized) {
1325
+ base.width = "auto";
1326
+ base.minWidth = "max-content";
1327
+ base.maxWidth = "none";
1328
+ } else {
1329
+ base.width = typeof columnState.width === "number" ? `${columnState.width}px` : columnState.width;
1330
+ base.minWidth = column.minWidth || MIN_COLUMN_WIDTH;
1331
+ base.maxWidth = column.maxWidth || MAX_COLUMN_WIDTH;
1332
+ }
1333
+ return base;
1334
+ }, [column, columnState.width, isColumnAutoSized]);
1261
1335
  return /* @__PURE__ */ jsxs2(
1262
1336
  "div",
1263
1337
  {
1264
1338
  className: `${cellClasses} ${column.headerClassName || ""} ${column.sticky ? `sticky-${column.sticky}` : ""}`,
1265
- style: {
1266
- width: columnState.width,
1267
- minWidth: column.minWidth || MIN_COLUMN_WIDTH,
1268
- maxWidth: column.maxWidth || MAX_COLUMN_WIDTH,
1269
- flexShrink: 0,
1270
- ...column.sticky && {
1271
- position: "sticky",
1272
- [column.sticky]: 0,
1273
- zIndex: 2,
1274
- backgroundColor: "var(--bg-secondary, #2b2b2b)"
1275
- },
1276
- ...column.headerStyle
1277
- },
1339
+ style: cellStyle,
1278
1340
  role: "columnheader",
1279
1341
  "aria-sort": sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : "none",
1280
1342
  onClick: handleClick,
@@ -1317,6 +1379,7 @@ function GridHeader({
1317
1379
  enableDragDrop = true,
1318
1380
  enableResize = true,
1319
1381
  enableSelection = false,
1382
+ enableExpansion = false,
1320
1383
  allSelected = false,
1321
1384
  someSelected = false,
1322
1385
  onSelectAll,
@@ -1389,18 +1452,16 @@ function GridHeader({
1389
1452
  }, [sticky]);
1390
1453
  return /* @__PURE__ */ jsxs2("div", { className: `${headerClasses} ${className}`, style, role: "row", children: [
1391
1454
  enableSelection && /* @__PURE__ */ jsx3("div", { className: "grid-header-select", children: /* @__PURE__ */ jsx3(
1392
- "input",
1455
+ Checkbox,
1393
1456
  {
1394
- type: "checkbox",
1395
1457
  checked: allSelected,
1396
- ref: (el) => {
1397
- if (el) el.indeterminate = someSelected && !allSelected;
1398
- },
1399
- onChange: onSelectAll,
1400
- className: "grid-header-checkbox",
1458
+ indeterminate: someSelected && !allSelected,
1459
+ onChange: () => onSelectAll == null ? void 0 : onSelectAll(),
1460
+ size: "sm",
1401
1461
  "aria-label": "Select all rows"
1402
1462
  }
1403
1463
  ) }),
1464
+ enableExpansion && /* @__PURE__ */ jsx3("div", { className: "grid-header-expand-spacer", "aria-hidden": true }),
1404
1465
  visibleColumns.map((col, index) => {
1405
1466
  const colState = columnStates.find((cs) => cs.id === col.id) || {
1406
1467
  id: col.id,
@@ -1430,6 +1491,7 @@ function GridHeader({
1430
1491
  hasFilter,
1431
1492
  isDragging: dragDrop.draggingColumnId === col.id,
1432
1493
  isDragOver: dragDrop.dragOverColumnId === col.id,
1494
+ isColumnAutoSized: state.autoSizedColumnIds.has(col.id),
1433
1495
  onSort: () => actions.toggleSorting(col.id),
1434
1496
  onFilterOpen: () => handleFilterClick(col.id),
1435
1497
  onResizeStart: handleResizeStart(col.id, colState.width),
@@ -1460,11 +1522,59 @@ function GridHeader({
1460
1522
  import { useCallback as useCallback10 } from "react";
1461
1523
 
1462
1524
  // src/components/GridRow/GridRow.tsx
1463
- import { useCallback as useCallback9, useMemo as useMemo10, useState as useState5 } from "react";
1525
+ import { useCallback as useCallback9, useMemo as useMemo10, useState as useState6 } from "react";
1526
+ import { Checkbox as Checkbox2 } from "@forgedevstack/bear";
1527
+
1528
+ // src/components/GridCell/GridCell.tsx
1529
+ import { useMemo as useMemo9, useCallback as useCallback8, useRef as useRef4, useEffect as useEffect4, useState as useState5 } from "react";
1530
+ import { Tooltip, Typography } from "@forgedevstack/bear";
1531
+
1532
+ // src/utils/highlight.utils.tsx
1533
+ import { jsx as jsx4 } from "react/jsx-runtime";
1534
+ function highlightMatch(text, term) {
1535
+ if (!term.trim()) return text;
1536
+ const parts = text.split(new RegExp(`(${escapeRegex(term)})`, "gi"));
1537
+ return parts.map(
1538
+ (part, i) => part.toLowerCase() === term.toLowerCase() ? /* @__PURE__ */ jsx4("mark", { className: "grid-cell-highlight", children: part }, i) : part
1539
+ );
1540
+ }
1541
+ function escapeRegex(s) {
1542
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1543
+ }
1544
+
1545
+ // src/utils/generateSampleData.ts
1546
+ function generateSampleData(columns, rowCount) {
1547
+ const ids = columns.map((c) => c.id);
1548
+ return Array.from({ length: rowCount }, (_, i) => {
1549
+ const row = {};
1550
+ ids.forEach((key) => {
1551
+ if (key === "id" || key === "idNumber") {
1552
+ row[key] = i + 1;
1553
+ } else if (key === "email") {
1554
+ row[key] = `user${i + 1}@example.com`;
1555
+ } else if (key === "name" || key === "firstName" || key === "title") {
1556
+ row[key] = `Sample ${i + 1}`;
1557
+ } else if (key === "status" || key === "role") {
1558
+ row[key] = ["active", "inactive", "pending"][i % 3];
1559
+ } else if (key === "date" || key === "joinDate" || key === "createdAt") {
1560
+ row[key] = new Date(2020 + i % 4, i % 12, i % 28 + 1).toISOString().slice(0, 10);
1561
+ } else if (key === "salary" || key === "amount" || key === "count") {
1562
+ row[key] = 1e3 * (i + 1) + i % 100;
1563
+ } else if (key === "department") {
1564
+ row[key] = ["Engineering", "Design", "Marketing", "Sales", "HR"][i % 5];
1565
+ } else {
1566
+ row[key] = `Value ${i + 1}`;
1567
+ }
1568
+ });
1569
+ if (!("id" in row) && ids.length > 0) {
1570
+ row.id = i + 1;
1571
+ }
1572
+ return row;
1573
+ });
1574
+ }
1464
1575
 
1465
1576
  // src/components/GridCell/GridCell.tsx
1466
- import { useMemo as useMemo9, useCallback as useCallback8 } from "react";
1467
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1577
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1468
1578
  var ALIGN_CLASSES2 = {
1469
1579
  left: "text-left justify-start",
1470
1580
  center: "text-center justify-center",
@@ -1474,6 +1584,7 @@ function GridCell({
1474
1584
  column,
1475
1585
  row,
1476
1586
  rowIndex,
1587
+ rowId,
1477
1588
  value,
1478
1589
  width,
1479
1590
  align = "left",
@@ -1485,20 +1596,18 @@ function GridCell({
1485
1596
  stickyOffset = 0,
1486
1597
  onClick
1487
1598
  }) {
1488
- const handleClick = useCallback8(
1489
- (e) => {
1490
- if (onClick) {
1491
- e.stopPropagation();
1492
- onClick({
1493
- row,
1494
- rowIndex,
1495
- columnId: column.id,
1496
- value
1497
- });
1498
- }
1499
- },
1500
- [onClick, row, rowIndex, column.id, value]
1501
- );
1599
+ var _a, _b, _c;
1600
+ const valueRef = useRef4(null);
1601
+ const [overflowTitle, setOverflowTitle] = useState5(void 0);
1602
+ const { state, actions, tableOptions } = useTableContext();
1603
+ const showOverflowTooltip = ((_a = column.showOverflowTooltip) != null ? _a : tableOptions.showOverflowTooltip) !== false;
1604
+ const hasSubCell = Boolean(column.renderSubCell);
1605
+ const trigger = (_c = (_b = column.subCellExpandTrigger) != null ? _b : tableOptions.subCellExpandTrigger) != null ? _c : "both";
1606
+ const showArrow = hasSubCell && (trigger === "arrow" || trigger === "both");
1607
+ const enableCellAutoSize = tableOptions.enableCellAutoSizeOnDoubleClick === true;
1608
+ const cellKey = `${String(rowId)}-${column.id}`;
1609
+ const isSubCellExpanded = state.expandedCellIds.has(cellKey);
1610
+ const isAutoSized = state.autoSizedColumnIds.has(column.id);
1502
1611
  const formattedValue = useMemo9(() => {
1503
1612
  if (column.render) {
1504
1613
  return column.render(value, row, rowIndex);
@@ -1514,9 +1623,53 @@ function GridCell({
1514
1623
  }
1515
1624
  return String(value);
1516
1625
  }, [column, row, rowIndex, value]);
1626
+ useEffect4(() => {
1627
+ var _a2;
1628
+ if (!showOverflowTooltip || !valueRef.current) return;
1629
+ const el = valueRef.current;
1630
+ const truncated = el.scrollWidth > el.clientWidth;
1631
+ const raw = (_a2 = el.textContent) != null ? _a2 : "";
1632
+ setOverflowTitle(truncated && raw ? raw : void 0);
1633
+ }, [showOverflowTooltip, formattedValue]);
1634
+ const handleClick = useCallback8(
1635
+ (e) => {
1636
+ if (onClick) {
1637
+ e.stopPropagation();
1638
+ onClick({
1639
+ row,
1640
+ rowIndex,
1641
+ columnId: column.id,
1642
+ value
1643
+ });
1644
+ }
1645
+ },
1646
+ [onClick, row, rowIndex, column.id, value]
1647
+ );
1648
+ const handleDoubleClick = useCallback8(
1649
+ (e) => {
1650
+ e.stopPropagation();
1651
+ if (hasSubCell && (trigger === "doubleClick" || trigger === "both")) {
1652
+ actions.toggleCellExpansion(rowId, column.id);
1653
+ } else if (enableCellAutoSize) {
1654
+ actions.toggleColumnAutoSize(column.id);
1655
+ }
1656
+ },
1657
+ [hasSubCell, trigger, enableCellAutoSize, actions, rowId, column.id]
1658
+ );
1659
+ const handleExpandClick = useCallback8(
1660
+ (e) => {
1661
+ e.stopPropagation();
1662
+ actions.toggleCellExpansion(rowId, column.id);
1663
+ },
1664
+ [actions, rowId, column.id]
1665
+ );
1517
1666
  const cellStyle = useMemo9(() => {
1518
1667
  const baseStyle = { ...style };
1519
- if (width !== void 0) {
1668
+ if (isAutoSized) {
1669
+ baseStyle.width = "auto";
1670
+ baseStyle.minWidth = "max-content";
1671
+ baseStyle.maxWidth = "none";
1672
+ } else if (width !== void 0) {
1520
1673
  baseStyle.width = typeof width === "number" ? `${width}px` : width;
1521
1674
  baseStyle.minWidth = baseStyle.width;
1522
1675
  baseStyle.maxWidth = baseStyle.width;
@@ -1524,7 +1677,7 @@ function GridCell({
1524
1677
  if (sticky) {
1525
1678
  baseStyle.position = "sticky";
1526
1679
  baseStyle.zIndex = 1;
1527
- baseStyle.backgroundColor = "var(--bg-primary, #1e1e1e)";
1680
+ baseStyle.backgroundColor = "var(--gt-bg-primary, #1e1e1e)";
1528
1681
  if (sticky === "left") {
1529
1682
  baseStyle.left = stickyOffset;
1530
1683
  } else if (sticky === "right") {
@@ -1532,9 +1685,11 @@ function GridCell({
1532
1685
  }
1533
1686
  }
1534
1687
  return baseStyle;
1535
- }, [style, width, sticky, stickyOffset]);
1688
+ }, [style, width, sticky, stickyOffset, isAutoSized]);
1536
1689
  const alignClass = ALIGN_CLASSES2[align];
1537
1690
  const stickyClass = sticky ? `sticky-${sticky}` : "";
1691
+ const shouldHighlight = state.globalFilter && typeof formattedValue === "string" && (!tableOptions.globalFilterColumns || tableOptions.globalFilterColumns.length === 0 || tableOptions.globalFilterColumns.includes(column.id));
1692
+ const cellContent = shouldHighlight ? highlightMatch(String(formattedValue), state.globalFilter) : formattedValue;
1538
1693
  return /* @__PURE__ */ jsxs3(
1539
1694
  "div",
1540
1695
  {
@@ -1543,25 +1698,55 @@ function GridCell({
1543
1698
  ${alignClass}
1544
1699
  ${stickyClass}
1545
1700
  ${onClick ? "cursor-pointer" : ""}
1701
+ ${hasSubCell ? "grid-cell--has-sub" : ""}
1702
+ ${isAutoSized ? "grid-cell--auto-sized" : ""}
1546
1703
  ${column.cellClassName || ""}
1547
1704
  ${className}
1548
1705
  `.trim(),
1549
1706
  style: { ...cellStyle, ...column.cellStyle },
1550
1707
  role: "cell",
1551
1708
  onClick: onClick ? handleClick : void 0,
1709
+ onDoubleClick: handleDoubleClick,
1552
1710
  children: [
1553
- showLabel && labelText && /* @__PURE__ */ jsxs3("span", { className: "grid-cell-label", children: [
1554
- labelText,
1555
- ":"
1711
+ /* @__PURE__ */ jsxs3("div", { className: "grid-cell-inner", children: [
1712
+ showLabel && labelText && /* @__PURE__ */ jsxs3(Typography, { component: "span", variant: "body2", color: "secondary", className: "grid-cell-label", children: [
1713
+ labelText,
1714
+ ":"
1715
+ ] }),
1716
+ /* @__PURE__ */ jsx5("div", { className: "grid-cell-value-wrapper", style: { minWidth: 0, overflow: "hidden" }, children: overflowTitle ? /* @__PURE__ */ jsx5(Tooltip, { content: overflowTitle, placement: "top", delay: 200, children: /* @__PURE__ */ jsx5(
1717
+ "span",
1718
+ {
1719
+ ref: valueRef,
1720
+ className: `grid-cell-value ${isAutoSized ? "" : "grid-cell-value--truncate"}`,
1721
+ children: /* @__PURE__ */ jsx5(Typography, { component: "span", variant: "body2", className: "grid-cell-value-text", children: cellContent })
1722
+ }
1723
+ ) }) : /* @__PURE__ */ jsx5(
1724
+ "span",
1725
+ {
1726
+ ref: valueRef,
1727
+ className: `grid-cell-value ${isAutoSized ? "" : "grid-cell-value--truncate"}`,
1728
+ children: /* @__PURE__ */ jsx5(Typography, { component: "span", variant: "body2", children: cellContent })
1729
+ }
1730
+ ) }),
1731
+ showArrow && /* @__PURE__ */ jsx5(
1732
+ "button",
1733
+ {
1734
+ type: "button",
1735
+ className: `grid-cell-expand-trigger ${isSubCellExpanded ? "grid-cell-expand-trigger--expanded" : ""}`,
1736
+ onClick: handleExpandClick,
1737
+ "aria-label": isSubCellExpanded ? "Collapse" : "Expand",
1738
+ "aria-expanded": isSubCellExpanded
1739
+ }
1740
+ )
1556
1741
  ] }),
1557
- /* @__PURE__ */ jsx4("span", { className: "grid-cell-value truncate", children: formattedValue })
1742
+ hasSubCell && isSubCellExpanded && column.renderSubCell && /* @__PURE__ */ jsx5("div", { className: "grid-cell-subcell", children: column.renderSubCell(row) })
1558
1743
  ]
1559
1744
  }
1560
1745
  );
1561
1746
  }
1562
1747
 
1563
1748
  // src/components/GridRow/GridRow.tsx
1564
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1749
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1565
1750
  function GridRow({
1566
1751
  row,
1567
1752
  rowIndex,
@@ -1585,7 +1770,7 @@ function GridRow({
1585
1770
  renderExpansion,
1586
1771
  getRowId
1587
1772
  }) {
1588
- const [isHovered, setIsHovered] = useState5(false);
1773
+ const [isHovered, setIsHovered] = useState6(false);
1589
1774
  const handleClick = useCallback9(() => {
1590
1775
  if (isDisabled) return;
1591
1776
  onClick == null ? void 0 : onClick(row, rowIndex);
@@ -1601,10 +1786,13 @@ function GridRow({
1601
1786
  },
1602
1787
  [onContextMenu, row, rowIndex, isDisabled]
1603
1788
  );
1604
- const handleSelectChange = useCallback9(() => {
1605
- if (isDisabled) return;
1606
- onSelect == null ? void 0 : onSelect(!isSelected);
1607
- }, [onSelect, isSelected, isDisabled]);
1789
+ const handleSelectChange = useCallback9(
1790
+ (selected) => {
1791
+ if (isDisabled) return;
1792
+ onSelect == null ? void 0 : onSelect(selected);
1793
+ },
1794
+ [onSelect, isDisabled]
1795
+ );
1608
1796
  const handleExpandToggle = useCallback9(() => {
1609
1797
  if (isDisabled) return;
1610
1798
  onExpand == null ? void 0 : onExpand(!isExpanded);
@@ -1673,18 +1861,17 @@ function GridRow({
1673
1861
  onMouseEnter: () => setIsHovered(true),
1674
1862
  onMouseLeave: () => setIsHovered(false),
1675
1863
  children: [
1676
- enableSelection && /* @__PURE__ */ jsx5("div", { className: "grid-row-select", children: /* @__PURE__ */ jsx5(
1677
- "input",
1864
+ enableSelection && /* @__PURE__ */ jsx6("div", { className: "grid-row-select", children: /* @__PURE__ */ jsx6(
1865
+ Checkbox2,
1678
1866
  {
1679
- type: "checkbox",
1680
- checked: isSelected,
1681
- onChange: handleSelectChange,
1867
+ checked: isSelected != null ? isSelected : false,
1868
+ onChange: (e) => handleSelectChange(e.target.checked),
1682
1869
  disabled: isDisabled,
1683
- className: "grid-row-checkbox",
1870
+ size: "sm",
1684
1871
  "aria-label": "Select row"
1685
1872
  }
1686
1873
  ) }),
1687
- enableExpansion && renderExpansion && /* @__PURE__ */ jsx5("div", { className: "grid-row-expand", children: /* @__PURE__ */ jsx5(
1874
+ enableExpansion && renderExpansion && /* @__PURE__ */ jsx6("div", { className: "grid-row-expand", children: /* @__PURE__ */ jsx6(
1688
1875
  "button",
1689
1876
  {
1690
1877
  onClick: handleExpandToggle,
@@ -1692,7 +1879,7 @@ function GridRow({
1692
1879
  className: "grid-row-expand-button",
1693
1880
  "aria-label": isExpanded ? "Collapse row" : "Expand row",
1694
1881
  "aria-expanded": isExpanded,
1695
- children: /* @__PURE__ */ jsx5(
1882
+ children: /* @__PURE__ */ jsx6(
1696
1883
  "span",
1697
1884
  {
1698
1885
  className: `transform transition-transform duration-200 ${isExpanded ? "rotate-90" : ""}`,
@@ -1724,12 +1911,13 @@ function GridRow({
1724
1911
  }
1725
1912
  }
1726
1913
  }
1727
- return /* @__PURE__ */ jsx5(
1914
+ return /* @__PURE__ */ jsx6(
1728
1915
  GridCell,
1729
1916
  {
1730
1917
  column: col,
1731
1918
  row,
1732
1919
  rowIndex,
1920
+ rowId: getRowId(row),
1733
1921
  value: getCellValue(col),
1734
1922
  width,
1735
1923
  align: col.align,
@@ -1746,12 +1934,12 @@ function GridRow({
1746
1934
  ]
1747
1935
  }
1748
1936
  ),
1749
- isExpanded && renderExpansion && /* @__PURE__ */ jsx5("div", { className: "grid-row-expansion", children: renderExpansion(row) })
1937
+ isExpanded && renderExpansion && /* @__PURE__ */ jsx6("div", { className: "grid-row-expansion", children: renderExpansion(row, getRowId(row)) })
1750
1938
  ] });
1751
1939
  }
1752
1940
 
1753
1941
  // src/components/GridBody/GridBody.tsx
1754
- import { jsx as jsx6 } from "react/jsx-runtime";
1942
+ import { jsx as jsx7 } from "react/jsx-runtime";
1755
1943
  function GridBody({
1756
1944
  data,
1757
1945
  columns,
@@ -1792,7 +1980,7 @@ function GridBody({
1792
1980
  if (data.length === 0) {
1793
1981
  return null;
1794
1982
  }
1795
- return /* @__PURE__ */ jsx6("div", { className: `grid-body ${className}`, style, role: "rowgroup", children: data.map((row, index) => {
1983
+ return /* @__PURE__ */ jsx7("div", { className: `grid-body ${className}`, style, role: "rowgroup", children: data.map((row, index) => {
1796
1984
  var _a, _b;
1797
1985
  const rowId = getRowId(row);
1798
1986
  const isSelected = selectedIds.has(rowId);
@@ -1800,7 +1988,7 @@ function GridBody({
1800
1988
  const isDisabled = (_a = isRowDisabled == null ? void 0 : isRowDisabled(row)) != null ? _a : false;
1801
1989
  const rowClassName = (_b = getRowClassName == null ? void 0 : getRowClassName(row, index)) != null ? _b : "";
1802
1990
  const rowStyle = getRowStyle == null ? void 0 : getRowStyle(row, index);
1803
- return /* @__PURE__ */ jsx6(
1991
+ return /* @__PURE__ */ jsx7(
1804
1992
  GridRow,
1805
1993
  {
1806
1994
  row,
@@ -1829,181 +2017,11 @@ function GridBody({
1829
2017
  }) });
1830
2018
  }
1831
2019
 
1832
- // src/components/Pagination/Pagination.tsx
1833
- import { useMemo as useMemo11, useCallback as useCallback11 } from "react";
1834
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1835
- function Pagination({
1836
- page,
1837
- pageSize,
1838
- totalItems,
1839
- totalPages,
1840
- pageSizeOptions = [10, 20, 50, 100],
1841
- showFirstLast = true,
1842
- showPageNumbers = true,
1843
- maxPageButtons = FIVE,
1844
- className = "",
1845
- style,
1846
- onPageChange,
1847
- onPageSizeChange
1848
- }) {
1849
- const { state } = useTableContext();
1850
- const { translations } = state;
1851
- const canGoPrevious = page > ONE;
1852
- const canGoNext = page < totalPages;
1853
- const startItem = (page - ONE) * pageSize + ONE;
1854
- const endItem = Math.min(page * pageSize, totalItems);
1855
- const handleFirstPage = useCallback11(() => {
1856
- onPageChange(ONE);
1857
- }, [onPageChange]);
1858
- const handlePreviousPage = useCallback11(() => {
1859
- if (canGoPrevious) {
1860
- onPageChange(page - ONE);
1861
- }
1862
- }, [canGoPrevious, page, onPageChange]);
1863
- const handleNextPage = useCallback11(() => {
1864
- if (canGoNext) {
1865
- onPageChange(page + ONE);
1866
- }
1867
- }, [canGoNext, page, onPageChange]);
1868
- const handleLastPage = useCallback11(() => {
1869
- onPageChange(totalPages);
1870
- }, [onPageChange, totalPages]);
1871
- const handlePageSizeChange = useCallback11(
1872
- (event) => {
1873
- onPageSizeChange(Number(event.target.value));
1874
- },
1875
- [onPageSizeChange]
1876
- );
1877
- const pageNumbers = useMemo11(() => {
1878
- if (!showPageNumbers || totalPages <= ONE) return [];
1879
- const pages = [];
1880
- const halfMax = Math.floor(maxPageButtons / 2);
1881
- let start = Math.max(ONE, page - halfMax);
1882
- let end = Math.min(totalPages, page + halfMax);
1883
- if (page <= halfMax) {
1884
- end = Math.min(totalPages, maxPageButtons);
1885
- }
1886
- if (page > totalPages - halfMax) {
1887
- start = Math.max(ONE, totalPages - maxPageButtons + ONE);
1888
- }
1889
- if (start > ONE) {
1890
- pages.push(ONE);
1891
- if (start > 2) {
1892
- pages.push("ellipsis");
1893
- }
1894
- }
1895
- for (let i = start; i <= end; i++) {
1896
- if (!pages.includes(i)) {
1897
- pages.push(i);
1898
- }
1899
- }
1900
- if (end < totalPages) {
1901
- if (end < totalPages - ONE) {
1902
- pages.push("ellipsis");
1903
- }
1904
- pages.push(totalPages);
1905
- }
1906
- return pages;
1907
- }, [page, totalPages, showPageNumbers, maxPageButtons]);
1908
- if (totalItems === 0) {
1909
- return null;
1910
- }
1911
- return /* @__PURE__ */ jsxs5(
1912
- "div",
1913
- {
1914
- className: `grid-pagination ${className}`,
1915
- style,
1916
- role: "navigation",
1917
- "aria-label": "Pagination",
1918
- children: [
1919
- /* @__PURE__ */ jsxs5("div", { className: "grid-pagination-info", children: [
1920
- /* @__PURE__ */ jsxs5("div", { className: "grid-pagination-range", children: [
1921
- startItem,
1922
- "-",
1923
- endItem,
1924
- " ",
1925
- translations.of,
1926
- " ",
1927
- totalItems
1928
- ] }),
1929
- /* @__PURE__ */ jsxs5("div", { className: "grid-pagination-size", children: [
1930
- /* @__PURE__ */ jsxs5("label", { htmlFor: "page-size", children: [
1931
- translations.rowsPerPage,
1932
- ":"
1933
- ] }),
1934
- /* @__PURE__ */ jsx7(
1935
- "select",
1936
- {
1937
- id: "page-size",
1938
- value: pageSize,
1939
- onChange: handlePageSizeChange,
1940
- className: "px-2 py-1 text-sm rounded",
1941
- children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx7("option", { value: size, children: size }, size))
1942
- }
1943
- )
1944
- ] })
1945
- ] }),
1946
- /* @__PURE__ */ jsxs5("div", { className: "grid-pagination-controls", children: [
1947
- showFirstLast && /* @__PURE__ */ jsx7(
1948
- "button",
1949
- {
1950
- onClick: handleFirstPage,
1951
- disabled: !canGoPrevious,
1952
- className: "p-2 rounded text-theme-secondary",
1953
- "aria-label": translations.first,
1954
- children: "<<"
1955
- }
1956
- ),
1957
- /* @__PURE__ */ jsx7(
1958
- "button",
1959
- {
1960
- onClick: handlePreviousPage,
1961
- disabled: !canGoPrevious,
1962
- className: "p-2 rounded text-theme-secondary",
1963
- "aria-label": translations.previous,
1964
- children: "<"
1965
- }
1966
- ),
1967
- showPageNumbers && /* @__PURE__ */ jsx7("div", { className: "grid-pagination-pages", children: pageNumbers.map(
1968
- (pageNum, index) => pageNum === "ellipsis" ? /* @__PURE__ */ jsx7("span", { className: "px-2 text-theme-muted", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ jsx7(
1969
- "button",
1970
- {
1971
- onClick: () => onPageChange(pageNum),
1972
- className: `min-w-[32px] h-8 px-2 rounded text-sm ${pageNum === page ? "active" : ""}`,
1973
- "aria-current": pageNum === page ? "page" : void 0,
1974
- children: pageNum
1975
- },
1976
- pageNum
1977
- )
1978
- ) }),
1979
- /* @__PURE__ */ jsx7(
1980
- "button",
1981
- {
1982
- onClick: handleNextPage,
1983
- disabled: !canGoNext,
1984
- className: "p-2 rounded text-theme-secondary",
1985
- "aria-label": translations.next,
1986
- children: ">"
1987
- }
1988
- ),
1989
- showFirstLast && /* @__PURE__ */ jsx7(
1990
- "button",
1991
- {
1992
- onClick: handleLastPage,
1993
- disabled: !canGoNext,
1994
- className: "p-2 rounded text-theme-secondary",
1995
- "aria-label": translations.last,
1996
- children: ">>"
1997
- }
1998
- )
1999
- ] })
2000
- ]
2001
- }
2002
- );
2003
- }
2020
+ // src/components/GridTable/GridTable.tsx
2021
+ import { Pagination as BearPagination, Typography as Typography3, Select, BearProvider } from "@forgedevstack/bear";
2004
2022
 
2005
2023
  // src/components/Skeleton/Skeleton.tsx
2006
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
2024
+ import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
2007
2025
  function SkeletonCell({ width = DEFAULT_COLUMN_WIDTH, height = 16, animate = true }) {
2008
2026
  const widthStyle = typeof width === "number" ? `${width}px` : width;
2009
2027
  return /* @__PURE__ */ jsx8(
@@ -2045,7 +2063,7 @@ function Skeleton({
2045
2063
  showHeader = true,
2046
2064
  animate = true
2047
2065
  }) {
2048
- return /* @__PURE__ */ jsxs6("div", { className: `grid-skeleton ${className}`, style, role: "status", "aria-label": "Loading", children: [
2066
+ return /* @__PURE__ */ jsxs5("div", { className: `grid-skeleton ${className}`, style, role: "status", "aria-label": "Loading", children: [
2049
2067
  showHeader && /* @__PURE__ */ jsx8("div", { className: "grid-skeleton-header", children: Array.from({ length: columns }).map((_, index) => {
2050
2068
  var _a;
2051
2069
  return /* @__PURE__ */ jsx8(
@@ -2077,8 +2095,203 @@ function Skeleton({
2077
2095
  ] });
2078
2096
  }
2079
2097
 
2098
+ // src/components/TableStudioPanel/TableStudioPanel.tsx
2099
+ import { useState as useState7, useCallback as useCallback11 } from "react";
2100
+ import { Typography as Typography2 } from "@forgedevstack/bear";
2101
+ import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
2102
+ var DEFAULT_ROW_COUNT = 10;
2103
+ function TableStudioPanel({
2104
+ data,
2105
+ columns,
2106
+ propsSnapshot,
2107
+ onDataChange,
2108
+ open = true,
2109
+ onOpenChange
2110
+ }) {
2111
+ const [activeTab, setActiveTab] = useState7("data");
2112
+ const [generateCount, setGenerateCount] = useState7(DEFAULT_ROW_COUNT);
2113
+ const handleGenerate = useCallback11(() => {
2114
+ if (!onDataChange) return;
2115
+ const count = Math.min(100, Math.max(1, generateCount));
2116
+ const generated = generateSampleData(columns, count);
2117
+ onDataChange(generated);
2118
+ setActiveTab("data");
2119
+ }, [columns, generateCount, onDataChange]);
2120
+ const panelContent = /* @__PURE__ */ jsxs6(Fragment3, { children: [
2121
+ /* @__PURE__ */ jsx9(
2122
+ "div",
2123
+ {
2124
+ style: {
2125
+ display: "flex",
2126
+ borderBottom: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
2127
+ padding: "0.25rem 0",
2128
+ gap: 2
2129
+ },
2130
+ children: ["data", "props", "generate"].map((tab) => /* @__PURE__ */ jsx9(
2131
+ "button",
2132
+ {
2133
+ type: "button",
2134
+ onClick: () => setActiveTab(tab),
2135
+ style: {
2136
+ flex: 1,
2137
+ padding: "0.5rem 0.5rem",
2138
+ border: "none",
2139
+ borderRadius: 4,
2140
+ background: activeTab === tab ? "var(--gt-bg-tertiary)" : "transparent",
2141
+ color: "var(--gt-text-primary)",
2142
+ cursor: "pointer",
2143
+ fontWeight: activeTab === tab ? 600 : 400,
2144
+ fontSize: 12,
2145
+ textTransform: "capitalize"
2146
+ },
2147
+ children: tab
2148
+ },
2149
+ tab
2150
+ ))
2151
+ }
2152
+ ),
2153
+ /* @__PURE__ */ jsxs6("div", { style: { flex: 1, overflow: "auto", padding: "0.75rem" }, children: [
2154
+ activeTab === "data" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2155
+ /* @__PURE__ */ jsxs6(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: [
2156
+ "Data (",
2157
+ data.length,
2158
+ " rows)"
2159
+ ] }),
2160
+ /* @__PURE__ */ jsx9(
2161
+ "pre",
2162
+ {
2163
+ style: {
2164
+ margin: 0,
2165
+ fontSize: 11,
2166
+ fontFamily: "monospace",
2167
+ whiteSpace: "pre-wrap",
2168
+ wordBreak: "break-word",
2169
+ color: "var(--gt-text-primary)"
2170
+ },
2171
+ children: JSON.stringify(data, null, 2)
2172
+ }
2173
+ )
2174
+ ] }),
2175
+ activeTab === "props" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2176
+ /* @__PURE__ */ jsx9(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: "Props" }),
2177
+ /* @__PURE__ */ jsx9("dl", { style: { margin: 0, fontSize: 13, color: "var(--gt-text-primary)" }, children: Object.entries(propsSnapshot).map(([key, value]) => /* @__PURE__ */ jsxs6("div", { style: { marginBottom: "0.5rem" }, children: [
2178
+ /* @__PURE__ */ jsx9("dt", { style: { fontWeight: 600, marginBottom: 2 }, children: key }),
2179
+ /* @__PURE__ */ jsx9("dd", { style: { margin: 0, color: "var(--gt-text-secondary)" }, children: typeof value === "object" && value !== null ? JSON.stringify(value) : String(value) })
2180
+ ] }, key)) })
2181
+ ] }),
2182
+ activeTab === "generate" && /* @__PURE__ */ jsxs6(Fragment3, { children: [
2183
+ /* @__PURE__ */ jsx9(Typography2, { variant: "subtitle2", component: "h3", style: { marginBottom: "0.5rem" }, children: "Generate sample data" }),
2184
+ /* @__PURE__ */ jsx9("p", { style: { fontSize: 12, color: "var(--gt-text-secondary)", marginBottom: "0.75rem" }, children: "Create rows from column definitions. Uses placeholders for common fields (name, email, id, etc.)." }),
2185
+ /* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem" }, children: [
2186
+ /* @__PURE__ */ jsxs6("label", { style: { fontSize: 12, fontWeight: 500 }, children: [
2187
+ "Rows",
2188
+ /* @__PURE__ */ jsx9(
2189
+ "input",
2190
+ {
2191
+ type: "number",
2192
+ min: 1,
2193
+ max: 100,
2194
+ value: generateCount,
2195
+ onChange: (e) => setGenerateCount(Number(e.target.value) || 1),
2196
+ style: {
2197
+ display: "block",
2198
+ marginTop: 4,
2199
+ width: "100%",
2200
+ padding: "6px 8px",
2201
+ borderRadius: 4,
2202
+ border: "1px solid var(--gt-border-color)",
2203
+ background: "var(--gt-bg-primary)",
2204
+ color: "var(--gt-text-primary)"
2205
+ }
2206
+ }
2207
+ )
2208
+ ] }),
2209
+ /* @__PURE__ */ jsx9(
2210
+ "button",
2211
+ {
2212
+ type: "button",
2213
+ onClick: handleGenerate,
2214
+ disabled: !onDataChange,
2215
+ style: {
2216
+ padding: "8px 12px",
2217
+ borderRadius: 6,
2218
+ border: "none",
2219
+ background: onDataChange ? "var(--gt-accent-primary)" : "var(--gt-bg-tertiary)",
2220
+ color: onDataChange ? "#fff" : "var(--gt-text-muted)",
2221
+ cursor: onDataChange ? "pointer" : "not-allowed",
2222
+ fontWeight: 500,
2223
+ fontSize: 13
2224
+ },
2225
+ children: "Generate data"
2226
+ }
2227
+ ),
2228
+ !onDataChange && /* @__PURE__ */ jsx9("span", { style: { fontSize: 11, color: "var(--gt-text-muted)" }, children: "Table must use studio with controllable data to generate." })
2229
+ ] })
2230
+ ] })
2231
+ ] })
2232
+ ] });
2233
+ const width = 320;
2234
+ const isCollapsed = !open;
2235
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
2236
+ /* @__PURE__ */ jsx9(
2237
+ "button",
2238
+ {
2239
+ type: "button",
2240
+ onClick: () => onOpenChange == null ? void 0 : onOpenChange(!open),
2241
+ className: "grid-table-studio-toggle",
2242
+ style: {
2243
+ position: "fixed",
2244
+ right: open ? width : 0,
2245
+ top: "50%",
2246
+ transform: "translateY(-50%)",
2247
+ zIndex: 10001,
2248
+ width: 24,
2249
+ height: 48,
2250
+ border: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
2251
+ borderRight: "none",
2252
+ borderRadius: "8px 0 0 8px",
2253
+ background: "var(--gt-bg-secondary, #f5f5f5)",
2254
+ color: "var(--gt-text-primary)",
2255
+ cursor: "pointer",
2256
+ display: "flex",
2257
+ alignItems: "center",
2258
+ justifyContent: "center",
2259
+ fontSize: 14,
2260
+ boxShadow: " -2px 0 8px rgba(0,0,0,0.08)"
2261
+ },
2262
+ "aria-label": open ? "Close studio panel" : "Open studio panel",
2263
+ children: open ? "\u203A" : "\u2039"
2264
+ }
2265
+ ),
2266
+ /* @__PURE__ */ jsx9(
2267
+ "aside",
2268
+ {
2269
+ className: "grid-table-studio-panel",
2270
+ style: {
2271
+ position: "fixed",
2272
+ top: 0,
2273
+ right: 0,
2274
+ bottom: 0,
2275
+ width: isCollapsed ? 0 : width,
2276
+ minWidth: isCollapsed ? 0 : 280,
2277
+ borderLeft: "1px solid var(--gt-border-color, rgba(0,0,0,0.08))",
2278
+ backgroundColor: "var(--gt-bg-secondary, #f5f5f5)",
2279
+ display: "flex",
2280
+ flexDirection: "column",
2281
+ overflow: "hidden",
2282
+ zIndex: 1e4,
2283
+ boxShadow: isCollapsed ? "none" : "-4px 0 12px rgba(0,0,0,0.08)",
2284
+ transition: "width 0.2s ease, box-shadow 0.2s ease"
2285
+ },
2286
+ "aria-label": "Table studio panel",
2287
+ children: !isCollapsed && panelContent
2288
+ }
2289
+ )
2290
+ ] });
2291
+ }
2292
+
2080
2293
  // src/components/EmptyState/EmptyState.tsx
2081
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2294
+ import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
2082
2295
  function EmptyState({
2083
2296
  title,
2084
2297
  description,
@@ -2098,15 +2311,15 @@ function EmptyState({
2098
2311
  style,
2099
2312
  role: "status",
2100
2313
  children: [
2101
- icon && /* @__PURE__ */ jsx9("div", { className: "grid-empty-icon", children: icon }),
2102
- !icon && /* @__PURE__ */ jsx9("div", { className: "grid-empty-icon", children: /* @__PURE__ */ jsx9(
2314
+ icon && /* @__PURE__ */ jsx10("div", { className: "grid-empty-icon", children: icon }),
2315
+ !icon && /* @__PURE__ */ jsx10("div", { className: "grid-empty-icon", children: /* @__PURE__ */ jsx10(
2103
2316
  "svg",
2104
2317
  {
2105
2318
  className: "icon-lg",
2106
2319
  fill: "none",
2107
2320
  viewBox: "0 0 24 24",
2108
2321
  stroke: "currentColor",
2109
- children: /* @__PURE__ */ jsx9(
2322
+ children: /* @__PURE__ */ jsx10(
2110
2323
  "path",
2111
2324
  {
2112
2325
  strokeLinecap: "round",
@@ -2117,21 +2330,21 @@ function EmptyState({
2117
2330
  )
2118
2331
  }
2119
2332
  ) }),
2120
- /* @__PURE__ */ jsx9("h3", { className: "grid-empty-title", children: displayTitle }),
2121
- displayDescription && /* @__PURE__ */ jsx9("p", { className: "grid-empty-description", children: displayDescription }),
2122
- action && /* @__PURE__ */ jsx9("div", { className: "grid-empty-action", children: action })
2333
+ /* @__PURE__ */ jsx10("h3", { className: "grid-empty-title", children: displayTitle }),
2334
+ displayDescription && /* @__PURE__ */ jsx10("p", { className: "grid-empty-description", children: displayDescription }),
2335
+ action && /* @__PURE__ */ jsx10("div", { className: "grid-empty-action", children: action })
2123
2336
  ]
2124
2337
  }
2125
2338
  );
2126
2339
  }
2127
2340
 
2128
2341
  // src/components/MobileDrawer/MobileDrawer.tsx
2129
- import { useEffect as useEffect4, useCallback as useCallback12 } from "react";
2130
- import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2342
+ import { useEffect as useEffect5, useCallback as useCallback12 } from "react";
2343
+ import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
2131
2344
  function DrawerHeader({ title, onClose }) {
2132
2345
  return /* @__PURE__ */ jsxs8("div", { className: "drawer-header", children: [
2133
- /* @__PURE__ */ jsx10("h3", { children: title }),
2134
- /* @__PURE__ */ jsx10(
2346
+ /* @__PURE__ */ jsx11("h3", { children: title }),
2347
+ /* @__PURE__ */ jsx11(
2135
2348
  "button",
2136
2349
  {
2137
2350
  onClick: onClose,
@@ -2156,7 +2369,7 @@ function FilterContent() {
2156
2369
  translations.filter,
2157
2370
  "(s) active"
2158
2371
  ] }),
2159
- filters.length > 0 && /* @__PURE__ */ jsx10(
2372
+ filters.length > 0 && /* @__PURE__ */ jsx11(
2160
2373
  "button",
2161
2374
  {
2162
2375
  onClick: handleClearAll,
@@ -2165,13 +2378,13 @@ function FilterContent() {
2165
2378
  }
2166
2379
  )
2167
2380
  ] }),
2168
- /* @__PURE__ */ jsx10("div", { className: "space-y-3", children: columns.filter((col) => col.filterable !== false).map((col) => {
2381
+ /* @__PURE__ */ jsx11("div", { className: "space-y-3", children: columns.filter((col) => col.filterable !== false).map((col) => {
2169
2382
  var _a;
2170
2383
  const existingFilter = filters.find((f) => f.columnId === col.id);
2171
2384
  const headerText = typeof col.header === "string" ? col.header : col.id;
2172
2385
  return /* @__PURE__ */ jsxs8("div", { className: "filter-item", children: [
2173
- /* @__PURE__ */ jsx10("label", { className: "block text-sm font-medium text-theme-secondary mb-1", children: headerText }),
2174
- /* @__PURE__ */ jsx10(
2386
+ /* @__PURE__ */ jsx11("label", { className: "block text-sm font-medium text-theme-secondary mb-1", children: headerText }),
2387
+ /* @__PURE__ */ jsx11(
2175
2388
  "input",
2176
2389
  {
2177
2390
  type: "text",
@@ -2205,7 +2418,7 @@ function SortContent() {
2205
2418
  translations.sort,
2206
2419
  "(s) active"
2207
2420
  ] }),
2208
- sorting.length > 0 && /* @__PURE__ */ jsx10(
2421
+ sorting.length > 0 && /* @__PURE__ */ jsx11(
2209
2422
  "button",
2210
2423
  {
2211
2424
  onClick: handleClearAll,
@@ -2214,7 +2427,7 @@ function SortContent() {
2214
2427
  }
2215
2428
  )
2216
2429
  ] }),
2217
- /* @__PURE__ */ jsx10("div", { className: "space-y-2", children: columns.filter((col) => col.sortable !== false).map((col) => {
2430
+ /* @__PURE__ */ jsx11("div", { className: "space-y-2", children: columns.filter((col) => col.sortable !== false).map((col) => {
2218
2431
  const sortItem = sorting.find((s) => s.columnId === col.id);
2219
2432
  const headerText = typeof col.header === "string" ? col.header : col.id;
2220
2433
  return /* @__PURE__ */ jsxs8(
@@ -2223,8 +2436,8 @@ function SortContent() {
2223
2436
  onClick: () => actions.toggleSorting(col.id),
2224
2437
  className: `w-full px-3 py-2 rounded ${sortItem ? "active" : ""}`,
2225
2438
  children: [
2226
- /* @__PURE__ */ jsx10("span", { className: "text-sm text-theme-primary", children: headerText }),
2227
- /* @__PURE__ */ jsx10("span", { className: "text-xs text-theme-muted", children: (sortItem == null ? void 0 : sortItem.direction) === "asc" ? translations.sortAsc : (sortItem == null ? void 0 : sortItem.direction) === "desc" ? translations.sortDesc : "-" })
2439
+ /* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-primary", children: headerText }),
2440
+ /* @__PURE__ */ jsx11("span", { className: "text-xs text-theme-muted", children: (sortItem == null ? void 0 : sortItem.direction) === "asc" ? translations.sortAsc : (sortItem == null ? void 0 : sortItem.direction) === "desc" ? translations.sortDesc : "-" })
2228
2441
  ]
2229
2442
  },
2230
2443
  col.id
@@ -2237,8 +2450,8 @@ function ColumnsContent() {
2237
2450
  const { translations, columns, columnStates } = state;
2238
2451
  return /* @__PURE__ */ jsxs8("div", { className: "drawer-columns-content", children: [
2239
2452
  /* @__PURE__ */ jsxs8("div", { children: [
2240
- /* @__PURE__ */ jsx10("span", { className: "text-sm text-theme-muted", children: translations.showColumns }),
2241
- /* @__PURE__ */ jsx10(
2453
+ /* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-muted", children: translations.showColumns }),
2454
+ /* @__PURE__ */ jsx11(
2242
2455
  "button",
2243
2456
  {
2244
2457
  onClick: actions.resetColumns,
@@ -2247,7 +2460,7 @@ function ColumnsContent() {
2247
2460
  }
2248
2461
  )
2249
2462
  ] }),
2250
- /* @__PURE__ */ jsx10("div", { className: "space-y-2", children: columns.map((col) => {
2463
+ /* @__PURE__ */ jsx11("div", { className: "space-y-2", children: columns.map((col) => {
2251
2464
  const colState = columnStates.find((cs) => cs.id === col.id);
2252
2465
  const isVisible = (colState == null ? void 0 : colState.visible) !== false;
2253
2466
  const headerText = typeof col.header === "string" ? col.header : col.id;
@@ -2256,7 +2469,7 @@ function ColumnsContent() {
2256
2469
  {
2257
2470
  className: "px-3 py-2 rounded cursor-pointer",
2258
2471
  children: [
2259
- /* @__PURE__ */ jsx10(
2472
+ /* @__PURE__ */ jsx11(
2260
2473
  "input",
2261
2474
  {
2262
2475
  type: "checkbox",
@@ -2265,7 +2478,7 @@ function ColumnsContent() {
2265
2478
  className: "w-4 h-4 rounded"
2266
2479
  }
2267
2480
  ),
2268
- /* @__PURE__ */ jsx10("span", { className: "text-sm text-theme-primary", children: headerText })
2481
+ /* @__PURE__ */ jsx11("span", { className: "text-sm text-theme-primary", children: headerText })
2269
2482
  ]
2270
2483
  },
2271
2484
  col.id
@@ -2285,7 +2498,7 @@ function MobileDrawer({
2285
2498
  className = "",
2286
2499
  style
2287
2500
  }) {
2288
- useEffect4(() => {
2501
+ useEffect5(() => {
2289
2502
  if (isOpen) {
2290
2503
  document.body.style.overflow = "hidden";
2291
2504
  } else {
@@ -2295,7 +2508,7 @@ function MobileDrawer({
2295
2508
  document.body.style.overflow = "";
2296
2509
  };
2297
2510
  }, [isOpen]);
2298
- useEffect4(() => {
2511
+ useEffect5(() => {
2299
2512
  const handleEscape = (e) => {
2300
2513
  if (e.key === "Escape" && isOpen) {
2301
2514
  onClose();
@@ -2308,7 +2521,7 @@ function MobileDrawer({
2308
2521
  return null;
2309
2522
  }
2310
2523
  return /* @__PURE__ */ jsxs8("div", { className: `mobile-drawer-container ${className}`, style, children: [
2311
- /* @__PURE__ */ jsx10(
2524
+ /* @__PURE__ */ jsx11(
2312
2525
  "div",
2313
2526
  {
2314
2527
  className: "mobile-drawer-overlay",
@@ -2331,11 +2544,11 @@ function MobileDrawer({
2331
2544
  "aria-modal": "true",
2332
2545
  "aria-labelledby": "drawer-title",
2333
2546
  children: [
2334
- /* @__PURE__ */ jsx10(DrawerHeader, { title: DRAWER_TITLES[content], onClose }),
2547
+ /* @__PURE__ */ jsx11(DrawerHeader, { title: DRAWER_TITLES[content], onClose }),
2335
2548
  /* @__PURE__ */ jsxs8("div", { className: "drawer-content", children: [
2336
- content === "filter" && /* @__PURE__ */ jsx10(FilterContent, {}),
2337
- content === "sort" && /* @__PURE__ */ jsx10(SortContent, {}),
2338
- content === "columns" && /* @__PURE__ */ jsx10(ColumnsContent, {})
2549
+ content === "filter" && /* @__PURE__ */ jsx11(FilterContent, {}),
2550
+ content === "sort" && /* @__PURE__ */ jsx11(SortContent, {}),
2551
+ content === "columns" && /* @__PURE__ */ jsx11(ColumnsContent, {})
2339
2552
  ] })
2340
2553
  ]
2341
2554
  }
@@ -2344,7 +2557,7 @@ function MobileDrawer({
2344
2557
  }
2345
2558
 
2346
2559
  // src/components/GridTable/GridTable.tsx
2347
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
2560
+ import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
2348
2561
  function GridTableContent({
2349
2562
  data,
2350
2563
  columns,
@@ -2382,10 +2595,18 @@ function GridTableContent({
2382
2595
  renderHeader,
2383
2596
  renderFooter,
2384
2597
  className = "",
2385
- style
2598
+ style,
2599
+ showOverflowTooltip,
2600
+ enableCellAutoSizeOnDoubleClick,
2601
+ subCellExpandTrigger,
2602
+ expandRowOnDoubleClick,
2603
+ themeMode,
2604
+ paginationConfig
2386
2605
  }) {
2606
+ var _a, _b;
2387
2607
  const { state, actions, computed } = useTableContext();
2388
2608
  const { shouldShowMobileView, breakpointValue } = useBreakpoint();
2609
+ const themeClass = themeMode === "dark" ? "dark" : themeMode === "light" ? "light" : void 0;
2389
2610
  const getRowIdFn = useCallback13(
2390
2611
  (row) => {
2391
2612
  if (getRowId) return getRowId(row);
@@ -2414,6 +2635,22 @@ function GridTableContent({
2414
2635
  },
2415
2636
  [actions]
2416
2637
  );
2638
+ const handleRowDoubleClick = useCallback13(
2639
+ (row, index) => {
2640
+ if (expandRowOnDoubleClick) {
2641
+ actions.toggleRowExpansion(getRowIdFn(row));
2642
+ }
2643
+ onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, index);
2644
+ },
2645
+ [expandRowOnDoubleClick, actions, getRowIdFn, onRowDoubleClick]
2646
+ );
2647
+ const handleSelectAll = useCallback13(() => {
2648
+ if (computed.allSelected) {
2649
+ actions.deselectAll();
2650
+ } else {
2651
+ actions.selectAll();
2652
+ }
2653
+ }, [computed.allSelected, actions]);
2417
2654
  const handleFilterOpen = useCallback13(
2418
2655
  (columnId) => {
2419
2656
  if (shouldShowMobileView) {
@@ -2424,7 +2661,7 @@ function GridTableContent({
2424
2661
  },
2425
2662
  [shouldShowMobileView, actions]
2426
2663
  );
2427
- const containerStyle = useMemo12(() => {
2664
+ const containerStyle = useMemo11(() => {
2428
2665
  const baseStyle = { ...style, ...styles.root };
2429
2666
  if (dimensions == null ? void 0 : dimensions.width) {
2430
2667
  baseStyle.width = breakpointValue(dimensions.width, "auto");
@@ -2437,20 +2674,20 @@ function GridTableContent({
2437
2674
  }
2438
2675
  return baseStyle;
2439
2676
  }, [style, styles.root, dimensions, breakpointValue]);
2440
- const columnWidths = useMemo12(() => {
2677
+ const columnWidths = useMemo11(() => {
2441
2678
  return state.columnStates.map((cs) => cs.width);
2442
2679
  }, [state.columnStates]);
2443
2680
  if (error) {
2444
2681
  const errorMessage = typeof error === "string" ? error : error.message;
2445
2682
  if (errorContent) {
2446
- return /* @__PURE__ */ jsx11("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: typeof errorContent === "function" ? errorContent(error) : errorContent });
2683
+ return /* @__PURE__ */ jsx12("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: typeof errorContent === "function" ? errorContent(error) : errorContent });
2447
2684
  }
2448
- return /* @__PURE__ */ jsx11("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx11(
2685
+ return /* @__PURE__ */ jsx12("div", { className: `grid-table-error ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx12(
2449
2686
  EmptyState,
2450
2687
  {
2451
2688
  title: state.translations.errorLoading,
2452
2689
  description: errorMessage,
2453
- action: onRetry && /* @__PURE__ */ jsx11(
2690
+ action: onRetry && /* @__PURE__ */ jsx12(
2454
2691
  "button",
2455
2692
  {
2456
2693
  onClick: onRetry,
@@ -2463,9 +2700,9 @@ function GridTableContent({
2463
2700
  }
2464
2701
  if (loading) {
2465
2702
  if (loadingContent) {
2466
- return /* @__PURE__ */ jsx11("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: loadingContent });
2703
+ return /* @__PURE__ */ jsx12("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: loadingContent });
2467
2704
  }
2468
- return /* @__PURE__ */ jsx11("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx11(
2705
+ return /* @__PURE__ */ jsx12("div", { className: `grid-table-loading ${classNames.root || ""} ${className}`, style: containerStyle, children: /* @__PURE__ */ jsx12(
2469
2706
  Skeleton,
2470
2707
  {
2471
2708
  rows: 5,
@@ -2479,17 +2716,17 @@ function GridTableContent({
2479
2716
  ) });
2480
2717
  }
2481
2718
  const isEmpty = computed.paginatedData.length === 0;
2482
- return /* @__PURE__ */ jsxs9(
2719
+ const tableContent = /* @__PURE__ */ jsxs9(
2483
2720
  "div",
2484
2721
  {
2485
2722
  className: `grid-table rounded-lg border overflow-hidden ${classNames.root || ""} ${className}`,
2486
2723
  style: containerStyle,
2487
2724
  role: "table",
2488
2725
  children: [
2489
- renderHeader && /* @__PURE__ */ jsx11("div", { className: "grid-table-custom-header", children: renderHeader() }),
2726
+ renderHeader && /* @__PURE__ */ jsx12("div", { className: "grid-table-custom-header", children: renderHeader() }),
2490
2727
  showGlobalFilter && /* @__PURE__ */ jsxs9("div", { className: "grid-table-toolbar", children: [
2491
2728
  /* @__PURE__ */ jsxs9("div", { className: "toolbar-search-wrapper", children: [
2492
- /* @__PURE__ */ jsx11(
2729
+ /* @__PURE__ */ jsx12(
2493
2730
  "svg",
2494
2731
  {
2495
2732
  className: "search-icon",
@@ -2497,10 +2734,10 @@ function GridTableContent({
2497
2734
  viewBox: "0 0 24 24",
2498
2735
  stroke: "currentColor",
2499
2736
  strokeWidth: 2,
2500
- children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" })
2737
+ children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" })
2501
2738
  }
2502
2739
  ),
2503
- /* @__PURE__ */ jsx11(
2740
+ /* @__PURE__ */ jsx12(
2504
2741
  "input",
2505
2742
  {
2506
2743
  type: "text",
@@ -2510,13 +2747,13 @@ function GridTableContent({
2510
2747
  className: "w-full pl-10 pr-3 py-2 text-sm rounded"
2511
2748
  }
2512
2749
  ),
2513
- state.globalFilter && /* @__PURE__ */ jsx11(
2750
+ state.globalFilter && /* @__PURE__ */ jsx12(
2514
2751
  "button",
2515
2752
  {
2516
2753
  onClick: () => actions.setGlobalFilter(""),
2517
2754
  className: "clear-button",
2518
2755
  "aria-label": "Clear search",
2519
- children: /* @__PURE__ */ jsx11("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
2756
+ children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) })
2520
2757
  }
2521
2758
  )
2522
2759
  ] }),
@@ -2526,7 +2763,7 @@ function GridTableContent({
2526
2763
  onClick: () => actions.clearFilters(),
2527
2764
  className: "filter-badge",
2528
2765
  children: [
2529
- /* @__PURE__ */ jsx11("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }),
2766
+ /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }),
2530
2767
  /* @__PURE__ */ jsxs9("span", { children: [
2531
2768
  state.filters.length,
2532
2769
  " filter",
@@ -2536,37 +2773,37 @@ function GridTableContent({
2536
2773
  }
2537
2774
  ),
2538
2775
  shouldShowMobileView && /* @__PURE__ */ jsxs9("div", { className: "toolbar-actions", children: [
2539
- /* @__PURE__ */ jsx11(
2776
+ /* @__PURE__ */ jsx12(
2540
2777
  "button",
2541
2778
  {
2542
2779
  onClick: () => actions.openMobileDrawer("filter"),
2543
2780
  className: "toolbar-action-button",
2544
2781
  "aria-label": state.translations.filter,
2545
- children: /* @__PURE__ */ jsx11("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" }) })
2782
+ children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z" }) })
2546
2783
  }
2547
2784
  ),
2548
- /* @__PURE__ */ jsx11(
2785
+ /* @__PURE__ */ jsx12(
2549
2786
  "button",
2550
2787
  {
2551
2788
  onClick: () => actions.openMobileDrawer("sort"),
2552
2789
  className: "toolbar-action-button",
2553
2790
  "aria-label": state.translations.sort,
2554
- children: /* @__PURE__ */ jsx11("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) })
2791
+ children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4" }) })
2555
2792
  }
2556
2793
  ),
2557
- /* @__PURE__ */ jsx11(
2794
+ /* @__PURE__ */ jsx12(
2558
2795
  "button",
2559
2796
  {
2560
2797
  onClick: () => actions.openMobileDrawer("columns"),
2561
2798
  className: "toolbar-action-button",
2562
2799
  "aria-label": state.translations.columns,
2563
- children: /* @__PURE__ */ jsx11("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx11("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" }) })
2800
+ children: /* @__PURE__ */ jsx12("svg", { className: "icon-md", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx12("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2" }) })
2564
2801
  }
2565
2802
  )
2566
2803
  ] })
2567
2804
  ] }),
2568
2805
  /* @__PURE__ */ jsxs9("div", { className: "grid-table-container overflow-auto", children: [
2569
- !shouldShowMobileView && /* @__PURE__ */ jsx11(
2806
+ !shouldShowMobileView && /* @__PURE__ */ jsx12(
2570
2807
  GridHeader,
2571
2808
  {
2572
2809
  columns,
@@ -2579,24 +2816,25 @@ function GridTableContent({
2579
2816
  enableDragDrop,
2580
2817
  enableResize: enableColumnResize,
2581
2818
  enableSelection: enableRowSelection,
2819
+ enableExpansion: enableRowExpansion,
2582
2820
  allSelected: computed.allSelected,
2583
2821
  someSelected: computed.someSelected,
2584
- onSelectAll: actions.selectAll,
2822
+ onSelectAll: handleSelectAll,
2585
2823
  onFilterOpen: handleFilterOpen,
2586
2824
  getSortDirection: (colId) => {
2587
- var _a;
2825
+ var _a2;
2588
2826
  const sort = state.sorting.find((s) => s.columnId === colId);
2589
- return (_a = sort == null ? void 0 : sort.direction) != null ? _a : null;
2827
+ return (_a2 = sort == null ? void 0 : sort.direction) != null ? _a2 : null;
2590
2828
  }
2591
2829
  }
2592
2830
  ),
2593
- isEmpty ? emptyContent || /* @__PURE__ */ jsx11(
2831
+ isEmpty ? emptyContent || /* @__PURE__ */ jsx12(
2594
2832
  EmptyState,
2595
2833
  {
2596
2834
  className: classNames.empty,
2597
2835
  style: styles.empty
2598
2836
  }
2599
- ) : /* @__PURE__ */ jsx11(
2837
+ ) : /* @__PURE__ */ jsx12(
2600
2838
  GridBody,
2601
2839
  {
2602
2840
  data: computed.paginatedData,
@@ -2611,7 +2849,7 @@ function GridTableContent({
2611
2849
  selectedIds: state.selectedIds,
2612
2850
  expandedIds: state.expandedIds,
2613
2851
  onRowClick,
2614
- onRowDoubleClick,
2852
+ onRowDoubleClick: handleRowDoubleClick,
2615
2853
  onCellClick,
2616
2854
  onRowSelect: handleRowSelect,
2617
2855
  onRowExpand: handleRowExpand,
@@ -2623,27 +2861,50 @@ function GridTableContent({
2623
2861
  }
2624
2862
  )
2625
2863
  ] }),
2626
- showPagination && !isEmpty && /* @__PURE__ */ jsx11(
2627
- Pagination,
2628
- {
2629
- page: state.page,
2630
- pageSize: state.pageSize,
2631
- totalItems: computed.sortedData.length,
2632
- totalPages: computed.totalPages,
2633
- className: classNames.pagination,
2634
- style: styles.pagination,
2635
- onPageChange: (page) => {
2636
- actions.setPage(page);
2637
- onPageChange == null ? void 0 : onPageChange(page, state.pageSize);
2638
- },
2639
- onPageSizeChange: (pageSize) => {
2640
- actions.setPageSize(pageSize);
2641
- onPageChange == null ? void 0 : onPageChange(1, pageSize);
2864
+ showPagination && !isEmpty && /* @__PURE__ */ jsxs9("div", { className: `grid-pagination ${(_a = classNames.pagination) != null ? _a : ""}`, style: styles.pagination, role: "navigation", "aria-label": "Pagination", children: [
2865
+ /* @__PURE__ */ jsxs9("div", { className: "grid-pagination-info", children: [
2866
+ /* @__PURE__ */ jsxs9(Typography3, { component: "span", variant: "body2", color: "secondary", children: [
2867
+ (state.page - 1) * state.pageSize + 1,
2868
+ "-",
2869
+ Math.min(state.page * state.pageSize, computed.sortedData.length),
2870
+ " ",
2871
+ state.translations.of,
2872
+ " ",
2873
+ computed.sortedData.length
2874
+ ] }),
2875
+ /* @__PURE__ */ jsx12(Typography3, { component: "span", variant: "caption", color: "secondary", className: "bear-sr-only", children: state.translations.rowsPerPage }),
2876
+ /* @__PURE__ */ jsx12(
2877
+ Select,
2878
+ {
2879
+ value: String(state.pageSize),
2880
+ onChange: (value) => {
2881
+ const pageSize = Number(value);
2882
+ actions.setPageSize(pageSize);
2883
+ onPageChange == null ? void 0 : onPageChange(1, pageSize);
2884
+ },
2885
+ options: ((_b = paginationConfig == null ? void 0 : paginationConfig.pageSizeOptions) != null ? _b : [10, 20, 50, 100]).map((size) => ({ value: String(size), label: String(size) })),
2886
+ size: "sm"
2887
+ }
2888
+ )
2889
+ ] }),
2890
+ /* @__PURE__ */ jsx12("div", { className: "grid-pagination-controls", children: /* @__PURE__ */ jsx12(
2891
+ BearPagination,
2892
+ {
2893
+ count: Math.max(1, computed.totalPages),
2894
+ page: state.page,
2895
+ onChange: (page) => {
2896
+ actions.setPage(page);
2897
+ onPageChange == null ? void 0 : onPageChange(page, state.pageSize);
2898
+ },
2899
+ showFirstLast: true,
2900
+ showPrevNext: true,
2901
+ size: "sm",
2902
+ variant: "outlined"
2642
2903
  }
2643
- }
2644
- ),
2645
- renderFooter && /* @__PURE__ */ jsx11("div", { className: "grid-table-custom-footer", children: renderFooter() }),
2646
- /* @__PURE__ */ jsx11(
2904
+ ) })
2905
+ ] }),
2906
+ renderFooter && /* @__PURE__ */ jsx12("div", { className: "grid-table-custom-footer", children: renderFooter() }),
2907
+ /* @__PURE__ */ jsx12(
2647
2908
  MobileDrawer,
2648
2909
  {
2649
2910
  isOpen: state.showMobileDrawer,
@@ -2656,6 +2917,10 @@ function GridTableContent({
2656
2917
  ]
2657
2918
  }
2658
2919
  );
2920
+ if (themeClass) {
2921
+ return /* @__PURE__ */ jsx12("div", { className: themeClass, children: tableContent });
2922
+ }
2923
+ return tableContent;
2659
2924
  }
2660
2925
  function GridTable({
2661
2926
  data,
@@ -2670,12 +2935,26 @@ function GridTable({
2670
2935
  sortConfig,
2671
2936
  enableMultiSelect = false,
2672
2937
  getRowId,
2938
+ showOverflowTooltip,
2939
+ enableCellAutoSizeOnDoubleClick,
2940
+ subCellExpandTrigger,
2941
+ expandRowOnDoubleClick,
2942
+ themeMode,
2943
+ themeOverride,
2944
+ studio = false,
2673
2945
  ...props
2674
2946
  }) {
2675
- return /* @__PURE__ */ jsx11(
2947
+ var _a, _b;
2948
+ const [studioData, setStudioData] = useState8(data);
2949
+ const [studioOpen, setStudioOpen] = useState8(true);
2950
+ useEffect6(() => {
2951
+ if (studio) setStudioData(data);
2952
+ }, [data, studio]);
2953
+ const effectiveData = studio ? studioData : data;
2954
+ const tableContent = /* @__PURE__ */ jsx12(
2676
2955
  TableProvider,
2677
2956
  {
2678
- data,
2957
+ data: effectiveData,
2679
2958
  columns,
2680
2959
  loading,
2681
2960
  error,
@@ -2688,19 +2967,223 @@ function GridTable({
2688
2967
  enableMultiSort: sortConfig == null ? void 0 : sortConfig.multiSort,
2689
2968
  enableMultiSelect,
2690
2969
  getRowId,
2691
- children: /* @__PURE__ */ jsx11(
2970
+ showOverflowTooltip,
2971
+ enableCellAutoSizeOnDoubleClick,
2972
+ subCellExpandTrigger,
2973
+ expandRowOnDoubleClick,
2974
+ children: /* @__PURE__ */ jsx12(
2692
2975
  GridTableContent,
2693
2976
  {
2694
- data,
2977
+ data: effectiveData,
2695
2978
  columns,
2696
2979
  loading,
2697
2980
  error,
2698
2981
  getRowId,
2982
+ themeMode,
2983
+ paginationConfig,
2699
2984
  ...props
2700
2985
  }
2701
2986
  )
2702
2987
  }
2703
2988
  );
2989
+ const withTheme = themeOverride && Object.keys(themeOverride).length > 0 ? /* @__PURE__ */ jsx12(BearProvider, { theme: themeOverride, defaultMode: themeMode === "dark" ? "dark" : "light", children: tableContent }) : tableContent;
2990
+ if (studio) {
2991
+ return /* @__PURE__ */ jsxs9(Fragment4, { children: [
2992
+ /* @__PURE__ */ jsx12("div", { className: "grid-table-studio-main", style: { width: "100%" }, children: withTheme }),
2993
+ /* @__PURE__ */ jsx12(
2994
+ TableStudioPanel,
2995
+ {
2996
+ data: studioData,
2997
+ columns,
2998
+ propsSnapshot: {
2999
+ themeMode,
3000
+ themeOverride,
3001
+ showPagination: (_a = props.showPagination) != null ? _a : true,
3002
+ showGlobalFilter: (_b = props.showGlobalFilter) != null ? _b : true,
3003
+ enableRowSelection: props.enableRowSelection,
3004
+ enableRowExpansion: props.enableRowExpansion
3005
+ },
3006
+ onDataChange: setStudioData,
3007
+ open: studioOpen,
3008
+ onOpenChange: setStudioOpen
3009
+ }
3010
+ )
3011
+ ] });
3012
+ }
3013
+ return withTheme;
3014
+ }
3015
+
3016
+ // src/components/Pagination/Pagination.tsx
3017
+ import { useMemo as useMemo12, useCallback as useCallback14 } from "react";
3018
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
3019
+ function Pagination({
3020
+ page,
3021
+ pageSize,
3022
+ totalItems,
3023
+ totalPages,
3024
+ pageSizeOptions = [10, 20, 50, 100],
3025
+ showFirstLast = true,
3026
+ showPageNumbers = true,
3027
+ maxPageButtons = FIVE,
3028
+ className = "",
3029
+ style,
3030
+ onPageChange,
3031
+ onPageSizeChange
3032
+ }) {
3033
+ const { state } = useTableContext();
3034
+ const { translations } = state;
3035
+ const canGoPrevious = page > ONE;
3036
+ const canGoNext = page < totalPages;
3037
+ const startItem = (page - ONE) * pageSize + ONE;
3038
+ const endItem = Math.min(page * pageSize, totalItems);
3039
+ const handleFirstPage = useCallback14(() => {
3040
+ onPageChange(ONE);
3041
+ }, [onPageChange]);
3042
+ const handlePreviousPage = useCallback14(() => {
3043
+ if (canGoPrevious) {
3044
+ onPageChange(page - ONE);
3045
+ }
3046
+ }, [canGoPrevious, page, onPageChange]);
3047
+ const handleNextPage = useCallback14(() => {
3048
+ if (canGoNext) {
3049
+ onPageChange(page + ONE);
3050
+ }
3051
+ }, [canGoNext, page, onPageChange]);
3052
+ const handleLastPage = useCallback14(() => {
3053
+ onPageChange(totalPages);
3054
+ }, [onPageChange, totalPages]);
3055
+ const handlePageSizeChange = useCallback14(
3056
+ (event) => {
3057
+ onPageSizeChange(Number(event.target.value));
3058
+ },
3059
+ [onPageSizeChange]
3060
+ );
3061
+ const pageNumbers = useMemo12(() => {
3062
+ if (!showPageNumbers || totalPages <= ONE) return [];
3063
+ const pages = [];
3064
+ const halfMax = Math.floor(maxPageButtons / 2);
3065
+ let start = Math.max(ONE, page - halfMax);
3066
+ let end = Math.min(totalPages, page + halfMax);
3067
+ if (page <= halfMax) {
3068
+ end = Math.min(totalPages, maxPageButtons);
3069
+ }
3070
+ if (page > totalPages - halfMax) {
3071
+ start = Math.max(ONE, totalPages - maxPageButtons + ONE);
3072
+ }
3073
+ if (start > ONE) {
3074
+ pages.push(ONE);
3075
+ if (start > 2) {
3076
+ pages.push("ellipsis");
3077
+ }
3078
+ }
3079
+ for (let i = start; i <= end; i++) {
3080
+ if (!pages.includes(i)) {
3081
+ pages.push(i);
3082
+ }
3083
+ }
3084
+ if (end < totalPages) {
3085
+ if (end < totalPages - ONE) {
3086
+ pages.push("ellipsis");
3087
+ }
3088
+ pages.push(totalPages);
3089
+ }
3090
+ return pages;
3091
+ }, [page, totalPages, showPageNumbers, maxPageButtons]);
3092
+ if (totalItems === 0) {
3093
+ return null;
3094
+ }
3095
+ return /* @__PURE__ */ jsxs10(
3096
+ "div",
3097
+ {
3098
+ className: `grid-pagination ${className}`,
3099
+ style,
3100
+ role: "navigation",
3101
+ "aria-label": "Pagination",
3102
+ children: [
3103
+ /* @__PURE__ */ jsxs10("div", { className: "grid-pagination-info", children: [
3104
+ /* @__PURE__ */ jsxs10("div", { className: "grid-pagination-range", children: [
3105
+ startItem,
3106
+ "-",
3107
+ endItem,
3108
+ " ",
3109
+ translations.of,
3110
+ " ",
3111
+ totalItems
3112
+ ] }),
3113
+ /* @__PURE__ */ jsxs10("div", { className: "grid-pagination-size", children: [
3114
+ /* @__PURE__ */ jsxs10("label", { htmlFor: "page-size", children: [
3115
+ translations.rowsPerPage,
3116
+ ":"
3117
+ ] }),
3118
+ /* @__PURE__ */ jsx13(
3119
+ "select",
3120
+ {
3121
+ id: "page-size",
3122
+ value: pageSize,
3123
+ onChange: handlePageSizeChange,
3124
+ className: "px-2 py-1 text-sm rounded",
3125
+ children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx13("option", { value: size, children: size }, size))
3126
+ }
3127
+ )
3128
+ ] })
3129
+ ] }),
3130
+ /* @__PURE__ */ jsxs10("div", { className: "grid-pagination-controls", children: [
3131
+ showFirstLast && /* @__PURE__ */ jsx13(
3132
+ "button",
3133
+ {
3134
+ onClick: handleFirstPage,
3135
+ disabled: !canGoPrevious,
3136
+ className: "p-2 rounded text-theme-secondary",
3137
+ "aria-label": translations.first,
3138
+ children: "<<"
3139
+ }
3140
+ ),
3141
+ /* @__PURE__ */ jsx13(
3142
+ "button",
3143
+ {
3144
+ onClick: handlePreviousPage,
3145
+ disabled: !canGoPrevious,
3146
+ className: "p-2 rounded text-theme-secondary",
3147
+ "aria-label": translations.previous,
3148
+ children: "<"
3149
+ }
3150
+ ),
3151
+ showPageNumbers && /* @__PURE__ */ jsx13("div", { className: "grid-pagination-pages", children: pageNumbers.map(
3152
+ (pageNum, index) => pageNum === "ellipsis" ? /* @__PURE__ */ jsx13("span", { className: "px-2 text-theme-muted", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ jsx13(
3153
+ "button",
3154
+ {
3155
+ onClick: () => onPageChange(pageNum),
3156
+ className: `min-w-[32px] h-8 px-2 rounded text-sm ${pageNum === page ? "active" : ""}`,
3157
+ "aria-current": pageNum === page ? "page" : void 0,
3158
+ children: pageNum
3159
+ },
3160
+ pageNum
3161
+ )
3162
+ ) }),
3163
+ /* @__PURE__ */ jsx13(
3164
+ "button",
3165
+ {
3166
+ onClick: handleNextPage,
3167
+ disabled: !canGoNext,
3168
+ className: "p-2 rounded text-theme-secondary",
3169
+ "aria-label": translations.next,
3170
+ children: ">"
3171
+ }
3172
+ ),
3173
+ showFirstLast && /* @__PURE__ */ jsx13(
3174
+ "button",
3175
+ {
3176
+ onClick: handleLastPage,
3177
+ disabled: !canGoNext,
3178
+ className: "p-2 rounded text-theme-secondary",
3179
+ "aria-label": translations.last,
3180
+ children: ">>"
3181
+ }
3182
+ )
3183
+ ] })
3184
+ ]
3185
+ }
3186
+ );
2704
3187
  }
2705
3188
  export {
2706
3189
  BREAKPOINTS,