@flipdish/ui-library 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/organisms/SidebarNavigation/components/nav-button.cjs +5 -2
- package/dist/components/organisms/SidebarNavigation/components/nav-button.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-button.d.ts +4 -2
- package/dist/components/organisms/SidebarNavigation/components/nav-button.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-button.js +6 -3
- package/dist/components/organisms/SidebarNavigation/components/nav-button.js.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-item.cjs +12 -7
- package/dist/components/organisms/SidebarNavigation/components/nav-item.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-item.d.ts +6 -2
- package/dist/components/organisms/SidebarNavigation/components/nav-item.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-item.js +13 -8
- package/dist/components/organisms/SidebarNavigation/components/nav-item.js.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-list.cjs +3 -3
- package/dist/components/organisms/SidebarNavigation/components/nav-list.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-list.d.ts +3 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-list.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/components/nav-list.js +3 -3
- package/dist/components/organisms/SidebarNavigation/components/nav-list.js.map +1 -1
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.cjs +56 -0
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.cjs.map +1 -0
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.d.ts +24 -0
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.d.ts.map +1 -0
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.js +54 -0
- package/dist/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.js.map +1 -0
- package/dist/components/organisms/SidebarNavigation/index.cjs +49 -67
- package/dist/components/organisms/SidebarNavigation/index.cjs.map +1 -1
- package/dist/components/organisms/SidebarNavigation/index.d.ts +4 -3
- package/dist/components/organisms/SidebarNavigation/index.d.ts.map +1 -1
- package/dist/components/organisms/SidebarNavigation/index.js +50 -68
- package/dist/components/organisms/SidebarNavigation/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,9 +5,12 @@ var Tooltip = require('@flipdish/ui-library/components/atoms/Tooltip');
|
|
|
5
5
|
var cx = require('@flipdish/ui-library/utilities/cx');
|
|
6
6
|
var reactAriaComponents = require('react-aria-components');
|
|
7
7
|
|
|
8
|
-
const NavButton = ({ current, label, href, icon: Icon, className, tooltipPlacement = 'right', onClick, children, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
8
|
+
const NavButton = ({ current, selected, label, href, icon: Icon, className, tooltipPlacement = 'right', onClick, children, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
9
9
|
const iconOnly = !children;
|
|
10
|
-
|
|
10
|
+
// `current` means "this is the current page" (→ aria-current); `selected` is the
|
|
11
|
+
// brand-highlight state (open/selected section), which may differ from the page.
|
|
12
|
+
const isSelected = selected ?? current;
|
|
13
|
+
return (jsxRuntime.jsx(Tooltip.Tooltip, { isDisabled: !label, title: label, placement: tooltipPlacement, children: jsxRuntime.jsxs(reactAriaComponents.Link, { href: href, "aria-label": label, "aria-current": current ? 'page' : undefined, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, onClick: onClick, className: cx.cx('group/item relative flex w-full cursor-pointer items-center justify-center gap-1 rounded-md bg-transparent outline-focus-ring transition duration-100 ease-linear select-none hover:bg-secondary_hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2', isSelected && 'bg-brand-primary hover:bg-brand-primary', iconOnly ? 'size-9' : 'px-2 py-1.5', className), children: [Icon && (jsxRuntime.jsx(Icon, { "aria-hidden": "true", className: cx.cx('size-5 shrink-0 text-fg-quaternary transition-inherit-all group-hover/item:text-fg-quaternary_hover', isSelected && 'text-fg-brand-primary group-hover/item:text-fg-brand-primary') })), children && (jsxRuntime.jsx("span", { className: cx.cx('px-0.5 text-sm font-semibold transition duration-100 ease-linear group-hover/item:text-secondary_hover', isSelected && 'text-brand-secondary'), children: children }))] }) }));
|
|
11
14
|
};
|
|
12
15
|
|
|
13
16
|
exports.NavButton = NavButton;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-button.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"sourcesContent":[null],"names":["_jsx","Tooltip","
|
|
1
|
+
{"version":3,"file":"nav-button.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"sourcesContent":[null],"names":["_jsx","Tooltip","_jsxs","AriaLink","cx"],"mappings":";;;;;;;AAkCO,MAAM,SAAS,GAAG,CAAC,EACxB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,SAAS,EACT,gBAAgB,GAAG,OAAO,EAC1B,OAAO,EACP,QAAQ,EACR,eAAe,EAAE,YAAY,EAC7B,eAAe,EAAE,YAAY,GACd,KAAI;AACnB,IAAA,MAAM,QAAQ,GAAG,CAAC,QAAQ;;;AAG1B,IAAA,MAAM,UAAU,GAAG,QAAQ,IAAI,OAAO;IAEtC,QACEA,cAAA,CAACC,eAAO,EAAA,EAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAA,QAAA,EACpEC,eAAA,CAACC,wBAAQ,IACP,IAAI,EAAE,IAAI,EAAA,YAAA,EACE,KAAK,EAAA,cAAA,EACH,OAAO,GAAG,MAAM,GAAG,SAAS,EAAA,eAAA,EAC3B,YAAY,EAAA,eAAA,EACZ,YAAY,EAC3B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAEC,KAAE,CACX,kRAAkR,EAClR,UAAU,IAAI,yCAAyC,EACvD,QAAQ,GAAG,QAAQ,GAAG,aAAa,EACnC,SAAS,CACV,EAAA,QAAA,EAAA,CAEA,IAAI,KACHJ,cAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EACS,MAAM,EAClB,SAAS,EAAEI,KAAE,CACX,qGAAqG,EACrG,UAAU,IAAI,8DAA8D,CAC7E,EAAA,CACD,CACH,EAEA,QAAQ,KACPJ,cAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAEI,KAAE,CACX,wGAAwG,EACxG,UAAU,IAAI,sBAAsB,CACrC,EAAA,QAAA,EAEA,QAAQ,EAAA,CACJ,CACR,CAAA,EAAA,CACQ,EAAA,CACH;AAEd;;;;"}
|
|
@@ -10,8 +10,10 @@ interface NavButtonProps {
|
|
|
10
10
|
icon?: FC<{
|
|
11
11
|
className?: string;
|
|
12
12
|
}>;
|
|
13
|
-
/** Whether the button is
|
|
13
|
+
/** Whether the button is the current page — drives `aria-current="page"`. */
|
|
14
14
|
current?: boolean;
|
|
15
|
+
/** Whether the item is the selected/open section — drives brand styling without implying it is the current page. Defaults to `current`. */
|
|
16
|
+
selected?: boolean;
|
|
15
17
|
/** Handler for click events. */
|
|
16
18
|
onClick?: MouseEventHandler;
|
|
17
19
|
/** Additional CSS classes to apply to the button. */
|
|
@@ -25,6 +27,6 @@ interface NavButtonProps {
|
|
|
25
27
|
/** Content to display. */
|
|
26
28
|
children?: ReactNode;
|
|
27
29
|
}
|
|
28
|
-
export declare const NavButton: ({ current, label, href, icon: Icon, className, tooltipPlacement, onClick, children, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, }: NavButtonProps) => import("react").JSX.Element;
|
|
30
|
+
export declare const NavButton: ({ current, selected, label, href, icon: Icon, className, tooltipPlacement, onClick, children, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, }: NavButtonProps) => import("react").JSX.Element;
|
|
29
31
|
export {};
|
|
30
32
|
//# sourceMappingURL=nav-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-button.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9D,UAAU,cAAc;IACtB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,
|
|
1
|
+
{"version":3,"file":"nav-button.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9D,UAAU,cAAc;IACtB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2IAA2I;IAC3I,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,gBAAgB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;IACvD,0FAA0F;IAC1F,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED,eAAO,MAAM,SAAS,GAAI,+JAYvB,cAAc,gCA6ChB,CAAC"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Tooltip } from '@flipdish/ui-library/components/atoms/Tooltip';
|
|
3
3
|
import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
4
|
-
import {
|
|
4
|
+
import { Link } from 'react-aria-components';
|
|
5
5
|
|
|
6
|
-
const NavButton = ({ current, label, href, icon: Icon, className, tooltipPlacement = 'right', onClick, children, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
6
|
+
const NavButton = ({ current, selected, label, href, icon: Icon, className, tooltipPlacement = 'right', onClick, children, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
7
7
|
const iconOnly = !children;
|
|
8
|
-
|
|
8
|
+
// `current` means "this is the current page" (→ aria-current); `selected` is the
|
|
9
|
+
// brand-highlight state (open/selected section), which may differ from the page.
|
|
10
|
+
const isSelected = selected ?? current;
|
|
11
|
+
return (jsx(Tooltip, { isDisabled: !label, title: label, placement: tooltipPlacement, children: jsxs(Link, { href: href, "aria-label": label, "aria-current": current ? 'page' : undefined, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, onClick: onClick, className: cx('group/item relative flex w-full cursor-pointer items-center justify-center gap-1 rounded-md bg-transparent outline-focus-ring transition duration-100 ease-linear select-none hover:bg-secondary_hover focus-visible:z-10 focus-visible:outline-2 focus-visible:outline-offset-2', isSelected && 'bg-brand-primary hover:bg-brand-primary', iconOnly ? 'size-9' : 'px-2 py-1.5', className), children: [Icon && (jsx(Icon, { "aria-hidden": "true", className: cx('size-5 shrink-0 text-fg-quaternary transition-inherit-all group-hover/item:text-fg-quaternary_hover', isSelected && 'text-fg-brand-primary group-hover/item:text-fg-brand-primary') })), children && (jsx("span", { className: cx('px-0.5 text-sm font-semibold transition duration-100 ease-linear group-hover/item:text-secondary_hover', isSelected && 'text-brand-secondary'), children: children }))] }) }));
|
|
9
12
|
};
|
|
10
13
|
|
|
11
14
|
export { NavButton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-button.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"nav-button.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-button.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaLink"],"mappings":";;;;;AAkCO,MAAM,SAAS,GAAG,CAAC,EACxB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,IAAI,EAAE,IAAI,EACV,SAAS,EACT,gBAAgB,GAAG,OAAO,EAC1B,OAAO,EACP,QAAQ,EACR,eAAe,EAAE,YAAY,EAC7B,eAAe,EAAE,YAAY,GACd,KAAI;AACnB,IAAA,MAAM,QAAQ,GAAG,CAAC,QAAQ;;;AAG1B,IAAA,MAAM,UAAU,GAAG,QAAQ,IAAI,OAAO;IAEtC,QACEA,GAAA,CAAC,OAAO,EAAA,EAAC,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAA,QAAA,EACpEC,IAAA,CAACC,IAAQ,IACP,IAAI,EAAE,IAAI,EAAA,YAAA,EACE,KAAK,EAAA,cAAA,EACH,OAAO,GAAG,MAAM,GAAG,SAAS,EAAA,eAAA,EAC3B,YAAY,EAAA,eAAA,EACZ,YAAY,EAC3B,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,EAAE,CACX,kRAAkR,EAClR,UAAU,IAAI,yCAAyC,EACvD,QAAQ,GAAG,QAAQ,GAAG,aAAa,EACnC,SAAS,CACV,EAAA,QAAA,EAAA,CAEA,IAAI,KACHF,GAAA,CAAC,IAAI,EAAA,EAAA,aAAA,EACS,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,qGAAqG,EACrG,UAAU,IAAI,8DAA8D,CAC7E,EAAA,CACD,CACH,EAEA,QAAQ,KACPA,GAAA,CAAA,MAAA,EAAA,EACE,SAAS,EAAE,EAAE,CACX,wGAAwG,EACxG,UAAU,IAAI,sBAAsB,CACrC,EAAA,QAAA,EAEA,QAAQ,EAAA,CACJ,CACR,CAAA,EAAA,CACQ,EAAA,CACH;AAEd;;;;"}
|
|
@@ -16,21 +16,26 @@ const styles = cx.sortCx({
|
|
|
16
16
|
rootSelected: 'bg-brand-primary hover:bg-brand-primary',
|
|
17
17
|
});
|
|
18
18
|
const StatusDot = ({ status }) => (jsxRuntime.jsx("span", { "aria-hidden": "true", className: cx.cx('mr-2 size-2 shrink-0 rounded-full', status === 'online' ? 'bg-success-solid' : 'bg-fg-quaternary') }));
|
|
19
|
-
const NavItemBase = ({ current, type, badge, href, icon: Icon, children, truncate = true, status, onClick, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
19
|
+
const NavItemBase = ({ current, selected, type, badge, href, icon: Icon, children, truncate = true, status, onClick, hasSubmenu, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
20
|
+
// `current` means "this is the current page" (→ aria-current); `selected` is the
|
|
21
|
+
// brand-highlight state (open/selected section), which may differ from the page.
|
|
22
|
+
const isSelected = selected ?? current;
|
|
23
|
+
const iconElement = Icon && (jsxRuntime.jsx(Icon, { "aria-hidden": "true", className: cx.cx('mr-2 size-5 shrink-0 text-fg-quaternary transition-inherit-all group-hover/item:text-fg-quaternary_hover', isSelected && 'text-fg-brand-primary group-hover/item:text-fg-brand-primary') }));
|
|
24
|
+
const badgeElement = badge && (typeof badge === 'string' || typeof badge === 'number') ? (jsxRuntime.jsx(Badge.Badge, { className: "ml-3", color: isSelected ? 'brand' : 'gray', type: "pill-color", size: "sm", children: badge })) : (badge);
|
|
25
|
+
const labelElement = (jsxRuntime.jsx("span", { className: cx.cx('flex-1 text-sm font-semibold text-secondary transition-inherit-all group-hover/item:text-secondary_hover', truncate && 'truncate', isSelected && 'text-brand-secondary group-hover/item:text-brand-secondary'), children: children }));
|
|
23
26
|
const isExternal = href?.startsWith('http');
|
|
24
27
|
const externalIcon = isExternal && jsxRuntime.jsx(uiIcons.Share04, { className: "size-4 stroke-[2.5px] text-fg-quaternary" });
|
|
28
|
+
// A trailing chevron on a section parent signals it has a revealable sub-navigation tier.
|
|
29
|
+
const submenuChevron = hasSubmenu && (jsxRuntime.jsx(uiIcons.ChevronRight, { "aria-hidden": "true", className: cx.cx('ml-3 size-4 shrink-0 stroke-[2.5px] text-fg-quaternary', isSelected && 'text-fg-brand-primary') }));
|
|
25
30
|
if (type === 'collapsible') {
|
|
26
31
|
return (
|
|
27
32
|
// biome-ignore lint/a11y/noStaticElementInteractions: This is a summary element
|
|
28
|
-
jsxRuntime.jsxs("summary", { className: cx.cx('p-2', styles.root,
|
|
33
|
+
jsxRuntime.jsxs("summary", { className: cx.cx('p-2', styles.root, isSelected && styles.rootSelected), onClick: onClick, children: [status && jsxRuntime.jsx(StatusDot, { status: status }), iconElement, labelElement, badgeElement, jsxRuntime.jsx(uiIcons.ChevronDown, { "aria-hidden": "true", className: "ml-3 size-4 shrink-0 stroke-[2.5px] text-fg-quaternary in-open:-scale-y-100" })] }));
|
|
29
34
|
}
|
|
30
35
|
if (type === 'collapsible-child') {
|
|
31
|
-
return (jsxRuntime.jsxs(reactAriaComponents.Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx.cx('py-2 pr-3 pl-10', styles.root,
|
|
36
|
+
return (jsxRuntime.jsxs(reactAriaComponents.Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx.cx('py-2 pr-3 pl-10', styles.root, isSelected && styles.rootSelected), onClick: onClick, "aria-current": current ? 'page' : undefined, children: [labelElement, externalIcon, badgeElement] }));
|
|
32
37
|
}
|
|
33
|
-
return (jsxRuntime.jsxs(reactAriaComponents.Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx.cx('group/item p-2', styles.root,
|
|
38
|
+
return (jsxRuntime.jsxs(reactAriaComponents.Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx.cx('group/item p-2', styles.root, isSelected && styles.rootSelected), onClick: onClick, "aria-current": current ? 'page' : undefined, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, children: [status && jsxRuntime.jsx(StatusDot, { status: status }), iconElement, labelElement, externalIcon, badgeElement, submenuChevron] }));
|
|
34
39
|
};
|
|
35
40
|
|
|
36
41
|
exports.NavItemBase = NavItemBase;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-item.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"sourcesContent":[null],"names":["sortCx","_jsx","cx","Badge","Share04","_jsxs","ChevronDown","AriaLink"],"mappings":";;;;;;;;AAQA;;;;AAIG;AACH,MAAM,MAAM,GAAGA,SAAM,CAAC;AACpB,IAAA,IAAI,EAAE,qQAAqQ;AAC3Q,IAAA,YAAY,EAAE,yCAAyC;AACxD,CAAA,CAAC;
|
|
1
|
+
{"version":3,"file":"nav-item.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"sourcesContent":[null],"names":["sortCx","_jsx","cx","Badge","Share04","ChevronRight","_jsxs","ChevronDown","AriaLink"],"mappings":"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"}
|
|
@@ -12,14 +12,18 @@ interface NavItemBaseProps {
|
|
|
12
12
|
icon?: FC<HTMLAttributes<HTMLOrSVGElement>>;
|
|
13
13
|
/** Badge to display. */
|
|
14
14
|
badge?: ReactNode;
|
|
15
|
-
/** Whether the nav item is
|
|
15
|
+
/** Whether the nav item is the current page — drives `aria-current="page"`. */
|
|
16
16
|
current?: boolean;
|
|
17
|
+
/** Whether the item is the selected/open section — drives brand styling without implying it is the current page. Defaults to `current`. */
|
|
18
|
+
selected?: boolean;
|
|
17
19
|
/** Whether to truncate the label text. */
|
|
18
20
|
truncate?: boolean;
|
|
19
21
|
/** Optional leading status dot rendered before the icon. */
|
|
20
22
|
status?: NavItemStatus;
|
|
21
23
|
/** Handler for click events. */
|
|
22
24
|
onClick?: MouseEventHandler;
|
|
25
|
+
/** Whether this item is a section parent — renders a trailing chevron signalling a revealable sub-navigation tier. */
|
|
26
|
+
hasSubmenu?: boolean;
|
|
23
27
|
/** Disclosure state when the item triggers a revealed region (e.g. a sub-nav panel). */
|
|
24
28
|
'aria-expanded'?: boolean;
|
|
25
29
|
/** ID of the region this item controls when it acts as a disclosure trigger. */
|
|
@@ -27,6 +31,6 @@ interface NavItemBaseProps {
|
|
|
27
31
|
/** Content to display. */
|
|
28
32
|
children?: ReactNode;
|
|
29
33
|
}
|
|
30
|
-
export declare const NavItemBase: ({ current, type, badge, href, icon: Icon, children, truncate, status, onClick, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, }: NavItemBaseProps) => import("react").JSX.Element;
|
|
34
|
+
export declare const NavItemBase: ({ current, selected, type, badge, href, icon: Icon, children, truncate, status, onClick, hasSubmenu, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, }: NavItemBaseProps) => import("react").JSX.Element;
|
|
31
35
|
export {};
|
|
32
36
|
//# sourceMappingURL=nav-item.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-item.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAa9E,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD,UAAU,gBAAgB;IACxB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,mBAAmB,CAAC;IACnD,iCAAiC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5C,wBAAwB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"nav-item.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,EAAE,cAAc,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAa9E,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjD,UAAU,gBAAgB;IACxB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,mBAAmB,CAAC;IACnD,iCAAiC;IACjC,IAAI,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC5C,wBAAwB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2IAA2I;IAC3I,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gCAAgC;IAChC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,sHAAsH;IACtH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD,eAAO,MAAM,WAAW,GAAI,sKAczB,gBAAgB,gCAgGlB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { Share04, ChevronDown } from '@flipdish/ui-icons';
|
|
2
|
+
import { Share04, ChevronRight, ChevronDown } from '@flipdish/ui-icons';
|
|
3
3
|
import { Badge } from '@flipdish/ui-library/components/atoms/Badge';
|
|
4
4
|
import { sortCx, cx } from '@flipdish/ui-library/utilities/cx';
|
|
5
5
|
import { Link } from 'react-aria-components';
|
|
@@ -14,21 +14,26 @@ const styles = sortCx({
|
|
|
14
14
|
rootSelected: 'bg-brand-primary hover:bg-brand-primary',
|
|
15
15
|
});
|
|
16
16
|
const StatusDot = ({ status }) => (jsx("span", { "aria-hidden": "true", className: cx('mr-2 size-2 shrink-0 rounded-full', status === 'online' ? 'bg-success-solid' : 'bg-fg-quaternary') }));
|
|
17
|
-
const NavItemBase = ({ current, type, badge, href, icon: Icon, children, truncate = true, status, onClick, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
17
|
+
const NavItemBase = ({ current, selected, type, badge, href, icon: Icon, children, truncate = true, status, onClick, hasSubmenu, 'aria-expanded': ariaExpanded, 'aria-controls': ariaControls, }) => {
|
|
18
|
+
// `current` means "this is the current page" (→ aria-current); `selected` is the
|
|
19
|
+
// brand-highlight state (open/selected section), which may differ from the page.
|
|
20
|
+
const isSelected = selected ?? current;
|
|
21
|
+
const iconElement = Icon && (jsx(Icon, { "aria-hidden": "true", className: cx('mr-2 size-5 shrink-0 text-fg-quaternary transition-inherit-all group-hover/item:text-fg-quaternary_hover', isSelected && 'text-fg-brand-primary group-hover/item:text-fg-brand-primary') }));
|
|
22
|
+
const badgeElement = badge && (typeof badge === 'string' || typeof badge === 'number') ? (jsx(Badge, { className: "ml-3", color: isSelected ? 'brand' : 'gray', type: "pill-color", size: "sm", children: badge })) : (badge);
|
|
23
|
+
const labelElement = (jsx("span", { className: cx('flex-1 text-sm font-semibold text-secondary transition-inherit-all group-hover/item:text-secondary_hover', truncate && 'truncate', isSelected && 'text-brand-secondary group-hover/item:text-brand-secondary'), children: children }));
|
|
21
24
|
const isExternal = href?.startsWith('http');
|
|
22
25
|
const externalIcon = isExternal && jsx(Share04, { className: "size-4 stroke-[2.5px] text-fg-quaternary" });
|
|
26
|
+
// A trailing chevron on a section parent signals it has a revealable sub-navigation tier.
|
|
27
|
+
const submenuChevron = hasSubmenu && (jsx(ChevronRight, { "aria-hidden": "true", className: cx('ml-3 size-4 shrink-0 stroke-[2.5px] text-fg-quaternary', isSelected && 'text-fg-brand-primary') }));
|
|
23
28
|
if (type === 'collapsible') {
|
|
24
29
|
return (
|
|
25
30
|
// biome-ignore lint/a11y/noStaticElementInteractions: This is a summary element
|
|
26
|
-
jsxs("summary", { className: cx('p-2', styles.root,
|
|
31
|
+
jsxs("summary", { className: cx('p-2', styles.root, isSelected && styles.rootSelected), onClick: onClick, children: [status && jsx(StatusDot, { status: status }), iconElement, labelElement, badgeElement, jsx(ChevronDown, { "aria-hidden": "true", className: "ml-3 size-4 shrink-0 stroke-[2.5px] text-fg-quaternary in-open:-scale-y-100" })] }));
|
|
27
32
|
}
|
|
28
33
|
if (type === 'collapsible-child') {
|
|
29
|
-
return (jsxs(Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx('py-2 pr-3 pl-10', styles.root,
|
|
34
|
+
return (jsxs(Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx('py-2 pr-3 pl-10', styles.root, isSelected && styles.rootSelected), onClick: onClick, "aria-current": current ? 'page' : undefined, children: [labelElement, externalIcon, badgeElement] }));
|
|
30
35
|
}
|
|
31
|
-
return (jsxs(Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx('group/item p-2', styles.root,
|
|
36
|
+
return (jsxs(Link, { href: href, target: isExternal ? '_blank' : '_self', rel: "noopener noreferrer", className: cx('group/item p-2', styles.root, isSelected && styles.rootSelected), onClick: onClick, "aria-current": current ? 'page' : undefined, "aria-expanded": ariaExpanded, "aria-controls": ariaControls, children: [status && jsx(StatusDot, { status: status }), iconElement, labelElement, externalIcon, badgeElement, submenuChevron] }));
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
export { NavItemBase };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-item.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaLink"],"mappings":";;;;;;AAQA;;;;AAIG;AACH,MAAM,MAAM,GAAG,MAAM,CAAC;AACpB,IAAA,IAAI,EAAE,qQAAqQ;AAC3Q,IAAA,YAAY,EAAE,yCAAyC;AACxD,CAAA,CAAC;
|
|
1
|
+
{"version":3,"file":"nav-item.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-item.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaLink"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var cx = require('@flipdish/ui-library/utilities/cx');
|
|
5
5
|
var navItem = require('./nav-item.cjs');
|
|
6
6
|
|
|
7
|
-
const NavList = ({ activeUrl, items, className }) => {
|
|
7
|
+
const NavList = ({ activeUrl, items, className, onNavigate }) => {
|
|
8
8
|
const activeItem = items.find((item) => item.href === activeUrl || item.items?.some((subItem) => subItem.href === activeUrl));
|
|
9
9
|
return (jsxRuntime.jsx("ul", { className: cx.cx('flex flex-col px-4 pt-5', className), children: items.map((item, index) => {
|
|
10
10
|
if (item.divider) {
|
|
@@ -13,9 +13,9 @@ const NavList = ({ activeUrl, items, className }) => {
|
|
|
13
13
|
jsxRuntime.jsx("li", { className: "w-full px-0.5 py-2", children: jsxRuntime.jsx("hr", { className: "h-px w-full border-none bg-border-secondary" }) }, index));
|
|
14
14
|
}
|
|
15
15
|
if (item.items?.length) {
|
|
16
|
-
return (jsxRuntime.jsxs("details", { open: activeItem?.href === item.href, className: "appearance-none py-0.25", children: [jsxRuntime.jsx(navItem.NavItemBase, { href: item.href, badge: item.badge, icon: item.icon, type: "collapsible", children: item.label }), jsxRuntime.jsx("dd", { children: jsxRuntime.jsx("ul", { className: "pb-1", children: item.items.map((childItem) => (jsxRuntime.jsx("li", { className: "py-0.25", children: jsxRuntime.jsx(navItem.NavItemBase, { href: childItem.href, badge: childItem.badge, type: "collapsible-child", current: activeUrl === childItem.href, children: childItem.label }) }, childItem.label))) }) })] }, item.label));
|
|
16
|
+
return (jsxRuntime.jsxs("details", { open: activeItem?.href === item.href, className: "appearance-none py-0.25", children: [jsxRuntime.jsx(navItem.NavItemBase, { href: item.href, badge: item.badge, icon: item.icon, type: "collapsible", children: item.label }), jsxRuntime.jsx("dd", { children: jsxRuntime.jsx("ul", { className: "pb-1", children: item.items.map((childItem) => (jsxRuntime.jsx("li", { className: "py-0.25", children: jsxRuntime.jsx(navItem.NavItemBase, { href: childItem.href, badge: childItem.badge, type: "collapsible-child", current: activeUrl === childItem.href, onClick: onNavigate, children: childItem.label }) }, childItem.label))) }) })] }, item.label));
|
|
17
17
|
}
|
|
18
|
-
return (jsxRuntime.jsx("li", { className: "py-px", children: jsxRuntime.jsx(navItem.NavItemBase, { type: "link", badge: item.badge, icon: item.icon, href: item.href, current: activeUrl === item.href, children: item.label }) }, item.label));
|
|
18
|
+
return (jsxRuntime.jsx("li", { className: "py-px", children: jsxRuntime.jsx(navItem.NavItemBase, { type: "link", badge: item.badge, icon: item.icon, href: item.href, current: activeUrl === item.href, onClick: onNavigate, children: item.label }) }, item.label));
|
|
19
19
|
}) }));
|
|
20
20
|
};
|
|
21
21
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-list.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"sourcesContent":[null],"names":["_jsx","cx","_jsxs","NavItemBase"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"nav-list.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"sourcesContent":[null],"names":["_jsx","cx","_jsxs","NavItemBase"],"mappings":";;;;;;AAiBO,MAAM,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAgB,KAAI;AACnF,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAqC,KAAK,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAC7H;IAED,QACEA,uBAAI,SAAS,EAAEC,KAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,YACpD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AACzB,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB;;AAEE,gBAAAD,cAAA,CAAA,IAAA,EAAA,EAAgB,SAAS,EAAC,oBAAoB,EAAA,QAAA,EAC5CA,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,6CAA6C,EAAA,CAAG,EAAA,EADvD,KAAK,CAET;YAET;AAEA,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;gBACtB,QACEE,eAAA,CAAA,SAAA,EAAA,EAA0B,IAAI,EAAE,UAAU,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,SAAS,EAAC,yBAAyB,EAAA,QAAA,EAAA,CACjGF,cAAA,CAACG,mBAAW,EAAA,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,aAAa,EAAA,QAAA,EACjF,IAAI,CAAC,KAAK,EAAA,CACC,EAEdH,cAAA,CAAA,IAAA,EAAA,EAAA,QAAA,EACEA,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,MAAM,EAAA,QAAA,EACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAsB,MACrCA,cAAA,CAAA,IAAA,EAAA,EAA0B,SAAS,EAAC,SAAS,EAAA,QAAA,EAC3CA,cAAA,CAACG,mBAAW,EAAA,EACV,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,IAAI,EAAC,mBAAmB,EACxB,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,IAAI,EACrC,OAAO,EAAE,UAAU,EAAA,QAAA,EAElB,SAAS,CAAC,KAAK,EAAA,CACJ,EAAA,EATP,SAAS,CAAC,KAAK,CAUnB,CACN,CAAC,EAAA,CACC,EAAA,CACF,CAAA,EAAA,EArBO,IAAI,CAAC,KAAK,CAsBd;YAEd;YAEA,QACEH,cAAA,CAAA,IAAA,EAAA,EAAqB,SAAS,EAAC,OAAO,YACpCA,cAAA,CAACG,mBAAW,EAAA,EAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAA,QAAA,EAChI,IAAI,CAAC,KAAK,EAAA,CACC,EAAA,EAHP,IAAI,CAAC,KAAK,CAId;QAET,CAAC,CAAC,EAAA,CACC;AAET;;;;"}
|
|
@@ -6,7 +6,9 @@ interface NavListProps {
|
|
|
6
6
|
className?: string;
|
|
7
7
|
/** List of items to display. */
|
|
8
8
|
items: (NavItemType | NavItemDividerType)[];
|
|
9
|
+
/** Called when a destination link is activated — used to close the mobile drawer on navigation. */
|
|
10
|
+
onNavigate?: () => void;
|
|
9
11
|
}
|
|
10
|
-
export declare const NavList: ({ activeUrl, items, className }: NavListProps) => import("react").JSX.Element;
|
|
12
|
+
export declare const NavList: ({ activeUrl, items, className, onNavigate }: NavListProps) => import("react").JSX.Element;
|
|
11
13
|
export {};
|
|
12
14
|
//# sourceMappingURL=nav-list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-list.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGlF,UAAU,YAAY;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,KAAK,EAAE,CAAC,WAAW,GAAG,kBAAkB,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"nav-list.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGlF,UAAU,YAAY;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,KAAK,EAAE,CAAC,WAAW,GAAG,kBAAkB,CAAC,EAAE,CAAC;IAC5C,mGAAmG;IACnG,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,OAAO,GAAI,6CAA6C,YAAY,gCAuDhF,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
3
3
|
import { NavItemBase } from './nav-item.js';
|
|
4
4
|
|
|
5
|
-
const NavList = ({ activeUrl, items, className }) => {
|
|
5
|
+
const NavList = ({ activeUrl, items, className, onNavigate }) => {
|
|
6
6
|
const activeItem = items.find((item) => item.href === activeUrl || item.items?.some((subItem) => subItem.href === activeUrl));
|
|
7
7
|
return (jsx("ul", { className: cx('flex flex-col px-4 pt-5', className), children: items.map((item, index) => {
|
|
8
8
|
if (item.divider) {
|
|
@@ -11,9 +11,9 @@ const NavList = ({ activeUrl, items, className }) => {
|
|
|
11
11
|
jsx("li", { className: "w-full px-0.5 py-2", children: jsx("hr", { className: "h-px w-full border-none bg-border-secondary" }) }, index));
|
|
12
12
|
}
|
|
13
13
|
if (item.items?.length) {
|
|
14
|
-
return (jsxs("details", { open: activeItem?.href === item.href, className: "appearance-none py-0.25", children: [jsx(NavItemBase, { href: item.href, badge: item.badge, icon: item.icon, type: "collapsible", children: item.label }), jsx("dd", { children: jsx("ul", { className: "pb-1", children: item.items.map((childItem) => (jsx("li", { className: "py-0.25", children: jsx(NavItemBase, { href: childItem.href, badge: childItem.badge, type: "collapsible-child", current: activeUrl === childItem.href, children: childItem.label }) }, childItem.label))) }) })] }, item.label));
|
|
14
|
+
return (jsxs("details", { open: activeItem?.href === item.href, className: "appearance-none py-0.25", children: [jsx(NavItemBase, { href: item.href, badge: item.badge, icon: item.icon, type: "collapsible", children: item.label }), jsx("dd", { children: jsx("ul", { className: "pb-1", children: item.items.map((childItem) => (jsx("li", { className: "py-0.25", children: jsx(NavItemBase, { href: childItem.href, badge: childItem.badge, type: "collapsible-child", current: activeUrl === childItem.href, onClick: onNavigate, children: childItem.label }) }, childItem.label))) }) })] }, item.label));
|
|
15
15
|
}
|
|
16
|
-
return (jsx("li", { className: "py-px", children: jsx(NavItemBase, { type: "link", badge: item.badge, icon: item.icon, href: item.href, current: activeUrl === item.href, children: item.label }) }, item.label));
|
|
16
|
+
return (jsx("li", { className: "py-px", children: jsx(NavItemBase, { type: "link", badge: item.badge, icon: item.icon, href: item.href, current: activeUrl === item.href, onClick: onNavigate, children: item.label }) }, item.label));
|
|
17
17
|
}) }));
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nav-list.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"nav-list.js","sources":["../../../../../src/components/organisms/SidebarNavigation/components/nav-list.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;AAiBO,MAAM,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAgB,KAAI;AACnF,IAAA,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAC3B,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAqC,KAAK,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAC7H;IAED,QACEA,YAAI,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,SAAS,CAAC,YACpD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AACzB,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB;;AAEE,gBAAAA,GAAA,CAAA,IAAA,EAAA,EAAgB,SAAS,EAAC,oBAAoB,EAAA,QAAA,EAC5CA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,6CAA6C,EAAA,CAAG,EAAA,EADvD,KAAK,CAET;YAET;AAEA,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;gBACtB,QACEC,IAAA,CAAA,SAAA,EAAA,EAA0B,IAAI,EAAE,UAAU,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,SAAS,EAAC,yBAAyB,EAAA,QAAA,EAAA,CACjGD,GAAA,CAAC,WAAW,EAAA,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAC,aAAa,EAAA,QAAA,EACjF,IAAI,CAAC,KAAK,EAAA,CACC,EAEdA,GAAA,CAAA,IAAA,EAAA,EAAA,QAAA,EACEA,GAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,MAAM,EAAA,QAAA,EACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAsB,MACrCA,GAAA,CAAA,IAAA,EAAA,EAA0B,SAAS,EAAC,SAAS,EAAA,QAAA,EAC3CA,GAAA,CAAC,WAAW,EAAA,EACV,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,IAAI,EAAC,mBAAmB,EACxB,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,IAAI,EACrC,OAAO,EAAE,UAAU,EAAA,QAAA,EAElB,SAAS,CAAC,KAAK,EAAA,CACJ,EAAA,EATP,SAAS,CAAC,KAAK,CAUnB,CACN,CAAC,EAAA,CACC,EAAA,CACF,CAAA,EAAA,EArBO,IAAI,CAAC,KAAK,CAsBd;YAEd;YAEA,QACEA,GAAA,CAAA,IAAA,EAAA,EAAqB,SAAS,EAAC,OAAO,YACpCA,GAAA,CAAC,WAAW,EAAA,EAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAA,QAAA,EAChI,IAAI,CAAC,KAAK,EAAA,CACC,EAAA,EAHP,IAAI,CAAC,KAAK,CAId;QAET,CAAC,CAAC,EAAA,CACC;AAET;;;;"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keyboard access to the dual-tier sub-navigation. The panel is otherwise reachable
|
|
7
|
+
* only by hover or by tabbing past every primary item, so `ArrowRight` on a parent
|
|
8
|
+
* jumps focus straight into its panel and `ArrowLeft`/`Escape` returns focus to the
|
|
9
|
+
* parent that opened it.
|
|
10
|
+
*/
|
|
11
|
+
const useDualTierKeyboard = ({ isPanelVisible, currentLabel, onSelectSection, onReveal }) => {
|
|
12
|
+
const panelRef = React.useRef(null);
|
|
13
|
+
// The primary item that opened the panel, so ArrowLeft/Escape can restore focus.
|
|
14
|
+
const triggerRef = React.useRef(null);
|
|
15
|
+
// Set when a keyboard action should move focus into the panel once it renders.
|
|
16
|
+
const focusPanelOnOpen = React.useRef(false);
|
|
17
|
+
const focusFirstPanelItem = () => panelRef.current?.querySelector('a, button')?.focus();
|
|
18
|
+
// Move focus into the panel once it has rendered (or swapped section) after a
|
|
19
|
+
// keyboard-triggered open.
|
|
20
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: focusFirstPanelItem only reads the stable panelRef
|
|
21
|
+
React.useEffect(() => {
|
|
22
|
+
if (isPanelVisible && focusPanelOnOpen.current) {
|
|
23
|
+
focusPanelOnOpen.current = false;
|
|
24
|
+
focusFirstPanelItem();
|
|
25
|
+
}
|
|
26
|
+
}, [isPanelVisible, currentLabel]);
|
|
27
|
+
/**
|
|
28
|
+
* `ArrowRight` on a parent selects its section, reveals the panel, and moves focus
|
|
29
|
+
* into it — or focuses it immediately when it is already the open section.
|
|
30
|
+
*/
|
|
31
|
+
const handleTriggerKeyDown = (label, hasChildren) => (event) => {
|
|
32
|
+
if (event.key !== 'ArrowRight' || !hasChildren)
|
|
33
|
+
return;
|
|
34
|
+
event.preventDefault();
|
|
35
|
+
triggerRef.current = event.currentTarget.querySelector('a, button');
|
|
36
|
+
if (isPanelVisible && currentLabel === label) {
|
|
37
|
+
focusFirstPanelItem();
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
focusPanelOnOpen.current = true;
|
|
41
|
+
onSelectSection(label);
|
|
42
|
+
onReveal();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/** `ArrowLeft`/`Escape` inside the panel returns focus to the parent that opened it. */
|
|
46
|
+
const handlePanelKeyDown = (event) => {
|
|
47
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'Escape')
|
|
48
|
+
return;
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
triggerRef.current?.focus();
|
|
51
|
+
};
|
|
52
|
+
return { panelRef, handleTriggerKeyDown, handlePanelKeyDown };
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
exports.useDualTierKeyboard = useDualTierKeyboard;
|
|
56
|
+
//# sourceMappingURL=use-dual-tier-keyboard.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-dual-tier-keyboard.cjs","sources":["../../../../../src/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.ts"],"sourcesContent":[null],"names":["useRef","useEffect"],"mappings":";;;;AAgBA;;;;;AAKG;AACI,MAAM,mBAAmB,GAAG,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAA2B,KAAI;AAC1H,IAAA,MAAM,QAAQ,GAAGA,YAAM,CAAiB,IAAI,CAAC;;AAE7C,IAAA,MAAM,UAAU,GAAGA,YAAM,CAAqB,IAAI,CAAC;;AAEnD,IAAA,MAAM,gBAAgB,GAAGA,YAAM,CAAC,KAAK,CAAC;AAEtC,IAAA,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAc,WAAW,CAAC,EAAE,KAAK,EAAE;;;;IAKpGC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI,cAAc,IAAI,gBAAgB,CAAC,OAAO,EAAE;AAC9C,YAAA,gBAAgB,CAAC,OAAO,GAAG,KAAK;AAChC,YAAA,mBAAmB,EAAE;QACvB;AACF,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAElC;;;AAGG;AACH,IAAA,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,WAAoB,KAAK,CAAC,KAAmC,KAAI;AAC5G,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,WAAW;YAAE;QAChD,KAAK,CAAC,cAAc,EAAE;QACtB,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,aAAa,CAAc,WAAW,CAAC;AAChF,QAAA,IAAI,cAAc,IAAI,YAAY,KAAK,KAAK,EAAE;AAC5C,YAAA,mBAAmB,EAAE;QACvB;aAAO;AACL,YAAA,gBAAgB,CAAC,OAAO,GAAG,IAAI;YAC/B,eAAe,CAAC,KAAK,CAAC;AACtB,YAAA,QAAQ,EAAE;QACZ;AACF,IAAA,CAAC;;AAGD,IAAA,MAAM,kBAAkB,GAAG,CAAC,KAAoC,KAAI;QAClE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;YAAE;QACzD,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE;AAC7B,IAAA,CAAC;AAED,IAAA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,kBAAkB,EAAE;AAC/D;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { KeyboardEvent } from 'react';
|
|
2
|
+
interface DualTierKeyboardOptions {
|
|
3
|
+
/** Whether the secondary sub-navigation panel is currently visible. */
|
|
4
|
+
isPanelVisible: boolean;
|
|
5
|
+
/** Label of the section whose children the panel currently shows. */
|
|
6
|
+
currentLabel: string | undefined;
|
|
7
|
+
/** Select a section as the current one (which reveals its children in the panel). */
|
|
8
|
+
onSelectSection: (label: string) => void;
|
|
9
|
+
/** Mark the panel as revealed because focus has moved within the sidebar. */
|
|
10
|
+
onReveal: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Keyboard access to the dual-tier sub-navigation. The panel is otherwise reachable
|
|
14
|
+
* only by hover or by tabbing past every primary item, so `ArrowRight` on a parent
|
|
15
|
+
* jumps focus straight into its panel and `ArrowLeft`/`Escape` returns focus to the
|
|
16
|
+
* parent that opened it.
|
|
17
|
+
*/
|
|
18
|
+
export declare const useDualTierKeyboard: ({ isPanelVisible, currentLabel, onSelectSection, onReveal }: DualTierKeyboardOptions) => {
|
|
19
|
+
panelRef: import("react").RefObject<HTMLDivElement | null>;
|
|
20
|
+
handleTriggerKeyDown: (label: string, hasChildren: boolean) => (event: KeyboardEvent<HTMLLIElement>) => void;
|
|
21
|
+
handlePanelKeyDown: (event: KeyboardEvent<HTMLDivElement>) => void;
|
|
22
|
+
};
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=use-dual-tier-keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-dual-tier-keyboard.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,UAAU,uBAAuB;IAC/B,uEAAuE;IACvE,cAAc,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,qFAAqF;IACrF,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,6DAA6D,uBAAuB;;kCAuBjF,MAAM,eAAe,OAAO,MAAM,OAAO,aAAa,CAAC,aAAa,CAAC;gCAcvE,aAAa,CAAC,cAAc,CAAC;CAOjE,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Keyboard access to the dual-tier sub-navigation. The panel is otherwise reachable
|
|
5
|
+
* only by hover or by tabbing past every primary item, so `ArrowRight` on a parent
|
|
6
|
+
* jumps focus straight into its panel and `ArrowLeft`/`Escape` returns focus to the
|
|
7
|
+
* parent that opened it.
|
|
8
|
+
*/
|
|
9
|
+
const useDualTierKeyboard = ({ isPanelVisible, currentLabel, onSelectSection, onReveal }) => {
|
|
10
|
+
const panelRef = useRef(null);
|
|
11
|
+
// The primary item that opened the panel, so ArrowLeft/Escape can restore focus.
|
|
12
|
+
const triggerRef = useRef(null);
|
|
13
|
+
// Set when a keyboard action should move focus into the panel once it renders.
|
|
14
|
+
const focusPanelOnOpen = useRef(false);
|
|
15
|
+
const focusFirstPanelItem = () => panelRef.current?.querySelector('a, button')?.focus();
|
|
16
|
+
// Move focus into the panel once it has rendered (or swapped section) after a
|
|
17
|
+
// keyboard-triggered open.
|
|
18
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: focusFirstPanelItem only reads the stable panelRef
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (isPanelVisible && focusPanelOnOpen.current) {
|
|
21
|
+
focusPanelOnOpen.current = false;
|
|
22
|
+
focusFirstPanelItem();
|
|
23
|
+
}
|
|
24
|
+
}, [isPanelVisible, currentLabel]);
|
|
25
|
+
/**
|
|
26
|
+
* `ArrowRight` on a parent selects its section, reveals the panel, and moves focus
|
|
27
|
+
* into it — or focuses it immediately when it is already the open section.
|
|
28
|
+
*/
|
|
29
|
+
const handleTriggerKeyDown = (label, hasChildren) => (event) => {
|
|
30
|
+
if (event.key !== 'ArrowRight' || !hasChildren)
|
|
31
|
+
return;
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
triggerRef.current = event.currentTarget.querySelector('a, button');
|
|
34
|
+
if (isPanelVisible && currentLabel === label) {
|
|
35
|
+
focusFirstPanelItem();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
focusPanelOnOpen.current = true;
|
|
39
|
+
onSelectSection(label);
|
|
40
|
+
onReveal();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/** `ArrowLeft`/`Escape` inside the panel returns focus to the parent that opened it. */
|
|
44
|
+
const handlePanelKeyDown = (event) => {
|
|
45
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'Escape')
|
|
46
|
+
return;
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
triggerRef.current?.focus();
|
|
49
|
+
};
|
|
50
|
+
return { panelRef, handleTriggerKeyDown, handlePanelKeyDown };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { useDualTierKeyboard };
|
|
54
|
+
//# sourceMappingURL=use-dual-tier-keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-dual-tier-keyboard.js","sources":["../../../../../src/components/organisms/SidebarNavigation/hooks/use-dual-tier-keyboard.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAgBA;;;;;AAKG;AACI,MAAM,mBAAmB,GAAG,CAAC,EAAE,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAA2B,KAAI;AAC1H,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC;;AAE7C,IAAA,MAAM,UAAU,GAAG,MAAM,CAAqB,IAAI,CAAC;;AAEnD,IAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,KAAK,CAAC;AAEtC,IAAA,MAAM,mBAAmB,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAc,WAAW,CAAC,EAAE,KAAK,EAAE;;;;IAKpG,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,cAAc,IAAI,gBAAgB,CAAC,OAAO,EAAE;AAC9C,YAAA,gBAAgB,CAAC,OAAO,GAAG,KAAK;AAChC,YAAA,mBAAmB,EAAE;QACvB;AACF,IAAA,CAAC,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAElC;;;AAGG;AACH,IAAA,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAE,WAAoB,KAAK,CAAC,KAAmC,KAAI;AAC5G,QAAA,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY,IAAI,CAAC,WAAW;YAAE;QAChD,KAAK,CAAC,cAAc,EAAE;QACtB,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC,aAAa,CAAC,aAAa,CAAc,WAAW,CAAC;AAChF,QAAA,IAAI,cAAc,IAAI,YAAY,KAAK,KAAK,EAAE;AAC5C,YAAA,mBAAmB,EAAE;QACvB;aAAO;AACL,YAAA,gBAAgB,CAAC,OAAO,GAAG,IAAI;YAC/B,eAAe,CAAC,KAAK,CAAC;AACtB,YAAA,QAAQ,EAAE;QACZ;AACF,IAAA,CAAC;;AAGD,IAAA,MAAM,kBAAkB,GAAG,CAAC,KAAoC,KAAI;QAClE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;YAAE;QACzD,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE;AAC7B,IAAA,CAAC;AAED,IAAA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,kBAAkB,EAAE;AAC/D;;;;"}
|
|
@@ -13,6 +13,7 @@ var navAccountCard = require('./components/nav-account-card.cjs');
|
|
|
13
13
|
var navButton = require('./components/nav-button.cjs');
|
|
14
14
|
var navItem = require('./components/nav-item.cjs');
|
|
15
15
|
var navList = require('./components/nav-list.cjs');
|
|
16
|
+
var useDualTierKeyboard = require('./hooks/use-dual-tier-keyboard.cjs');
|
|
16
17
|
var sidebarMenuButton = require('./components/sidebar-menu-button.cjs');
|
|
17
18
|
|
|
18
19
|
const COLLAPSED_WIDTH = 68;
|
|
@@ -22,11 +23,12 @@ const SECONDARY_SIDEBAR_WIDTH = 256;
|
|
|
22
23
|
* The primary app-shell navigation rail. It renders a logo, a list of
|
|
23
24
|
* destinations, footer links, and an account card, and can be toggled between a
|
|
24
25
|
* labelled list and an icon-only strip (the choice persists across reloads).
|
|
25
|
-
* Hovering
|
|
26
|
-
*
|
|
26
|
+
* Hovering (or focusing) the sidebar reveals a secondary sub-navigation panel
|
|
27
|
+
* listing the current section's children; clicking a primary item switches the
|
|
28
|
+
* current section and navigates. Below the `lg` breakpoint it collapses into a
|
|
27
29
|
* mobile header with a slide-over menu.
|
|
28
30
|
*
|
|
29
|
-
* @summary
|
|
31
|
+
* @summary Navigate app sections through a collapsible, dual-tier sidebar rail.
|
|
30
32
|
*/
|
|
31
33
|
const SidebarNavigation = ({ activeUrl, items, footerItems = [], account, collapsed, defaultCollapsed = false, onCollapsedChange, persistCollapsed = true, hideBorder, hideRightBorder, showMobileHeader = true, mobileMenuOpen, onMobileMenuOpenChange, }) => {
|
|
32
34
|
const isControlled = collapsed !== undefined;
|
|
@@ -58,87 +60,67 @@ const SidebarNavigation = ({ activeUrl, items, footerItems = [], account, collap
|
|
|
58
60
|
localStorageUtils.sidebarCollapsedStorage.set(next);
|
|
59
61
|
};
|
|
60
62
|
const isActive = (item) => item.href === activeUrl || item.items?.some((sub) => sub.href === activeUrl);
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
// Dual-tier reveal: the secondary panel is shown whenever the
|
|
64
|
+
// pointer is over — or focus is within — the sidebar, and it always lists the
|
|
65
|
+
// children of `currentItem`. `currentItem` is seeded from the active route and
|
|
66
|
+
// switched by clicking (or keyboard-activating) a primary item, which also
|
|
67
|
+
// navigates. Only `currentItem` is highlighted, so exactly one item is ever active.
|
|
68
|
+
const sections = [...items, ...footerItems];
|
|
69
|
+
const activeItem = sections.find((item) => isActive(item));
|
|
70
|
+
const activeLabel = activeItem?.label;
|
|
71
|
+
// Track the current section by its (unique) label rather than the object, so it
|
|
72
|
+
// survives the consumer passing a fresh `items` array and never collides on href.
|
|
73
|
+
const [currentLabel, setCurrentLabel] = React.useState(activeLabel);
|
|
74
|
+
// Keep the selected section in sync with the active route when it changes externally
|
|
75
|
+
// (browser navigation, a controlled `activeUrl`, or asynchronously-loaded items).
|
|
76
|
+
React.useEffect(() => {
|
|
77
|
+
if (activeLabel !== undefined)
|
|
78
|
+
setCurrentLabel(activeLabel);
|
|
79
|
+
}, [activeLabel]);
|
|
80
|
+
const currentItem = sections.find((item) => item.label === currentLabel);
|
|
81
|
+
const [isHovering, setIsHovering] = React.useState(false);
|
|
82
|
+
const [isFocusWithin, setIsFocusWithin] = React.useState(false);
|
|
83
|
+
const isSecondarySidebarVisible = (isHovering || isFocusWithin) && Boolean(currentItem?.items?.length);
|
|
66
84
|
const panelId = React.useId();
|
|
67
85
|
// Ties the built-in mobile toggle to the drawer it opens via `aria-controls`.
|
|
68
86
|
const mobileMenuId = React.useId();
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
const suppressReveal = React.useRef(false);
|
|
76
|
-
const focusFirstPanelItem = () => panelRef.current?.querySelector('a, button')?.focus();
|
|
77
|
-
// Move focus into the panel once it has rendered after a keyboard-triggered open.
|
|
78
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: focusFirstPanelItem only reads the stable panelRef
|
|
79
|
-
React.useEffect(() => {
|
|
80
|
-
if (isSecondarySidebarVisible && focusPanelOnOpen.current) {
|
|
81
|
-
focusPanelOnOpen.current = false;
|
|
82
|
-
focusFirstPanelItem();
|
|
83
|
-
}
|
|
84
|
-
}, [isSecondarySidebarVisible]);
|
|
85
|
-
const revealSubNav = (item) => {
|
|
86
|
-
if (suppressReveal.current) {
|
|
87
|
-
suppressReveal.current = false;
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
if (item.items?.length) {
|
|
91
|
-
setPanelItem(item);
|
|
92
|
-
setShowSubNav(true);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// Hovering/focusing a leaf destination closes any open panel.
|
|
96
|
-
setShowSubNav(false);
|
|
97
|
-
}
|
|
87
|
+
// Only *keyboard* focus holds the panel open. Focus parked on a just-clicked link
|
|
88
|
+
// (pointer modality) must not — otherwise the panel lingers after a mouse click even
|
|
89
|
+
// once the pointer leaves. Gating on `:focus-visible` keeps the mouse behaviour
|
|
90
|
+
// identical to Untitled UI (closes on pointer-leave) while preserving keyboard reach.
|
|
91
|
+
const handleContainerFocus = (event) => {
|
|
92
|
+
setIsFocusWithin(event.target.matches(':focus-visible'));
|
|
98
93
|
};
|
|
99
|
-
const hideSubNav = () => setShowSubNav(false);
|
|
100
94
|
const handleContainerBlur = (event) => {
|
|
101
95
|
if (!event.currentTarget.contains(event.relatedTarget))
|
|
102
|
-
|
|
103
|
-
};
|
|
104
|
-
// ArrowRight on a parent item opens (if needed) and moves focus into the panel.
|
|
105
|
-
const handlePrimaryKeyDown = (item) => (event) => {
|
|
106
|
-
if (event.key !== 'ArrowRight' || !item.items?.length)
|
|
107
|
-
return;
|
|
108
|
-
event.preventDefault();
|
|
109
|
-
triggerRef.current = event.currentTarget.querySelector('a, button');
|
|
110
|
-
if (isSecondarySidebarVisible && panelItem?.label === item.label) {
|
|
111
|
-
focusFirstPanelItem();
|
|
112
|
-
}
|
|
113
|
-
else {
|
|
114
|
-
focusPanelOnOpen.current = true;
|
|
115
|
-
setPanelItem(item);
|
|
116
|
-
setShowSubNav(true);
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
// ArrowLeft/Escape inside the panel closes it and restores focus to the parent.
|
|
120
|
-
const handlePanelKeyDown = (event) => {
|
|
121
|
-
if (event.key !== 'ArrowLeft' && event.key !== 'Escape')
|
|
122
|
-
return;
|
|
123
|
-
event.preventDefault();
|
|
124
|
-
suppressReveal.current = true;
|
|
125
|
-
hideSubNav();
|
|
126
|
-
triggerRef.current?.focus();
|
|
96
|
+
setIsFocusWithin(false);
|
|
127
97
|
};
|
|
98
|
+
const { panelRef, handleTriggerKeyDown, handlePanelKeyDown } = useDualTierKeyboard.useDualTierKeyboard({
|
|
99
|
+
isPanelVisible: isSecondarySidebarVisible,
|
|
100
|
+
currentLabel,
|
|
101
|
+
onSelectSection: setCurrentLabel,
|
|
102
|
+
onReveal: () => setIsFocusWithin(true),
|
|
103
|
+
});
|
|
128
104
|
const renderPrimaryItems = (list) => list.map((item) => {
|
|
129
105
|
const hasChildren = Boolean(item.items?.length);
|
|
130
|
-
|
|
106
|
+
// `isCurrentPage` (exact URL match) drives `aria-current`; `isSelected` (the open
|
|
107
|
+
// section) drives the brand highlight. A parent whose child is active is selected
|
|
108
|
+
// but is NOT the current page.
|
|
109
|
+
const isCurrentPage = item.href === activeUrl;
|
|
110
|
+
const isSelected = currentLabel === item.label;
|
|
111
|
+
const isOpen = hasChildren && isSelected && isSecondarySidebarVisible;
|
|
131
112
|
// Disclosure semantics: parents announce their expanded state and, once open, the panel they control.
|
|
132
113
|
const disclosure = {
|
|
133
114
|
'aria-expanded': hasChildren ? isOpen : undefined,
|
|
134
115
|
'aria-controls': isOpen ? panelId : undefined,
|
|
135
116
|
};
|
|
136
|
-
|
|
117
|
+
const selectSection = () => setCurrentLabel(item.label);
|
|
118
|
+
return (jsxRuntime.jsx("li", { className: isCollapsed ? undefined : 'py-px', onKeyDown: handleTriggerKeyDown(item.label, hasChildren), children: isCollapsed ? (jsxRuntime.jsx(navButton.NavButton, { current: isCurrentPage, selected: isSelected, href: item.href, onClick: selectSection, label: item.label || '', icon: item.icon, ...disclosure })) : (jsxRuntime.jsx(navItem.NavItemBase, { type: "link", current: isCurrentPage, selected: isSelected, href: item.href, icon: item.icon, badge: item.badge, hasSubmenu: hasChildren, onClick: selectSection, ...disclosure, children: item.label })) }, item.label));
|
|
137
119
|
});
|
|
138
120
|
const mainSidebar = (jsxRuntime.jsxs(react.motion.aside, { animate: { width: isCollapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH }, transition: { type: 'spring', damping: 26, stiffness: 220, bounce: 0 }, className: cx.cx('flex h-full max-h-full flex-col justify-between overflow-x-hidden overflow-y-auto bg-secondary', !hideBorder && 'border-r border-secondary'), children: [jsxRuntime.jsxs("div", { className: "flex flex-col", children: [isCollapsed ? (jsxRuntime.jsx("div", { className: "flex justify-center px-3 py-5", children: jsxRuntime.jsx(UtilityButton.ButtonUtility, { size: "sm", color: "tertiary", tooltip: "Expand", "aria-label": "Expand navigation", icon: uiIcons.ChevronRightDouble, onClick: () => setCollapsed(false) }) })) : (jsxRuntime.jsxs("div", { className: "relative flex items-center px-5 py-5", children: [jsxRuntime.jsx(FlipdishLogo.FlipdishLogo, { size: "md" }), jsxRuntime.jsx("div", { className: "absolute top-5 right-4", children: jsxRuntime.jsx(UtilityButton.ButtonUtility, { size: "sm", color: "tertiary", tooltip: "Collapse", "aria-label": "Collapse navigation", icon: uiIcons.ChevronLeftDouble, onClick: () => setCollapsed(true) }) })] })), jsxRuntime.jsx("ul", { className: cx.cx('flex flex-col gap-0.5', isCollapsed ? 'items-center px-3.5' : 'px-4 pt-1'), children: renderPrimaryItems(items) })] }), jsxRuntime.jsxs("div", { className: cx.cx('mt-auto flex flex-col gap-3 py-4', isCollapsed ? 'items-center px-3' : 'px-4'), children: [footerItems.length > 0 && jsxRuntime.jsx("ul", { className: cx.cx('flex flex-col gap-0.5', isCollapsed && 'items-center'), children: renderPrimaryItems(footerItems) }), account &&
|
|
139
121
|
(isCollapsed ? (jsxRuntime.jsx(navAccountCard.NavAccountCard, { variant: "avatar", account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })) : (jsxRuntime.jsx(navAccountCard.NavAccountCard, { account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })))] })] }));
|
|
140
|
-
const secondarySidebar =
|
|
141
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "z-50 hidden lg:fixed lg:inset-y-0 lg:left-0 lg:flex",
|
|
122
|
+
const secondarySidebar = currentItem && (jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: isSecondarySidebarVisible && (jsxRuntime.jsx(react.motion.div, { ref: panelRef, id: panelId, onKeyDown: handlePanelKeyDown, role: "group", "aria-label": `${currentItem.label} pages`, initial: { width: 0, borderColor: 'var(--color-border-secondary)' }, animate: { width: SECONDARY_SIDEBAR_WIDTH, borderColor: 'var(--color-border-secondary)' }, exit: { width: 0, borderColor: 'rgba(0,0,0,0)', transition: { borderColor: { type: 'tween', delay: 0.05 } } }, transition: { type: 'spring', damping: 26, stiffness: 220, bounce: 0 }, className: cx.cx('relative h-full overflow-x-hidden overflow-y-auto bg-primary', !(hideBorder || hideRightBorder) && 'box-content border-r border-secondary'), children: jsxRuntime.jsxs("div", { style: { width: SECONDARY_SIDEBAR_WIDTH }, className: "flex h-full flex-col px-4 pt-6", children: [jsxRuntime.jsx("h3", { className: "px-2 text-sm font-semibold text-tertiary", children: currentItem.label }), jsxRuntime.jsx("ul", { className: "py-2", children: currentItem.items?.map((item) => (jsxRuntime.jsx("li", { className: "py-px", children: jsxRuntime.jsx(navItem.NavItemBase, { type: "link", current: activeUrl === item.href, href: item.href, icon: item.icon, badge: item.badge, children: item.label }) }, item.label))) })] }) })) }));
|
|
123
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "z-50 hidden lg:fixed lg:inset-y-0 lg:left-0 lg:flex", onPointerEnter: () => setIsHovering(true), onPointerLeave: () => setIsHovering(false), onFocus: handleContainerFocus, onBlur: handleContainerBlur, children: [mainSidebar, secondarySidebar] }), jsxRuntime.jsx("div", { style: { paddingLeft: isCollapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH }, className: "invisible hidden lg:sticky lg:top-0 lg:bottom-0 lg:left-0 lg:block" }), showMobileHeader && jsxRuntime.jsx(mobileHeader.MobileNavigationHeader, { isOpen: isMobileMenuOpen, onOpenChange: setMobileMenuOpen, controls: mobileMenuId }), jsxRuntime.jsx(mobileHeader.MobileNavigationDrawer, { id: mobileMenuId, isOpen: isMobileMenuOpen, onOpenChange: setMobileMenuOpen, children: jsxRuntime.jsxs("aside", { className: "group flex h-full max-h-full w-full max-w-full flex-col justify-between overflow-y-auto bg-secondary pt-4", children: [jsxRuntime.jsx("div", { className: "px-4", children: jsxRuntime.jsx(FlipdishLogo.FlipdishLogo, { size: "sm" }) }), jsxRuntime.jsx(navList.NavList, { activeUrl: activeUrl, items: items, onNavigate: () => setMobileMenuOpen(false) }), jsxRuntime.jsxs("div", { className: "mt-auto flex flex-col gap-3 p-4", children: [footerItems.length > 0 && (jsxRuntime.jsx("ul", { className: "flex flex-col gap-0.5", children: footerItems.map((item) => (jsxRuntime.jsx("li", { children: jsxRuntime.jsx(navItem.NavItemBase, { type: "link", current: activeUrl === item.href, href: item.href, icon: item.icon, badge: item.badge, onClick: () => setMobileMenuOpen(false), children: item.label }) }, item.label))) })), account && jsxRuntime.jsx(navAccountCard.NavAccountCard, { account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })] })] }) })] }));
|
|
142
124
|
};
|
|
143
125
|
|
|
144
126
|
exports.NavAccountCard = navAccountCard.NavAccountCard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"sourcesContent":[null],"names":["useState","useEffect","sidebarCollapsedStorage","useId","
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"sourcesContent":[null],"names":["useState","useEffect","sidebarCollapsedStorage","useId","useDualTierKeyboard","_jsx","NavButton","NavItemBase","_jsxs","motion","cx","ButtonUtility","ChevronRightDouble","FlipdishLogo","ChevronLeftDouble","NavAccountCard","AnimatePresence","_Fragment","MobileNavigationHeader","MobileNavigationDrawer","NavList"],"mappings":";;;;;;;;;;;;;;;;;;AA0DA,MAAM,eAAe,GAAG,EAAE;AAC1B,MAAM,cAAc,GAAG,GAAG;AAC1B,MAAM,uBAAuB,GAAG,GAAG;AAEnC;;;;;;;;;;AAUG;AACI,MAAM,iBAAiB,GAAG,CAAC,EAChC,SAAS,EACT,KAAK,EACL,WAAW,GAAG,EAAE,EAChB,OAAO,EACP,SAAS,EACT,gBAAgB,GAAG,KAAK,EACxB,iBAAiB,EACjB,gBAAgB,GAAG,IAAI,EACvB,UAAU,EACV,eAAe,EACf,gBAAgB,GAAG,IAAI,EACvB,cAAc,EACd,sBAAsB,GACC,KAAI;AAC3B,IAAA,MAAM,YAAY,GAAG,SAAS,KAAK,SAAS;IAC5C,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAGA,cAAQ,CAAC,gBAAgB,CAAC;IAC5E,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,GAAG,iBAAiB;;AAGhE,IAAA,MAAM,sBAAsB,GAAG,cAAc,KAAK,SAAS;IAC3D,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IAC3E,MAAM,gBAAgB,GAAG,sBAAsB,GAAG,cAAc,GAAG,sBAAsB;AACzF,IAAA,MAAM,iBAAiB,GAAG,CAAC,IAAa,KAAI;AAC1C,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAC9B,QAAA,IAAI,CAAC,sBAAsB;YAAE,yBAAyB,CAAC,IAAI,CAAC;AAC9D,IAAA,CAAC;;IAGDC,eAAS,CAAC,MAAK;QACb,IAAI,YAAY,IAAI,CAAC,gBAAgB;YAAE;AACvC,QAAA,MAAM,MAAM,GAAGC,yCAAuB,CAAC,GAAG,EAAE;QAC5C,IAAI,MAAM,KAAK,IAAI;YAAE,oBAAoB,CAAC,MAAM,CAAC;AACnD,IAAA,CAAC,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;AAEpC,IAAA,MAAM,YAAY,GAAG,CAAC,IAAa,KAAI;AACrC,QAAA,iBAAiB,GAAG,IAAI,CAAC;AACzB,QAAA,IAAI,YAAY;YAAE;QAClB,oBAAoB,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,gBAAgB;AAAE,YAAAA,yCAAuB,CAAC,GAAG,CAAC,IAAI,CAAC;AACzD,IAAA,CAAC;AAED,IAAA,MAAM,QAAQ,GAAG,CAAC,IAAoB,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC;;;;;;IAOvH,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC;AAC3C,IAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC1D,IAAA,MAAM,WAAW,GAAG,UAAU,EAAE,KAAK;;;IAIrC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAGF,cAAQ,CAAqB,WAAW,CAAC;;;IAIjFC,eAAS,CAAC,MAAK;QACb,IAAI,WAAW,KAAK,SAAS;YAAE,eAAe,CAAC,WAAW,CAAC;AAC7D,IAAA,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;AAEjB,IAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,YAAY,CAAC;IACxE,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAGD,cAAQ,CAAC,KAAK,CAAC;IACnD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;AACzD,IAAA,MAAM,yBAAyB,GAAG,CAAC,UAAU,IAAI,aAAa,KAAK,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC;AAEtG,IAAA,MAAM,OAAO,GAAGG,WAAK,EAAE;;AAEvB,IAAA,MAAM,YAAY,GAAGA,WAAK,EAAE;;;;;AAM5B,IAAA,MAAM,oBAAoB,GAAG,CAAC,KAAiC,KAAI;QACjE,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC1D,IAAA,CAAC;AAED,IAAA,MAAM,mBAAmB,GAAG,CAAC,KAAiC,KAAI;QAChE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;YAAE,gBAAgB,CAAC,KAAK,CAAC;AACjF,IAAA,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,GAAGC,uCAAmB,CAAC;AACjF,QAAA,cAAc,EAAE,yBAAyB;QACzC,YAAY;AACZ,QAAA,eAAe,EAAE,eAAe;AAChC,QAAA,QAAQ,EAAE,MAAM,gBAAgB,CAAC,IAAI,CAAC;AACvC,KAAA,CAAC;AAEF,IAAA,MAAM,kBAAkB,GAAG,CAAC,IAAsB,KAChD,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;QAChB,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;;;;AAI/C,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS;AAC7C,QAAA,MAAM,UAAU,GAAG,YAAY,KAAK,IAAI,CAAC,KAAK;AAC9C,QAAA,MAAM,MAAM,GAAG,WAAW,IAAI,UAAU,IAAI,yBAAyB;;AAErE,QAAA,MAAM,UAAU,GAAG;YACjB,eAAe,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS;YACjD,eAAe,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;SAC9C;QACD,MAAM,aAAa,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;AAEvD,QAAA,QACEC,cAAA,CAAA,IAAA,EAAA,EAAqB,SAAS,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,EAAA,QAAA,EACxH,WAAW,IACVA,cAAA,CAACC,mBAAS,EAAA,EACR,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE,EACvB,IAAI,EAAE,IAAI,CAAC,IAAI,EAAA,GACX,UAAU,EAAA,CACd,KAEFD,cAAA,CAACE,mBAAW,EAAA,EACV,IAAI,EAAC,MAAM,EACX,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,UAAU,EAAE,WAAW,EACvB,OAAO,EAAE,aAAa,EAAA,GAClB,UAAU,EAAA,QAAA,EAEb,IAAI,CAAC,KAAK,EAAA,CACC,CACf,EAAA,EAzBM,IAAI,CAAC,KAAK,CA0Bd;AAET,IAAA,CAAC,CAAC;IAEJ,MAAM,WAAW,IACfC,eAAA,CAACC,YAAM,CAAC,KAAK,EAAA,EACX,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,EAAE,EAClE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,EACtE,SAAS,EAAEC,KAAE,CACX,gGAAgG,EAChG,CAAC,UAAU,IAAI,2BAA2B,CAC3C,EAAA,QAAA,EAAA,CAEDF,yBAAK,SAAS,EAAC,eAAe,EAAA,QAAA,EAAA,CAE3B,WAAW,IACVH,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,+BAA+B,YAC5CA,cAAA,CAACM,2BAAa,EAAA,EACZ,IAAI,EAAC,IAAI,EACT,KAAK,EAAC,UAAU,EAChB,OAAO,EAAC,QAAQ,gBACL,mBAAmB,EAC9B,IAAI,EAAEC,0BAAkB,EACxB,OAAO,EAAE,MAAM,YAAY,CAAC,KAAK,CAAC,EAAA,CAClC,EAAA,CACE,KAENJ,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,sCAAsC,EAAA,QAAA,EAAA,CACnDH,cAAA,CAACQ,yBAAY,EAAA,EAAC,IAAI,EAAC,IAAI,EAAA,CAAG,EAC1BR,wBAAK,SAAS,EAAC,wBAAwB,EAAA,QAAA,EACrCA,cAAA,CAACM,2BAAa,IACZ,IAAI,EAAC,IAAI,EACT,KAAK,EAAC,UAAU,EAChB,OAAO,EAAC,UAAU,EAAA,YAAA,EACP,qBAAqB,EAChC,IAAI,EAAEG,yBAAiB,EACvB,OAAO,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,EAAA,CACjC,GACE,CAAA,EAAA,CACF,CACP,EAEDT,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAEK,KAAE,CAAC,uBAAuB,EAAE,WAAW,GAAG,qBAAqB,GAAG,WAAW,CAAC,EAAA,QAAA,EAAG,kBAAkB,CAAC,KAAK,CAAC,EAAA,CAAM,CAAA,EAAA,CAC3H,EAENF,yBAAK,SAAS,EAAEE,KAAE,CAAC,kCAAkC,EAAE,WAAW,GAAG,mBAAmB,GAAG,MAAM,CAAC,EAAA,QAAA,EAAA,CAC/F,WAAW,CAAC,MAAM,GAAG,CAAC,IAAIL,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAEK,KAAE,CAAC,uBAAuB,EAAE,WAAW,IAAI,cAAc,CAAC,EAAA,QAAA,EAAG,kBAAkB,CAAC,WAAW,CAAC,EAAA,CAAM,EAE3I,OAAO;AACN,yBAAC,WAAW,IACVL,cAAA,CAACU,6BAAc,EAAA,EAAC,OAAO,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAA,CAAI,KAErIV,cAAA,CAACU,6BAAc,EAAA,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAA,CAAI,CACrH,CAAC,CAAA,EAAA,CACA,CAAA,EAAA,CACO,CAChB;IAED,MAAM,gBAAgB,GAAG,WAAW,KAClCV,eAACW,qBAAe,EAAA,EAAC,OAAO,EAAE,KAAK,EAAA,QAAA,EAC5B,yBAAyB,KACxBX,cAAA,CAACI,YAAM,CAAC,GAAG,IACT,GAAG,EAAE,QAAQ,EACb,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,kBAAkB,EAC7B,IAAI,EAAC,OAAO,EAAA,YAAA,EACA,CAAA,EAAG,WAAW,CAAC,KAAK,QAAQ,EACxC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,EACnE,OAAO,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,+BAA+B,EAAE,EACzF,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,EAC7G,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,EACtE,SAAS,EAAEC,KAAE,CACX,8DAA8D,EAC9D,EAAE,UAAU,IAAI,eAAe,CAAC,IAAI,uCAAuC,CAC5E,EAAA,QAAA,EAEDF,eAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,SAAS,EAAC,gCAAgC,EAAA,QAAA,EAAA,CACxFH,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,0CAA0C,YAAE,WAAW,CAAC,KAAK,EAAA,CAAM,EACjFA,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,MAAM,EAAA,QAAA,EACjB,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,MAC3BA,cAAA,CAAA,IAAA,EAAA,EAAqB,SAAS,EAAC,OAAO,EAAA,QAAA,EACpCA,cAAA,CAACE,mBAAW,EAAA,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAA,QAAA,EAC3G,IAAI,CAAC,KAAK,EAAA,CACC,IAHP,IAAI,CAAC,KAAK,CAId,CACN,CAAC,EAAA,CACC,CAAA,EAAA,CACD,EAAA,CACK,CACd,EAAA,CACe,CACnB;IAED,QACEC,eAAA,CAAAS,mBAAA,EAAA,EAAA,QAAA,EAAA,CAIET,eAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,qDAAqD,EAC/D,cAAc,EAAE,MAAM,aAAa,CAAC,IAAI,CAAC,EACzC,cAAc,EAAE,MAAM,aAAa,CAAC,KAAK,CAAC,EAC1C,OAAO,EAAE,oBAAoB,EAC7B,MAAM,EAAE,mBAAmB,EAAA,QAAA,EAAA,CAE1B,WAAW,EACX,gBAAgB,CAAA,EAAA,CACb,EAINH,cAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAE,EAAE,WAAW,EAAE,WAAW,GAAG,eAAe,GAAG,cAAc,EAAE,EACtE,SAAS,EAAC,oEAAoE,EAAA,CAC9E,EAID,gBAAgB,IAAIA,cAAA,CAACa,mCAAsB,EAAA,EAAC,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,YAAY,EAAA,CAAI,EAClIb,cAAA,CAACc,mCAAsB,EAAA,EAAC,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAA,QAAA,EACjGX,eAAA,CAAA,OAAA,EAAA,EAAO,SAAS,EAAC,2GAA2G,EAAA,QAAA,EAAA,CAC1HH,cAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,MAAM,EAAA,QAAA,EACnBA,cAAA,CAACQ,yBAAY,EAAA,EAAC,IAAI,EAAC,IAAI,EAAA,CAAG,EAAA,CACtB,EAENR,cAAA,CAACe,eAAO,EAAA,EAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC,KAAK,CAAC,EAAA,CAAI,EAE3FZ,eAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,iCAAiC,EAAA,QAAA,EAAA,CAC7C,WAAW,CAAC,MAAM,GAAG,CAAC,KACrBH,cAAA,CAAA,IAAA,EAAA,EAAI,SAAS,EAAC,uBAAuB,EAAA,QAAA,EAClC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,MACpBA,cAAA,CAAA,IAAA,EAAA,EAAA,QAAA,EACEA,cAAA,CAACE,mBAAW,EAAA,EACV,IAAI,EAAC,MAAM,EACX,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC,IAAI,EAChC,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,OAAO,EAAE,MAAM,iBAAiB,CAAC,KAAK,CAAC,EAAA,QAAA,EAEtC,IAAI,CAAC,KAAK,EAAA,CACC,EAAA,EAVP,IAAI,CAAC,KAAK,CAWd,CACN,CAAC,EAAA,CACC,CACN,EAEA,OAAO,IAAIF,cAAA,CAACU,6BAAc,EAAA,EAAC,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAA,CAAI,CAAA,EAAA,CAC5H,CAAA,EAAA,CACA,EAAA,CACe,CAAA,EAAA,CACxB;AAEP;;;;;;;;"}
|
|
@@ -46,11 +46,12 @@ export interface SidebarNavigationProps {
|
|
|
46
46
|
* The primary app-shell navigation rail. It renders a logo, a list of
|
|
47
47
|
* destinations, footer links, and an account card, and can be toggled between a
|
|
48
48
|
* labelled list and an icon-only strip (the choice persists across reloads).
|
|
49
|
-
* Hovering
|
|
50
|
-
*
|
|
49
|
+
* Hovering (or focusing) the sidebar reveals a secondary sub-navigation panel
|
|
50
|
+
* listing the current section's children; clicking a primary item switches the
|
|
51
|
+
* current section and navigates. Below the `lg` breakpoint it collapses into a
|
|
51
52
|
* mobile header with a slide-over menu.
|
|
52
53
|
*
|
|
53
|
-
* @summary
|
|
54
|
+
* @summary Navigate app sections through a collapsible, dual-tier sidebar rail.
|
|
54
55
|
*/
|
|
55
56
|
export declare const SidebarNavigation: ({ activeUrl, items, footerItems, account, collapsed, defaultCollapsed, onCollapsedChange, persistCollapsed, hideBorder, hideRightBorder, showMobileHeader, mobileMenuOpen, onMobileMenuOpenChange, }: SidebarNavigationProps) => import("react").JSX.Element;
|
|
56
57
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAKpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACtJ,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAElG,KAAK,cAAc,GAAG,WAAW,GAAG;IAAE,IAAI,EAAE,EAAE,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,uCAAuC;IACvC,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,sHAAsH;IACtH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,8GAA8G;IAC9G,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,0FAA0F;IAC1F,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qEAAqE;IACrE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oEAAoE;IACpE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,4FAA4F;IAC5F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CAClD;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,GAAI,sMAc/B,sBAAsB,gCAiRxB,CAAC"}
|
|
@@ -5,13 +5,14 @@ import { ButtonUtility } from '@flipdish/ui-library/components/atoms/UtilityButt
|
|
|
5
5
|
import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
6
6
|
import { sidebarCollapsedStorage } from '@flipdish/ui-library/utilities/localStorageUtils';
|
|
7
7
|
import { motion, AnimatePresence } from 'motion/react';
|
|
8
|
-
import { useState, useEffect, useId
|
|
8
|
+
import { useState, useEffect, useId } from 'react';
|
|
9
9
|
import { MobileNavigationHeader, MobileNavigationDrawer } from './components/mobile-header.js';
|
|
10
10
|
import { NavAccountCard } from './components/nav-account-card.js';
|
|
11
11
|
export { NavAccountMenu } from './components/nav-account-card.js';
|
|
12
12
|
import { NavButton } from './components/nav-button.js';
|
|
13
13
|
import { NavItemBase } from './components/nav-item.js';
|
|
14
14
|
import { NavList } from './components/nav-list.js';
|
|
15
|
+
import { useDualTierKeyboard } from './hooks/use-dual-tier-keyboard.js';
|
|
15
16
|
export { SidebarMenuButton } from './components/sidebar-menu-button.js';
|
|
16
17
|
|
|
17
18
|
const COLLAPSED_WIDTH = 68;
|
|
@@ -21,11 +22,12 @@ const SECONDARY_SIDEBAR_WIDTH = 256;
|
|
|
21
22
|
* The primary app-shell navigation rail. It renders a logo, a list of
|
|
22
23
|
* destinations, footer links, and an account card, and can be toggled between a
|
|
23
24
|
* labelled list and an icon-only strip (the choice persists across reloads).
|
|
24
|
-
* Hovering
|
|
25
|
-
*
|
|
25
|
+
* Hovering (or focusing) the sidebar reveals a secondary sub-navigation panel
|
|
26
|
+
* listing the current section's children; clicking a primary item switches the
|
|
27
|
+
* current section and navigates. Below the `lg` breakpoint it collapses into a
|
|
26
28
|
* mobile header with a slide-over menu.
|
|
27
29
|
*
|
|
28
|
-
* @summary
|
|
30
|
+
* @summary Navigate app sections through a collapsible, dual-tier sidebar rail.
|
|
29
31
|
*/
|
|
30
32
|
const SidebarNavigation = ({ activeUrl, items, footerItems = [], account, collapsed, defaultCollapsed = false, onCollapsedChange, persistCollapsed = true, hideBorder, hideRightBorder, showMobileHeader = true, mobileMenuOpen, onMobileMenuOpenChange, }) => {
|
|
31
33
|
const isControlled = collapsed !== undefined;
|
|
@@ -57,87 +59,67 @@ const SidebarNavigation = ({ activeUrl, items, footerItems = [], account, collap
|
|
|
57
59
|
sidebarCollapsedStorage.set(next);
|
|
58
60
|
};
|
|
59
61
|
const isActive = (item) => item.href === activeUrl || item.items?.some((sub) => sub.href === activeUrl);
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
// Dual-tier reveal: the secondary panel is shown whenever the
|
|
63
|
+
// pointer is over — or focus is within — the sidebar, and it always lists the
|
|
64
|
+
// children of `currentItem`. `currentItem` is seeded from the active route and
|
|
65
|
+
// switched by clicking (or keyboard-activating) a primary item, which also
|
|
66
|
+
// navigates. Only `currentItem` is highlighted, so exactly one item is ever active.
|
|
67
|
+
const sections = [...items, ...footerItems];
|
|
68
|
+
const activeItem = sections.find((item) => isActive(item));
|
|
69
|
+
const activeLabel = activeItem?.label;
|
|
70
|
+
// Track the current section by its (unique) label rather than the object, so it
|
|
71
|
+
// survives the consumer passing a fresh `items` array and never collides on href.
|
|
72
|
+
const [currentLabel, setCurrentLabel] = useState(activeLabel);
|
|
73
|
+
// Keep the selected section in sync with the active route when it changes externally
|
|
74
|
+
// (browser navigation, a controlled `activeUrl`, or asynchronously-loaded items).
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (activeLabel !== undefined)
|
|
77
|
+
setCurrentLabel(activeLabel);
|
|
78
|
+
}, [activeLabel]);
|
|
79
|
+
const currentItem = sections.find((item) => item.label === currentLabel);
|
|
80
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
81
|
+
const [isFocusWithin, setIsFocusWithin] = useState(false);
|
|
82
|
+
const isSecondarySidebarVisible = (isHovering || isFocusWithin) && Boolean(currentItem?.items?.length);
|
|
65
83
|
const panelId = useId();
|
|
66
84
|
// Ties the built-in mobile toggle to the drawer it opens via `aria-controls`.
|
|
67
85
|
const mobileMenuId = useId();
|
|
68
|
-
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const suppressReveal = useRef(false);
|
|
75
|
-
const focusFirstPanelItem = () => panelRef.current?.querySelector('a, button')?.focus();
|
|
76
|
-
// Move focus into the panel once it has rendered after a keyboard-triggered open.
|
|
77
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: focusFirstPanelItem only reads the stable panelRef
|
|
78
|
-
useEffect(() => {
|
|
79
|
-
if (isSecondarySidebarVisible && focusPanelOnOpen.current) {
|
|
80
|
-
focusPanelOnOpen.current = false;
|
|
81
|
-
focusFirstPanelItem();
|
|
82
|
-
}
|
|
83
|
-
}, [isSecondarySidebarVisible]);
|
|
84
|
-
const revealSubNav = (item) => {
|
|
85
|
-
if (suppressReveal.current) {
|
|
86
|
-
suppressReveal.current = false;
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (item.items?.length) {
|
|
90
|
-
setPanelItem(item);
|
|
91
|
-
setShowSubNav(true);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// Hovering/focusing a leaf destination closes any open panel.
|
|
95
|
-
setShowSubNav(false);
|
|
96
|
-
}
|
|
86
|
+
// Only *keyboard* focus holds the panel open. Focus parked on a just-clicked link
|
|
87
|
+
// (pointer modality) must not — otherwise the panel lingers after a mouse click even
|
|
88
|
+
// once the pointer leaves. Gating on `:focus-visible` keeps the mouse behaviour
|
|
89
|
+
// identical to Untitled UI (closes on pointer-leave) while preserving keyboard reach.
|
|
90
|
+
const handleContainerFocus = (event) => {
|
|
91
|
+
setIsFocusWithin(event.target.matches(':focus-visible'));
|
|
97
92
|
};
|
|
98
|
-
const hideSubNav = () => setShowSubNav(false);
|
|
99
93
|
const handleContainerBlur = (event) => {
|
|
100
94
|
if (!event.currentTarget.contains(event.relatedTarget))
|
|
101
|
-
|
|
102
|
-
};
|
|
103
|
-
// ArrowRight on a parent item opens (if needed) and moves focus into the panel.
|
|
104
|
-
const handlePrimaryKeyDown = (item) => (event) => {
|
|
105
|
-
if (event.key !== 'ArrowRight' || !item.items?.length)
|
|
106
|
-
return;
|
|
107
|
-
event.preventDefault();
|
|
108
|
-
triggerRef.current = event.currentTarget.querySelector('a, button');
|
|
109
|
-
if (isSecondarySidebarVisible && panelItem?.label === item.label) {
|
|
110
|
-
focusFirstPanelItem();
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
focusPanelOnOpen.current = true;
|
|
114
|
-
setPanelItem(item);
|
|
115
|
-
setShowSubNav(true);
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
// ArrowLeft/Escape inside the panel closes it and restores focus to the parent.
|
|
119
|
-
const handlePanelKeyDown = (event) => {
|
|
120
|
-
if (event.key !== 'ArrowLeft' && event.key !== 'Escape')
|
|
121
|
-
return;
|
|
122
|
-
event.preventDefault();
|
|
123
|
-
suppressReveal.current = true;
|
|
124
|
-
hideSubNav();
|
|
125
|
-
triggerRef.current?.focus();
|
|
95
|
+
setIsFocusWithin(false);
|
|
126
96
|
};
|
|
97
|
+
const { panelRef, handleTriggerKeyDown, handlePanelKeyDown } = useDualTierKeyboard({
|
|
98
|
+
isPanelVisible: isSecondarySidebarVisible,
|
|
99
|
+
currentLabel,
|
|
100
|
+
onSelectSection: setCurrentLabel,
|
|
101
|
+
onReveal: () => setIsFocusWithin(true),
|
|
102
|
+
});
|
|
127
103
|
const renderPrimaryItems = (list) => list.map((item) => {
|
|
128
104
|
const hasChildren = Boolean(item.items?.length);
|
|
129
|
-
|
|
105
|
+
// `isCurrentPage` (exact URL match) drives `aria-current`; `isSelected` (the open
|
|
106
|
+
// section) drives the brand highlight. A parent whose child is active is selected
|
|
107
|
+
// but is NOT the current page.
|
|
108
|
+
const isCurrentPage = item.href === activeUrl;
|
|
109
|
+
const isSelected = currentLabel === item.label;
|
|
110
|
+
const isOpen = hasChildren && isSelected && isSecondarySidebarVisible;
|
|
130
111
|
// Disclosure semantics: parents announce their expanded state and, once open, the panel they control.
|
|
131
112
|
const disclosure = {
|
|
132
113
|
'aria-expanded': hasChildren ? isOpen : undefined,
|
|
133
114
|
'aria-controls': isOpen ? panelId : undefined,
|
|
134
115
|
};
|
|
135
|
-
|
|
116
|
+
const selectSection = () => setCurrentLabel(item.label);
|
|
117
|
+
return (jsx("li", { className: isCollapsed ? undefined : 'py-px', onKeyDown: handleTriggerKeyDown(item.label, hasChildren), children: isCollapsed ? (jsx(NavButton, { current: isCurrentPage, selected: isSelected, href: item.href, onClick: selectSection, label: item.label || '', icon: item.icon, ...disclosure })) : (jsx(NavItemBase, { type: "link", current: isCurrentPage, selected: isSelected, href: item.href, icon: item.icon, badge: item.badge, hasSubmenu: hasChildren, onClick: selectSection, ...disclosure, children: item.label })) }, item.label));
|
|
136
118
|
});
|
|
137
119
|
const mainSidebar = (jsxs(motion.aside, { animate: { width: isCollapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH }, transition: { type: 'spring', damping: 26, stiffness: 220, bounce: 0 }, className: cx('flex h-full max-h-full flex-col justify-between overflow-x-hidden overflow-y-auto bg-secondary', !hideBorder && 'border-r border-secondary'), children: [jsxs("div", { className: "flex flex-col", children: [isCollapsed ? (jsx("div", { className: "flex justify-center px-3 py-5", children: jsx(ButtonUtility, { size: "sm", color: "tertiary", tooltip: "Expand", "aria-label": "Expand navigation", icon: ChevronRightDouble, onClick: () => setCollapsed(false) }) })) : (jsxs("div", { className: "relative flex items-center px-5 py-5", children: [jsx(FlipdishLogo, { size: "md" }), jsx("div", { className: "absolute top-5 right-4", children: jsx(ButtonUtility, { size: "sm", color: "tertiary", tooltip: "Collapse", "aria-label": "Collapse navigation", icon: ChevronLeftDouble, onClick: () => setCollapsed(true) }) })] })), jsx("ul", { className: cx('flex flex-col gap-0.5', isCollapsed ? 'items-center px-3.5' : 'px-4 pt-1'), children: renderPrimaryItems(items) })] }), jsxs("div", { className: cx('mt-auto flex flex-col gap-3 py-4', isCollapsed ? 'items-center px-3' : 'px-4'), children: [footerItems.length > 0 && jsx("ul", { className: cx('flex flex-col gap-0.5', isCollapsed && 'items-center'), children: renderPrimaryItems(footerItems) }), account &&
|
|
138
120
|
(isCollapsed ? (jsx(NavAccountCard, { variant: "avatar", account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })) : (jsx(NavAccountCard, { account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })))] })] }));
|
|
139
|
-
const secondarySidebar =
|
|
140
|
-
return (jsxs(Fragment, { children: [jsxs("div", { className: "z-50 hidden lg:fixed lg:inset-y-0 lg:left-0 lg:flex",
|
|
121
|
+
const secondarySidebar = currentItem && (jsx(AnimatePresence, { initial: false, children: isSecondarySidebarVisible && (jsx(motion.div, { ref: panelRef, id: panelId, onKeyDown: handlePanelKeyDown, role: "group", "aria-label": `${currentItem.label} pages`, initial: { width: 0, borderColor: 'var(--color-border-secondary)' }, animate: { width: SECONDARY_SIDEBAR_WIDTH, borderColor: 'var(--color-border-secondary)' }, exit: { width: 0, borderColor: 'rgba(0,0,0,0)', transition: { borderColor: { type: 'tween', delay: 0.05 } } }, transition: { type: 'spring', damping: 26, stiffness: 220, bounce: 0 }, className: cx('relative h-full overflow-x-hidden overflow-y-auto bg-primary', !(hideBorder || hideRightBorder) && 'box-content border-r border-secondary'), children: jsxs("div", { style: { width: SECONDARY_SIDEBAR_WIDTH }, className: "flex h-full flex-col px-4 pt-6", children: [jsx("h3", { className: "px-2 text-sm font-semibold text-tertiary", children: currentItem.label }), jsx("ul", { className: "py-2", children: currentItem.items?.map((item) => (jsx("li", { className: "py-px", children: jsx(NavItemBase, { type: "link", current: activeUrl === item.href, href: item.href, icon: item.icon, badge: item.badge, children: item.label }) }, item.label))) })] }) })) }));
|
|
122
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: "z-50 hidden lg:fixed lg:inset-y-0 lg:left-0 lg:flex", onPointerEnter: () => setIsHovering(true), onPointerLeave: () => setIsHovering(false), onFocus: handleContainerFocus, onBlur: handleContainerBlur, children: [mainSidebar, secondarySidebar] }), jsx("div", { style: { paddingLeft: isCollapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH }, className: "invisible hidden lg:sticky lg:top-0 lg:bottom-0 lg:left-0 lg:block" }), showMobileHeader && jsx(MobileNavigationHeader, { isOpen: isMobileMenuOpen, onOpenChange: setMobileMenuOpen, controls: mobileMenuId }), jsx(MobileNavigationDrawer, { id: mobileMenuId, isOpen: isMobileMenuOpen, onOpenChange: setMobileMenuOpen, children: jsxs("aside", { className: "group flex h-full max-h-full w-full max-w-full flex-col justify-between overflow-y-auto bg-secondary pt-4", children: [jsx("div", { className: "px-4", children: jsx(FlipdishLogo, { size: "sm" }) }), jsx(NavList, { activeUrl: activeUrl, items: items, onNavigate: () => setMobileMenuOpen(false) }), jsxs("div", { className: "mt-auto flex flex-col gap-3 p-4", children: [footerItems.length > 0 && (jsx("ul", { className: "flex flex-col gap-0.5", children: footerItems.map((item) => (jsx("li", { children: jsx(NavItemBase, { type: "link", current: activeUrl === item.href, href: item.href, icon: item.icon, badge: item.badge, onClick: () => setMobileMenuOpen(false), children: item.label }) }, item.label))) })), account && jsx(NavAccountCard, { account: account.account, menuItems: account.menuItems, bottomMenuItems: account.bottomMenuItems })] })] }) })] }));
|
|
141
123
|
};
|
|
142
124
|
|
|
143
125
|
export { NavAccountCard, NavItemBase, SidebarNavigation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/SidebarNavigation/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
|