pixelize-design-library 2.4.2-beta.57 → 2.4.2-beta.59

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.
Files changed (152) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/COMPONENT-GOTCHAS.md +88 -2
  3. package/DESIGN-GUIDE.md +27 -4
  4. package/dist/Components/AppSwitcher/AppSwitcher.js +5 -1
  5. package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +2 -0
  6. package/dist/Components/AppSwitcher/AppSwitcherProps.js +7 -4
  7. package/dist/Components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  8. package/dist/Components/Breadcrumbs/Breadcrumbs.js +33 -10
  9. package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +16 -2
  10. package/dist/Components/Card/Card.d.ts +3 -1
  11. package/dist/Components/Card/Card.js +12 -2
  12. package/dist/Components/Card/CardProps.d.ts +5 -1
  13. package/dist/Components/Commerce/commerceTypes.d.ts +5 -0
  14. package/dist/Components/Editor/Editor.js +50 -2
  15. package/dist/Components/Editor/EditorFieldBar.d.ts +15 -0
  16. package/dist/Components/Editor/EditorFieldBar.js +19 -0
  17. package/dist/Components/Editor/EditorProps.d.ts +74 -1
  18. package/dist/Components/Editor/MakeDynamicDialog.d.ts +12 -0
  19. package/dist/Components/Editor/MakeDynamicDialog.js +59 -0
  20. package/dist/Components/Editor/editorLabels.d.ts +4 -0
  21. package/dist/Components/Editor/editorLabels.js +24 -0
  22. package/dist/Components/Editor/editorTokenStyles.d.ts +28 -0
  23. package/dist/Components/Editor/editorTokenStyles.js +30 -0
  24. package/dist/Components/Editor/editorTokens.d.ts +26 -0
  25. package/dist/Components/Editor/editorTokens.js +134 -0
  26. package/dist/Components/Editor/useEditorBridge.d.ts +40 -0
  27. package/dist/Components/Editor/useEditorBridge.js +141 -0
  28. package/dist/Components/Kbd/Kbd.d.ts +6 -0
  29. package/dist/Components/Kbd/Kbd.js +33 -0
  30. package/dist/Components/Kbd/KbdProps.d.ts +17 -0
  31. package/dist/Components/Kbd/KbdProps.js +2 -0
  32. package/dist/Components/LauncherTrigger/LauncherTrigger.d.ts +4 -0
  33. package/dist/Components/LauncherTrigger/LauncherTrigger.js +41 -0
  34. package/dist/Components/LauncherTrigger/LauncherTriggerProps.d.ts +16 -0
  35. package/dist/Components/LauncherTrigger/LauncherTriggerProps.js +2 -0
  36. package/dist/Components/MediaGallery/MediaGallery.js +1 -1
  37. package/dist/Components/NavLauncher/NavLauncher.d.ts +3 -0
  38. package/dist/Components/NavLauncher/NavLauncher.js +395 -0
  39. package/dist/Components/NavLauncher/NavLauncherProps.d.ts +187 -0
  40. package/dist/Components/NavLauncher/NavLauncherProps.js +2 -0
  41. package/dist/Components/NavLauncher/NewTabLink.d.ts +3 -0
  42. package/dist/Components/NavLauncher/NewTabLink.js +14 -0
  43. package/dist/Components/NavLauncher/PinToggle.d.ts +3 -0
  44. package/dist/Components/NavLauncher/PinToggle.js +21 -0
  45. package/dist/Components/NavLauncher/launcherParts.d.ts +93 -0
  46. package/dist/Components/NavLauncher/launcherParts.js +130 -0
  47. package/dist/Components/NavLauncher/match.d.ts +53 -0
  48. package/dist/Components/NavLauncher/match.js +178 -0
  49. package/dist/Components/NavLauncher/revealStyles.d.ts +4 -0
  50. package/dist/Components/NavLauncher/revealStyles.js +19 -0
  51. package/dist/Components/NavigationBar/NavigationBar.d.ts +1 -1
  52. package/dist/Components/NavigationBar/NavigationBar.js +2 -2
  53. package/dist/Components/NavigationBar/NavigationBarProps.d.ts +2 -0
  54. package/dist/Components/PageHeader/PageHeader.d.ts +1 -1
  55. package/dist/Components/PageHeader/PageHeader.js +9 -2
  56. package/dist/Components/PageHeader/PageHeaderProps.d.ts +8 -0
  57. package/dist/Components/PdfViewer/PdfViewer.d.ts +21 -4
  58. package/dist/Components/PdfViewer/PdfViewer.js +124 -3
  59. package/dist/Components/ProductCard/ProductCard.js +8 -3
  60. package/dist/Components/ProductCard/ProductCardMedia.js +3 -3
  61. package/dist/Components/ProductCard/QuickAddSheet.js +2 -2
  62. package/dist/Components/ProductCard/cardMetrics.d.ts +1 -0
  63. package/dist/Components/ProductCard/cardMetrics.js +3 -2
  64. package/dist/Components/ProductDetails/ProductDetails.d.ts +1 -1
  65. package/dist/Components/ProductDetails/ProductDetails.js +6 -5
  66. package/dist/Components/ProductDetails/ProductDetailsProps.d.ts +2 -0
  67. package/dist/Components/Search/Search.js +2 -1
  68. package/dist/Components/SideBar/SecondaryBar.js +4 -3
  69. package/dist/Components/SideBar/SideBar.d.ts +1 -1
  70. package/dist/Components/SideBar/SideBar.js +30 -9
  71. package/dist/Components/SideBar/SideBarProps.d.ts +32 -0
  72. package/dist/Components/SideBar/components/MenuItemBox.d.ts +6 -0
  73. package/dist/Components/SideBar/components/MenuItemBox.js +8 -4
  74. package/dist/Components/SideBar/components/MenuPopoverContent.js +3 -2
  75. package/dist/Components/SideBar/components/OtherApps.js +2 -1
  76. package/dist/Components/SideBar/components/PinnedSection.d.ts +17 -0
  77. package/dist/Components/SideBar/components/PinnedSection.js +98 -0
  78. package/dist/Components/SideBar/sidebarFocus.d.ts +23 -0
  79. package/dist/Components/SideBar/sidebarFocus.js +20 -0
  80. package/dist/Components/StageProgress/StageProgress.js +2 -2
  81. package/dist/Components/StageProgress/StageProgressProps.d.ts +2 -0
  82. package/dist/Components/StageProgress/StepperStage.js +5 -2
  83. package/dist/Components/WizardDialog/WizardDialog.d.ts +9 -0
  84. package/dist/Components/WizardDialog/WizardDialog.js +102 -0
  85. package/dist/Components/WizardDialog/WizardDialogProps.d.ts +48 -0
  86. package/dist/Components/WizardDialog/WizardDialogProps.js +2 -0
  87. package/dist/Components/WizardDialog/useWizardFlow.d.ts +22 -0
  88. package/dist/Components/WizardDialog/useWizardFlow.js +47 -0
  89. package/dist/Components/WizardDialog/wizardSteps.d.ts +31 -0
  90. package/dist/Components/WizardDialog/wizardSteps.js +40 -0
  91. package/dist/Hooks/useMatchMedia.d.ts +2 -0
  92. package/dist/Hooks/useMatchMedia.js +36 -0
  93. package/dist/Theme/chakra/motion.js +2 -16
  94. package/dist/Utils/price.js +11 -6
  95. package/dist/esm/Components/AppSwitcher/AppSwitcher.js +2 -1
  96. package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +5 -3
  97. package/dist/esm/Components/Breadcrumbs/Breadcrumbs.js +35 -12
  98. package/dist/esm/Components/Card/Card.js +12 -2
  99. package/dist/esm/Components/Editor/Editor.js +48 -3
  100. package/dist/esm/Components/Editor/EditorFieldBar.js +13 -0
  101. package/dist/esm/Components/Editor/MakeDynamicDialog.js +20 -0
  102. package/dist/esm/Components/Editor/editorLabels.js +20 -0
  103. package/dist/esm/Components/Editor/editorTokenStyles.js +25 -0
  104. package/dist/esm/Components/Editor/editorTokens.js +121 -0
  105. package/dist/esm/Components/Editor/useEditorBridge.js +138 -0
  106. package/dist/esm/Components/Kbd/Kbd.js +28 -0
  107. package/dist/esm/Components/Kbd/KbdProps.js +1 -0
  108. package/dist/esm/Components/LauncherTrigger/LauncherTrigger.js +37 -0
  109. package/dist/esm/Components/LauncherTrigger/LauncherTriggerProps.js +1 -0
  110. package/dist/esm/Components/MediaGallery/MediaGallery.js +1 -1
  111. package/dist/esm/Components/NavLauncher/NavLauncher.js +356 -0
  112. package/dist/esm/Components/NavLauncher/NavLauncherProps.js +1 -0
  113. package/dist/esm/Components/NavLauncher/NewTabLink.js +11 -0
  114. package/dist/esm/Components/NavLauncher/PinToggle.js +18 -0
  115. package/dist/esm/Components/NavLauncher/launcherParts.js +110 -0
  116. package/dist/esm/Components/NavLauncher/match.js +172 -0
  117. package/dist/esm/Components/NavLauncher/revealStyles.js +15 -0
  118. package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
  119. package/dist/esm/Components/PageHeader/PageHeader.js +9 -2
  120. package/dist/esm/Components/PdfViewer/PdfViewer.js +123 -2
  121. package/dist/esm/Components/ProductCard/ProductCard.js +9 -4
  122. package/dist/esm/Components/ProductCard/ProductCardMedia.js +3 -3
  123. package/dist/esm/Components/ProductCard/QuickAddSheet.js +2 -2
  124. package/dist/esm/Components/ProductCard/cardMetrics.js +2 -1
  125. package/dist/esm/Components/ProductDetails/ProductDetails.js +6 -5
  126. package/dist/esm/Components/Search/Search.js +3 -2
  127. package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
  128. package/dist/esm/Components/SideBar/SideBar.js +31 -10
  129. package/dist/esm/Components/SideBar/components/MenuItemBox.js +4 -2
  130. package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +3 -2
  131. package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
  132. package/dist/esm/Components/SideBar/components/PinnedSection.js +92 -0
  133. package/dist/esm/Components/SideBar/sidebarFocus.js +15 -0
  134. package/dist/esm/Components/StageProgress/StageProgress.js +2 -2
  135. package/dist/esm/Components/StageProgress/StepperStage.js +5 -2
  136. package/dist/esm/Components/WizardDialog/WizardDialog.js +58 -0
  137. package/dist/esm/Components/WizardDialog/WizardDialogProps.js +1 -0
  138. package/dist/esm/Components/WizardDialog/useWizardFlow.js +44 -0
  139. package/dist/esm/Components/WizardDialog/wizardSteps.js +35 -0
  140. package/dist/esm/Hooks/useMatchMedia.js +32 -0
  141. package/dist/esm/Theme/chakra/motion.js +2 -16
  142. package/dist/esm/Utils/price.js +11 -6
  143. package/dist/esm/index.js +7 -0
  144. package/dist/index.d.ts +19 -4
  145. package/dist/index.js +21 -1
  146. package/package.json +1 -1
  147. package/dist/Components/MediaGallery/useMatchMedia.d.ts +0 -2
  148. package/dist/Components/MediaGallery/useMatchMedia.js +0 -20
  149. package/dist/Components/ProductCard/useMinWidth.d.ts +0 -2
  150. package/dist/Components/ProductCard/useMinWidth.js +0 -20
  151. package/dist/esm/Components/MediaGallery/useMatchMedia.js +0 -16
  152. package/dist/esm/Components/ProductCard/useMinWidth.js +0 -16
@@ -13,6 +13,7 @@ const sidebarId_1 = require("./sidebarId");
13
13
  const Sidebar_1 = require("../../Constants/Sidebar");
14
14
  const overlay_styles_1 = require("../../Theme/chakra/overlay.styles");
15
15
  const motion_1 = require("../../Theme/chakra/motion");
16
+ const sidebarFocus_1 = require("./sidebarFocus");
16
17
  const motion_2 = require("../../Theme/tokens/primitives/motion");
17
18
  const lucide_react_1 = require("lucide-react");
18
19
  // Overlay stacking — mirrors theme.zIndices (overlay=1300 scrim, modal=1400 panel).
@@ -24,6 +25,18 @@ const Z_PANEL = 1400;
24
25
  const RAIL_WIDTH = "4.688rem";
25
26
  const PANEL_EASE = "cubic-bezier(0.22, 1, 0.36, 1)";
26
27
  const EXPANDED_WIDTH = "13rem";
28
+ const COLLAPSE_MS = { ...motion_2.MOTION_MS, slow: 260 };
29
+ const NO_ACTIVE_MENU = "\u0000pinned-active";
30
+ const inlineTransitions = (collapse) => {
31
+ var _a;
32
+ if (collapse === "none")
33
+ return { width: "none", shadow: "none" };
34
+ const ms = COLLAPSE_MS[(_a = collapse.speed) !== null && _a !== void 0 ? _a : "slow"];
35
+ return {
36
+ width: `width ${ms}ms ${PANEL_EASE}`,
37
+ shadow: collapse.animateShadow === false ? "none" : `box-shadow ${ms}ms ${motion_2.MOTION_EASE}`,
38
+ };
39
+ };
27
40
  const OVERLAY_WIDTH = "14.7rem";
28
41
  const FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
29
42
  const MenuItems_1 = __importDefault(require("./components/MenuItems"));
@@ -31,6 +44,7 @@ const defaultLogo_1 = __importDefault(require("../../Assets/defaultLogo"));
31
44
  const OverflowTooltipText_1 = __importDefault(require("./components/OverflowTooltipText"));
32
45
  const SecondaryBar_1 = __importDefault(require("./SecondaryBar"));
33
46
  const OtherApps_1 = __importDefault(require("./components/OtherApps"));
47
+ const PinnedSection_1 = __importDefault(require("./components/PinnedSection"));
34
48
  const sidebarScale_1 = require("./sidebarScale");
35
49
  const viewportHeight_1 = require("../../Theme/tokens/builders/viewportHeight");
36
50
  const SidebarHeader = ({ logo, companyName, companySubtitle, toggle, isLoading, onToggle, overlay, onClose, }) => {
@@ -47,6 +61,7 @@ const SidebarHeader = ({ logo, companyName, companySubtitle, toggle, isLoading,
47
61
  // some brands (zinc), making the tile disappear. See THEME-CONTRACT.md sidebar rules.
48
62
  bg: theme.colors.sidebar.activeBg, color: activeAccent.label, borderRadius: "lg", boxSize: "1.75rem", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", flexShrink: 0, cursor: toggle ? "pointer" : undefined, onClick: toggle ? onToggle : undefined, children: (0, jsx_runtime_1.jsx)(defaultLogo_1.default, {}) }));
49
63
  return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { h: Sidebar_1.HEADER_HEIGHT, w: "100%", alignItems: "center", justifyContent: toggle ? "center" : "flex-start", gap: 2, px: toggle ? "8px" : "10px", borderBottom: "1px solid", borderColor: theme.colors.sidebar.divider, 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: sidebarScale_1.SIDEBAR_CHROME.titleFontSize, 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: sidebarScale_1.SIDEBAR_CHROME.metaFontSize, color: theme.colors.sidebar.mutedLabel, 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: "lg", bg: "whiteAlpha.200", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, position: "relative", _hover: { bg: "whiteAlpha.300" }, transition: "background 0.15s", sx: {
64
+ ...(0, sidebarFocus_1.sidebarFocusStyles)(theme.colors),
50
65
  "&::after": {
51
66
  content: '""',
52
67
  position: "absolute",
@@ -65,7 +80,7 @@ const SkeletonMenuRow = ({ toggle }) => {
65
80
  const AddNewButton = ({ toggle, onClick, overlay }) => {
66
81
  const theme = (0, useCustomTheme_1.useCustomTheme)();
67
82
  const activeAccent = (0, sidebarAccentColors_1.getSidebarActiveAccent)(theme.colors);
68
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", "data-group": "", "aria-label": "Add New", alignItems: "center", gap: "9px", px: "10px", py: overlay ? "11px" : "7px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", mb: "2px", justifyContent: toggle ? "center" : "flex-start", _hover: { backgroundColor: "whiteAlpha.200" }, 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: activeAccent.icon }) }), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, color: theme.colors.white, fontWeight: "medium", children: "Add New" }))] }));
83
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", "data-group": "", "aria-label": "Add New", alignItems: "center", gap: "9px", px: "10px", py: overlay ? "11px" : "7px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", mb: "2px", justifyContent: toggle ? "center" : "flex-start", _hover: { backgroundColor: "whiteAlpha.200" }, transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), 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: activeAccent.icon }) }), !toggle && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, color: theme.colors.white, fontWeight: "medium", children: "Add New" }))] }));
69
84
  };
70
85
  const deriveInitials = (user) => {
71
86
  if (user.initials)
@@ -83,13 +98,13 @@ const UserFooter = ({ user, toggle, overlay }) => {
83
98
  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",
84
99
  // Same rail-safe pairing as the logo tile — primary.opacity[32] was invisible on zinc/skyline.
85
100
  bg: theme.colors.sidebar.activeBg, color: activeAccent.label, display: "flex", alignItems: "center", justifyContent: "center", fontSize: sidebarScale_1.SIDEBAR_CHROME.metaFontSize, fontWeight: 600, flexShrink: 0, children: deriveInitials(user) }));
86
- return ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: theme.colors.sidebar.divider, py: 2, px: "6px", flexShrink: 0, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", onClick: user.onClick, align: "center", gap: 2, px: 2, py: overlay ? "10px" : "6px", w: "100%", borderRadius: "lg", cursor: "pointer", bg: "transparent", border: "none", justify: toggle ? "center" : "flex-start", _hover: { bg: "whiteAlpha.200" }, 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: sidebarScale_1.SIDEBAR_CHROME.labelFontSize, fontWeight: 500, color: theme.colors.white, isTruncated: true, children: user.name }), user.role && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_CHROME.metaFontSize, color: theme.colors.sidebar.mutedLabel, isTruncated: true, children: user.role }))] })), !toggle && (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 14, color: theme.colors.sidebar.mutedIcon })] }) }));
101
+ return ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: theme.colors.sidebar.divider, py: 2, px: "6px", flexShrink: 0, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", onClick: user.onClick, align: "center", gap: 2, px: 2, py: overlay ? "10px" : "6px", w: "100%", borderRadius: "lg", cursor: "pointer", bg: "transparent", border: "none", justify: toggle ? "center" : "flex-start", _hover: { bg: "whiteAlpha.200" }, transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), 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: sidebarScale_1.SIDEBAR_CHROME.labelFontSize, fontWeight: 500, color: theme.colors.white, isTruncated: true, children: user.name }), user.role && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_CHROME.metaFontSize, color: theme.colors.sidebar.mutedLabel, isTruncated: true, children: user.role }))] })), !toggle && (0, jsx_runtime_1.jsx)(lucide_react_1.MoreVertical, { size: 14, color: theme.colors.sidebar.mutedIcon })] }) }));
87
102
  };
88
103
  // Footer "cell" — one segment of the Collapse | Hide/Show control.
89
104
  const ControlCell = ({ onClick, ariaLabel, label, accent, children }) => {
90
105
  const theme = (0, useCustomTheme_1.useCustomTheme)();
91
106
  const activeAccent = (0, sidebarAccentColors_1.getSidebarActiveAccent)(theme.colors);
92
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", "aria-label": ariaLabel, flex: "1", minW: 0, alignItems: "center", justifyContent: "center", gap: "7px", px: "10px", py: "14px", cursor: "pointer", border: "none", bg: accent ? "whiteAlpha.300" : "transparent", onClick: onClick, _hover: { bg: accent ? "whiteAlpha.400" : "whiteAlpha.200" }, transition: "background 0.15s", children: [children, label && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_CHROME.labelFontSize, color: accent ? activeAccent.label : theme.colors.sidebar.mutedLabel, fontWeight: "medium", children: label }))] }));
107
+ return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { as: "button", type: "button", "aria-label": ariaLabel, flex: "1", minW: 0, alignItems: "center", justifyContent: "center", gap: "7px", px: "10px", py: "14px", cursor: "pointer", border: "none", bg: accent ? "whiteAlpha.300" : "transparent", onClick: onClick, _hover: { bg: accent ? "whiteAlpha.400" : "whiteAlpha.200" }, transition: "background 0.15s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), children: [children, label && ((0, jsx_runtime_1.jsx)(react_2.Text, { fontSize: sidebarScale_1.SIDEBAR_CHROME.labelFontSize, color: accent ? activeAccent.label : theme.colors.sidebar.mutedLabel, fontWeight: "medium", children: label }))] }));
93
108
  };
94
109
  // Collapse (mini-rail) sits next to the Hide/Show navbar-mode toggle. In the
95
110
  // desktop mobile-nav overlay only "Show" (return to the docked sidebar) is shown;
@@ -108,7 +123,7 @@ const FooterControls = ({ toggle, overlay, mobileNav, onToggleCollapse, onToggle
108
123
  return shell((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ControlCell, { onClick: onToggleCollapse, ariaLabel: toggle ? "Expand sidebar" : undefined, label: toggle ? undefined : "Collapse", children: toggle ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRightToLine, { size: 14, color: iconColor })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ArrowLeftToLine, { size: 14, color: iconColor })) }), onToggleMobileNav && ((0, jsx_runtime_1.jsx)(ControlCell, { onClick: onToggleMobileNav, ariaLabel: toggle ? "Show sidebar in overlay mode" : undefined, label: toggle ? undefined : "Hide", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Maximize2, { size: 14, color: iconColor }) }))] }));
109
124
  };
110
125
  // --- Main Sidebar component ---
111
- 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, peekOpen = false, onPeekEnd, }) {
126
+ 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, peekOpen = false, onPeekEnd, pinnedItems, pinnedLabel, onUnpin, activePinnedId, pinnedLimit, pinnedLabels, collapseTransition = { speed: "slow" }, autoCollapse = true, }) {
112
127
  var _a, _b;
113
128
  const theme = (0, useCustomTheme_1.useCustomTheme)();
114
129
  const scrollContainerId = (0, sidebarId_1.sanitizeId)((0, react_1.useId)());
@@ -148,20 +163,24 @@ function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick,
148
163
  const activeTop = menus.find((m) => String(m.title) === String(activeMenu)) ||
149
164
  menus.find((m) => String(m.id) === String(activeMenu));
150
165
  const secondaryItems = (_b = activeTop === null || activeTop === void 0 ? void 0 : activeTop.secondaryItems) !== null && _b !== void 0 ? _b : [];
166
+ const inline = inlineTransitions(collapseTransition);
167
+ const pinnedActive = activePinnedId != null && !!(pinnedItems === null || pinnedItems === void 0 ? void 0 : pinnedItems.some((p) => String(p.id) === String(activePinnedId)));
151
168
  // Sync toggle with external `open` prop.
152
169
  // `open=false` → collapsed (toggle=true); `open=true` → expanded (toggle=false).
153
170
  (0, react_1.useEffect)(() => {
171
+ if (!autoCollapse)
172
+ return;
154
173
  const shouldBeCollapsed = !open;
155
174
  if (shouldBeCollapsed !== toggleRef.current) {
156
175
  changeToggleRef.current();
157
176
  }
158
- }, [open]);
177
+ }, [open, autoCollapse]);
159
178
  // Auto-collapse the main sidebar whenever a secondary panel is active.
160
179
  (0, react_1.useEffect)(() => {
161
- if (secondaryItems.length > 0 && !toggleRef.current) {
180
+ if (autoCollapse && secondaryItems.length > 0 && !toggleRef.current) {
162
181
  changeToggleRef.current();
163
182
  }
164
- }, [secondaryItems.length]);
183
+ }, [secondaryItems.length, autoCollapse]);
165
184
  // Esc closes the overlay.
166
185
  (0, react_1.useEffect)(() => {
167
186
  if (!isOverlayOpen)
@@ -263,12 +282,14 @@ function Sidebar({ menus, activeMenu, handleMenuClick, handleSecondaryNavClick,
263
282
  base: dragging
264
283
  ? "none"
265
284
  : "transform 0.28s cubic-bezier(0.22, 1, 0.36, 1)",
266
- lg: (0, motion_2.transitionFor)(["box-shadow"], "base"),
285
+ lg: inline.shadow,
267
286
  }, borderRadius: "none", boxShadow: mobileNav ? theme.shadows["2xl"] : { base: theme.shadows["2xl"], lg: theme.shadows.lg }, display: "flex", background: theme.colors.sidebar.background[500], borderRight: "1px solid", borderColor: theme.colors.sidebar.divider, role: overlay ? "dialog" : undefined, "aria-modal": overlay ? true : undefined, "aria-label": overlay ? "Main navigation" : undefined, ...(overlay && !isOverlayOpen ? { inert: "" } : {}), sx: {
268
287
  ...viewportHeight_1.fullViewportHeight,
269
288
  touchAction: overlay ? "pan-y" : "auto",
270
289
  [motion_1.REDUCED_MOTION_QUERY]: { "&, & *": { transition: "none", animation: "none" } },
271
290
  }, onMouseLeave: overlayPeeking ? onPeekEnd : undefined, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: onPointerUp, onPointerCancel: onPointerUp, children: [(0, jsx_runtime_1.jsx)(react_2.Box, { width: mobileNav
272
291
  ? OVERLAY_WIDTH
273
- : { base: OVERLAY_WIDTH, lg: effToggle ? RAIL_WIDTH : EXPANDED_WIDTH }, transition: `width 0.26s ${PANEL_EASE}`, display: "flex", flexDirection: "column", justifyContent: "space-between", sx: { "@media (prefers-reduced-motion: reduce)": { transition: "none" } }, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { flexDir: "column", w: "100%", as: "nav", "aria-label": "Main navigation", h: "100%", 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: scrollContainerId, flex: "1", minH: 0, w: "100%", overflowY: "auto", overflowX: "hidden", py: 2, px: "6px", sx: (0, Sidebar_1.cssForScrollBar)(theme), 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, overlay: overlay, containerId: scrollContainerId })) }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flexShrink: 0, children: [!isDisableAddNew && ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: theme.colors.sidebar.divider, py: 2, px: "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: effToggle, 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: theme.colors.sidebar.mutedIcon, "aria-hidden": "true" }))] })] }));
292
+ : { base: OVERLAY_WIDTH, lg: effToggle ? RAIL_WIDTH : EXPANDED_WIDTH }, transition: mobileNav
293
+ ? `width 0.26s ${PANEL_EASE}`
294
+ : { base: `width 0.26s ${PANEL_EASE}`, lg: inline.width }, display: "flex", flexDirection: "column", justifyContent: "space-between", sx: { "@media (prefers-reduced-motion: reduce)": { transition: "none" } }, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { flexDir: "column", w: "100%", as: "nav", "aria-label": "Main navigation", h: "100%", 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: scrollContainerId, flex: "1", minH: 0, w: "100%", overflowY: "auto", overflowX: "hidden", py: 2, px: "6px", sx: (0, Sidebar_1.cssForScrollBar)(theme), 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.jsxs)(jsx_runtime_1.Fragment, { children: [pinnedItems && pinnedItems.length > 0 && ((0, jsx_runtime_1.jsx)(PinnedSection_1.default, { items: pinnedItems, label: pinnedLabel, limit: pinnedLimit, toggle: effToggle, overlay: overlay, activeId: activePinnedId, labels: pinnedLabels, onItemClick: handleMenuClickInternal, onUnpin: onUnpin })), (0, jsx_runtime_1.jsx)(MenuItems_1.default, { activeMenu: pinnedActive ? NO_ACTIVE_MENU : activeMenu, menus: menus, handleMenuClick: handleMenuClickInternal, toggle: effToggle, selectedSubMenu: selectedSubMenu, overlay: overlay, containerId: scrollContainerId })] })) }), (0, jsx_runtime_1.jsxs)(react_2.Box, { flexShrink: 0, children: [!isDisableAddNew && ((0, jsx_runtime_1.jsx)(react_2.Box, { borderTop: "1px solid", borderColor: theme.colors.sidebar.divider, py: 2, px: "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: effToggle, 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: theme.colors.sidebar.mutedIcon, "aria-hidden": "true" }))] })] }));
274
295
  }
@@ -47,6 +47,38 @@ export type SidebarProps = {
47
47
  /** Shows the sidebar without pinning — closes on pointer-leave. Wire to NavigationBar's `onSideBarPeek`. */
48
48
  peekOpen?: boolean;
49
49
  onPeekEnd?: () => void;
50
+ /** Rendered above `menus` under a `pinnedLabel` heading; the whole block is omitted when empty. */
51
+ pinnedItems?: SidebarPinnedItem[];
52
+ /** Heading above the pinned block; defaults to "Pinned". */
53
+ pinnedLabel?: string;
54
+ /** Shows an unpin button on row hover/focus (always visible in the overlay); omit for read-only rows. */
55
+ onUnpin?: (item: SidebarPinnedItem) => void;
56
+ /** Matched against pinned ids for the active state; while it matches, the same id in `menus` is not highlighted. */
57
+ activePinnedId?: string | number | null;
58
+ /** Rows shown before the rest collapse behind a "Show N more" row; defaults to 5. */
59
+ pinnedLimit?: number;
60
+ /** Overrides for the pinned block's strings; `{count}` and `{title}` are substituted. */
61
+ pinnedLabels?: SidebarPinnedLabels;
62
+ /** Inline (`lg`+) collapse/expand animation; defaults to `{ speed: "slow" }` (260ms). Overlay slide is unaffected. */
63
+ collapseTransition?: SidebarCollapseTransition;
64
+ /** Defaults to true: a menu with `secondaryItems` (and the `open` prop) call `changeToggle` for you. False: `toggle` alone decides. */
65
+ autoCollapse?: boolean;
66
+ };
67
+ /** One pinned shortcut row; the same fields as a menu item, minus the lock/disabled/submenu states. */
68
+ export type SidebarPinnedItem = Pick<MenuProps, "id" | "title" | "icon" | "url" | "badge">;
69
+ /** Strings for the pinned block; every key is optional and falls back to English. */
70
+ export type SidebarPinnedLabels = {
71
+ /** Default "Show {count} more". */
72
+ showMore?: string;
73
+ /** Default "Show less". */
74
+ showLess?: string;
75
+ /** Default "Unpin {title}". */
76
+ unpin?: string;
77
+ };
78
+ /** `"none"` is instant; otherwise `speed` picks 150/200/260ms and `animateShadow` (default true) toggles the panel shadow. */
79
+ export type SidebarCollapseTransition = "none" | {
80
+ speed?: "fast" | "base" | "slow";
81
+ animateShadow?: boolean;
50
82
  };
51
83
  /** One nav item; `subMenu` renders inline (expand/collapse), `secondaryItems` opens a separate SecondaryBar instead. */
52
84
  export type MenuProps = {
@@ -11,5 +11,11 @@ interface Props {
11
11
  /** Overlay (touch) presentation — rows grow to a 48px touch target instead of the 32px desktop row. */
12
12
  overlay?: boolean;
13
13
  }
14
+ /**
15
+ * These rows are real `<a href>`s now, so the browser's own gestures have to keep working —
16
+ * cmd/ctrl-click for a new tab, shift for a window, middle-click. Only a plain left click is
17
+ * routed through the in-app handler.
18
+ */
19
+ export declare const isBrowserNavigationGesture: (e: React.MouseEvent) => boolean;
14
20
  declare const MenuItemBox: React.FC<Props>;
15
21
  export default MenuItemBox;
@@ -36,6 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isBrowserNavigationGesture = void 0;
39
40
  const jsx_runtime_1 = require("react/jsx-runtime");
40
41
  const react_1 = __importStar(require("react"));
41
42
  const react_2 = require("@chakra-ui/react");
@@ -50,6 +51,7 @@ const paletteFromTheme_1 = require("../../../Theme/chakra/paletteFromTheme");
50
51
  const TextTruncation_1 = __importDefault(require("./TextTruncation"));
51
52
  const sidebarId_1 = require("../sidebarId");
52
53
  const ToolTip_1 = __importDefault(require("../../ToolTip/ToolTip"));
54
+ const sidebarFocus_1 = require("../sidebarFocus");
53
55
  const sidebarScale_1 = require("../sidebarScale");
54
56
  /**
55
57
  * These rows are real `<a href>`s now, so the browser's own gestures have to keep working —
@@ -57,6 +59,7 @@ const sidebarScale_1 = require("../sidebarScale");
57
59
  * routed through the in-app handler.
58
60
  */
59
61
  const isBrowserNavigationGesture = (e) => e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0;
62
+ exports.isBrowserNavigationGesture = isBrowserNavigationGesture;
60
63
  const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle, overlay = false, }) => {
61
64
  var _a, _b, _c, _d, _e;
62
65
  const theme = (0, useCustomTheme_1.useCustomTheme)();
@@ -124,6 +127,7 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
124
127
  cursor: isBlocked ? "not-allowed" : "pointer",
125
128
  opacity: isBlocked ? 0.6 : 1,
126
129
  transition: "background 0.12s",
130
+ sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors),
127
131
  };
128
132
  const buttonContent = ((0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", w: "100%", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", overflow: "hidden", children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { position: "relative", display: "flex", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(react_2.Icon, { as: icon, fontSize: "md", verticalAlign: "middle", color: isAnyActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isAnyActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" }), toggle && (badgeValue != null || hasSubmenuBadge) && ((0, jsx_runtime_1.jsx)(react_2.Box, { position: "absolute", top: "0", right: "0", w: "0.375rem", h: "0.375rem", borderRadius: "full", bg: theme.colors.sidebar.semanticText.error }))] }), !toggle && ((0, jsx_runtime_1.jsx)(TextTruncation_1.default
129
133
  // open={isOpen}
@@ -143,14 +147,14 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
143
147
  if (toggle) {
144
148
  // Collapsed sidebar: show Popover
145
149
  return ((0, jsx_runtime_1.jsxs)(react_2.Popover, { trigger: "hover", placement: "right-start", closeOnBlur: false, isLazy: true, children: [(0, jsx_runtime_1.jsx)(react_2.PopoverTrigger, { children: (0, jsx_runtime_1.jsx)(react_2.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-label": title, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
146
- if (!hasSubMenu && url && isBrowserNavigationGesture(e))
150
+ if (!hasSubMenu && url && (0, exports.isBrowserNavigationGesture)(e))
147
151
  return;
148
152
  e.preventDefault();
149
153
  handleToggleSubMenu(e);
150
154
  }, "data-menu-id": String((_c = menu.id) !== null && _c !== void 0 ? _c : title), children: buttonContent }) }), (0, jsx_runtime_1.jsx)(react_2.Portal, { children: (0, jsx_runtime_1.jsx)(react_2.PopoverContent, { borderRadius: "lg", bg: theme.colors.sidebar.elevated, boxShadow: "lg", minW: "10rem", maxW: "14rem", py: "0.125rem", ml: "-0.5rem", border: 'none', cursor: isBlocked ? "not-allowed" : "pointer", zIndex: 1500, children: (0, jsx_runtime_1.jsx)(react_2.PopoverBody, { p: "0.625rem", color: theme.colors.white, children: (0, jsx_runtime_1.jsx)(MenuPopoverContent_1.default, { menu: menu, handleMenuClick: handleClick, activeMenu: activeMenu }) }) }) })] }));
151
155
  }
152
156
  const row = ((0, jsx_runtime_1.jsx)(react_2.Box, { ...commonStyles, as: rowAs, type: hasSubMenu ? "button" : undefined, href: hasSubMenu ? undefined : url !== null && url !== void 0 ? url : "#", "aria-expanded": hasSubMenu ? !!isOpen : undefined, "aria-controls": hasSubMenu ? submenuPanelId : undefined, "aria-current": isAnyActive ? "page" : undefined, "aria-disabled": isBlocked ? true : undefined, onClick: (e) => {
153
- if (!hasSubMenu && url && isBrowserNavigationGesture(e))
157
+ if (!hasSubMenu && url && (0, exports.isBrowserNavigationGesture)(e))
154
158
  return;
155
159
  e.preventDefault();
156
160
  handleToggleSubMenu(e);
@@ -171,12 +175,12 @@ const MenuItemBox = ({ menu, activeMenu, toggle, handleClick, isOpen, onToggle,
171
175
  ? "whiteAlpha.400"
172
176
  : "whiteAlpha.200",
173
177
  }, opacity: isSubBlocked ? 0.6 : 1, cursor: isSubBlocked ? "not-allowed" : "pointer", pointerEvents: isSubBlocked ? "none" : "auto", onClick: (e) => {
174
- if (sub.url && isBrowserNavigationGesture(e))
178
+ if (sub.url && (0, exports.isBrowserNavigationGesture)(e))
175
179
  return;
176
180
  e.preventDefault();
177
181
  if (!isSubBlocked)
178
182
  handleClick === null || handleClick === void 0 ? void 0 : handleClick(sub);
179
- }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, transition: "background 0.12s", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? ((0, jsx_runtime_1.jsx)(react_2.Icon, { as: sub.icon, fontSize: sidebarScale_1.SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, lineHeight: "1", color: isSubActive ? activeAccent.label : theme.colors.sidebar.mutedLabel, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? ((0, jsx_runtime_1.jsx)(react_2.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
183
+ }, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? ((0, jsx_runtime_1.jsx)(react_2.Icon, { as: sub.icon, fontSize: sidebarScale_1.SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : ((0, jsx_runtime_1.jsx)(react_2.Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, lineHeight: "1", color: isSubActive ? activeAccent.label : theme.colors.sidebar.mutedLabel, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? ((0, jsx_runtime_1.jsx)(react_2.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon })) : (() => {
180
184
  var _a, _b, _c, _d;
181
185
  const subCfg = typeof sub.badge === "object" && sub.badge !== null
182
186
  ? sub.badge
@@ -14,6 +14,7 @@ const sidebarAccent_1 = require("../../../Theme/tokens/builders/sidebarAccent");
14
14
  const paletteFromTheme_1 = require("../../../Theme/chakra/paletteFromTheme");
15
15
  const TextTruncation_1 = __importDefault(require("./TextTruncation"));
16
16
  const ToolTip_1 = __importDefault(require("../../ToolTip/ToolTip"));
17
+ const sidebarFocus_1 = require("../sidebarFocus");
17
18
  const sidebarScale_1 = require("../sidebarScale");
18
19
  const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
19
20
  var _a;
@@ -31,7 +32,7 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
31
32
  if (!isBlocked)
32
33
  handleMenuClick === null || handleMenuClick === void 0 ? void 0 : handleMenuClick(menu);
33
34
  }
34
- }, cursor: !hasSubMenu ? (isBlocked ? "not-allowed" : "pointer") : "default", "aria-disabled": !hasSubMenu && isBlocked ? true : undefined, children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: icon, fontSize: "md", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontWeight: 600, fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, flex: "1", color: theme.colors.white, children: title }), (() => {
35
+ }, cursor: !hasSubMenu ? (isBlocked ? "not-allowed" : "pointer") : "default", "aria-disabled": !hasSubMenu && isBlocked ? true : undefined, sx: hasSubMenu ? undefined : (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors, theme.colors.sidebar.elevated), children: [(0, jsx_runtime_1.jsx)(react_1.Icon, { as: icon, fontSize: "md", flexShrink: 0, color: !hasSubMenu && isParentActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon }), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontWeight: 600, fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, flex: "1", color: theme.colors.white, children: title }), (() => {
35
36
  var _a, _b, _c, _d;
36
37
  const cfg = typeof badge === "object" && badge !== null
37
38
  ? badge
@@ -55,7 +56,7 @@ const MenuPopoverContent = ({ menu, handleMenuClick, activeMenu, }) => {
55
56
  }, px: 2, h: sidebarScale_1.SIDEBAR_ROW.subHeight, mb: "2px", borderRadius: "lg", align: "center", justify: "space-between", gap: 2, borderLeft: "2px solid", borderLeftColor: isSubActive ? theme.colors.sidebar.activeIcon : "transparent", bg: isSubActive ? "whiteAlpha.300" : "transparent", _hover: {
56
57
  bg: isSubBlocked ? "transparent" : isSubActive ? "whiteAlpha.400" : "whiteAlpha.200",
57
58
  cursor: !isSubBlocked ? "pointer" : "not-allowed",
58
- }, opacity: isSubBlocked ? 0.5 : 1, pointerEvents: isSubBlocked ? "none" : "auto", transition: "background 0.12s", children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: sub.icon, fontSize: sidebarScale_1.SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : ((0, jsx_runtime_1.jsx)(react_1.Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (sub.lockedReason ? ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: sub.lockedReason, placement: "top", children: (0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon }) })) : ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon }))) : (() => {
59
+ }, opacity: isSubBlocked ? 0.5 : 1, pointerEvents: isSubBlocked ? "none" : "auto", transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors, theme.colors.sidebar.elevated), children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: "1", children: [sub.icon ? ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: sub.icon, fontSize: sidebarScale_1.SIDEBAR_ROW.iconSize, flexShrink: 0, color: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" })) : ((0, jsx_runtime_1.jsx)(react_1.Box, { w: "5px", h: "5px", borderRadius: "full", flexShrink: 0, bg: isSubActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isSubActive ? undefined : { bg: theme.colors.white }, transition: "background 0.12s" })), (0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, fontWeight: isSubActive ? 600 : 500, flex: 1, color: isSubActive ? activeAccent.label : theme.colors.white, _groupHover: isSubActive ? undefined : { color: theme.colors.white }, children: sub.title })] }), sub.locked ? (sub.lockedReason ? ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: sub.lockedReason, placement: "top", children: (0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon }) })) : ((0, jsx_runtime_1.jsx)(react_1.Icon, { as: lucide_react_1.LockKeyhole, fontSize: "md", color: theme.colors.sidebar.mutedIcon }))) : (() => {
59
60
  var _a, _b, _c, _d;
60
61
  const cfg = typeof sub.badge === "object" && sub.badge !== null
61
62
  ? sub.badge
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const jsx_runtime_1 = require("react/jsx-runtime");
4
4
  const react_1 = require("@chakra-ui/react");
5
5
  const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
6
+ const sidebarFocus_1 = require("../sidebarFocus");
6
7
  const OtherApps = ({ toggle, otherApps }) => {
7
8
  const theme = (0, useCustomTheme_1.useCustomTheme)();
8
9
  if (!otherApps || otherApps.length === 0)
@@ -12,7 +13,7 @@ const OtherApps = ({ toggle, otherApps }) => {
12
13
  return ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "center", color: theme.colors.sidebar.mutedIcon, fontSize: "15px", flexShrink: 0, children: (_a = app.icon) !== null && _a !== void 0 ? _a : ((0, jsx_runtime_1.jsx)(react_1.Box, { w: "0.5rem", h: "0.5rem", borderRadius: "full", bg: app.color, boxShadow: `0 0 5px ${app.color}`, flexShrink: 0 })) }));
13
14
  };
14
15
  // Grid cell: icon on top, truncated label below (label hidden when collapsed).
15
- const appCell = (app) => ((0, jsx_runtime_1.jsxs)(react_1.Flex, { as: "button", type: "button", direction: "column", align: "center", justify: "center", gap: "3px", px: "2px", py: "6px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", _hover: { backgroundColor: "whiteAlpha.200" }, transition: "background 0.12s", onClick: app.onClick, children: [appIcon(app), !toggle && ((0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "9.5px", color: theme.colors.sidebar.mutedLabel, textAlign: "center", maxW: "44px", isTruncated: true, children: app.name }))] }));
16
+ const appCell = (app) => ((0, jsx_runtime_1.jsxs)(react_1.Flex, { as: "button", type: "button", direction: "column", align: "center", justify: "center", gap: "3px", px: "2px", py: "6px", borderRadius: "lg", cursor: "pointer", border: "none", bg: "transparent", w: "100%", _hover: { backgroundColor: "whiteAlpha.200" }, transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), onClick: app.onClick, children: [appIcon(app), !toggle && ((0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "9.5px", color: theme.colors.sidebar.mutedLabel, textAlign: "center", maxW: "44px", isTruncated: true, children: app.name }))] }));
16
17
  const flyoutBody = (app) => {
17
18
  var _a;
18
19
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.Flex, { alignItems: "center", gap: 2, mb: 1, onClick: app.onClick, children: [(_a = app.icon) !== null && _a !== void 0 ? _a : ((0, jsx_runtime_1.jsx)(react_1.Box, { w: "0.5rem", h: "0.5rem", borderRadius: "full", bg: app.color, boxShadow: `0 0 5px ${app.color}`, flexShrink: 0 })), (0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "sm", fontWeight: 700, color: theme.colors.white, children: app.name })] }), app.description && ((0, jsx_runtime_1.jsx)(react_1.Text, { fontSize: "xs", color: theme.colors.sidebar.mutedLabel, children: app.description }))] }));
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import type { SidebarPinnedItem, SidebarPinnedLabels } from "../SideBarProps";
3
+ export declare const DEFAULT_PINNED_LABEL = "Pinned";
4
+ export declare const DEFAULT_PINNED_LIMIT = 5;
5
+ type PinnedSectionProps = {
6
+ items: SidebarPinnedItem[];
7
+ label?: string;
8
+ limit?: number;
9
+ toggle: boolean;
10
+ overlay: boolean;
11
+ activeId?: string | number | null;
12
+ labels?: SidebarPinnedLabels;
13
+ onItemClick: (item: SidebarPinnedItem) => void;
14
+ onUnpin?: (item: SidebarPinnedItem) => void;
15
+ };
16
+ declare const PinnedSection: React.FC<PinnedSectionProps>;
17
+ export default PinnedSection;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_PINNED_LIMIT = exports.DEFAULT_PINNED_LABEL = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const react_2 = require("@chakra-ui/react");
10
+ const lucide_react_1 = require("lucide-react");
11
+ const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
12
+ const sidebarFocus_1 = require("../sidebarFocus");
13
+ const tone_1 = require("../../../Theme/tokens/builders/tone");
14
+ const sidebarAccent_1 = require("../../../Theme/tokens/builders/sidebarAccent");
15
+ const paletteFromTheme_1 = require("../../../Theme/chakra/paletteFromTheme");
16
+ const sidebarAccentColors_1 = require("../sidebarAccentColors");
17
+ const sidebarId_1 = require("../sidebarId");
18
+ const sidebarScale_1 = require("../sidebarScale");
19
+ const ToolTip_1 = __importDefault(require("../../ToolTip/ToolTip"));
20
+ const TextTruncation_1 = __importDefault(require("./TextTruncation"));
21
+ const MenuItemBox_1 = require("./MenuItemBox");
22
+ exports.DEFAULT_PINNED_LABEL = "Pinned";
23
+ exports.DEFAULT_PINNED_LIMIT = 5;
24
+ const DEFAULT_LABELS = {
25
+ showMore: "Show {count} more",
26
+ showLess: "Show less",
27
+ unpin: "Unpin {title}",
28
+ };
29
+ const UNPIN_SIZE = "24px";
30
+ const LADDER = { hover: "whiteAlpha.200", active: "whiteAlpha.300", activeHover: "whiteAlpha.400" };
31
+ const VISUALLY_HIDDEN = {
32
+ position: "absolute",
33
+ width: "1px",
34
+ height: "1px",
35
+ padding: 0,
36
+ margin: "-1px",
37
+ clip: "rect(0, 0, 0, 0)",
38
+ whiteSpace: "nowrap",
39
+ border: 0,
40
+ };
41
+ const readBadge = (badge) => {
42
+ var _a;
43
+ const cfg = typeof badge === "object" && badge !== null ? badge : null;
44
+ const value = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.count) !== null && _a !== void 0 ? _a : (typeof badge !== "object" ? badge : undefined);
45
+ return { cfg, value };
46
+ };
47
+ const PinnedSection = ({ items, label = exports.DEFAULT_PINNED_LABEL, limit = exports.DEFAULT_PINNED_LIMIT, toggle, overlay, activeId, labels, onItemClick, onUnpin, }) => {
48
+ const theme = (0, useCustomTheme_1.useCustomTheme)();
49
+ const activeAccent = (0, sidebarAccentColors_1.getSidebarActiveAccent)(theme.colors);
50
+ const text = { ...DEFAULT_LABELS, ...labels };
51
+ const headingId = `pinned-${(0, sidebarId_1.sanitizeId)((0, react_1.useId)())}`;
52
+ const cap = Math.max(1, limit);
53
+ const rowHeight = overlay ? sidebarScale_1.SIDEBAR_ROW.overlayHeight : sidebarScale_1.SIDEBAR_ROW.height;
54
+ const activeIndex = activeId == null ? -1 : items.findIndex((i) => String(i.id) === String(activeId));
55
+ const [showAll, setShowAll] = (0, react_1.useState)(activeIndex >= cap);
56
+ (0, react_1.useEffect)(() => {
57
+ if (activeIndex >= cap)
58
+ setShowAll(true);
59
+ }, [activeIndex, cap]);
60
+ if (items.length === 0)
61
+ return null;
62
+ const hiddenCount = Math.max(0, items.length - cap);
63
+ const visible = showAll ? items : items.slice(0, cap);
64
+ const badgeSurface = (0, sidebarAccent_1.sidebarRowPeak)(theme.colors.sidebar.background[500]);
65
+ const unpinReplacesBadge = !!onUnpin && !overlay;
66
+ const renderBadge = (badge) => {
67
+ var _a, _b, _c;
68
+ const { cfg, value } = readBadge(badge);
69
+ if (value == null)
70
+ return null;
71
+ const tone = (0, tone_1.resolveSoftTone)(theme.colors, (0, paletteFromTheme_1.scaleFor)(theme.colors, (_a = cfg === null || cfg === void 0 ? void 0 : cfg.color) !== null && _a !== void 0 ? _a : "teal"), badgeSurface);
72
+ return ((0, jsx_runtime_1.jsx)(react_2.Badge, { bg: tone.bg, color: tone.fg, fontSize: "xs", variant: (_b = cfg === null || cfg === void 0 ? void 0 : cfg.variant) !== null && _b !== void 0 ? _b : "subtle", borderRadius: (_c = cfg === null || cfg === void 0 ? void 0 : cfg.radius) !== null && _c !== void 0 ? _c : "full", ...(unpinReplacesBadge
73
+ ? { _groupHover: { opacity: 0 }, _groupFocusWithin: { opacity: 0 } }
74
+ : {}), children: value }));
75
+ };
76
+ const renderRow = (item) => {
77
+ const isActive = activeIndex >= 0 && String(item.id) === String(activeId);
78
+ const anchor = ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "a", href: item.url, "data-group": "", "data-pinned-id": String(item.id), "aria-label": toggle ? item.title : undefined, "aria-current": isActive ? "page" : undefined, display: "flex", alignItems: "center", textAlign: "left", textDecoration: "none", w: "100%", h: rowHeight, borderRadius: "lg", pl: "10px", pr: !toggle && onUnpin ? `calc(10px + ${UNPIN_SIZE})` : "10px", fontWeight: "medium", borderLeft: "2px solid", borderLeftColor: isActive ? theme.colors.sidebar.activeIcon : "transparent", backgroundColor: isActive ? LADDER.active : "transparent", color: theme.colors.sidebar.mutedIcon, _hover: { backgroundColor: isActive ? LADDER.activeHover : LADDER.hover }, cursor: "pointer", transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), onClick: (e) => {
79
+ if (item.url && (0, MenuItemBox_1.isBrowserNavigationGesture)(e))
80
+ return;
81
+ e.preventDefault();
82
+ onItemClick(item);
83
+ }, children: (0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", justify: toggle ? "center" : "space-between", w: "100%", children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", gap: "9px", overflow: "hidden", flex: toggle ? undefined : 1, minW: 0, children: [(0, jsx_runtime_1.jsxs)(react_2.Box, { position: "relative", display: "flex", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(react_2.Icon, { as: item.icon, fontSize: "md", color: isActive ? activeAccent.icon : theme.colors.sidebar.mutedIcon, _groupHover: isActive ? undefined : { color: theme.colors.white }, transition: "color 0.12s" }), toggle && readBadge(item.badge).value != null && ((0, jsx_runtime_1.jsx)(react_2.Box, { position: "absolute", top: "0", right: "0", w: "0.375rem", h: "0.375rem", borderRadius: "full", bg: theme.colors.sidebar.semanticText.error }))] }), !toggle && ((0, jsx_runtime_1.jsx)(TextTruncation_1.default, { fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, lineHeight: "1", flex: "1", color: isActive ? activeAccent.label : theme.colors.white, fontWeight: isActive ? 600 : 500, _groupHover: isActive ? undefined : { color: theme.colors.white }, children: item.title }))] }), !toggle && renderBadge(item.badge)] }) }));
84
+ return ((0, jsx_runtime_1.jsxs)(react_2.Box, { as: "li", listStyleType: "none", position: "relative", "data-group": "", children: [toggle ? ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: item.title, placement: "right", children: anchor })) : (anchor), onUnpin && !toggle && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "button", type: "button", "aria-label": text.unpin.replace("{title}", item.title), onClick: () => onUnpin(item), position: "absolute", top: "50%", right: "6px", transform: "translateY(-50%)", w: UNPIN_SIZE, h: UNPIN_SIZE, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "lg", border: "none", bg: "transparent", cursor: "pointer", color: theme.colors.sidebar.mutedIcon, opacity: overlay ? 1 : 0, _groupHover: { opacity: 1 }, _groupFocusWithin: { opacity: 1 }, _hover: {
85
+ bg: LADDER.active,
86
+ color: theme.colors.white,
87
+ }, transition: "opacity 0.12s, background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), children: (0, jsx_runtime_1.jsx)(react_2.Icon, { as: lucide_react_1.PinOff, fontSize: "sm" }) }))] }, String(item.id)));
88
+ };
89
+ const disclosureLabel = showAll
90
+ ? text.showLess
91
+ : text.showMore.replace("{count}", String(hiddenCount));
92
+ const disclosureButton = ((0, jsx_runtime_1.jsxs)(react_2.Box, { as: "button", type: "button", "aria-expanded": showAll, "aria-label": toggle ? disclosureLabel : undefined, onClick: () => setShowAll((v) => !v), display: "flex", alignItems: "center", justifyContent: toggle ? "center" : "flex-start", gap: "9px", w: "100%", h: rowHeight, px: "10px", borderRadius: "lg", border: "none", borderLeft: "2px solid transparent", bg: "transparent", cursor: "pointer", color: theme.colors.sidebar.mutedLabel, fontSize: sidebarScale_1.SIDEBAR_ROW.fontSize, fontWeight: "medium", _hover: {
93
+ backgroundColor: LADDER.hover,
94
+ color: theme.colors.white,
95
+ }, transition: "background 0.12s", sx: (0, sidebarFocus_1.sidebarFocusStyles)(theme.colors), children: [(0, jsx_runtime_1.jsx)(react_2.Icon, { as: showAll ? lucide_react_1.ChevronUp : lucide_react_1.ChevronDown, fontSize: "md", flexShrink: 0 }), !toggle && (0, jsx_runtime_1.jsx)("span", { children: disclosureLabel })] }));
96
+ return ((0, jsx_runtime_1.jsxs)(react_2.Box, { mb: toggle ? "5px" : "3px", "data-testid": "sidebar-pinned", children: [(0, jsx_runtime_1.jsx)(react_2.Box, { id: headingId, as: "h2", px: "10px", pt: overlay ? "6px" : "10px", pb: "3px", fontSize: "9.5px", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.1em", color: theme.colors.sidebar.mutedLabel, whiteSpace: "nowrap", overflow: "hidden", sx: toggle ? VISUALLY_HIDDEN : undefined, children: label }), (0, jsx_runtime_1.jsxs)(react_2.Box, { as: "ul", "aria-labelledby": headingId, display: "flex", flexDirection: "column", gap: "2px", m: 0, p: 0, children: [visible.map(renderRow), hiddenCount > 0 && ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "li", listStyleType: "none", children: toggle ? ((0, jsx_runtime_1.jsx)(ToolTip_1.default, { label: disclosureLabel, placement: "right", children: disclosureButton })) : (disclosureButton) }))] }), (0, jsx_runtime_1.jsx)(react_2.Box, { h: "1px", bg: theme.colors.sidebar.divider, mx: 2, mt: overlay ? "6px" : "8px", mb: overlay ? "3px" : "5px" })] }));
97
+ };
98
+ exports.default = PinnedSection;
@@ -0,0 +1,23 @@
1
+ import type { PaletteProps } from "../../Theme/tokens/types";
2
+ type RailColors = Pick<PaletteProps, "focusRing" | "sidebar">;
3
+ /** The ring is derived for the canvas; the rail is near-black in both modes, so it is re-settled against the rail. */
4
+ export declare const sidebarFocusRing: (colors: RailColors, surface?: string) => {
5
+ focusRing: {
6
+ ring: string;
7
+ halo: string;
8
+ };
9
+ };
10
+ /** `focusVisibleStyles` for a control sitting on the rail (or on `surface`, e.g. the flyout). */
11
+ export declare const sidebarFocusStyles: (colors: RailColors, surface?: string) => {
12
+ _focusVisible: {
13
+ outline: string;
14
+ outlineOffset: string;
15
+ boxShadow: string;
16
+ };
17
+ "&:hover:focus-visible, &:active:focus-visible, &[data-active]:focus-visible": {
18
+ outline: string;
19
+ outlineOffset: string;
20
+ boxShadow: string;
21
+ };
22
+ };
23
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sidebarFocusStyles = exports.sidebarFocusRing = void 0;
4
+ const focusRing_styles_1 = require("../../Theme/chakra/focusRing.styles");
5
+ const outlineRung_1 = require("../../Theme/tokens/builders/outlineRung");
6
+ const cache = new Map();
7
+ /** The ring is derived for the canvas; the rail is near-black in both modes, so it is re-settled against the rail. */
8
+ const sidebarFocusRing = (colors, surface = colors.sidebar.background[500]) => {
9
+ const key = `${colors.focusRing.ring}|${surface}`;
10
+ let tokens = cache.get(key);
11
+ if (!tokens) {
12
+ tokens = { ring: (0, outlineRung_1.liftToContrast)(colors.focusRing.ring, surface, outlineRung_1.AA_NON_TEXT), halo: surface };
13
+ cache.set(key, tokens);
14
+ }
15
+ return { focusRing: tokens };
16
+ };
17
+ exports.sidebarFocusRing = sidebarFocusRing;
18
+ /** `focusVisibleStyles` for a control sitting on the rail (or on `surface`, e.g. the flyout). */
19
+ const sidebarFocusStyles = (colors, surface) => (0, focusRing_styles_1.focusVisibleStyles)((0, exports.sidebarFocusRing)(colors, surface));
20
+ exports.sidebarFocusStyles = sidebarFocusStyles;
@@ -32,12 +32,12 @@ const StageProgress = ({ stages, variant = "chevron", value, onChange, size = "m
32
32
  return "upcoming";
33
33
  };
34
34
  const total = stages.length;
35
- return ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: variant === "stepper" ? "flex-start" : "stretch", gap: gapFor[variant], overflowX: "auto", p: "0.1rem", sx: (0, scrollbar_1.scrollbarStyles)(theme.colors, "overlay"), children: stages.map((stage, index) => {
35
+ return ((0, jsx_runtime_1.jsx)(react_1.Box, { as: variant === "stepper" ? "ol" : undefined, m: variant === "stepper" ? 0 : undefined, listStyleType: variant === "stepper" ? "none" : undefined, display: "flex", alignItems: variant === "stepper" ? "flex-start" : "stretch", gap: gapFor[variant], overflowX: "auto", p: "0.1rem", sx: (0, scrollbar_1.scrollbarStyles)(theme.colors, "overlay"), children: stages.map((stage, index) => {
36
36
  var _a;
37
37
  const state = stateFor(index);
38
38
  const stageDisabled = (_a = stage.isDisabled) !== null && _a !== void 0 ? _a : stage.disabled;
39
39
  if (variant === "stepper") {
40
- return ((0, jsx_runtime_1.jsx)(StepperStage_1.default, { label: stage.label, number: index + 1, state: state, size: size, colorScheme: colorScheme, isReadOnly: isReadOnly, isDisabled: stageDisabled, showCheck: showCheck, isFirst: index === 0, isLast: index === total - 1, leftDone: activeIndex > -1 && index <= activeIndex, rightDone: activeIndex > -1 && index < activeIndex, scrollIntoViewWhenActive: scrollActiveIntoView, onClick: () => onChange === null || onChange === void 0 ? void 0 : onChange(stage.id, stage, index) }, stage.id));
40
+ return ((0, jsx_runtime_1.jsx)(StepperStage_1.default, { label: stage.label, number: index + 1, state: state, size: size, colorScheme: colorScheme, isReadOnly: isReadOnly, isDisabled: stageDisabled, showCheck: showCheck, isFirst: index === 0, isLast: index === total - 1, leftDone: activeIndex > -1 && index <= activeIndex, rightDone: activeIndex > -1 && index < activeIndex, scrollIntoViewWhenActive: scrollActiveIntoView, asListItem: true, onClick: () => onChange === null || onChange === void 0 ? void 0 : onChange(stage.id, stage, index) }, stage.id));
41
41
  }
42
42
  return ((0, jsx_runtime_1.jsx)(StageItem_1.default, { label: stage.label, index: index, total: total, state: state, variant: variant, size: size, colorScheme: colorScheme, isReadOnly: isReadOnly, isDisabled: stageDisabled, showCheck: showCheck, minWidth: minStageWidth, scrollIntoViewWhenActive: scrollActiveIntoView, tooltipThreshold: tooltipThreshold, onClick: () => onChange === null || onChange === void 0 ? void 0 : onChange(stage.id, stage, index) }, stage.id));
43
43
  }) }));
@@ -110,6 +110,8 @@ export interface StepperStageProps {
110
110
  rightDone: boolean;
111
111
  /** Only scrolls when this node's own state is "active" — a no-op otherwise. */
112
112
  scrollIntoViewWhenActive?: boolean;
113
+ /** Wraps the node in an `li` so a parent `ol` is a valid list; StageProgress sets it for variant="stepper". */
114
+ asListItem?: boolean;
113
115
  }
114
116
  /** Color set for one scheme's states, returned by resolveStagePalette (soft/strong/muted + text). */
115
117
  export interface StagePalette {
@@ -13,7 +13,7 @@ const sizeMap = {
13
13
  md: { circle: "30px", font: "0.8rem", label: "0.8rem", icon: 14, minW: "104px" },
14
14
  lg: { circle: "38px", font: "0.95rem", label: "0.9rem", icon: 16, minW: "124px" },
15
15
  };
16
- const StepperStage = ({ label, number, state, size = "md", colorScheme = "primary", onClick, isReadOnly = false, isDisabled, disabled: legacyDisabled = false, showCheck = true, isFirst, isLast, leftDone, rightDone, scrollIntoViewWhenActive = true, }) => {
16
+ const StepperStage = ({ label, number, state, size = "md", colorScheme = "primary", onClick, isReadOnly = false, isDisabled, disabled: legacyDisabled = false, showCheck = true, isFirst, isLast, leftDone, rightDone, scrollIntoViewWhenActive = true, asListItem = false, }) => {
17
17
  const disabled = isDisabled !== null && isDisabled !== void 0 ? isDisabled : legacyDisabled;
18
18
  const theme = (0, useCustomTheme_1.useCustomTheme)();
19
19
  const palette = (0, StageProgressProps_1.resolveStagePalette)(theme, colorScheme);
@@ -35,10 +35,13 @@ const StepperStage = ({ label, number, state, size = "md", colorScheme = "primar
35
35
  const circleColor = filled ? palette.onStrong : palette.mutedText;
36
36
  const circleBorder = filled ? palette.strong : palette.muted;
37
37
  const line = (done, hidden) => ((0, jsx_runtime_1.jsx)(react_2.Box, { flex: "1", height: "2px", bg: done ? palette.strong : palette.muted, visibility: hidden ? "hidden" : "visible", transition: "background 0.18s ease" }));
38
- return ((0, jsx_runtime_1.jsxs)(react_2.Flex, { ref: ref, direction: "column", align: "center", flex: "1", minWidth: s.minW, flexShrink: 0, as: (interactive ? "button" : "div"), type: interactive ? "button" : undefined, "data-group": "", "aria-disabled": disabled ? true : undefined, border: "none", bg: "transparent", cursor: interactive ? "pointer" : "default", opacity: disabled ? 0.55 : 1, onClick: interactive ? onClick : undefined, borderRadius: "lg", sx: interactive ? (0, focusRing_styles_1.focusVisibleStyles)(theme.colors) : undefined, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", width: "100%", children: [line(leftDone, isFirst), (0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", justify: "center", boxSize: s.circle, borderRadius: "full", flexShrink: 0, bg: circleBg, color: circleColor, border: "2px solid", borderColor: circleBorder, fontSize: s.font, fontWeight: 600, transition: (0, primitives_1.transitionFor)(["background-color", "border-color", "color", "box-shadow"]), "aria-current": state === "active" ? "step" : undefined, sx: state === "active"
38
+ const node = ((0, jsx_runtime_1.jsxs)(react_2.Flex, { ref: ref, direction: "column", align: "center", flex: "1", minWidth: s.minW, flexShrink: 0, as: (interactive ? "button" : "div"), type: interactive ? "button" : undefined, "data-group": "", "aria-disabled": disabled ? true : undefined, border: "none", bg: "transparent", cursor: interactive ? "pointer" : "default", opacity: disabled ? 0.55 : 1, onClick: interactive ? onClick : undefined, borderRadius: "lg", sx: interactive ? (0, focusRing_styles_1.focusVisibleStyles)(theme.colors) : undefined, children: [(0, jsx_runtime_1.jsxs)(react_2.Flex, { align: "center", width: "100%", children: [line(leftDone, isFirst), (0, jsx_runtime_1.jsx)(react_2.Flex, { align: "center", justify: "center", boxSize: s.circle, borderRadius: "full", flexShrink: 0, bg: circleBg, color: circleColor, border: "2px solid", borderColor: circleBorder, fontSize: s.font, fontWeight: 600, transition: (0, primitives_1.transitionFor)(["background-color", "border-color", "color", "box-shadow"]), "aria-current": state === "active" ? "step" : undefined, sx: state === "active"
39
39
  ? { boxShadow: `0 0 0 4px ${palette.soft}` }
40
40
  : undefined, _groupHover: interactive
41
41
  ? { borderColor: palette.strong, bg: palette.strong, color: palette.onStrong }
42
42
  : undefined, children: showCheck && state === "completed" ? (0, jsx_runtime_1.jsx)(lucide_react_1.Check, { size: s.icon }) : number }), line(rightDone, isLast)] }), (0, jsx_runtime_1.jsx)(react_2.Text, { mt: 2, px: 1, borderRadius: "sm", fontSize: s.label, fontWeight: state === "active" ? 600 : 500, color: state === "upcoming" ? palette.mutedText : palette.softText, textAlign: "center", noOfLines: 2, transition: "background 0.18s ease, color 0.18s ease", _groupHover: interactive ? { bg: palette.strong, color: palette.onStrong } : undefined, children: label })] }));
43
+ if (!asListItem)
44
+ return node;
45
+ return ((0, jsx_runtime_1.jsx)(react_2.Box, { as: "li", display: "flex", flex: "1", minWidth: s.minW, flexShrink: 0, listStyleType: "none", children: node }));
43
46
  };
44
47
  exports.default = StepperStage;
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import type { WizardDialogProps, WizardProps } from "./WizardDialogProps";
3
+ export { wizardTransition, firstInvalidStep, INITIAL_WIZARD_STATE } from "./wizardSteps";
4
+ export type { WizardAction, WizardState, StepValidator } from "./wizardSteps";
5
+ /** Modal wizard that owns step state: validated Continue, locked future steps, error summary, review on the last step. */
6
+ export declare const WizardDialog: React.FC<WizardDialogProps>;
7
+ /** The same wizard inline, for a full-page flow rather than a modal. */
8
+ export declare const Wizard: React.FC<WizardProps>;
9
+ export default WizardDialog;