@eztrak/shared 0.14.0 → 0.15.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.
@@ -1522,7 +1522,8 @@ function PopupCellRenderer({
1522
1522
  params,
1523
1523
  onAction,
1524
1524
  placement = "bottom-end",
1525
- tippyProps
1525
+ tippyProps,
1526
+ ariaLabel = "Row actions"
1526
1527
  }) {
1527
1528
  const [visible, setVisible] = useState4(false);
1528
1529
  const show = () => setVisible(true);
@@ -1558,7 +1559,7 @@ function PopupCellRenderer({
1558
1559
  "flex items-center justify-center gap-2 rounded-full text-gray-500 hover:text-gray-800",
1559
1560
  className
1560
1561
  ),
1561
- "aria-label": "Row actions",
1562
+ "aria-label": ariaLabel,
1562
1563
  children: [
1563
1564
  !hideTitle && title,
1564
1565
  /* @__PURE__ */ jsx12(ActionIcon, { "aria-hidden": true })
@@ -1569,10 +1570,305 @@ function PopupCellRenderer({
1569
1570
  ) });
1570
1571
  }
1571
1572
 
1573
+ // src/components/row-actions/presets.ts
1574
+ import {
1575
+ FaArchive,
1576
+ FaCheckCircle,
1577
+ FaDownload,
1578
+ FaEdit,
1579
+ FaEye,
1580
+ FaFileAlt,
1581
+ FaHistory,
1582
+ FaTrashAlt
1583
+ } from "react-icons/fa";
1584
+ var ROW_ACTION_ITEM_HOVER_CLASS = "hover:bg-primary-50 hover:text-primary-150";
1585
+ var ROW_ACTION_DEFAULT_ICON_SIZE = 16;
1586
+ var ROW_ACTION_DEFAULT_MENU_TOOLTIP_STYLE = {
1587
+ zIndex: 1e4
1588
+ };
1589
+ var ROW_ACTION_PRESETS = {
1590
+ edit: { label: "Edit", icon: FaEdit },
1591
+ delete: { label: "Delete", icon: FaTrashAlt, danger: true },
1592
+ view: { label: "View", icon: FaEye },
1593
+ notes: { label: "Notes", icon: FaFileAlt },
1594
+ history: { label: "History", icon: FaHistory },
1595
+ download: { label: "Download", icon: FaDownload },
1596
+ archive: { label: "Archive", icon: FaArchive },
1597
+ resolve: { label: "Resolve", icon: FaCheckCircle }
1598
+ };
1599
+
1600
+ // src/components/row-actions/ActionMenuItem.tsx
1601
+ import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1602
+ function ActionMenuItem({
1603
+ label,
1604
+ icon: Icon,
1605
+ iconSize = ROW_ACTION_DEFAULT_ICON_SIZE,
1606
+ iconClassName,
1607
+ tooltip,
1608
+ tooltipPlacement = "top",
1609
+ tooltipDelayShow,
1610
+ tooltipDelayHide,
1611
+ tooltipClassName,
1612
+ tooltipStyle,
1613
+ disabled = false,
1614
+ danger = false,
1615
+ highlight = false,
1616
+ showLabel = true,
1617
+ className,
1618
+ onClick
1619
+ }) {
1620
+ const tooltipText = tooltip ?? label;
1621
+ return /* @__PURE__ */ jsx13(
1622
+ ToolTip,
1623
+ {
1624
+ text: tooltipText,
1625
+ disabled: !tooltipText,
1626
+ placement: tooltipPlacement,
1627
+ delayShow: tooltipDelayShow,
1628
+ delayHide: tooltipDelayHide,
1629
+ tooltipClassName,
1630
+ tooltipStyle: { ...ROW_ACTION_DEFAULT_MENU_TOOLTIP_STYLE, ...tooltipStyle },
1631
+ className: showLabel ? "block w-full" : "inline-flex",
1632
+ children: /* @__PURE__ */ jsxs10(
1633
+ "button",
1634
+ {
1635
+ type: "button",
1636
+ disabled,
1637
+ "aria-label": label,
1638
+ onClick: (event) => {
1639
+ event.stopPropagation();
1640
+ if (disabled) return;
1641
+ onClick();
1642
+ },
1643
+ className: cn(
1644
+ "flex items-center gap-2 text-sm transition-colors duration-150",
1645
+ showLabel ? "w-full rounded-xl px-3 py-2 text-left" : "justify-center rounded-md p-1",
1646
+ disabled ? "cursor-not-allowed opacity-50" : ROW_ACTION_ITEM_HOVER_CLASS,
1647
+ danger && "text-red-500",
1648
+ highlight && !danger && "text-primary-150",
1649
+ className
1650
+ ),
1651
+ children: [
1652
+ Icon ? /* @__PURE__ */ jsx13(
1653
+ Icon,
1654
+ {
1655
+ className: cn("shrink-0", iconClassName),
1656
+ "aria-hidden": true,
1657
+ size: iconSize
1658
+ }
1659
+ ) : null,
1660
+ showLabel ? /* @__PURE__ */ jsx13("span", { children: label }) : null
1661
+ ]
1662
+ }
1663
+ )
1664
+ }
1665
+ );
1666
+ }
1667
+
1668
+ // src/components/row-actions/resolveActions.ts
1669
+ function evalFlag(flag, data) {
1670
+ if (typeof flag === "function") return Boolean(flag(data));
1671
+ return Boolean(flag);
1672
+ }
1673
+ function mergePreset(name, overrides) {
1674
+ if (!name) return void 0;
1675
+ const base = ROW_ACTION_PRESETS[name];
1676
+ const extra = overrides?.[name];
1677
+ if (!extra) return base;
1678
+ return { ...base, ...extra };
1679
+ }
1680
+ function resolveActions(actions, data, hasPermission, presets) {
1681
+ const list = typeof actions === "function" ? actions(data) : actions;
1682
+ return list.flatMap((action, index) => {
1683
+ const type = action.type ?? "item";
1684
+ const preset = mergePreset(action.preset, presets);
1685
+ const key = action.key ?? action.preset ?? `action-${index}`;
1686
+ const label = action.label ?? preset?.label ?? key;
1687
+ if (action.permission && hasPermission && !hasPermission(action.permission)) {
1688
+ return [];
1689
+ }
1690
+ if (evalFlag(action.hidden, data)) {
1691
+ return [];
1692
+ }
1693
+ const tooltip = action.tooltip === false ? void 0 : action.tooltip ?? (type === "divider" ? void 0 : label);
1694
+ const resolved = {
1695
+ key,
1696
+ type,
1697
+ label,
1698
+ icon: action.icon ?? preset?.icon,
1699
+ iconSize: action.iconSize,
1700
+ content: action.content,
1701
+ onClick: action.onClick,
1702
+ disabled: evalFlag(action.disabled, data),
1703
+ danger: action.danger ?? preset?.danger ?? false,
1704
+ highlight: evalFlag(action.highlight, data),
1705
+ tooltip,
1706
+ tooltipPlacement: action.tooltipPlacement,
1707
+ confirm: action.confirm,
1708
+ closeOnClick: action.closeOnClick !== false,
1709
+ className: action.className
1710
+ };
1711
+ return [resolved];
1712
+ });
1713
+ }
1714
+
1715
+ // src/components/row-actions/RowActions.tsx
1716
+ import { Fragment as Fragment3, jsx as jsx14 } from "react/jsx-runtime";
1717
+ function runAction(action, data, hide, confirmFn = confirmationAlert) {
1718
+ if (!action.onClick) {
1719
+ if (action.closeOnClick) hide?.();
1720
+ return;
1721
+ }
1722
+ const execute = () => action.onClick?.(data);
1723
+ if (action.confirm) {
1724
+ confirmFn?.(execute, action.confirm);
1725
+ } else {
1726
+ execute();
1727
+ }
1728
+ if (action.closeOnClick) {
1729
+ hide?.();
1730
+ }
1731
+ }
1732
+ function RowActions({
1733
+ actions,
1734
+ data,
1735
+ mode = "menu",
1736
+ actionIcon,
1737
+ className,
1738
+ menuClassName,
1739
+ itemClassName,
1740
+ itemIconClassName,
1741
+ iconSize = ROW_ACTION_DEFAULT_ICON_SIZE,
1742
+ triggerTooltip = "Actions",
1743
+ triggerAriaLabel = "Row actions",
1744
+ hasPermission,
1745
+ placement = "bottom-end",
1746
+ tippyProps,
1747
+ presets,
1748
+ confirmFn = confirmationAlert,
1749
+ tooltipPlacement = "top",
1750
+ tooltipDelayShow,
1751
+ tooltipDelayHide,
1752
+ tooltipClassName,
1753
+ tooltipStyle,
1754
+ renderItem,
1755
+ renderMenu,
1756
+ renderTrigger
1757
+ }) {
1758
+ const resolved = resolveActions(actions, data, hasPermission, presets);
1759
+ if (resolved.length === 0) {
1760
+ return null;
1761
+ }
1762
+ const mergedTooltipStyle = {
1763
+ ...ROW_ACTION_DEFAULT_MENU_TOOLTIP_STYLE,
1764
+ ...tooltipStyle
1765
+ };
1766
+ const renderDefaultItem = (action, hide, showLabel = true) => {
1767
+ if (action.type === "divider") {
1768
+ return /* @__PURE__ */ jsx14(
1769
+ "div",
1770
+ {
1771
+ role: "separator",
1772
+ className: cn("my-1 h-px bg-gray-100", action.className)
1773
+ },
1774
+ action.key
1775
+ );
1776
+ }
1777
+ if (action.content) {
1778
+ return /* @__PURE__ */ jsx14("div", { className: action.className, children: action.content }, action.key);
1779
+ }
1780
+ return /* @__PURE__ */ jsx14(
1781
+ ActionMenuItem,
1782
+ {
1783
+ label: action.label,
1784
+ icon: action.icon,
1785
+ iconSize: action.iconSize ?? iconSize,
1786
+ iconClassName: itemIconClassName,
1787
+ tooltip: action.tooltip,
1788
+ tooltipPlacement: action.tooltipPlacement ?? tooltipPlacement,
1789
+ tooltipDelayShow,
1790
+ tooltipDelayHide,
1791
+ tooltipClassName,
1792
+ tooltipStyle: mergedTooltipStyle,
1793
+ disabled: action.disabled,
1794
+ danger: action.danger,
1795
+ highlight: action.highlight,
1796
+ showLabel,
1797
+ className: cn(itemClassName, action.className),
1798
+ onClick: () => runAction(action, data, hide, confirmFn)
1799
+ },
1800
+ action.key
1801
+ );
1802
+ };
1803
+ const renderItems = (hide, showLabel = true) => resolved.map((action) => {
1804
+ const defaultItem = renderDefaultItem(action, hide, showLabel);
1805
+ if (!renderItem) return defaultItem;
1806
+ return /* @__PURE__ */ jsx14("div", { children: renderItem(action, { data, hide: hide ?? (() => void 0), defaultItem }) }, action.key);
1807
+ });
1808
+ if (mode === "inline") {
1809
+ const inlineItems = renderItems(void 0, false);
1810
+ return /* @__PURE__ */ jsx14("div", { className: cn("flex h-full items-center justify-center gap-1", className), children: inlineItems });
1811
+ }
1812
+ const triggerTooltipText = triggerTooltip === false ? void 0 : triggerTooltip;
1813
+ const buildMenu = (hide) => {
1814
+ const defaultMenu = /* @__PURE__ */ jsx14(
1815
+ "div",
1816
+ {
1817
+ className: cn(
1818
+ "flex min-w-[180px] flex-col rounded-lg border border-gray-100 bg-white p-2 shadow-lg",
1819
+ menuClassName
1820
+ ),
1821
+ children: renderItems(hide, true)
1822
+ }
1823
+ );
1824
+ if (!renderMenu) return defaultMenu;
1825
+ return renderMenu({
1826
+ data,
1827
+ actions: resolved,
1828
+ hide,
1829
+ defaultMenu
1830
+ });
1831
+ };
1832
+ if (renderTrigger) {
1833
+ return /* @__PURE__ */ jsx14(Fragment3, { children: renderTrigger({
1834
+ data,
1835
+ actions: resolved,
1836
+ hide: () => void 0,
1837
+ defaultMenu: buildMenu(() => void 0)
1838
+ }) });
1839
+ }
1840
+ return /* @__PURE__ */ jsx14(
1841
+ ToolTip,
1842
+ {
1843
+ text: triggerTooltipText,
1844
+ disabled: !triggerTooltipText,
1845
+ placement: tooltipPlacement,
1846
+ delayShow: tooltipDelayShow,
1847
+ delayHide: tooltipDelayHide,
1848
+ tooltipClassName,
1849
+ tooltipStyle,
1850
+ className: "flex h-full items-center justify-center",
1851
+ children: /* @__PURE__ */ jsx14(
1852
+ PopupCellRenderer,
1853
+ {
1854
+ params: { data },
1855
+ actionIcon,
1856
+ hideTitle: true,
1857
+ className,
1858
+ placement,
1859
+ tippyProps,
1860
+ ariaLabel: triggerAriaLabel,
1861
+ dropDownContent: (handleAction) => buildMenu(() => handleAction("close"))
1862
+ }
1863
+ )
1864
+ }
1865
+ );
1866
+ }
1867
+
1572
1868
  // src/components/table-error-boundary/TableErrorBoundary.tsx
1573
1869
  import { useMemo as useMemo2 } from "react";
1574
1870
  import { FaArrowsRotate, FaTriangleExclamation } from "react-icons/fa6";
1575
- import { Fragment as Fragment3, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
1871
+ import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
1576
1872
  var TableErrorBoundary = ({
1577
1873
  isError,
1578
1874
  isLoading = false,
@@ -1589,7 +1885,7 @@ var TableErrorBoundary = ({
1589
1885
  return "Unable to load table data. Please try again.";
1590
1886
  }, [error, errorMessage]);
1591
1887
  if (isLoading && !isError) {
1592
- return /* @__PURE__ */ jsx13(
1888
+ return /* @__PURE__ */ jsx15(
1593
1889
  "div",
1594
1890
  {
1595
1891
  className: cn(
@@ -1600,12 +1896,12 @@ var TableErrorBoundary = ({
1600
1896
  role: "status",
1601
1897
  "aria-live": "polite",
1602
1898
  "aria-busy": "true",
1603
- children: /* @__PURE__ */ jsx13(Loader, { size: "40px" })
1899
+ children: /* @__PURE__ */ jsx15(Loader, { size: "40px" })
1604
1900
  }
1605
1901
  );
1606
1902
  }
1607
1903
  if (isError) {
1608
- return /* @__PURE__ */ jsxs10(
1904
+ return /* @__PURE__ */ jsxs11(
1609
1905
  "div",
1610
1906
  {
1611
1907
  className: cn(
@@ -1616,7 +1912,7 @@ var TableErrorBoundary = ({
1616
1912
  role: "alert",
1617
1913
  "aria-live": "assertive",
1618
1914
  children: [
1619
- /* @__PURE__ */ jsx13(
1915
+ /* @__PURE__ */ jsx15(
1620
1916
  FaTriangleExclamation,
1621
1917
  {
1622
1918
  className: "text-red-500",
@@ -1624,11 +1920,11 @@ var TableErrorBoundary = ({
1624
1920
  "aria-hidden": true
1625
1921
  }
1626
1922
  ),
1627
- /* @__PURE__ */ jsxs10("div", { className: "max-w-md space-y-1", children: [
1628
- /* @__PURE__ */ jsx13("p", { className: "text-base font-semibold text-gray-800", children: "Failed to load data" }),
1629
- /* @__PURE__ */ jsx13("p", { className: "text-sm text-gray-600", children: message })
1923
+ /* @__PURE__ */ jsxs11("div", { className: "max-w-md space-y-1", children: [
1924
+ /* @__PURE__ */ jsx15("p", { className: "text-base font-semibold text-gray-800", children: "Failed to load data" }),
1925
+ /* @__PURE__ */ jsx15("p", { className: "text-sm text-gray-600", children: message })
1630
1926
  ] }),
1631
- refetch && /* @__PURE__ */ jsxs10(
1927
+ refetch && /* @__PURE__ */ jsxs11(
1632
1928
  "button",
1633
1929
  {
1634
1930
  type: "button",
@@ -1636,7 +1932,7 @@ var TableErrorBoundary = ({
1636
1932
  disabled: isLoading,
1637
1933
  className: "inline-flex items-center gap-2 rounded-lg bg-primary-150 px-4 py-2 text-sm font-medium text-white transition-colors hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60",
1638
1934
  children: [
1639
- /* @__PURE__ */ jsx13(FaArrowsRotate, { className: cn(isLoading && "animate-spin") }),
1935
+ /* @__PURE__ */ jsx15(FaArrowsRotate, { className: cn(isLoading && "animate-spin") }),
1640
1936
  isLoading ? "Retrying..." : "Try again"
1641
1937
  ]
1642
1938
  }
@@ -1645,7 +1941,7 @@ var TableErrorBoundary = ({
1645
1941
  }
1646
1942
  );
1647
1943
  }
1648
- return /* @__PURE__ */ jsx13(Fragment3, { children });
1944
+ return /* @__PURE__ */ jsx15(Fragment4, { children });
1649
1945
  };
1650
1946
 
1651
1947
  export {
@@ -1664,6 +1960,13 @@ export {
1664
1960
  TooltipText,
1665
1961
  CustomCellEditor,
1666
1962
  PopupCellRenderer,
1963
+ ROW_ACTION_ITEM_HOVER_CLASS,
1964
+ ROW_ACTION_DEFAULT_ICON_SIZE,
1965
+ ROW_ACTION_DEFAULT_MENU_TOOLTIP_STYLE,
1966
+ ROW_ACTION_PRESETS,
1967
+ ActionMenuItem,
1968
+ resolveActions,
1969
+ RowActions,
1667
1970
  TableErrorBoundary
1668
1971
  };
1669
- //# sourceMappingURL=chunk-JATUZDLG.mjs.map
1972
+ //# sourceMappingURL=chunk-KFBKDGZV.mjs.map