pixelize-design-library 2.3.14 → 2.3.16

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.
@@ -12,3 +12,47 @@ Accordion, Breadcrumbs, NavigationBar, SideBar, Header, Drawer, FilterSidebar.
12
12
 
13
13
  - SideBar/Header have sub-`components/` folders
14
14
  - Used by crm-frontend, account-frontend sidebars
15
+
16
+ ## SideBar — responsive overlay (< lg / 992px)
17
+
18
+ At/above `lg` the SideBar is unchanged: inline, sticky, with the collapse/mini-rail
19
+ (`toggle`). Below `lg` it becomes a slide-in **overlay** above the content (it leaves
20
+ layout flow, so content stays full-width — not shrunk):
21
+
22
+ - `mobileOpen?: boolean` + `onMobileClose?: () => void` props drive the overlay. Wire
23
+ `mobileOpen` to the NavigationBar hamburger (`sideBarToggole` / `onSideBarToggole`).
24
+ - Overlay is always expanded (collapse/mini-rail is desktop-only and hidden < lg). The
25
+ header's trailing control becomes a Close (X) instead of the collapse chevron.
26
+ - Dismiss: backdrop scrim click, **Esc**, the Close button, or **swipe-left** on the
27
+ panel. Body scroll is locked while open; panel exposes `role="dialog"`/`aria-modal`.
28
+ - NavigationBar hamburger now shows below `lg` (was `< md`); its panel icon is
29
+ state-aware (`PanelLeftClose` open / `PanelRightClose` closed).
30
+ - The overlay panel has **square edges** (no border radius).
31
+
32
+ Breakpoint, scrim/slide, and z-index are Chakra responsive props (no JS flash) when
33
+ `mobileNav` is off; the breakpoint is read once via `useBreakpointValue({ base: true, lg: false })`.
34
+
35
+ ## SideBar — Hide/Show (mobile navbar on big screens)
36
+
37
+ A footer **Hide/Show** toggle (next to Collapse) switches the navbar *presentation*
38
+ between the docked desktop sidebar and the mobile-style overlay — at **any** width, so
39
+ desktop users can get the full-screen content experience. It is a layout switch, **not**
40
+ a close: toggling never hides the navigation.
41
+
42
+ - `mobileNav?: boolean` forces overlay presentation regardless of breakpoint:
43
+ `overlay = (below lg) || mobileNav`. `onToggleMobileNav?: () => void` backs the
44
+ footer control (render the control only when provided).
45
+ - Footer control: docked → segmented **Collapse | Hide**; desktop mobile-nav overlay →
46
+ **Show** (return to docked). Pure below-`lg` overlay shows no navbar-mode control.
47
+ - Wire so entering mobile-nav also opens the overlay (sidebar stays visible) and leaving
48
+ docks it — see `App.tsx`. NavigationBar `forceSideBarToggle` shows the hamburger at all
49
+ widths while `mobileNav` is on.
50
+ - Selecting a **leaf** menu item in overlay mode auto-closes the overlay (content returns
51
+ to full-screen); submenu **parents** only expand and do not close it.
52
+
53
+ ### Known gaps
54
+
55
+ - `SecondaryBar` keeps its current side-by-side stacking inside the overlay — revisit if
56
+ it feels cramped on very narrow screens.
57
+ - Consumer apps (crm/account/…) must pass `mobileOpen`/`onMobileClose` to adopt overlay
58
+ mode; until then they get the unchanged inline sidebar.
package/dist/App.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAQA,OAAO,cAAc,CAAC;AAyDtB,iBAAS,GAAG,4CAgEX;AAED,eAAe,GAAG,CAAC"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAQA,OAAO,cAAc,CAAC;AAyDtB,iBAAS,GAAG,4CAkFX;AAED,eAAe,GAAG,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { NavbarProps } from "./NavigationBarProps";
2
- export default function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavOnClick, handleLogout, logoutText, navigationBarText, sideBarToggole, onSideBarToggole, }: NavbarProps): import("react/jsx-runtime").JSX.Element;
2
+ export default function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavOnClick, handleLogout, logoutText, navigationBarText, sideBarToggole, onSideBarToggole, forceSideBarToggle, }: NavbarProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=NavigationBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationBar.d.ts","sourceRoot":"","sources":["../../../src/Components/NavigationBar/NavigationBar.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAS9D,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC9B,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,GAChB,EAAE,WAAW,2CAkKb"}
1
+ {"version":3,"file":"NavigationBar.d.ts","sourceRoot":"","sources":["../../../src/Components/NavigationBar/NavigationBar.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAS9D,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC9B,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,kBAA0B,GAC1B,EAAE,WAAW,2CAmKb"}
@@ -5,7 +5,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("@chakra-ui/react");
6
6
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
7
7
  const lucide_react_1 = require("lucide-react");
8
- function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavOnClick, handleLogout, logoutText, navigationBarText, sideBarToggole, onSideBarToggole, }) {
8
+ function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavOnClick, handleLogout, logoutText, navigationBarText, sideBarToggole, onSideBarToggole, forceSideBarToggle = false, }) {
9
9
  var _a, _b, _c, _d;
10
10
  const theme = (0, useCustomTheme_1.useCustomTheme)();
11
11
  // Shared rounded pill affordance for the bar's icon controls.
@@ -35,7 +35,7 @@ function NavBar({ userAvathar, userName, userRole, navMenu, moreIcon, handleNavO
35
35
  _focus: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
36
36
  _active: { bg: theme.colors.primary[50], color: theme.colors.primary[700] },
37
37
  };
38
- return ((0, jsx_runtime_1.jsx)(react_1.Box, { bg: theme.colors.backgroundColor.light, px: 4, borderBottom: "1px solid", borderColor: "blackAlpha.100", children: (0, jsx_runtime_1.jsxs)(react_1.Flex, { h: 16, alignItems: "center", justifyContent: "space-between", children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", gap: 1.5, alignItems: "center", children: [(0, jsx_runtime_1.jsx)(react_1.Box, { onClick: () => onSideBarToggole === null || onSideBarToggole === void 0 ? void 0 : onSideBarToggole(), display: { base: "flex", lg: "none", xl: "none", md: "none" }, ...iconButtonStyle, children: sideBarToggole ? ((0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeftClose, { size: "1.25rem" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.PanelRightClose, { size: "1.25rem" })) }), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) && ((0, jsx_runtime_1.jsx)(react_1.Box, { ...iconButtonStyle, display: "flex", onClick: () => { var _a; return (_a = navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) === null || _a === void 0 ? void 0 : _a.call(navigationBarText); }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CircleArrowLeft, { size: "1.25rem", color: (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b[500] }) })), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text) && ((0, jsx_runtime_1.jsx)(react_1.Text, { color: (_d = (_c = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _c === void 0 ? void 0 : _c.secondary) === null || _d === void 0 ? void 0 : _d[500], fontSize: "1.25rem", fontWeight: 600, fontFamily: "open-sans, sans-serif", letterSpacing: "-0.013rem", children: navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text }))] }), (0, jsx_runtime_1.jsx)(react_1.Flex, { minW: 0, flexShrink: 1, children: (0, jsx_runtime_1.jsxs)(react_1.Stack, { direction: "row", alignItems: "center", spacing: 4, minW: 0, children: [moreIcon && ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", minW: 0, children: moreIcon })), (0, jsx_runtime_1.jsxs)(react_1.Menu, { children: [(0, jsx_runtime_1.jsx)(react_1.MenuButton, { as: react_1.Button, rounded: "full", variant: "link", cursor: "pointer", minW: 0, flexShrink: 0, children: (0, jsx_runtime_1.jsx)(react_1.Avatar, { size: "sm", name: userName, src: userAvathar }) }), (0, jsx_runtime_1.jsx)(react_1.MenuList, { alignItems: "center", zIndex: 5, p: 0, py: "0.375rem", bg: theme.colors.backgroundColor.light, border: "1px solid", borderColor: "blackAlpha.100", borderRadius: "0.75rem", boxShadow: "lg", color: "gray.700", overflow: "hidden", children: (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", flexDirection: "column", maxH: "90vh", children: [(0, jsx_runtime_1.jsx)(react_1.Center, { pt: 4, pb: 2, children: (0, jsx_runtime_1.jsx)(react_1.Avatar, { size: "xl", name: userName, src: userAvathar }) }), (0, jsx_runtime_1.jsxs)(react_1.Center, { flexDirection: "column", gap: "0.125rem", pb: 2, px: 4, children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontWeight: 600, fontSize: "14px", color: "gray.800", isTruncated: true, maxW: "100%", children: userName }), userRole && ((0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "11px", color: "gray.500", isTruncated: true, maxW: "100%", children: userRole }))] }), (0, jsx_runtime_1.jsx)(react_1.MenuDivider, { borderColor: "blackAlpha.100" }), (0, jsx_runtime_1.jsx)(react_1.Box, { flex: 1, overflowY: "auto", children: navMenu === null || navMenu === void 0 ? void 0 : navMenu.map((menu, idx) => {
38
+ return ((0, jsx_runtime_1.jsx)(react_1.Box, { bg: theme.colors.backgroundColor.light, px: 4, borderBottom: "1px solid", borderColor: "blackAlpha.100", children: (0, jsx_runtime_1.jsxs)(react_1.Flex, { h: 16, alignItems: "center", justifyContent: "space-between", children: [(0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", gap: 1.5, alignItems: "center", children: [(0, jsx_runtime_1.jsx)(react_1.Box, { onClick: () => onSideBarToggole === null || onSideBarToggole === void 0 ? void 0 : onSideBarToggole(), display: forceSideBarToggle ? "flex" : { base: "flex", lg: "none" }, "aria-label": sideBarToggole ? "Close navigation menu" : "Open navigation menu", ...iconButtonStyle, children: sideBarToggole ? ((0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeftClose, { size: "1.25rem" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.PanelRightClose, { size: "1.25rem" })) }), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) && ((0, jsx_runtime_1.jsx)(react_1.Box, { ...iconButtonStyle, display: "flex", onClick: () => { var _a; return (_a = navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.onIconClick) === null || _a === void 0 ? void 0 : _a.call(navigationBarText); }, children: (0, jsx_runtime_1.jsx)(lucide_react_1.CircleArrowLeft, { size: "1.25rem", color: (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b[500] }) })), (navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text) && ((0, jsx_runtime_1.jsx)(react_1.Text, { color: (_d = (_c = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _c === void 0 ? void 0 : _c.secondary) === null || _d === void 0 ? void 0 : _d[500], fontSize: "1.25rem", fontWeight: 600, fontFamily: "open-sans, sans-serif", letterSpacing: "-0.013rem", children: navigationBarText === null || navigationBarText === void 0 ? void 0 : navigationBarText.text }))] }), (0, jsx_runtime_1.jsx)(react_1.Flex, { minW: 0, flexShrink: 1, children: (0, jsx_runtime_1.jsxs)(react_1.Stack, { direction: "row", alignItems: "center", spacing: 4, minW: 0, children: [moreIcon && ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", minW: 0, children: moreIcon })), (0, jsx_runtime_1.jsxs)(react_1.Menu, { children: [(0, jsx_runtime_1.jsx)(react_1.MenuButton, { as: react_1.Button, rounded: "full", variant: "link", cursor: "pointer", minW: 0, flexShrink: 0, children: (0, jsx_runtime_1.jsx)(react_1.Avatar, { size: "sm", name: userName, src: userAvathar }) }), (0, jsx_runtime_1.jsx)(react_1.MenuList, { alignItems: "center", zIndex: 5, p: 0, py: "0.375rem", bg: theme.colors.backgroundColor.light, border: "1px solid", borderColor: "blackAlpha.100", borderRadius: "0.75rem", boxShadow: "lg", color: "gray.700", overflow: "hidden", children: (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", flexDirection: "column", maxH: "90vh", children: [(0, jsx_runtime_1.jsx)(react_1.Center, { pt: 4, pb: 2, children: (0, jsx_runtime_1.jsx)(react_1.Avatar, { size: "xl", name: userName, src: userAvathar }) }), (0, jsx_runtime_1.jsxs)(react_1.Center, { flexDirection: "column", gap: "0.125rem", pb: 2, px: 4, children: [(0, jsx_runtime_1.jsx)(react_1.Text, { fontWeight: 600, fontSize: "14px", color: "gray.800", isTruncated: true, maxW: "100%", children: userName }), userRole && ((0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "11px", color: "gray.500", isTruncated: true, maxW: "100%", children: userRole }))] }), (0, jsx_runtime_1.jsx)(react_1.MenuDivider, { borderColor: "blackAlpha.100" }), (0, jsx_runtime_1.jsx)(react_1.Box, { flex: 1, overflowY: "auto", children: navMenu === null || navMenu === void 0 ? void 0 : navMenu.map((menu, idx) => {
39
39
  var _a, _b, _c;
40
40
  return ((0, jsx_runtime_1.jsxs)(react_1.MenuItem, { onClick: () => handleNavOnClick(menu.url), sx: menuItemStyle, children: [menu.icon && ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", flexShrink: 0, sx: { "& svg": { width: "16px", height: "16px" } }, children: menu === null || menu === void 0 ? void 0 : menu.icon })), (0, jsx_runtime_1.jsx)(react_1.Box, { children: menu.title })] }, `${String((_c = (_b = (_a = menu.id) !== null && _a !== void 0 ? _a : menu.url) !== null && _b !== void 0 ? _b : menu.title) !== null && _c !== void 0 ? _c : idx)}-${idx}`));
41
41
  }) }), (0, jsx_runtime_1.jsx)(react_1.MenuDivider, { borderColor: "blackAlpha.100" }), (0, jsx_runtime_1.jsxs)(react_1.MenuItem, { onClick: handleLogout, sx: {
@@ -14,6 +14,13 @@ export type NavbarProps = {
14
14
  };
15
15
  sideBarToggole?: boolean;
16
16
  onSideBarToggole?: () => void;
17
+ /**
18
+ * Force the sidebar hamburger to show at all widths (not just below `lg`).
19
+ * Set this when the sidebar is in "mobile navbar" mode on a big screen, so the
20
+ * hamburger remains available to open the overlay. Defaults to `false`
21
+ * (hamburger shows only below `lg`).
22
+ */
23
+ forceSideBarToggle?: boolean;
17
24
  };
18
25
  export type MenuProps = {
19
26
  id?: string | number;
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationBarProps.d.ts","sourceRoot":"","sources":["../../../src/Components/NavigationBar/NavigationBarProps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE;QAClB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC"}
1
+ {"version":3,"file":"NavigationBarProps.d.ts","sourceRoot":"","sources":["../../../src/Components/NavigationBar/NavigationBarProps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE;QAClB,IAAI,EAAE,SAAS,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;IACF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC"}
@@ -1,3 +1,3 @@
1
1
  import { SidebarProps } from "./SideBarProps";
2
- export default function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick, toggle, changeToggle, logo, companyName, companySubtitle, user, isDisableAddNew, onAddNewClick, selectedSubMenu, selectedSecondaryItem, isLoading, loadingLines, open, otherApps, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
2
+ export default function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick, toggle, changeToggle, logo, companyName, companySubtitle, user, isDisableAddNew, onAddNewClick, selectedSubMenu, selectedSecondaryItem, isLoading, loadingLines, open, otherApps, mobileOpen, onMobileClose, mobileNav, onToggleMobileNav, }: SidebarProps): import("react/jsx-runtime").JSX.Element;
3
3
  //# sourceMappingURL=SideBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SideBar.d.ts","sourceRoot":"","sources":["../../../src/Components/SideBar/SideBar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAe,MAAM,gBAAgB,CAAC;AAkU3D,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,eAAe,EACf,uBAAuB,EACvB,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,eAAe,EACf,IAAI,EACJ,eAAuB,EACvB,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,YAAY,EACZ,IAAW,EACX,SAAS,GACV,EAAE,YAAY,2CAoHd"}
1
+ {"version":3,"file":"SideBar.d.ts","sourceRoot":"","sources":["../../../src/Components/SideBar/SideBar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAe,MAAM,gBAAgB,CAAC;AAuZ3D,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,eAAe,EACf,uBAAuB,EACvB,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,WAAW,EACX,eAAe,EACf,IAAI,EACJ,eAAuB,EACvB,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,YAAY,EACZ,IAAW,EACX,SAAS,EACT,UAAkB,EAClB,aAAa,EACb,SAAiB,EACjB,iBAAiB,GAClB,EAAE,YAAY,2CAsRd"}
@@ -10,23 +10,28 @@ const react_2 = require("@chakra-ui/react");
10
10
  const useCustomTheme_1 = require("../../Theme/useCustomTheme");
11
11
  const Sidebar_1 = require("../../Constants/Sidebar");
12
12
  const lucide_react_1 = require("lucide-react");
13
+ // Overlay stacking — mirrors theme.zIndices (overlay=1300 scrim, modal=1400 panel).
14
+ const Z_SCRIM = 1300;
15
+ const Z_PANEL = 1400;
16
+ // Width of the slide-in overlay panel (a touch wider than the inline 13rem for touch).
17
+ const OVERLAY_WIDTH = "16rem";
13
18
  const MenuItems_1 = __importDefault(require("./components/MenuItems"));
14
19
  const defaultLogo_1 = __importDefault(require("../../Assets/defaultLogo"));
15
20
  const OverflowTooltipText_1 = __importDefault(require("./components/OverflowTooltipText"));
16
21
  const SecondaryBar_1 = __importDefault(require("./SecondaryBar"));
17
22
  const OtherApps_1 = __importDefault(require("./components/OtherApps"));
18
- const SidebarHeader = ({ logo, companyName, companySubtitle, toggle, isLoading, onToggle, }) => {
23
+ const SidebarHeader = ({ logo, companyName, companySubtitle, toggle, isLoading, onToggle, overlay, onClose, }) => {
19
24
  const theme = (0, useCustomTheme_1.useCustomTheme)();
20
25
  if (isLoading) {
21
26
  return ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "100%", px: toggle ? 2 : 4, py: 2, h: Sidebar_1.HEADER_HEIGHT, display: "flex", alignItems: "center", flexShrink: 0, children: toggle ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", gap: 4, justifyContent: "center", w: "100%", children: (0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "28px", h: "28px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }) })) : ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 3, w: "100%", children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "28px", h: "28px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { h: "1.25rem", w: "60%", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" })] })) }));
22
27
  }
23
28
  const logoNode = logo ? ((0, jsx_runtime_1.jsx)(react_2.Image, { borderRadius: "md", boxSize: "1.75rem", src: logo, alt: "Company Logo", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { bg: theme.colors.primary[500], color: theme.colors.white, borderRadius: "md", boxSize: "1.75rem", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, "aria-label": toggle ? "Expand sidebar" : undefined, children: (0, jsx_runtime_1.jsx)(defaultLogo_1.default, {}) }));
24
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { h: Sidebar_1.HEADER_HEIGHT, w: "100%", alignItems: "center", justifyContent: toggle ? "center" : "flex-start", gap: "8px", px: toggle ? "8px" : "10px", borderBottom: "1px solid", borderColor: "whiteAlpha.100", minW: 0, overflow: "hidden", flexShrink: 0, children: [logoNode, !toggle && ((0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, children: [(0, jsx_runtime_1.jsx)(OverflowTooltipText_1.default, { placement: "right", fontWeight: 600, fontSize: "12.5px", textAlign: "left", color: theme.colors.white, lineHeight: "1.3", as: "p", width: "100%", children: companyName !== null && companyName !== void 0 ? companyName : "" }), companySubtitle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "10px", color: "whiteAlpha.500", lineHeight: "1.3", isTruncated: true, children: companySubtitle }))] })), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", onClick: onToggle, "aria-label": "Collapse sidebar", w: "22px", h: "22px", borderRadius: "5px", bg: "whiteAlpha.100", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, _hover: { bg: "whiteAlpha.300" }, transition: "background 0.15s", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 14, color: theme.colors.white, opacity: 0.6 }) }))] }));
29
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { h: Sidebar_1.HEADER_HEIGHT, w: "100%", alignItems: "center", justifyContent: toggle ? "center" : "flex-start", gap: "8px", px: toggle ? "8px" : "10px", borderBottom: "1px solid", borderColor: "whiteAlpha.100", minW: 0, overflow: "hidden", flexShrink: 0, children: [logoNode, !toggle && ((0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, children: [(0, jsx_runtime_1.jsx)(OverflowTooltipText_1.default, { placement: "right", fontWeight: 600, fontSize: "12.5px", textAlign: "left", color: theme.colors.white, lineHeight: "1.3", as: "p", width: "100%", children: companyName !== null && companyName !== void 0 ? companyName : "" }), companySubtitle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "10px", color: "whiteAlpha.500", lineHeight: "1.3", isTruncated: true, children: companySubtitle }))] })), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", onClick: overlay ? onClose : onToggle, "aria-label": overlay ? "Close menu" : "Collapse sidebar", w: "22px", h: "22px", borderRadius: "5px", bg: "whiteAlpha.100", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, _hover: { bg: "whiteAlpha.300" }, transition: "background 0.15s", children: overlay ? ((0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 15, color: theme.colors.white, opacity: 0.7 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronLeft, { size: 14, color: theme.colors.white, opacity: 0.6 })) }))] }));
25
30
  };
26
31
  const SkeletonMenuRow = ({ toggle }) => ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "100%", px: toggle ? 1 : 2, py: 2, children: toggle ? ((0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", gap: 4, justifyContent: "center", children: (0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "24px", h: "24px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }) })) : ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: 3, children: [(0, jsx_runtime_1.jsx)(react_2.Skeleton, { w: "18px", h: "18px", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" }), (0, jsx_runtime_1.jsx)(react_2.Skeleton, { h: "0.875rem", w: "80%", borderRadius: "md", startColor: "gray.600", endColor: "gray.500" })] })) }));
27
- const AddNewButton = ({ toggle, onClick }) => {
32
+ const AddNewButton = ({ toggle, onClick, overlay }) => {
28
33
  const theme = (0, useCustomTheme_1.useCustomTheme)();
29
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { role: "group", alignItems: "center", gap: "9px", px: "10px", py: "7px", borderRadius: "7px", cursor: "pointer", w: "100%", mb: "2px", justifyContent: toggle ? "center" : "flex-start", _hover: { backgroundColor: "whiteAlpha.100" }, transition: "background 0.12s", onClick: onClick, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { w: "18px", h: "18px", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { size: 16, color: theme.colors.primary[300] }) }), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "12.5px", color: "whiteAlpha.900", fontWeight: "medium", children: "Add New" }))] }));
34
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { role: "group", alignItems: "center", gap: "9px", px: "10px", py: overlay ? "11px" : "7px", borderRadius: "7px", cursor: "pointer", w: "100%", mb: "2px", justifyContent: toggle ? "center" : "flex-start", _hover: { backgroundColor: "whiteAlpha.100" }, transition: "background 0.12s", onClick: onClick, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { w: "18px", h: "18px", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { size: 16, color: theme.colors.primary[300] }) }), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "12.5px", color: "whiteAlpha.900", fontWeight: "medium", children: "Add New" }))] }));
30
35
  };
31
36
  const deriveInitials = (user) => {
32
37
  if (user.initials)
@@ -38,19 +43,53 @@ const deriveInitials = (user) => {
38
43
  return parts[0].slice(0, 2).toUpperCase();
39
44
  return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
40
45
  };
41
- const UserFooter = ({ user, toggle }) => {
46
+ const UserFooter = ({ user, toggle, overlay }) => {
42
47
  const theme = (0, useCustomTheme_1.useCustomTheme)();
43
48
  const avatar = user.avatarUrl ? ((0, jsx_runtime_1.jsx)(react_2.Image, { src: user.avatarUrl, alt: user.name, boxSize: "26px", borderRadius: "full", objectFit: "cover", flexShrink: 0 })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { boxSize: "26px", borderRadius: "full", bg: theme.colors.primary.opacity[32], color: theme.colors.primary[300], display: "flex", alignItems: "center", justifyContent: "center", fontSize: "10px", fontWeight: 600, flexShrink: 0, children: deriveInitials(user) }));
44
- return ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "8px 6px", flexShrink: 0, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", onClick: user.onClick, align: "center", gap: "8px", px: "8px", py: "6px", w: "100%", borderRadius: "7px", cursor: "pointer", bg: "transparent", border: "none", justify: toggle ? "center" : "flex-start", _hover: { bg: "whiteAlpha.100" }, transition: "background 0.12s", children: [avatar, !toggle && ((0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, textAlign: "left", children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "11.5px", fontWeight: 500, color: "whiteAlpha.800", isTruncated: true, children: user.name }), user.role && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "10px", color: "whiteAlpha.500", isTruncated: true, children: user.role }))] })), !toggle && (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 14, color: theme.colors.white, opacity: 0.3 })] }) }));
49
+ return ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "8px 6px", flexShrink: 0, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", onClick: user.onClick, align: "center", gap: "8px", px: "8px", py: overlay ? "10px" : "6px", w: "100%", borderRadius: "7px", cursor: "pointer", bg: "transparent", border: "none", justify: toggle ? "center" : "flex-start", _hover: { bg: "whiteAlpha.100" }, transition: "background 0.12s", children: [avatar, !toggle && ((0, jsx_runtime_1.jsxs)(react_2.Box, { flex: "1", minW: 0, textAlign: "left", children: [(0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "11.5px", fontWeight: 500, color: "whiteAlpha.800", isTruncated: true, children: user.name }), user.role && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "10px", color: "whiteAlpha.500", isTruncated: true, children: user.role }))] })), !toggle && (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 14, color: theme.colors.white, opacity: 0.3 })] }) }));
45
50
  };
46
- const CollapseButton = ({ toggle, onToggle }) => {
51
+ // Footer "cell" one segment of the Collapse | Hide/Show control.
52
+ const ControlCell = ({ onClick, label, accent, children }) => {
47
53
  const theme = (0, useCustomTheme_1.useCustomTheme)();
48
- return ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "6px", flexShrink: 0, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { alignItems: "center", justifyContent: "center", gap: "7px", px: "8px", py: "5px", borderRadius: "6px", cursor: "pointer", w: toggle ? "auto" : "100%", mx: toggle ? "auto" : 0, bg: "whiteAlpha.100", onClick: onToggle, _hover: { bg: "whiteAlpha.300" }, transition: "background 0.15s", children: [toggle ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRightToLine, { size: 14, color: theme.colors.white, opacity: 0.6 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeftToLine, { size: 14, color: theme.colors.white, opacity: 0.6 })), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "11.5px", color: "whiteAlpha.700", fontWeight: "medium", children: "Collapse" }))] }) }));
54
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", flex: "1", minW: 0, alignItems: "center", justifyContent: "center", gap: "7px", px: "6px", py: "8px", cursor: "pointer", border: "none", bg: accent ? theme.colors.primary.opacity[16] : "transparent", onClick: onClick, _hover: { bg: accent ? theme.colors.primary.opacity[32] : "whiteAlpha.100" }, transition: "background 0.15s", children: [children, label && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: "11.5px", color: accent ? theme.colors.primary[300] : "whiteAlpha.700", fontWeight: "medium", children: label }))] }));
55
+ };
56
+ // Collapse (mini-rail) sits next to the Hide/Show navbar-mode toggle. In the
57
+ // desktop mobile-nav overlay only "Show" (return to the docked sidebar) is shown;
58
+ // below `lg` (pure responsive overlay) there is no navbar-mode control.
59
+ const FooterControls = ({ toggle, overlay, mobileNav, onToggleCollapse, onToggleMobileNav, }) => {
60
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
61
+ const iconColor = theme.colors.white;
62
+ const shell = (children) => ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "6px", flexShrink: 0, children: (0, jsx_runtime_1.jsx)(react_2.Flex, { display: "flex", gap: "0", borderRadius: "8px", overflow: "hidden", border: "1px solid", borderColor: "whiteAlpha.100", bg: "whiteAlpha.50", sx: { "& > * + *": { borderLeft: "1px solid", borderColor: "whiteAlpha.100" } }, children: children }) }));
63
+ if (overlay) {
64
+ // Pure below-lg overlay (no manual nav-mode switch) → no footer control.
65
+ if (!mobileNav || !onToggleMobileNav)
66
+ return null;
67
+ return shell((0, jsx_runtime_1.jsx)(ControlCell, { onClick: onToggleMobileNav, label: "Show", accent: true, children: (0, jsx_runtime_1.jsx)(lucide_react_1.PanelLeft, { size: 14, color: theme.colors.primary[300] }) }));
68
+ }
69
+ return shell((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ControlCell, { onClick: onToggleCollapse, label: toggle ? undefined : "Collapse", children: toggle ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRightToLine, { size: 14, color: iconColor, opacity: 0.6 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeftToLine, { size: 14, color: iconColor, opacity: 0.6 })) }), onToggleMobileNav && ((0, jsx_runtime_1.jsx)(ControlCell, { onClick: onToggleMobileNav, label: toggle ? undefined : "Hide", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { size: 14, color: iconColor, opacity: 0.6 }) }))] }));
49
70
  };
50
71
  // --- Main Sidebar component ---
51
- function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick, toggle, changeToggle, logo, companyName, companySubtitle, user, isDisableAddNew = false, onAddNewClick, selectedSubMenu, selectedSecondaryItem, isLoading, loadingLines, open = true, otherApps, }) {
52
- var _a;
72
+ function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick, toggle, changeToggle, logo, companyName, companySubtitle, user, isDisableAddNew = false, onAddNewClick, selectedSubMenu, selectedSecondaryItem, isLoading, loadingLines, open = true, otherApps, mobileOpen = false, onMobileClose, mobileNav = false, onToggleMobileNav, }) {
73
+ var _a, _b;
53
74
  const theme = (0, useCustomTheme_1.useCustomTheme)();
75
+ // Below `lg` the sidebar renders as a slide-in overlay above the content; at
76
+ // `lg` and up it is inline (the original behaviour, untouched).
77
+ const belowLg = (_a = (0, react_2.useBreakpointValue)({ base: true, lg: false }, { ssr: false })) !== null && _a !== void 0 ? _a : false;
78
+ // Overlay ("mobile navbar") presentation is active when the viewport is below
79
+ // `lg` OR the Hide/Show toggle has forced it on at any width.
80
+ const overlay = belowLg || mobileNav;
81
+ // In overlay mode the panel is always fully expanded — the mini-rail/collapse
82
+ // is a desktop-only space affordance — so children render as if `toggle=false`.
83
+ const effToggle = overlay ? false : toggle;
84
+ const isOverlayOpen = overlay && mobileOpen;
85
+ // In overlay mode, navigating to a leaf item auto-closes the overlay (content
86
+ // returns to full-screen). Parent items with a submenu only expand, so they
87
+ // must NOT close it.
88
+ const handleMenuClickInternal = (menu) => {
89
+ handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
90
+ if (overlay && !(menu.subMenu && menu.subMenu.length > 0))
91
+ onMobileClose === null || onMobileClose === void 0 ? void 0 : onMobileClose();
92
+ };
54
93
  // Refs let the effects read the latest values without adding them to dep arrays,
55
94
  // which would cause infinite toggle loops since changeToggle flips state.
56
95
  const toggleRef = (0, react_1.useRef)(toggle);
@@ -59,7 +98,7 @@ function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick,
59
98
  changeToggleRef.current = changeToggle;
60
99
  const activeTop = menus.find((m) => String(m.title) === String(activeMenu)) ||
61
100
  menus.find((m) => String(m.id) === String(activeMenu));
62
- const secondaryItems = (_a = activeTop === null || activeTop === void 0 ? void 0 : activeTop.secondaryItems) !== null && _a !== void 0 ? _a : [];
101
+ const secondaryItems = (_b = activeTop === null || activeTop === void 0 ? void 0 : activeTop.secondaryItems) !== null && _b !== void 0 ? _b : [];
63
102
  // Sync toggle with external `open` prop.
64
103
  // `open=false` → collapsed (toggle=true); `open=true` → expanded (toggle=false).
65
104
  (0, react_1.useEffect)(() => {
@@ -74,5 +113,84 @@ function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick,
74
113
  changeToggleRef.current();
75
114
  }
76
115
  }, [secondaryItems.length]);
77
- return ((0, jsx_runtime_1.jsxs)(react_2.Box, { transition: "all 0.5s", position: "sticky", height: "100vh", boxShadow: theme.shadows.lg, display: "flex", background: theme.colors.sidebar.background[500], borderRight: "1px solid", borderColor: "whiteAlpha.100", children: [(0, jsx_runtime_1.jsx)(react_2.Box, { width: toggle ? "4.688rem" : "13rem", transition: "width 0.5s ease", display: "flex", flexDirection: "column", justifyContent: "space-between", children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { flexDir: "column", w: "100%", as: "nav", h: "100vh", children: [(0, jsx_runtime_1.jsx)(SidebarHeader, { logo: logo, companyName: companyName, companySubtitle: companySubtitle, toggle: toggle, isLoading: isLoading, onToggle: changeToggle }), (0, jsx_runtime_1.jsx)(react_2.Box, { id: "sidebar-scroll-container", flex: "1", minH: 0, w: "100%", overflowY: "auto", overflowX: "hidden", p: "8px 6px", css: { ...Sidebar_1.FlexCss, transition: "all 0.3s ease" }, children: isLoading ? (Array.from({ length: loadingLines !== null && loadingLines !== void 0 ? loadingLines : 15 }).map((_, i) => ((0, jsx_runtime_1.jsx)(SkeletonMenuRow, { toggle: toggle }, i)))) : ((0, jsx_runtime_1.jsx)(MenuItems_1.default, { activeMenu: activeMenu, menus: menus, handleMenuClick: handleMenuClick !== null && handleMenuClick !== void 0 ? handleMenuClick : (() => { }), toggle: toggle, selectedSubMenu: selectedSubMenu })) }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flexShrink: 0, children: [!isDisableAddNew && ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "8px 6px", children: (0, jsx_runtime_1.jsx)(AddNewButton, { toggle: toggle, onClick: onAddNewClick }) })), (0, jsx_runtime_1.jsx)(OtherApps_1.default, { toggle: toggle, otherApps: otherApps !== null && otherApps !== void 0 ? otherApps : [] }), user && (0, jsx_runtime_1.jsx)(UserFooter, { user: user, toggle: toggle }), (0, jsx_runtime_1.jsx)(CollapseButton, { toggle: toggle, onToggle: changeToggle })] })] }) }), secondaryItems.length > 0 && ((0, jsx_runtime_1.jsx)(SecondaryBar_1.default, { items: secondaryItems, defaultCollapsed: toggle, collapsedWidth: "3.5rem", expandedWidth: "10rem", selected: selectedSecondaryItem, onItemClick: handleSecondaryNavClick, title: activeTop === null || activeTop === void 0 ? void 0 : activeTop.title, icon: activeTop === null || activeTop === void 0 ? void 0 : activeTop.icon }))] }));
116
+ // Esc closes the overlay.
117
+ (0, react_1.useEffect)(() => {
118
+ if (!isOverlayOpen)
119
+ return;
120
+ const onKey = (e) => {
121
+ if (e.key === "Escape")
122
+ onMobileClose === null || onMobileClose === void 0 ? void 0 : onMobileClose();
123
+ };
124
+ document.addEventListener("keydown", onKey);
125
+ return () => document.removeEventListener("keydown", onKey);
126
+ }, [isOverlayOpen, onMobileClose]);
127
+ // Lock body scroll while the overlay is open.
128
+ (0, react_1.useEffect)(() => {
129
+ if (!isOverlayOpen)
130
+ return;
131
+ const prev = document.body.style.overflow;
132
+ document.body.style.overflow = "hidden";
133
+ return () => {
134
+ document.body.style.overflow = prev;
135
+ };
136
+ }, [isOverlayOpen]);
137
+ // Swipe-left-to-close. Tracks pointer start; commits to a horizontal drag only
138
+ // when the gesture is mostly horizontal, so vertical menu scrolling is unaffected.
139
+ const dragStart = (0, react_1.useRef)(null);
140
+ const [dragX, setDragX] = (0, react_1.useState)(0);
141
+ const [dragging, setDragging] = (0, react_1.useState)(false);
142
+ const onPointerDown = (e) => {
143
+ if (!isOverlayOpen)
144
+ return;
145
+ dragStart.current = { x: e.clientX, y: e.clientY };
146
+ };
147
+ const onPointerMove = (e) => {
148
+ const start = dragStart.current;
149
+ if (!start)
150
+ return;
151
+ const dx = e.clientX - start.x;
152
+ const dy = e.clientY - start.y;
153
+ if (!dragging) {
154
+ if (Math.abs(dy) > Math.abs(dx)) {
155
+ dragStart.current = null; // vertical → let the list scroll
156
+ return;
157
+ }
158
+ if (dx < -6)
159
+ setDragging(true);
160
+ else
161
+ return;
162
+ }
163
+ setDragX(Math.min(0, dx));
164
+ };
165
+ const onPointerUp = (e) => {
166
+ const start = dragStart.current;
167
+ const committed = dragging;
168
+ dragStart.current = null;
169
+ setDragging(false);
170
+ setDragX(0);
171
+ if (committed && start && e.clientX - start.x < -96)
172
+ onMobileClose === null || onMobileClose === void 0 ? void 0 : onMobileClose();
173
+ };
174
+ const baseTransform = dragging
175
+ ? `translateX(${dragX}px)`
176
+ : isOverlayOpen
177
+ ? "translateX(0)"
178
+ : "translateX(-100%)";
179
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Box, { display: mobileNav ? "block" : { base: "block", lg: "none" }, position: "fixed", inset: 0, bg: "blackAlpha.600", zIndex: Z_SCRIM, opacity: isOverlayOpen ? 1 : 0, visibility: isOverlayOpen ? "visible" : "hidden", transition: "opacity 0.28s ease, visibility 0.28s ease", onClick: onMobileClose, "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)(react_2.Box, { position: mobileNav ? "fixed" : { base: "fixed", lg: "sticky" }, top: 0, left: mobileNav ? 0 : { base: 0, lg: "auto" }, bottom: mobileNav ? 0 : { base: 0, lg: "auto" }, zIndex: mobileNav ? Z_PANEL : { base: Z_PANEL, lg: "auto" }, height: "100vh", maxW: mobileNav ? "88vw" : { base: "88vw", lg: "none" }, transform: mobileNav ? baseTransform : { base: baseTransform, lg: "none" }, transition: mobileNav
180
+ ? dragging
181
+ ? "none"
182
+ : "transform 0.28s cubic-bezier(0.22, 1, 0.36, 1)"
183
+ : {
184
+ base: dragging
185
+ ? "none"
186
+ : "transform 0.28s cubic-bezier(0.22, 1, 0.36, 1)",
187
+ lg: "all 0.5s",
188
+ }, borderRadius: 0, boxShadow: mobileNav ? "10px 0 40px rgba(0,0,0,0.45)" : { base: "10px 0 40px rgba(0,0,0,0.45)", lg: theme.shadows.lg }, display: "flex", background: theme.colors.sidebar.background[500], borderRight: "1px solid", borderColor: "whiteAlpha.100", role: overlay ? "dialog" : undefined, "aria-modal": overlay ? true : undefined, "aria-label": overlay ? "Main navigation" : undefined, ...(overlay && !mobileOpen ? { inert: "" } : {}), sx: { touchAction: overlay ? "pan-y" : "auto" }, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerUp, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { width: mobileNav ? OVERLAY_WIDTH : { base: OVERLAY_WIDTH, lg: toggle ? "4.688rem" : "13rem" }, transition: "width 0.5s ease", display: "flex", flexDirection: "column", justifyContent: "space-between", children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { flexDir: "column", w: "100%", as: "nav", h: "100vh", children: [(0, jsx_runtime_1.jsx)(SidebarHeader, { logo: logo, companyName: companyName, companySubtitle: companySubtitle, toggle: effToggle, isLoading: isLoading, onToggle: changeToggle, overlay: overlay, onClose: onMobileClose }), (0, jsx_runtime_1.jsx)(react_2.Box, { id: "sidebar-scroll-container", flex: "1", minH: 0, w: "100%", overflowY: "auto", overflowX: "hidden", p: "8px 6px", css: {
189
+ ...Sidebar_1.FlexCss,
190
+ transition: "all 0.3s ease",
191
+ // (a) larger touch targets for menu rows in overlay mode
192
+ ...(overlay
193
+ ? { "[data-menu-id]": { paddingTop: "10px", paddingBottom: "10px" } }
194
+ : {}),
195
+ }, children: isLoading ? (Array.from({ length: loadingLines !== null && loadingLines !== void 0 ? loadingLines : 15 }).map((_, i) => ((0, jsx_runtime_1.jsx)(SkeletonMenuRow, { toggle: effToggle }, i)))) : ((0, jsx_runtime_1.jsx)(MenuItems_1.default, { activeMenu: activeMenu, menus: menus, handleMenuClick: handleMenuClickInternal, toggle: effToggle, selectedSubMenu: selectedSubMenu })) }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flexShrink: 0, children: [!isDisableAddNew && ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: "whiteAlpha.100", p: "8px 6px", children: (0, jsx_runtime_1.jsx)(AddNewButton, { toggle: effToggle, onClick: onAddNewClick, overlay: overlay }) })), (0, jsx_runtime_1.jsx)(OtherApps_1.default, { toggle: effToggle, otherApps: otherApps !== null && otherApps !== void 0 ? otherApps : [] }), user && (0, jsx_runtime_1.jsx)(UserFooter, { user: user, toggle: effToggle, overlay: overlay }), (0, jsx_runtime_1.jsx)(FooterControls, { toggle: toggle, overlay: overlay, mobileNav: mobileNav, onToggleCollapse: changeToggle, onToggleMobileNav: onToggleMobileNav })] })] }) }), secondaryItems.length > 0 && ((0, jsx_runtime_1.jsx)(SecondaryBar_1.default, { items: secondaryItems, defaultCollapsed: effToggle, collapsedWidth: "3.5rem", expandedWidth: "10rem", selected: selectedSecondaryItem, onItemClick: handleSecondaryNavClick, title: activeTop === null || activeTop === void 0 ? void 0 : activeTop.title, icon: activeTop === null || activeTop === void 0 ? void 0 : activeTop.icon })), overlay && ((0, jsx_runtime_1.jsx)(react_2.Box, { display: mobileOpen ? "block" : "none", position: "absolute", top: "50%", right: "6px", transform: "translateY(-50%)", w: "4px", h: "42px", borderRadius: "full", bg: "whiteAlpha.300", "aria-hidden": "true" }))] })] }));
78
196
  }
@@ -25,6 +25,31 @@ export type SidebarProps = {
25
25
  loadingLines?: number;
26
26
  open?: boolean;
27
27
  otherApps?: OtherAppsProps['otherApps'];
28
+ /**
29
+ * Below the `lg` breakpoint the sidebar renders as a slide-in overlay above
30
+ * the content (it does not occupy layout space). `mobileOpen` controls that
31
+ * overlay's visibility; it has no effect at `lg` and up, where the sidebar is
32
+ * always inline. Wire it to the NavigationBar hamburger (`onSideBarToggole`).
33
+ */
34
+ mobileOpen?: boolean;
35
+ /** Called when the overlay is dismissed (backdrop click, Esc, close button, or swipe). */
36
+ onMobileClose?: () => void;
37
+ /**
38
+ * Forces the "mobile navbar" presentation at ANY width: the sidebar leaves the
39
+ * inline layout and behaves as the slide-in overlay (hamburger + full-screen
40
+ * content), exactly like below `lg` — but on big screens too. This is a layout
41
+ * switch, not a close: toggling it never hides the navigation, it only changes
42
+ * how it is presented. When `false` the breakpoint alone decides (inline at
43
+ * `lg`+, overlay below `lg`).
44
+ */
45
+ mobileNav?: boolean;
46
+ /**
47
+ * Handler for the footer Hide/Show control that flips `mobileNav`. Render the
48
+ * control only when provided. Wire it so entering mobile-nav also opens the
49
+ * overlay (keeps the sidebar visible) and leaving it returns to the docked
50
+ * sidebar — see the playground for the canonical wiring.
51
+ */
52
+ onToggleMobileNav?: () => void;
28
53
  };
29
54
  export type MenuProps = {
30
55
  id: string | number;
@@ -1 +1 @@
1
- {"version":3,"file":"SideBarProps.d.ts","sourceRoot":"","sources":["../../../src/Components/SideBar/SideBarProps.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SideBarProps.d.ts","sourceRoot":"","sources":["../../../src/Components/SideBar/SideBarProps.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.3.14",
3
+ "version": "2.3.16",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",