{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "menubar",
  "type": "registry:ui",
  "title": "Menubar",
  "description": "Desktop-style horizontal menu bar (File / Edit / View) with dropdowns and keyboard navigation.",
  "dependencies": [
    "@radix-ui/react-menubar",
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/menubar.tsx",
      "type": "registry:ui",
      "content": "// @toreview\n\"use client\"\n\n/**\n * @fileoverview Menubar primitive — horizontal menu bar with dropdown menus, checkbox items, and keyboard navigation.\n * Built on Radix UI Menubar. Part of the Saasflare base component layer.\n * @module packages/ui/components/ui/menubar\n * @layer core\n *\n * @component\n * @example\n * import { Menubar, MenubarMenu, MenubarTrigger, MenubarContent, MenubarItem } from '@saasflare/ui';\n * <Menubar>\n *   <MenubarMenu>\n *     <MenubarTrigger>File</MenubarTrigger>\n *     <MenubarContent>\n *       <MenubarItem>New</MenubarItem>\n *       <MenubarItem>Open</MenubarItem>\n *     </MenubarContent>\n *   </MenubarMenu>\n * </Menubar>\n */\n\nimport * as React from \"react\"\nimport { CheckIcon, CaretRightIcon, CircleIcon } from \"@saasflare/ui\"\nimport * as MenubarPrimitive from \"@radix-ui/react-menubar\"\n\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/**\n * Props for {@link Menubar}.\n *\n * Extends the Radix Menubar root props with {@link SaasflareComponentProps},\n * so `surface`, `radius`, `animated`, and `iconWeight` can be supplied\n * per-instance or inherited from <SaasflareProvider>.\n */\ninterface MenubarProps\n  extends Omit<React.ComponentProps<typeof MenubarPrimitive.Root>, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {}\n\n/**\n * Root horizontal menu bar. Owns the Saasflare surface/radius/animated context for\n * its menus and emits the corresponding data attributes.\n */\nfunction Menubar({\n  className,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: MenubarProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n\n  return (\n    <MenubarPrimitive.Root\n      {...props}\n      data-slot=\"menubar\"\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n      className={cn(\n        \"flex h-9 items-center gap-1 rounded-md border bg-background p-1 shadow-xs\",\n        className\n      )}\n    />\n  )\n}\n\n/** A single menu within the menubar, pairing a trigger with its content. */\nfunction MenubarMenu({\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Menu>) {\n  return <MenubarPrimitive.Menu data-slot=\"menubar-menu\" {...props} />\n}\n\n/** Groups related menu items together for semantic structure. */\nfunction MenubarGroup({\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Group>) {\n  return <MenubarPrimitive.Group data-slot=\"menubar-group\" {...props} />\n}\n\n/** Portals menu content into the document body, outside the DOM flow. */\nfunction MenubarPortal({\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Portal>) {\n  return <MenubarPrimitive.Portal data-slot=\"menubar-portal\" {...props} />\n}\n\n/** Groups radio items so only one can be checked at a time. */\nfunction MenubarRadioGroup({\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {\n  return (\n    <MenubarPrimitive.RadioGroup data-slot=\"menubar-radio-group\" {...props} />\n  )\n}\n\n/** Clickable label that opens its associated menu. */\nfunction MenubarTrigger({\n  className,\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Trigger>) {\n  return (\n    <MenubarPrimitive.Trigger\n      data-slot=\"menubar-trigger\"\n      className={cn(\n        \"flex items-center rounded-sm px-2 py-1 text-sm font-medium outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Props for {@link MenubarContent}.\n *\n * Extends the Radix Menubar content props (`align`, `alignOffset`,\n * `sideOffset`, …) with {@link SaasflareComponentProps}.\n */\ninterface MenubarContentProps\n  extends Omit<React.ComponentProps<typeof MenubarPrimitive.Content>, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {}\n\n/**\n * Floating panel that holds a menu's items. Inherits surface/radius/animated and\n * emits the matching data attributes for CSS-driven motion.\n */\nfunction MenubarContent({\n  className,\n  align = \"start\",\n  alignOffset = -4,\n  sideOffset = 8,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: MenubarContentProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n\n  return (\n    <MenubarPortal>\n      <MenubarPrimitive.Content\n        {...props}\n        data-slot=\"menubar-content\"\n        data-surface={sf.surface}\n        data-radius={sf.radius}\n        data-animated={String(sf.animated)}\n        align={align}\n        alignOffset={alignOffset}\n        sideOffset={sideOffset}\n        className={cn(\n          \"z-50 min-w-[12rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n          className\n        )}\n      />\n    </MenubarPortal>\n  )\n}\n\n/** Selectable menu item. Supports an inset variant and a destructive variant. */\nfunction MenubarItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Item> & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <MenubarPrimitive.Item\n      data-slot=\"menubar-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:text-destructive!\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Menu item with a checkmark indicator reflecting its checked state. */\nfunction MenubarCheckboxItem({\n  className,\n  children,\n  checked,\n  iconWeight,\n  ...props\n}: Omit<React.ComponentProps<typeof MenubarPrimitive.CheckboxItem>, keyof SaasflareComponentProps> &\n  Pick<SaasflareComponentProps, \"iconWeight\">) {\n  const sf = useSaasflareProps({ iconWeight })\n  return (\n    <MenubarPrimitive.CheckboxItem\n      data-slot=\"menubar-checkbox-item\"\n      className={cn(\n        \"relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <MenubarPrimitive.ItemIndicator>\n          <CheckIcon weight={sf.iconWeight} className=\"size-4\" />\n        </MenubarPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </MenubarPrimitive.CheckboxItem>\n  )\n}\n\n/** Menu item with a dot indicator for single-selection radio groups. */\nfunction MenubarRadioItem({\n  className,\n  children,\n  iconWeight,\n  ...props\n}: Omit<React.ComponentProps<typeof MenubarPrimitive.RadioItem>, keyof SaasflareComponentProps> &\n  Pick<SaasflareComponentProps, \"iconWeight\">) {\n  const sf = useSaasflareProps({ iconWeight })\n  return (\n    <MenubarPrimitive.RadioItem\n      data-slot=\"menubar-radio-item\"\n      className={cn(\n        \"relative flex cursor-default items-center gap-2 rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n        <MenubarPrimitive.ItemIndicator>\n          <CircleIcon weight={sf.iconWeight} className=\"size-2 fill-current\" />\n        </MenubarPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </MenubarPrimitive.RadioItem>\n  )\n}\n\n/** Non-interactive heading used to caption a group of menu items. */\nfunction MenubarLabel({\n  className,\n  inset,\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Label> & {\n  inset?: boolean\n}) {\n  return (\n    <MenubarPrimitive.Label\n      data-slot=\"menubar-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Thin horizontal divider between groups of menu items. */\nfunction MenubarSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Separator>) {\n  return (\n    <MenubarPrimitive.Separator\n      data-slot=\"menubar-separator\"\n      className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\n/** Right-aligned hint showing the keyboard shortcut for a menu item. */\nfunction MenubarShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"menubar-shortcut\"\n      className={cn(\n        \"ml-auto text-xs tracking-widest text-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/** Wrapper for a nested submenu, pairing a sub-trigger with sub-content. */\nfunction MenubarSub({\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.Sub>) {\n  return <MenubarPrimitive.Sub data-slot=\"menubar-sub\" {...props} />\n}\n\n/** Menu item that opens a nested submenu, with a trailing caret indicator. */\nfunction MenubarSubTrigger({\n  className,\n  inset,\n  children,\n  iconWeight,\n  ...props\n}: Omit<React.ComponentProps<typeof MenubarPrimitive.SubTrigger>, keyof SaasflareComponentProps> & {\n  inset?: boolean\n} & Pick<SaasflareComponentProps, \"iconWeight\">) {\n  const sf = useSaasflareProps({ iconWeight })\n  return (\n    <MenubarPrimitive.SubTrigger\n      data-slot=\"menubar-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none focus:bg-accent focus:text-accent-foreground data-[inset]:pl-8 data-[state=open]:bg-accent data-[state=open]:text-accent-foreground\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <CaretRightIcon weight={sf.iconWeight} className=\"ml-auto h-4 w-4\" />\n    </MenubarPrimitive.SubTrigger>\n  )\n}\n\n/** Floating panel for a nested submenu's items. */\nfunction MenubarSubContent({\n  className,\n  ...props\n}: React.ComponentProps<typeof MenubarPrimitive.SubContent>) {\n  return (\n    <MenubarPrimitive.SubContent\n      data-slot=\"menubar-sub-content\"\n      className={cn(\n        \"z-50 min-w-[8rem] origin-(--radix-menubar-content-transform-origin) overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Menubar,\n  type MenubarProps,\n  type MenubarContentProps,\n  MenubarPortal,\n  MenubarMenu,\n  MenubarTrigger,\n  MenubarContent,\n  MenubarGroup,\n  MenubarSeparator,\n  MenubarLabel,\n  MenubarItem,\n  MenubarShortcut,\n  MenubarCheckboxItem,\n  MenubarRadioGroup,\n  MenubarRadioItem,\n  MenubarSub,\n  MenubarSubTrigger,\n  MenubarSubContent,\n}\n",
      "target": "components/ui/menubar.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/menubar.json"
  }
}
