pam-grid 1.0.8 → 1.1.0

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.d.mts CHANGED
@@ -16,9 +16,13 @@ interface SortState {
16
16
  dir: SortDir;
17
17
  }
18
18
  interface TableAction<T extends object> {
19
- label: string;
20
- icon?: string;
19
+ label?: string | ((row: T) => string);
20
+ icon?: string | ((row: T) => string);
21
+ onlyIcon?: boolean;
22
+ className?: string | ((row: T) => string);
23
+ disabled?: boolean | ((row: T) => boolean);
21
24
  isVisible?: boolean | ((row: T) => boolean);
25
+ tooltip?: string | ((row: T) => string);
22
26
  onClick: (row: T) => void;
23
27
  }
24
28
  interface AdvancedFilter {
@@ -86,6 +90,7 @@ interface GridFetaures<T extends object> {
86
90
  aggregation?: boolean;
87
91
  IsNumbering?: boolean;
88
92
  expand?: boolean;
93
+ fullScreen?: boolean;
89
94
  actions?: TableAction<T>[] | ((row: T, toggleExpand: (id: GridRowId) => void) => React.ReactNode);
90
95
  bulkActionsConfig?: BulkAction[];
91
96
  }
@@ -198,6 +203,7 @@ interface PamGridProps<T extends Record<string, any>> {
198
203
  rowKey?: keyof T;
199
204
  maxHeight?: string;
200
205
  isDropdown?: boolean;
206
+ customeDiv?: React.ReactNode;
201
207
  isFetching?: boolean;
202
208
  addNew?: () => void;
203
209
  renderExpanded?: (row: T) => React.ReactNode;
@@ -209,7 +215,7 @@ interface BulkAction {
209
215
  onBulkClick: (item: Set<GridRowId>) => Set<GridRowId>;
210
216
  }
211
217
 
212
- declare const PamGrid: <T extends Record<string, unknown>>({ columns, grid, loading, features, rowKey, isDropdown, maxHeight, isFetching, addNew, renderExpanded, }: PamGridProps<T>) => react_jsx_runtime.JSX.Element;
218
+ declare const PamGrid: <T extends Record<string, unknown>>({ columns, grid, loading, features, rowKey, isDropdown, maxHeight, isFetching, customeDiv, addNew, renderExpanded, }: PamGridProps<T>) => react_jsx_runtime.JSX.Element;
213
219
 
214
220
  declare const ColumnVisibilityPanel: <T extends Record<string, any>>({ columns, onToggle, }: ColumnVisibilityPanelProps<T>) => react_jsx_runtime.JSX.Element;
215
221
 
package/dist/index.d.ts CHANGED
@@ -16,9 +16,13 @@ interface SortState {
16
16
  dir: SortDir;
17
17
  }
18
18
  interface TableAction<T extends object> {
19
- label: string;
20
- icon?: string;
19
+ label?: string | ((row: T) => string);
20
+ icon?: string | ((row: T) => string);
21
+ onlyIcon?: boolean;
22
+ className?: string | ((row: T) => string);
23
+ disabled?: boolean | ((row: T) => boolean);
21
24
  isVisible?: boolean | ((row: T) => boolean);
25
+ tooltip?: string | ((row: T) => string);
22
26
  onClick: (row: T) => void;
23
27
  }
24
28
  interface AdvancedFilter {
@@ -86,6 +90,7 @@ interface GridFetaures<T extends object> {
86
90
  aggregation?: boolean;
87
91
  IsNumbering?: boolean;
88
92
  expand?: boolean;
93
+ fullScreen?: boolean;
89
94
  actions?: TableAction<T>[] | ((row: T, toggleExpand: (id: GridRowId) => void) => React.ReactNode);
90
95
  bulkActionsConfig?: BulkAction[];
91
96
  }
@@ -198,6 +203,7 @@ interface PamGridProps<T extends Record<string, any>> {
198
203
  rowKey?: keyof T;
199
204
  maxHeight?: string;
200
205
  isDropdown?: boolean;
206
+ customeDiv?: React.ReactNode;
201
207
  isFetching?: boolean;
202
208
  addNew?: () => void;
203
209
  renderExpanded?: (row: T) => React.ReactNode;
@@ -209,7 +215,7 @@ interface BulkAction {
209
215
  onBulkClick: (item: Set<GridRowId>) => Set<GridRowId>;
210
216
  }
211
217
 
212
- declare const PamGrid: <T extends Record<string, unknown>>({ columns, grid, loading, features, rowKey, isDropdown, maxHeight, isFetching, addNew, renderExpanded, }: PamGridProps<T>) => react_jsx_runtime.JSX.Element;
218
+ declare const PamGrid: <T extends Record<string, unknown>>({ columns, grid, loading, features, rowKey, isDropdown, maxHeight, isFetching, customeDiv, addNew, renderExpanded, }: PamGridProps<T>) => react_jsx_runtime.JSX.Element;
213
219
 
214
220
  declare const ColumnVisibilityPanel: <T extends Record<string, any>>({ columns, onToggle, }: ColumnVisibilityPanelProps<T>) => react_jsx_runtime.JSX.Element;
215
221
 
package/dist/index.js CHANGED
@@ -97,7 +97,7 @@ function AdvanceFilter({
97
97
  );
98
98
  };
99
99
  if (!type) return null;
100
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { width: 240 }, onClick: (e) => e.stopPropagation(), children: [
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { width: 270 }, onClick: (e) => e.stopPropagation(), children: [
101
101
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mb-2", children: [
102
102
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: "form-label", children: "Condition" }),
103
103
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
@@ -155,6 +155,15 @@ function AdvanceFilter({
155
155
 
156
156
  // src/core/utils.ts
157
157
  var import_react2 = require("react");
158
+ var EDGE_SIZE = 8;
159
+ var getResizeSide = (e, index) => {
160
+ const rect = e.currentTarget.getBoundingClientRect();
161
+ const nearRight = rect.right - e.clientX < EDGE_SIZE;
162
+ const nearLeft = e.clientX - rect.left < EDGE_SIZE;
163
+ if (nearRight) return "right";
164
+ if (nearLeft && index > 0) return "left";
165
+ return null;
166
+ };
158
167
  function getAdvancedFilterType(column) {
159
168
  const f = column.enableAdvancedFilter;
160
169
  if (!f) return null;
@@ -222,6 +231,9 @@ function useLocalStorageState(key, initialValue) {
222
231
  }, [key]);
223
232
  return [value, updateValue];
224
233
  }
234
+ var resolveValue = (value, row) => {
235
+ return typeof value === "function" ? value(row) : value;
236
+ };
225
237
 
226
238
  // src/components/FacetFilter.tsx
227
239
  var import_react3 = require("react");
@@ -1304,6 +1316,7 @@ var PamGrid = ({
1304
1316
  isDropdown = false,
1305
1317
  maxHeight = "80vh",
1306
1318
  isFetching = false,
1319
+ customeDiv,
1307
1320
  addNew,
1308
1321
  renderExpanded
1309
1322
  }) => {
@@ -1345,16 +1358,25 @@ var PamGrid = ({
1345
1358
  advanceFilters,
1346
1359
  setColumnAdvanceFilter
1347
1360
  } = grid ?? safeGridHandle;
1348
- const onResizeMouseDown = (e, key) => {
1361
+ const onResizeMouseDown = (e, key, side = "right") => {
1349
1362
  e.preventDefault();
1350
1363
  const startX = e.clientX;
1351
- const col = colState.find((c) => c.key === key);
1352
- if (!col) return;
1353
- const startWidth = col.width || 120;
1364
+ const colIndex = colState.findIndex((c) => c.key === key);
1365
+ if (colIndex === -1) return;
1366
+ let targetIndex = colIndex;
1367
+ if (side === "left" && colIndex > 0) {
1368
+ targetIndex = colIndex - 1;
1369
+ }
1370
+ const targetCol = colState[targetIndex];
1371
+ if (!targetCol) return;
1372
+ const startWidth = targetCol.width || 120;
1354
1373
  const onMove = (ev) => {
1355
- const diff = ev.clientX - startX;
1374
+ let diff = ev.clientX - startX;
1375
+ if (side === "left") {
1376
+ diff = -diff;
1377
+ }
1356
1378
  const newWidth = Math.max(60, startWidth + diff);
1357
- updateColumn(key, { width: newWidth });
1379
+ updateColumn(targetCol.key, { width: newWidth });
1358
1380
  };
1359
1381
  const onUp = () => {
1360
1382
  document.removeEventListener("mousemove", onMove);
@@ -1461,9 +1483,10 @@ var PamGrid = ({
1461
1483
  ]
1462
1484
  }
1463
1485
  ),
1464
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex-shrink-0", children: isFullScreen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Minimize_default, { onClick: () => setFullScreen(!isFullScreen) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Compress_default, { onClick: () => setFullScreen(!isFullScreen) }) })
1486
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `flex-shrink-0 ${features.fullScreen ? "" : "d-none"}`, children: isFullScreen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Minimize_default, { onClick: () => setFullScreen(!isFullScreen) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Compress_default, { onClick: () => setFullScreen(!isFullScreen) }) })
1465
1487
  ] }) })
1466
1488
  ] }),
1489
+ customeDiv && customeDiv,
1467
1490
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "d-flex flex-row gap-1", children: [
1468
1491
  selected.size > 0 && features.bulkActionsConfig && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(BulkAction_default, { records: selected, actions: features.bulkActionsConfig }),
1469
1492
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -1516,7 +1539,7 @@ var PamGrid = ({
1516
1539
  )
1517
1540
  }
1518
1541
  ),
1519
- visibleColumns.map((col) => {
1542
+ visibleColumns.map((col, index) => {
1520
1543
  const style = {
1521
1544
  minWidth: col.width || 120,
1522
1545
  width: col.width,
@@ -1539,18 +1562,41 @@ var PamGrid = ({
1539
1562
  onDragEnd: () => setDraggingCol(null),
1540
1563
  onDragOver: (e) => e.preventDefault(),
1541
1564
  onDrop: (e) => onDrop(e, col.key),
1565
+ onMouseMove: (e) => {
1566
+ const side = getResizeSide(e, index);
1567
+ if (side) {
1568
+ e.currentTarget.style.cursor = "col-resize";
1569
+ } else if (draggingCol === col.key) {
1570
+ e.currentTarget.style.cursor = "grabbing";
1571
+ } else if (features.reorder) {
1572
+ e.currentTarget.style.cursor = "grab";
1573
+ } else {
1574
+ e.currentTarget.style.cursor = "default";
1575
+ }
1576
+ },
1577
+ onMouseLeave: (e) => {
1578
+ e.currentTarget.style.cursor = "default";
1579
+ },
1580
+ onMouseDown: (e) => {
1581
+ const side = getResizeSide(e, index);
1582
+ if (!side) return;
1583
+ e.stopPropagation();
1584
+ onResizeMouseDown(e, col.key, side);
1585
+ },
1542
1586
  className: `pms-col-header vs-th
1543
- ${features.reorder ? "cursor-grab" : ""}
1544
- ${draggingCol === col.key ? "cursor-grabbing" : ""}
1545
- ${col.pinned ? `pinned pinned-${col.pinned}` : ""}
1546
- `,
1587
+ ${col.pinned ? `pinned pinned-${col.pinned}` : ""}
1588
+ `,
1547
1589
  style,
1548
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1549
- "div",
1550
- {
1551
- className: `d-flex align-items-center justify-content-${col.align ?? "between"} px-1 rounded ${col.pinned ? "z-6" : ""}`,
1552
- children: [
1553
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1590
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "d-flex align-items-center w-100 px-1", children: [
1591
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1592
+ "div",
1593
+ {
1594
+ className: `flex-grow-1 d-flex align-items-center
1595
+ ${col.align === "center" ? "justify-content-center" : ""}
1596
+ ${col.align === "end" ? "justify-content-end" : ""}
1597
+ ${!col.align || col.align === "start" ? "justify-content-start" : ""}
1598
+ `,
1599
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1554
1600
  "div",
1555
1601
  {
1556
1602
  onClick: () => col.sortable && changeSort(String(col.key)),
@@ -1560,31 +1606,23 @@ var PamGrid = ({
1560
1606
  sortBy.key === col.key && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1561
1607
  "i",
1562
1608
  {
1563
- className: `bx bx-sm ${sortBy.dir === "asc" ? "bxs-chevron-up" : "bxs-chevron-down"} cursor-pointer`
1609
+ className: `bx bx-sm ${sortBy.dir === "asc" ? "bxs-chevron-up" : "bxs-chevron-down"}`
1564
1610
  }
1565
- ),
1566
- col.pinned === col.key && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("i", { className: "bx bx-x cursor-pointer" })
1611
+ )
1567
1612
  ]
1568
1613
  }
1569
- ),
1570
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1571
- "i",
1572
- {
1573
- className: "bx bx-move-horizontal text-white cursor-resize",
1574
- onMouseDown: (e) => onResizeMouseDown(e, col.key)
1575
- }
1576
- ),
1577
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "d-flex align-items-center gap-1", children: features.pinning && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1578
- PamHeaderOption_default,
1579
- {
1580
- currentColumn: col,
1581
- gridFetaures: features,
1582
- grid
1583
- }
1584
- ) })
1585
- ]
1586
- }
1587
- )
1614
+ )
1615
+ }
1616
+ ),
1617
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "d-flex align-items-center gap-1 flex-shrink-0", children: features.pinning && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1618
+ PamHeaderOption_default,
1619
+ {
1620
+ currentColumn: col,
1621
+ gridFetaures: features,
1622
+ grid
1623
+ }
1624
+ ) })
1625
+ ] })
1588
1626
  },
1589
1627
  String(col.key)
1590
1628
  );
@@ -1592,7 +1630,7 @@ var PamGrid = ({
1592
1630
  features.actions && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1593
1631
  "th",
1594
1632
  {
1595
- className: "text-center sticky-action-column vs-th bg-white fw-semibold th-lastChild",
1633
+ className: "text-center sticky-action-column vs-th bg-white th-lastChild",
1596
1634
  style: { position: "sticky", right: 0, zIndex: 10 },
1597
1635
  children: "Action"
1598
1636
  }
@@ -1630,7 +1668,7 @@ var PamGrid = ({
1630
1668
  className: "text-start pinned pinned-left tr-group",
1631
1669
  children: [
1632
1670
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: g.displayLabel }),
1633
- features.aggregation && Object.keys(g.aggregates).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "ms-3 text-muted ", children: Object.entries(g.aggregates).map(([k, v]) => `${k}: ${v}`).join(" | ") })
1671
+ features.aggregation && Object.keys(g.aggregates).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "ms-3 text-secondary text-capitalize ", children: Object.entries(g.aggregates).map(([k, v]) => `${k}: ${v}`).join(" | ") })
1634
1672
  ]
1635
1673
  }
1636
1674
  ) }),
@@ -1751,34 +1789,58 @@ var PamGrid = ({
1751
1789
  width: "1%",
1752
1790
  whiteSpace: "nowrap"
1753
1791
  },
1754
- children: isDropdown ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-center ", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TableAction, { gridFetaures: features, row }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1792
+ children: isDropdown ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TableAction, { gridFetaures: features, row }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1755
1793
  "div",
1756
1794
  {
1757
1795
  className: "d-inline-flex justify-content-center align-items-center gap-2",
1758
1796
  style: { minWidth: "fit-content", padding: "0 4px" },
1759
1797
  children: Array.isArray(features.actions) ? features.actions.filter((act) => {
1760
- if (typeof act.isVisible === "function") {
1761
- return act.isVisible(row);
1762
- }
1763
- if (typeof act.isVisible === "boolean") {
1764
- return act.isVisible;
1765
- }
1766
- return true;
1767
- }).map((act, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1768
- "i",
1769
- {
1770
- title: act.label,
1771
- onClick: (e) => {
1772
- e.stopPropagation();
1773
- act.onClick && act.onClick(row);
1798
+ const visible = resolveValue(
1799
+ act.isVisible ?? true,
1800
+ row
1801
+ );
1802
+ return visible;
1803
+ }).map((act, i) => {
1804
+ const label = resolveValue(act.label, row);
1805
+ const icon = resolveValue(act.icon, row);
1806
+ const className = resolveValue(act.className, row);
1807
+ const disabled = resolveValue(
1808
+ act.disabled ?? false,
1809
+ row
1810
+ );
1811
+ return act.onlyIcon ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1812
+ "i",
1813
+ {
1814
+ title: label,
1815
+ onClick: (e) => {
1816
+ e.stopPropagation();
1817
+ if (!disabled) act.onClick?.(row);
1818
+ },
1819
+ className: `${icon} ${disabled ? "opacity-50" : ""}`,
1820
+ style: {
1821
+ cursor: disabled ? "not-allowed" : "pointer"
1822
+ },
1823
+ onMouseMove: (e) => typeof label === "string" && showTooltip(label, e.clientX, e.clientY),
1824
+ onMouseLeave: hideTooltip
1825
+ },
1826
+ i
1827
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1828
+ "button",
1829
+ {
1830
+ className,
1831
+ disabled,
1832
+ onClick: (e) => {
1833
+ e.stopPropagation();
1834
+ if (!disabled) act.onClick?.(row);
1835
+ },
1836
+ children: [
1837
+ icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("i", { className: `${icon} me-1` }),
1838
+ label
1839
+ ]
1774
1840
  },
1775
- className: `${act.icon}`,
1776
- onMouseEnter: (e) => showTooltip(act.label, e.clientX, e.clientY),
1777
- onMouseMove: (e) => showTooltip(act.label, e.clientX, e.clientY),
1778
- onMouseLeave: hideTooltip
1779
- },
1780
- i
1781
- )) : typeof features.actions === "function" ? features.actions(row, toggleExpand) : null
1841
+ i
1842
+ );
1843
+ }) : typeof features.actions === "function" ? features.actions(row, toggleExpand) : null
1782
1844
  }
1783
1845
  )
1784
1846
  }