{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "menubar",
  "title": "Menubar",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A horizontal application menu bar with roving focus across menus, submenus, shortcuts, checkbox and radio items, built on Radix.",
  "dependencies": [
    "radix-ui",
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/direction.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/menubar.tsx",
      "content": "// Ballmac UI: Menubar. https://ui.ballmac.com/components/menubar\n// Based on shadcn/ui Menubar (MIT, Copyright (c) 2023 shadcn), restyled with tokens, destructive and inset items, and a shortcut slot.\n\"use client\";\n\nimport * as React from \"react\";\nimport { Check, ChevronRight, Circle } from \"lucide-react\";\nimport { Menubar as Primitive } from \"radix-ui\";\nimport { useDirection } from \"@/lib/ballmac/direction\";\nimport { cn } from \"@/lib/utils\";\n\nconst itemBase =\n  \"relative flex min-h-8 cursor-default select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\";\n\nconst surface =\n  \"z-50 min-w-[12rem] overflow-hidden rounded-xl border bg-popover p-1 text-popover-foreground shadow-[0_12px_36px_-10px_rgb(0_0_0/0.25)] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:zoom-in-95 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 motion-reduce:animate-none\";\n\ntype MenubarProps = React.ComponentProps<typeof Primitive.Root>;\n/** The horizontal bar. Arrow keys move between menus; Enter or ArrowDown opens one. */\nfunction Menubar({ className, ...props }: MenubarProps) {\n  const dir = useDirection(props.dir);\n  return (\n    <Primitive.Root\n      dir={dir}\n      data-slot=\"menubar\"\n      className={cn(\n        \"flex h-9 w-fit items-center gap-1 rounded-lg border bg-background p-1 shadow-xs\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype MenubarMenuProps = React.ComponentProps<typeof Primitive.Menu>;\nfunction MenubarMenu(props: MenubarMenuProps) {\n  return <Primitive.Menu data-slot=\"menubar-menu\" {...props} />;\n}\n\ntype MenubarGroupProps = React.ComponentProps<typeof Primitive.Group>;\nfunction MenubarGroup(props: MenubarGroupProps) {\n  return <Primitive.Group data-slot=\"menubar-group\" {...props} />;\n}\n\ntype MenubarSubProps = React.ComponentProps<typeof Primitive.Sub>;\nfunction MenubarSub(props: MenubarSubProps) {\n  return <Primitive.Sub data-slot=\"menubar-sub\" {...props} />;\n}\n\ntype MenubarRadioGroupProps = React.ComponentProps<typeof Primitive.RadioGroup>;\nfunction MenubarRadioGroup(props: MenubarRadioGroupProps) {\n  return <Primitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />;\n}\n\ntype MenubarTriggerProps = React.ComponentProps<typeof Primitive.Trigger>;\nfunction MenubarTrigger({ className, ...props }: MenubarTriggerProps) {\n  return (\n    <Primitive.Trigger\n      data-slot=\"menubar-trigger\"\n      className={cn(\n        \"flex h-7 select-none items-center rounded-md px-2.5 text-sm font-medium outline-none transition-colors hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype MenubarContentProps = React.ComponentProps<typeof Primitive.Content>;\nfunction MenubarContent({\n  className,\n  align = \"start\",\n  alignOffset = -4,\n  sideOffset = 8,\n  collisionPadding = 12,\n  ...props\n}: MenubarContentProps) {\n  return (\n    <Primitive.Portal>\n      <Primitive.Content\n        data-slot=\"menubar-content\"\n        align={align}\n        alignOffset={alignOffset}\n        sideOffset={sideOffset}\n        collisionPadding={collisionPadding}\n        className={cn(\n          surface,\n          \"max-h-(--radix-menubar-content-available-height) origin-(--radix-menubar-content-transform-origin) overflow-y-auto\",\n          className,\n        )}\n        {...props}\n      />\n    </Primitive.Portal>\n  );\n}\n\ntype MenubarItemProps = React.ComponentProps<typeof Primitive.Item> & {\n  /** Indent the item so it lines up with items that show a check or icon. */\n  inset?: boolean;\n  /** Style the item as a destructive action (delete, sign out). */\n  destructive?: boolean;\n};\nfunction MenubarItem({\n  className,\n  inset,\n  destructive,\n  ...props\n}: MenubarItemProps) {\n  return (\n    <Primitive.Item\n      data-slot=\"menubar-item\"\n      data-inset={inset ? \"\" : undefined}\n      data-variant={destructive ? \"destructive\" : \"default\"}\n      className={cn(\n        itemBase,\n        \"data-[inset]:ps-8\",\n        \"data-[variant=destructive]:text-destructive data-[variant=destructive]:data-[highlighted]:bg-destructive/10 data-[variant=destructive]:data-[highlighted]:text-destructive data-[variant=destructive]:[&_svg]:!text-destructive\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype MenubarCheckboxItemProps = React.ComponentProps<\n  typeof Primitive.CheckboxItem\n>;\nfunction MenubarCheckboxItem({\n  className,\n  children,\n  ...props\n}: MenubarCheckboxItemProps) {\n  return (\n    <Primitive.CheckboxItem\n      data-slot=\"menubar-checkbox-item\"\n      className={cn(itemBase, \"ps-8\", className)}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute start-2 flex size-4 items-center justify-center\">\n        <Primitive.ItemIndicator>\n          <Check aria-hidden=\"true\" className=\"size-4 !text-foreground\" />\n        </Primitive.ItemIndicator>\n      </span>\n      {children}\n    </Primitive.CheckboxItem>\n  );\n}\n\ntype MenubarRadioItemProps = React.ComponentProps<\n  typeof Primitive.RadioItem\n>;\nfunction MenubarRadioItem({\n  className,\n  children,\n  ...props\n}: MenubarRadioItemProps) {\n  return (\n    <Primitive.RadioItem\n      data-slot=\"menubar-radio-item\"\n      className={cn(itemBase, \"ps-8\", className)}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute start-2 flex size-4 items-center justify-center\">\n        <Primitive.ItemIndicator>\n          <Circle\n            aria-hidden=\"true\"\n            className=\"size-2 fill-current !text-foreground\"\n          />\n        </Primitive.ItemIndicator>\n      </span>\n      {children}\n    </Primitive.RadioItem>\n  );\n}\n\ntype MenubarLabelProps = React.ComponentProps<typeof Primitive.Label> & {\n  /** Indent the label to match inset items. */\n  inset?: boolean;\n};\nfunction MenubarLabel({\n  className,\n  inset,\n  ...props\n}: MenubarLabelProps) {\n  return (\n    <Primitive.Label\n      data-slot=\"menubar-label\"\n      data-inset={inset ? \"\" : undefined}\n      className={cn(\n        \"px-2 py-1.5 text-xs font-medium text-muted-foreground data-[inset]:ps-8\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype MenubarSeparatorProps = React.ComponentProps<\n  typeof Primitive.Separator\n>;\nfunction MenubarSeparator({\n  className,\n  ...props\n}: MenubarSeparatorProps) {\n  return (\n    <Primitive.Separator\n      data-slot=\"menubar-separator\"\n      className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n      {...props}\n    />\n  );\n}\n\ntype MenubarShortcutProps = React.ComponentProps<\"span\">;\n/** Right-aligned keyboard hint. Decorative: the accessible name stays the item text, so add `aria-keyshortcuts` on the item when the shortcut is real. */\nfunction MenubarShortcut({\n  className,\n  ...props\n}: MenubarShortcutProps) {\n  return (\n    <span\n      data-slot=\"menubar-shortcut\"\n      aria-hidden=\"true\"\n      className={cn(\n        \"ms-auto ps-4 font-mono text-xs tracking-wide text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\ntype MenubarSubTriggerProps = React.ComponentProps<\n  typeof Primitive.SubTrigger\n> & {\n  /** Indent the trigger to match inset items. */\n  inset?: boolean;\n};\nfunction MenubarSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: MenubarSubTriggerProps) {\n  return (\n    <Primitive.SubTrigger\n      data-slot=\"menubar-sub-trigger\"\n      data-inset={inset ? \"\" : undefined}\n      className={cn(\n        itemBase,\n        \"data-[inset]:ps-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRight aria-hidden=\"true\" className=\"ms-auto size-4 rtl:rotate-180\" />\n    </Primitive.SubTrigger>\n  );\n}\n\ntype MenubarSubContentProps = React.ComponentProps<\n  typeof Primitive.SubContent\n>;\nfunction MenubarSubContent({\n  className,\n  collisionPadding = 12,\n  ...props\n}: MenubarSubContentProps) {\n  return (\n    <Primitive.Portal>\n      <Primitive.SubContent\n        data-slot=\"menubar-sub-content\"\n        collisionPadding={collisionPadding}\n        className={cn(\n          surface,\n          \"origin-(--radix-menubar-content-transform-origin)\",\n          className,\n        )}\n        {...props}\n      />\n    </Primitive.Portal>\n  );\n}\n\nexport {\n  Menubar,\n  MenubarMenu,\n  MenubarTrigger,\n  MenubarContent,\n  MenubarGroup,\n  MenubarItem,\n  MenubarCheckboxItem,\n  MenubarRadioGroup,\n  MenubarRadioItem,\n  MenubarLabel,\n  MenubarSeparator,\n  MenubarShortcut,\n  MenubarSub,\n  MenubarSubTrigger,\n  MenubarSubContent,\n  type MenubarProps,\n  type MenubarMenuProps,\n  type MenubarTriggerProps,\n  type MenubarContentProps,\n  type MenubarGroupProps,\n  type MenubarItemProps,\n  type MenubarCheckboxItemProps,\n  type MenubarRadioGroupProps,\n  type MenubarRadioItemProps,\n  type MenubarLabelProps,\n  type MenubarSeparatorProps,\n  type MenubarShortcutProps,\n  type MenubarSubProps,\n  type MenubarSubTriggerProps,\n  type MenubarSubContentProps,\n};\n",
      "type": "registry:ui",
      "target": "@components/ballmac/menubar.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "menu",
      "application",
      "desktop",
      "radix"
    ],
    "version": "1.0.0",
    "updated": "2026-09-30",
    "ai": {
      "summary": "A File / Edit / View style bar. Left and Right move between menus, Down opens one, and hovering across open menus switches them.",
      "whenToUse": [
        "Editors, dashboards and tools with many commands",
        "Desktop-style web apps"
      ],
      "whenNotToUse": [
        "Website navigation with links; use navigation-menu",
        "The macOS system menu bar mockup; use menu-bar"
      ],
      "composesWith": [
        "kbd",
        "dropdown-menu"
      ],
      "a11y": [
        {
          "keys": "ArrowLeft / ArrowRight",
          "action": "Moves focus between menu triggers"
        },
        {
          "keys": "ArrowDown / Enter / Space",
          "action": "Opens the focused menu"
        },
        {
          "keys": "ArrowUp / ArrowDown",
          "action": "Moves within a menu"
        },
        {
          "keys": "Escape",
          "action": "Closes the menu and returns to the bar"
        }
      ],
      "customization": [
        "value on each menu for a default open menu",
        "shortcut hints",
        "checkbox and radio items"
      ]
    },
    "source": {
      "name": "shadcn/ui Menubar",
      "url": "https://github.com/shadcn-ui/ui",
      "license": "MIT",
      "copyright": "Copyright (c) 2023 shadcn",
      "modified": true
    },
    "examples": [
      "menubar-demo",
      "menubar-states"
    ],
    "url": "https://ui.ballmac.com/components/menubar"
  },
  "categories": [
    "navigation"
  ],
  "type": "registry:ui"
}