@eztrak/shared 0.16.0 → 0.16.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ import {
28
28
  TooltipText,
29
29
  dropdownStyles,
30
30
  resolveActions
31
- } from "../chunk-PE7NNAX6.mjs";
31
+ } from "../chunk-MJWHQ24F.mjs";
32
32
  import "../chunk-EIX5CUQF.mjs";
33
33
  export {
34
34
  ActionMenuItem,
package/dist/index.js CHANGED
@@ -1530,6 +1530,9 @@ var import_react_dom = require("react-dom");
1530
1530
  var import_fa = require("react-icons/fa");
1531
1531
  var import_io5 = require("react-icons/io5");
1532
1532
 
1533
+ // src/components/Loader/Loader.css
1534
+ var import_loader = require("@eztrak/shared/components/loader.css");
1535
+
1533
1536
  // src/components/Loader/Loader.tsx
1534
1537
  var import_jsx_runtime6 = require("react/jsx-runtime");
1535
1538
  var Loader = ({ className, color = "#F54C00", size = "50px", speed = "1s" }) => {
@@ -2002,15 +2005,49 @@ function ToolTip({
2002
2005
 
2003
2006
  // src/components/sidebar/Sidebar.tsx
2004
2007
  var import_jsx_runtime13 = require("react/jsx-runtime");
2008
+ function getItemTooltip(item) {
2009
+ return item.tooltip || item.name;
2010
+ }
2011
+ function getTooltipPlacement(item, collapsed) {
2012
+ return item.tooltipPlacement || (collapsed ? "right" : "top");
2013
+ }
2014
+ function isItemActive(pathname, link) {
2015
+ if (!link || link === "#") return false;
2016
+ return pathname === link || pathname.startsWith(`${link}/`);
2017
+ }
2018
+ function SidebarItemLabel({
2019
+ name,
2020
+ collapsed,
2021
+ className
2022
+ }) {
2023
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2024
+ "span",
2025
+ {
2026
+ className: cn(
2027
+ className,
2028
+ collapsed && "block w-full text-center text-[10px] font-medium leading-tight line-clamp-2 wrap-break-word"
2029
+ ),
2030
+ children: name
2031
+ }
2032
+ );
2033
+ }
2034
+ function SidebarItemIcon({
2035
+ icon,
2036
+ className
2037
+ }) {
2038
+ if (!icon) return null;
2039
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: cn("inline-flex shrink-0", className), "aria-hidden": "true", children: icon });
2040
+ }
2005
2041
  function Sidebar({
2006
2042
  className,
2007
- sideCollapseWidth = "w-20",
2043
+ sideCollapseWidth = "w-24",
2008
2044
  sidebarWidth = "w-48",
2009
2045
  header,
2010
2046
  children,
2011
2047
  footer,
2012
2048
  items = [],
2013
2049
  logoUrl = "",
2050
+ logoRouteUrl = "",
2014
2051
  logoAltText = "Logo",
2015
2052
  collapseButtonText = "\u2B05\uFE0F Collapse",
2016
2053
  expandButtonText = "\u27A1\uFE0F",
@@ -2023,29 +2060,68 @@ function Sidebar({
2023
2060
  }) {
2024
2061
  const location = (0, import_react_router_dom6.useLocation)();
2025
2062
  const [collapsed, setCollapsed] = (0, import_react10.useState)(isCollapsed);
2026
- const [, setActiveLink] = (0, import_react10.useState)(location.pathname);
2027
- const [subItemsCollapsed, setSubItemsCollapsed] = (0, import_react10.useState)({});
2063
+ const [openGroups, setOpenGroups] = (0, import_react10.useState)({});
2064
+ const onCollapseChangeRef = (0, import_react10.useRef)(onCollapseChange);
2065
+ onCollapseChangeRef.current = onCollapseChange;
2028
2066
  (0, import_react10.useEffect)(() => {
2029
- if (onCollapseChange) {
2030
- onCollapseChange(collapsed);
2031
- }
2032
- }, [collapsed, onCollapseChange]);
2067
+ setCollapsed(isCollapsed);
2068
+ }, [isCollapsed]);
2033
2069
  (0, import_react10.useEffect)(() => {
2034
- setActiveLink(location.pathname);
2035
- }, [location]);
2070
+ onCollapseChangeRef.current?.(collapsed);
2071
+ }, [collapsed]);
2036
2072
  const toggleGroup = (group) => {
2037
- setSubItemsCollapsed((prevState) => ({
2073
+ setOpenGroups((prevState) => ({
2038
2074
  ...prevState,
2039
2075
  [group]: !prevState[group]
2040
2076
  }));
2041
2077
  };
2042
- const isActive = (link) => {
2043
- return location.pathname.startsWith(link);
2078
+ const itemLayoutClass = (active, itemClassName) => cn(
2079
+ "flex cursor-pointer",
2080
+ classNames?.navItem,
2081
+ collapsed && "w-full flex-col items-center justify-center gap-0.5 px-1 py-2 my-1 !mx-0 max-w-full min-w-0 box-border text-center min-h-11",
2082
+ active && "active",
2083
+ itemClassName
2084
+ );
2085
+ const renderLink = (item, key) => {
2086
+ const active = isItemActive(location.pathname, item.link);
2087
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "max-w-full min-w-0", "data-sidebar-item": item.name, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2088
+ ToolTip,
2089
+ {
2090
+ text: getItemTooltip(item),
2091
+ placement: getTooltipPlacement(item, collapsed),
2092
+ delayShow: 150,
2093
+ className: "block max-w-full min-w-0",
2094
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2095
+ import_react_router_dom6.Link,
2096
+ {
2097
+ to: item.link || "#",
2098
+ className: itemLayoutClass(active, item.itemClassName),
2099
+ "aria-current": active ? "page" : void 0,
2100
+ children: [
2101
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SidebarItemIcon, { icon: item.icon, className: classNames?.navItemText }),
2102
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2103
+ SidebarItemLabel,
2104
+ {
2105
+ name: item.name,
2106
+ collapsed,
2107
+ className: classNames?.navItemText
2108
+ }
2109
+ )
2110
+ ]
2111
+ }
2112
+ )
2113
+ }
2114
+ ) }, key);
2044
2115
  };
2045
2116
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2046
2117
  "div",
2047
2118
  {
2048
- className: `flex flex-col h-screen overflow-hidden ${collapsed ? `${sideCollapseWidth} justify-center items-center collapsed` : `${sidebarWidth}`} transition-all duration-100 ${className ?? ""}`,
2119
+ className: cn(
2120
+ "flex flex-col h-screen overflow-hidden",
2121
+ collapsed ? `${sideCollapseWidth} items-stretch collapsed` : sidebarWidth,
2122
+ "transition-[width] duration-200 ease-in-out motion-reduce:transition-none",
2123
+ className
2124
+ ),
2049
2125
  ...rest,
2050
2126
  children: [
2051
2127
  logoUrl && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
@@ -2055,134 +2131,205 @@ function Sidebar({
2055
2131
  "flex items-center justify-center h-16 border-b border-gray-300",
2056
2132
  classNames.logoSection
2057
2133
  ),
2058
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: logoUrl, alt: logoAltText, className: "h-10" })
2134
+ children: logoRouteUrl ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2135
+ import_react_router_dom6.Link,
2136
+ {
2137
+ to: logoRouteUrl,
2138
+ className: "sidebar-logo-link inline-flex items-center justify-center",
2139
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: logoUrl, alt: logoAltText, className: "h-10" })
2140
+ }
2141
+ ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: logoUrl, alt: logoAltText, className: "h-10" })
2059
2142
  }
2060
2143
  ),
2061
- header && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center justify-between p-4 border-b border-gray-300", children: header }),
2062
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("nav", { className: cn("flex-grow", classNames.navSection), children: items.map((item, index) => {
2063
- if (item.subItems) {
2064
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2065
- "div",
2066
- {
2067
- className: `my-2 ${item?.subItems && "has-sub-items"}`,
2068
- children: [
2069
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2070
- "div",
2071
- {
2072
- onClick: () => toggleGroup(item.name),
2073
- "data-sidebar-item": item.name,
2074
- "data-tooltip-id": item.name,
2075
- className: `flex cursor-pointer dropdown-title-wrapper ${classNames?.navItem ?? ""}`,
2076
- children: [
2077
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2078
- ToolTip,
2079
- {
2080
- text: item.tooltip || item.name,
2081
- placement: item.tooltipPlacement || "top",
2082
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center space-x-2", children: [
2083
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: classNames?.navItemText, children: item.icon }),
2084
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: classNames?.navItemText, children: item.name })
2085
- ] })
2086
- }
2087
- ),
2088
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2089
- "span",
2090
- {
2091
- className: `transform transition-transform ${subItemsCollapsed[item.name] ? "rotate-180" : "rotate-0"}`,
2092
- children: itemDropdownIcon
2093
- }
2094
- )
2095
- ]
2096
- }
2097
- ),
2098
- subItemsCollapsed[item.name] && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("collapse-btn-wrapper", classNames.subItem), children: item.subItems.map((subItem, subIndex) => {
2099
- if (subItem.component) {
2100
- const SubItemComponent = subItem.component;
2101
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SubItemComponent, {}, `${index}-${subIndex}`);
2102
- }
2103
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2104
- "div",
2105
- {
2106
- className: "w-full",
2107
- "data-sidebar-item": subItem.name,
2108
- "data-tooltip-id": subItem.name,
2109
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2110
- ToolTip,
2111
- {
2112
- text: item.tooltip || item.name,
2113
- placement: item.tooltipPlacement || "top",
2114
- className: "block w-full",
2115
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2116
- import_react_router_dom6.Link,
2117
- {
2118
- to: subItem.link || "#",
2119
- className: `flex ${classNames?.navItem ?? ""} ${isActive(subItem?.link ?? "") ? "active" : ""} ${item?.itemClassName}`,
2120
- onClick: () => subItem.link && setActiveLink(subItem.link || ""),
2121
- title: subItem.tooltip || subItem.name,
2122
- children: [
2123
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2124
- "span",
2125
- {
2126
- className: classNames.navItemText ?? "text-orange-600",
2127
- children: subItem.icon
2128
- }
2144
+ header && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center justify-between p-4 border-b border-gray-300 shrink-0", children: header }),
2145
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2146
+ "nav",
2147
+ {
2148
+ "aria-label": "Sidebar",
2149
+ className: cn(
2150
+ "grow min-h-0 min-w-0 w-full",
2151
+ classNames.navSection
2152
+ ),
2153
+ children: items.map((item, index) => {
2154
+ if (item.subItems) {
2155
+ const groupOpen = Boolean(openGroups[item.name]);
2156
+ const groupId = `sidebar-group-${index}`;
2157
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2158
+ "div",
2159
+ {
2160
+ className: cn(
2161
+ "has-sub-items max-w-full min-w-0 flex flex-col",
2162
+ collapsed ? "my-1" : "my-2"
2163
+ ),
2164
+ children: [
2165
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2166
+ ToolTip,
2167
+ {
2168
+ text: getItemTooltip(item),
2169
+ placement: getTooltipPlacement(item, collapsed),
2170
+ delayShow: 150,
2171
+ className: "flex flex-col w-full max-w-full min-w-0",
2172
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2173
+ "button",
2174
+ {
2175
+ type: "button",
2176
+ onClick: () => toggleGroup(item.name),
2177
+ "data-sidebar-item": item.name,
2178
+ "aria-expanded": groupOpen,
2179
+ "aria-controls": groupId,
2180
+ className: cn(
2181
+ itemLayoutClass(false, item.itemClassName),
2182
+ !collapsed && "dropdown-title-wrapper",
2183
+ "relative appearance-none border-0 bg-transparent [font:inherit]"
2184
+ ),
2185
+ children: [
2186
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2187
+ "span",
2188
+ {
2189
+ className: cn(
2190
+ "flex items-center min-w-0",
2191
+ collapsed ? "flex-col gap-0.5 w-full" : "space-x-2 flex-1"
2192
+ ),
2193
+ children: [
2194
+ collapsed ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "flex w-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
2195
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex w-3 shrink-0", "aria-hidden": "true" }),
2196
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2197
+ SidebarItemIcon,
2198
+ {
2199
+ icon: item.icon,
2200
+ className: classNames?.navItemText
2201
+ }
2202
+ ),
2203
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2204
+ "span",
2205
+ {
2206
+ className: cn(
2207
+ "sidebar-group-caret inline-flex w-3 shrink-0 items-center justify-center text-current [&>svg]:h-3 [&>svg]:w-3 transition-transform duration-200 motion-reduce:transition-none",
2208
+ groupOpen ? "rotate-180" : "rotate-0"
2209
+ ),
2210
+ "aria-hidden": "true",
2211
+ children: itemDropdownIcon
2212
+ }
2213
+ )
2214
+ ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center space-x-2 min-w-0 flex-1", children: [
2215
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2216
+ SidebarItemIcon,
2217
+ {
2218
+ icon: item.icon,
2219
+ className: classNames?.navItemText
2220
+ }
2221
+ ),
2222
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2223
+ SidebarItemLabel,
2224
+ {
2225
+ name: item.name,
2226
+ collapsed: false,
2227
+ className: classNames?.navItemText
2228
+ }
2229
+ )
2230
+ ] }),
2231
+ collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2232
+ SidebarItemLabel,
2233
+ {
2234
+ name: item.name,
2235
+ collapsed: true,
2236
+ className: classNames?.navItemText
2237
+ }
2238
+ )
2239
+ ]
2240
+ }
2241
+ ),
2242
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2243
+ "span",
2244
+ {
2245
+ className: cn(
2246
+ "transform transition-transform duration-200 motion-reduce:transition-none",
2247
+ groupOpen ? "rotate-180" : "rotate-0"
2248
+ ),
2249
+ "aria-hidden": "true",
2250
+ children: itemDropdownIcon
2251
+ }
2252
+ )
2253
+ ]
2254
+ }
2255
+ )
2256
+ }
2257
+ ),
2258
+ groupOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2259
+ "div",
2260
+ {
2261
+ id: groupId,
2262
+ role: "group",
2263
+ "aria-label": item.name,
2264
+ className: cn(
2265
+ collapsed ? "sidebar-sub-panel flex flex-col items-center max-w-full min-w-0 box-border" : "collapse-btn-wrapper",
2266
+ classNames.subItem
2267
+ ),
2268
+ children: item.subItems.map((subItem, subIndex) => {
2269
+ if (subItem.component) {
2270
+ const SubItemComponent = subItem.component;
2271
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2272
+ "div",
2273
+ {
2274
+ className: cn(
2275
+ "min-w-0 max-w-full",
2276
+ collapsed && "flex flex-col items-center text-center"
2129
2277
  ),
2130
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: classNames.navItemText, children: subItem.name })
2131
- ]
2132
- }
2133
- )
2134
- }
2135
- )
2136
- },
2137
- `${index}-${subIndex}`
2138
- );
2139
- }) })
2140
- ]
2141
- },
2142
- index
2143
- );
2278
+ "data-sidebar-item": subItem.name,
2279
+ children: [
2280
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SubItemComponent, {}),
2281
+ collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2282
+ SidebarItemLabel,
2283
+ {
2284
+ name: subItem.name,
2285
+ collapsed: true,
2286
+ className: classNames?.navItemText
2287
+ }
2288
+ )
2289
+ ]
2290
+ },
2291
+ `${index}-${subIndex}`
2292
+ );
2293
+ }
2294
+ return renderLink(subItem, `${index}-${subIndex}`);
2295
+ })
2296
+ }
2297
+ )
2298
+ ]
2299
+ },
2300
+ index
2301
+ );
2302
+ }
2303
+ if (item.component) {
2304
+ const ItemComponent = item.component;
2305
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ItemComponent, {}, index);
2306
+ }
2307
+ return renderLink(item, String(index));
2308
+ })
2144
2309
  }
2145
- if (item.component) {
2146
- const ItemComponent = item.component;
2147
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ItemComponent, {}, index);
2310
+ ),
2311
+ children != null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2312
+ "div",
2313
+ {
2314
+ className: cn(
2315
+ "sidebar-chrome w-full shrink-0",
2316
+ collapsed && "flex flex-col items-center"
2317
+ ),
2318
+ children
2148
2319
  }
2149
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2150
- "div",
2151
- {
2152
- className: "w-full",
2153
- "data-sidebar-item": item.name,
2154
- "data-tooltip-id": item.name,
2155
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2156
- ToolTip,
2157
- {
2158
- text: item.tooltip || item.name,
2159
- placement: item.tooltipPlacement || "top",
2160
- className: "block w-full",
2161
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2162
- import_react_router_dom6.Link,
2163
- {
2164
- to: item.link || "#",
2165
- className: `flex ${classNames?.navItem ?? ""} ${isActive(item.link || "") ? "active" : ""} ${item?.itemClassName}`,
2166
- onClick: () => setActiveLink(item.link || ""),
2167
- title: item.tooltip || item.name,
2168
- children: [
2169
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: classNames.navItemText ?? "text-orange-600", children: item.icon }),
2170
- !collapsed && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: classNames.navItemText, children: item.name })
2171
- ]
2172
- }
2173
- )
2174
- }
2175
- )
2176
- },
2177
- index
2178
- );
2179
- }) }),
2180
- children,
2320
+ ),
2181
2321
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2182
2322
  "button",
2183
2323
  {
2324
+ type: "button",
2184
2325
  onClick: () => setCollapsed(!collapsed),
2185
- className: cn("", classNames.collapseButton) ?? "p-4 border-t border-gray-300",
2326
+ "aria-expanded": !collapsed,
2327
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
2328
+ className: cn(
2329
+ "shrink-0 border-t border-gray-300",
2330
+ classNames.collapseButton,
2331
+ collapsed && "flex items-center justify-center"
2332
+ ),
2186
2333
  children: collapsed ? expandButtonText : collapseButtonText
2187
2334
  }
2188
2335
  ),