{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "menubar", "type": "registry:ui", "title": "Menubar", "files": [ { "path": "ui/menubar.tsrx", "type": "registry:ui", "target": "components/ui/menubar.tsrx", "content": "// Base UI base menubar — the bar runs on @octanejs/base-ui's `Menubar`, and every menu inside it\n// runs on `Menu`, the same primitive `dropdown-menu` uses. Class strings from the maintainer-supplied\n// radix source.\n//\n// PART MAPPING. Radix nests the whole family under one `Menubar` namespace; Base UI has a `Menubar`\n// component for the bar ONLY, and the menus are ordinary `Menu` parts:\n//\n// radix Menubar.Root / .Menu / .Trigger / .Content / .Item / .Sub / …\n// Base UI Menubar + Menu.Root / .Trigger / .Portal > .Positioner > .Popup / .Item / …\n//\n// CARRIED OVER FROM dropdown-menu, re-verified against this composition:\n// - `--radix-menubar-content-transform-origin` -> `--transform-origin`. A utility naming a\n// variable nothing sets does nothing, silently.\n// - The SUBMENU trigger marks itself open with `data-popup-open`, not the `data-open` the popup\n// carries, so radix's `data-open:bg-accent` there would never match.\n// - `Label` and `Separator` are plain host elements: `Menu.GroupLabel` throws outside a\n// `Menu.Group` while shadcn's label is standalone, and the `Menu` namespace ships no Separator\n// part at all (its sibling `ContextMenu` does).\n// - Radix's `focus:` item utilities carry over, because Base UI moves real DOM focus onto the\n// highlighted item.\n// - Positioning props are routed to the Positioner, not swept onto the Popup where they are inert.\n//\n// THE BAR TRIGGER IS THE ONE PLACE THIS FAMILY DIFFERS from the dropdown. Its radix class keys off\n// `aria-expanded:bg-muted` rather than a data attribute, and that carries over UNCHANGED — Base UI's\n// trigger publishes `aria-expanded=\"true\"` when its menu is open (verified by rendering). So the\n// `data-popup-open` rewrite above applies only to the submenu trigger, not to this one.\nimport { type OctaneNode } from 'octane';\nimport { Menubar as MenubarPrimitive } from '@octanejs/base-ui/menubar';\nimport { Menu as MenuPrimitive } from '@octanejs/base-ui/menu';\nimport { CheckIcon, ChevronRightIcon } from '@octanejs/lucide';\n\nimport { cn } from '@/lib/utils';\n\ntype Props = { className?: string; children?: OctaneNode } & Record;\n\nexport interface BaseUiPositioningProps {\n\t/** Forwarded to the Positioner; see the note at the top of this file. */\n\tside?: 'top' | 'right' | 'bottom' | 'left';\n\tsideOffset?: number;\n\talign?: 'start' | 'center' | 'end';\n\talignOffset?: number;\n\tanchor?: unknown;\n\tpositionMethod?: 'absolute' | 'fixed';\n\tcollisionBoundary?: unknown;\n\tcollisionPadding?: unknown;\n\tcollisionAvoidance?: unknown;\n\tarrowPadding?: number;\n\tsticky?: boolean;\n\tdisableAnchorTracking?: boolean;\n}\n\nexport function Menubar({ className, ...props }: Props) @{\n\t\n}\n\nexport function MenubarMenu(props: Record) @{\n\t\n}\n\nexport function MenubarGroup(props: Record) @{\n\t\n}\n\nexport function MenubarPortal(props: Record) @{\n\t\n}\n\nexport function MenubarRadioGroup(props: Record) @{\n\t\n}\n\nexport function MenubarTrigger({ className, ...props }: Props) @{\n\t\n}\n\nexport function MenubarContent({\n\tclassName,\n\talign = 'start',\n\talignOffset = -4,\n\tsideOffset = 8,\n\tside,\n\tanchor,\n\tpositionMethod,\n\tcollisionBoundary,\n\tcollisionPadding,\n\tcollisionAvoidance,\n\tarrowPadding,\n\tsticky,\n\tdisableAnchorTracking,\n\t...props\n}: Props & BaseUiPositioningProps) @{\n\t\n\t\t\n\t\t\t\n\t\t\n\t\n}\n\nexport function MenubarItem({ className, inset, variant = 'default', ...props }: Props & {\n\tinset?: boolean;\n\tvariant?: 'default' | 'destructive';\n}) @{\n\t\n}\n\nexport function MenubarCheckboxItem(props: Props & {\n\tchecked?: boolean;\n\tinset?: boolean;\n}) @{\n\tconst { className, children: _children, checked, inset, ...rest } = props;\n\n\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t{props.children}\n\t\n}\n\nexport function MenubarRadioItem(props: Props & { inset?: boolean }) @{\n\tconst { className, children: _children, inset, ...rest } = props;\n\n\t\n\t\t\n\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t\n\t\t{props.children}\n\t\n}\n\nexport function MenubarLabel({ className, inset, ...props }: Props & { inset?: boolean }) @{\n\t\n}\n\nexport function MenubarSeparator({ className, ...props }: Props) @{\n\t\n}\n\nexport function MenubarShortcut({ className, ...props }: Props) @{\n\t\n}\n\nexport function MenubarSub(props: Record) @{\n\t\n}\n\nexport function MenubarSubTrigger(props: Props & { inset?: boolean }) @{\n\tconst { className, children: _children, inset, ...rest } = props;\n\n\t\n\t\t{props.children}\n\t\t\n\t\n}\n\nexport function MenubarSubContent({\n\tclassName,\n\tside,\n\tsideOffset,\n\talign,\n\talignOffset,\n\tanchor,\n\tpositionMethod,\n\tcollisionBoundary,\n\tcollisionPadding,\n\tcollisionAvoidance,\n\tarrowPadding,\n\tsticky,\n\tdisableAnchorTracking,\n\t...props\n}: Props & BaseUiPositioningProps) @{\n\t\n\t\t\n\t\t\t\n\t\t\n\t\n}\n" } ], "dependencies": [ "@octanejs/base-ui@0.1.36", "@octanejs/lucide@0.1.33" ], "registryDependencies": [ "@octane/utils" ] }