Files
loyaly-merchant/src/shared/layouts/workspace/NavMenuButton.tsx

64 lines
2.3 KiB
TypeScript

'use client';
import {IconButton} from '@astryxdesign/core/IconButton';
import {Icon} from '@astryxdesign/core/Icon';
import {ICONS} from '@/shared/utils/icons';
import {useSidebar} from './SidebarProvider';
/**
* The one control that is never absent.
*
* It renders in the top bar's leading slot at EVERY width — the header is the
* only region of the shell that survives all three navigation states, so it is
* the only place a control can live and still be reachable when the nav it
* governs is collapsed or gone. Anything mounted inside the sidebar disappears
* with the sidebar, which is exactly how the rail became unreopenable.
*
* Three states, one button:
* drawer closed ☰ → open the overlay
* drawer open ☰ → close it (aria-expanded carries the state)
* rail collapsed panel-open → expand to 260px
* rail expanded panel-close → collapse to 84px
*
* 44px square below the breakpoint: IconButton's `lg` is 36px, which clears
* neither the WCAG 2.2 target-size minimum nor a thumb. `size-11` is the
* spacing-11 token (44px) through the Tailwind bridge, and it sits in the
* utilities layer so it wins over Astryx's own sizing without !important.
*/
export function NavMenuButton() {
const {isDrawer, isDrawerOpen, isCollapsed, toggle, controlsId} =
useSidebar();
const label = isDrawer
? isDrawerOpen
? 'Close navigation menu'
: 'Open navigation menu'
: isCollapsed
? 'Expand navigation'
: 'Collapse navigation';
const icon = isDrawer
? ICONS.menu
: isCollapsed
? ICONS.sidebarOpen
: ICONS.sidebarClose;
return (
<IconButton
icon={<Icon icon={icon} size={isDrawer ? 'md' : 'sm'} />}
label={label}
tooltip={label}
variant="ghost"
size={isDrawer ? 'lg' : 'md'}
onClick={toggle}
// Expanded/collapsed is the drawer's state; above the breakpoint the rail
// is always present, so only its width changes and aria-expanded would be
// a lie. aria-controls still points at the rail so the relationship holds.
aria-expanded={isDrawer ? isDrawerOpen : undefined}
aria-controls={controlsId}
className={isDrawer ? 'size-11' : undefined}
data-testid="nav-menu-button"
/>
);
}