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.
- package/CHANGELOG.md +86 -0
- package/COMPONENT-GOTCHAS.md +88 -2
- package/DESIGN-GUIDE.md +27 -4
- package/dist/Components/AppSwitcher/AppSwitcher.js +5 -1
- package/dist/Components/AppSwitcher/AppSwitcherProps.d.ts +2 -0
- package/dist/Components/AppSwitcher/AppSwitcherProps.js +7 -4
- package/dist/Components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
- package/dist/Components/Breadcrumbs/Breadcrumbs.js +33 -10
- package/dist/Components/Breadcrumbs/BreadcrumbsProps.d.ts +16 -2
- package/dist/Components/Card/Card.d.ts +3 -1
- package/dist/Components/Card/Card.js +12 -2
- package/dist/Components/Card/CardProps.d.ts +5 -1
- package/dist/Components/Commerce/commerceTypes.d.ts +5 -0
- package/dist/Components/Editor/Editor.js +50 -2
- package/dist/Components/Editor/EditorFieldBar.d.ts +15 -0
- package/dist/Components/Editor/EditorFieldBar.js +19 -0
- package/dist/Components/Editor/EditorProps.d.ts +74 -1
- package/dist/Components/Editor/MakeDynamicDialog.d.ts +12 -0
- package/dist/Components/Editor/MakeDynamicDialog.js +59 -0
- package/dist/Components/Editor/editorLabels.d.ts +4 -0
- package/dist/Components/Editor/editorLabels.js +24 -0
- package/dist/Components/Editor/editorTokenStyles.d.ts +28 -0
- package/dist/Components/Editor/editorTokenStyles.js +30 -0
- package/dist/Components/Editor/editorTokens.d.ts +26 -0
- package/dist/Components/Editor/editorTokens.js +134 -0
- package/dist/Components/Editor/useEditorBridge.d.ts +40 -0
- package/dist/Components/Editor/useEditorBridge.js +141 -0
- package/dist/Components/Kbd/Kbd.d.ts +6 -0
- package/dist/Components/Kbd/Kbd.js +33 -0
- package/dist/Components/Kbd/KbdProps.d.ts +17 -0
- package/dist/Components/Kbd/KbdProps.js +2 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.d.ts +4 -0
- package/dist/Components/LauncherTrigger/LauncherTrigger.js +41 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.d.ts +16 -0
- package/dist/Components/LauncherTrigger/LauncherTriggerProps.js +2 -0
- package/dist/Components/MediaGallery/MediaGallery.js +1 -1
- package/dist/Components/NavLauncher/NavLauncher.d.ts +3 -0
- package/dist/Components/NavLauncher/NavLauncher.js +395 -0
- package/dist/Components/NavLauncher/NavLauncherProps.d.ts +187 -0
- package/dist/Components/NavLauncher/NavLauncherProps.js +2 -0
- package/dist/Components/NavLauncher/NewTabLink.d.ts +3 -0
- package/dist/Components/NavLauncher/NewTabLink.js +14 -0
- package/dist/Components/NavLauncher/PinToggle.d.ts +3 -0
- package/dist/Components/NavLauncher/PinToggle.js +21 -0
- package/dist/Components/NavLauncher/launcherParts.d.ts +93 -0
- package/dist/Components/NavLauncher/launcherParts.js +130 -0
- package/dist/Components/NavLauncher/match.d.ts +53 -0
- package/dist/Components/NavLauncher/match.js +178 -0
- package/dist/Components/NavLauncher/revealStyles.d.ts +4 -0
- package/dist/Components/NavLauncher/revealStyles.js +19 -0
- package/dist/Components/NavigationBar/NavigationBar.d.ts +1 -1
- package/dist/Components/NavigationBar/NavigationBar.js +2 -2
- package/dist/Components/NavigationBar/NavigationBarProps.d.ts +2 -0
- package/dist/Components/PageHeader/PageHeader.d.ts +1 -1
- package/dist/Components/PageHeader/PageHeader.js +9 -2
- package/dist/Components/PageHeader/PageHeaderProps.d.ts +8 -0
- package/dist/Components/PdfViewer/PdfViewer.d.ts +21 -4
- package/dist/Components/PdfViewer/PdfViewer.js +124 -3
- package/dist/Components/ProductCard/ProductCard.js +8 -3
- package/dist/Components/ProductCard/ProductCardMedia.js +3 -3
- package/dist/Components/ProductCard/QuickAddSheet.js +2 -2
- package/dist/Components/ProductCard/cardMetrics.d.ts +1 -0
- package/dist/Components/ProductCard/cardMetrics.js +3 -2
- package/dist/Components/ProductDetails/ProductDetails.d.ts +1 -1
- package/dist/Components/ProductDetails/ProductDetails.js +6 -5
- package/dist/Components/ProductDetails/ProductDetailsProps.d.ts +2 -0
- package/dist/Components/Search/Search.js +2 -1
- package/dist/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/Components/SideBar/SideBar.d.ts +1 -1
- package/dist/Components/SideBar/SideBar.js +30 -9
- package/dist/Components/SideBar/SideBarProps.d.ts +32 -0
- package/dist/Components/SideBar/components/MenuItemBox.d.ts +6 -0
- package/dist/Components/SideBar/components/MenuItemBox.js +8 -4
- package/dist/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/Components/SideBar/components/PinnedSection.d.ts +17 -0
- package/dist/Components/SideBar/components/PinnedSection.js +98 -0
- package/dist/Components/SideBar/sidebarFocus.d.ts +23 -0
- package/dist/Components/SideBar/sidebarFocus.js +20 -0
- package/dist/Components/StageProgress/StageProgress.js +2 -2
- package/dist/Components/StageProgress/StageProgressProps.d.ts +2 -0
- package/dist/Components/StageProgress/StepperStage.js +5 -2
- package/dist/Components/WizardDialog/WizardDialog.d.ts +9 -0
- package/dist/Components/WizardDialog/WizardDialog.js +102 -0
- package/dist/Components/WizardDialog/WizardDialogProps.d.ts +48 -0
- package/dist/Components/WizardDialog/WizardDialogProps.js +2 -0
- package/dist/Components/WizardDialog/useWizardFlow.d.ts +22 -0
- package/dist/Components/WizardDialog/useWizardFlow.js +47 -0
- package/dist/Components/WizardDialog/wizardSteps.d.ts +31 -0
- package/dist/Components/WizardDialog/wizardSteps.js +40 -0
- package/dist/Hooks/useMatchMedia.d.ts +2 -0
- package/dist/Hooks/useMatchMedia.js +36 -0
- package/dist/Theme/chakra/motion.js +2 -16
- package/dist/Utils/price.js +11 -6
- package/dist/esm/Components/AppSwitcher/AppSwitcher.js +2 -1
- package/dist/esm/Components/AppSwitcher/AppSwitcherProps.js +5 -3
- package/dist/esm/Components/Breadcrumbs/Breadcrumbs.js +35 -12
- package/dist/esm/Components/Card/Card.js +12 -2
- package/dist/esm/Components/Editor/Editor.js +48 -3
- package/dist/esm/Components/Editor/EditorFieldBar.js +13 -0
- package/dist/esm/Components/Editor/MakeDynamicDialog.js +20 -0
- package/dist/esm/Components/Editor/editorLabels.js +20 -0
- package/dist/esm/Components/Editor/editorTokenStyles.js +25 -0
- package/dist/esm/Components/Editor/editorTokens.js +121 -0
- package/dist/esm/Components/Editor/useEditorBridge.js +138 -0
- package/dist/esm/Components/Kbd/Kbd.js +28 -0
- package/dist/esm/Components/Kbd/KbdProps.js +1 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTrigger.js +37 -0
- package/dist/esm/Components/LauncherTrigger/LauncherTriggerProps.js +1 -0
- package/dist/esm/Components/MediaGallery/MediaGallery.js +1 -1
- package/dist/esm/Components/NavLauncher/NavLauncher.js +356 -0
- package/dist/esm/Components/NavLauncher/NavLauncherProps.js +1 -0
- package/dist/esm/Components/NavLauncher/NewTabLink.js +11 -0
- package/dist/esm/Components/NavLauncher/PinToggle.js +18 -0
- package/dist/esm/Components/NavLauncher/launcherParts.js +110 -0
- package/dist/esm/Components/NavLauncher/match.js +172 -0
- package/dist/esm/Components/NavLauncher/revealStyles.js +15 -0
- package/dist/esm/Components/NavigationBar/NavigationBar.js +3 -3
- package/dist/esm/Components/PageHeader/PageHeader.js +9 -2
- package/dist/esm/Components/PdfViewer/PdfViewer.js +123 -2
- package/dist/esm/Components/ProductCard/ProductCard.js +9 -4
- package/dist/esm/Components/ProductCard/ProductCardMedia.js +3 -3
- package/dist/esm/Components/ProductCard/QuickAddSheet.js +2 -2
- package/dist/esm/Components/ProductCard/cardMetrics.js +2 -1
- package/dist/esm/Components/ProductDetails/ProductDetails.js +6 -5
- package/dist/esm/Components/Search/Search.js +3 -2
- package/dist/esm/Components/SideBar/SecondaryBar.js +4 -3
- package/dist/esm/Components/SideBar/SideBar.js +31 -10
- package/dist/esm/Components/SideBar/components/MenuItemBox.js +4 -2
- package/dist/esm/Components/SideBar/components/MenuPopoverContent.js +3 -2
- package/dist/esm/Components/SideBar/components/OtherApps.js +2 -1
- package/dist/esm/Components/SideBar/components/PinnedSection.js +92 -0
- package/dist/esm/Components/SideBar/sidebarFocus.js +15 -0
- package/dist/esm/Components/StageProgress/StageProgress.js +2 -2
- package/dist/esm/Components/StageProgress/StepperStage.js +5 -2
- package/dist/esm/Components/WizardDialog/WizardDialog.js +58 -0
- package/dist/esm/Components/WizardDialog/WizardDialogProps.js +1 -0
- package/dist/esm/Components/WizardDialog/useWizardFlow.js +44 -0
- package/dist/esm/Components/WizardDialog/wizardSteps.js +35 -0
- package/dist/esm/Hooks/useMatchMedia.js +32 -0
- package/dist/esm/Theme/chakra/motion.js +2 -16
- package/dist/esm/Utils/price.js +11 -6
- package/dist/esm/index.js +7 -0
- package/dist/index.d.ts +19 -4
- package/dist/index.js +21 -1
- package/package.json +1 -1
- package/dist/Components/MediaGallery/useMatchMedia.d.ts +0 -2
- package/dist/Components/MediaGallery/useMatchMedia.js +0 -20
- package/dist/Components/ProductCard/useMinWidth.d.ts +0 -2
- package/dist/Components/ProductCard/useMinWidth.js +0 -20
- package/dist/esm/Components/MediaGallery/useMatchMedia.js +0 -16
- 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:
|
|
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:
|
|
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
|
-
|
|
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;
|