1.0.0 • Published 7 months ago

@darksnow-ui/menubar v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

Menubar

A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands. Built on top of Radix UI Menubar primitive.

Installation

npm install @darksnow-ui/menubar

Peer Dependencies

npm install react react-dom

Usage

import {
  Menubar,
  MenubarContent,
  MenubarItem,
  MenubarMenu,
  MenubarSeparator,
  MenubarShortcut,
  MenubarTrigger,
} from "@darksnow-ui/menubar"

export function MenubarExample() {
  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>File</MenubarTrigger>
        <MenubarContent>
          <MenubarItem>
            New Tab <MenubarShortcut>⌘T</MenubarShortcut>
          </MenubarItem>
          <MenubarItem>New Window</MenubarItem>
          <MenubarSeparator />
          <MenubarItem>Print...</MenubarItem>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Examples

Basic Menubar

<Menubar>
  <MenubarMenu>
    <MenubarTrigger>File</MenubarTrigger>
    <MenubarContent>
      <MenubarItem>
        New Tab <MenubarShortcut>⌘T</MenubarShortcut>
      </MenubarItem>
      <MenubarItem>
        New Window <MenubarShortcut>⌘N</MenubarShortcut>
      </MenubarItem>
      <MenubarItem disabled>New Incognito Window</MenubarItem>
      <MenubarSeparator />
      <MenubarItem>
        Print... <MenubarShortcut>⌘P</MenubarShortcut>
      </MenubarItem>
    </MenubarContent>
  </MenubarMenu>
  <MenubarMenu>
    <MenubarTrigger>Edit</MenubarTrigger>
    <MenubarContent>
      <MenubarItem>
        Undo <MenubarShortcut>⌘Z</MenubarShortcut>
      </MenubarItem>
      <MenubarItem>
        Redo <MenubarShortcut>⇧⌘Z</MenubarShortcut>
      </MenubarItem>
      <MenubarSeparator />
      <MenubarItem>Cut</MenubarItem>
      <MenubarItem>Copy</MenubarItem>
      <MenubarItem>Paste</MenubarItem>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

With Submenus

<Menubar>
  <MenubarMenu>
    <MenubarTrigger>File</MenubarTrigger>
    <MenubarContent>
      <MenubarItem>New Tab</MenubarItem>
      <MenubarSeparator />
      <MenubarSub>
        <MenubarSubTrigger>Share</MenubarSubTrigger>
        <MenubarSubContent>
          <MenubarItem>Email link</MenubarItem>
          <MenubarItem>Messages</MenubarItem>
          <MenubarItem>Notes</MenubarItem>
        </MenubarSubContent>
      </MenubarSub>
      <MenubarSeparator />
      <MenubarItem>Print...</MenubarItem>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

With Checkbox Items

function MenubarWithCheckbox() {
  const [showBookmarks, setShowBookmarks] = useState(true)
  const [showFullURLs, setShowFullURLs] = useState(false)

  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>View</MenubarTrigger>
        <MenubarContent>
          <MenubarCheckboxItem
            checked={showBookmarks}
            onCheckedChange={setShowBookmarks}
          >
            Always Show Bookmarks Bar
          </MenubarCheckboxItem>
          <MenubarCheckboxItem
            checked={showFullURLs}
            onCheckedChange={setShowFullURLs}
          >
            Always Show Full URLs
          </MenubarCheckboxItem>
          <MenubarSeparator />
          <MenubarItem inset>
            Reload <MenubarShortcut>⌘R</MenubarShortcut>
          </MenubarItem>
          <MenubarItem disabled inset>
            Force Reload <MenubarShortcut>⇧⌘R</MenubarShortcut>
          </MenubarItem>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

With Radio Groups

function MenubarWithRadio() {
  const [person, setPerson] = useState("pedro")

  return (
    <Menubar>
      <MenubarMenu>
        <MenubarTrigger>Profiles</MenubarTrigger>
        <MenubarContent>
          <MenubarRadioGroup value={person} onValueChange={setPerson}>
            <MenubarRadioItem value="andy">Andy</MenubarRadioItem>
            <MenubarRadioItem value="benoit">Benoit</MenubarRadioItem>
            <MenubarRadioItem value="luis">Luis</MenubarRadioItem>
            <MenubarRadioItem value="pedro">Pedro</MenubarRadioItem>
          </MenubarRadioGroup>
          <MenubarSeparator />
          <MenubarItem inset>Edit...</MenubarItem>
          <MenubarSeparator />
          <MenubarItem inset>Add Profile...</MenubarItem>
        </MenubarContent>
      </MenubarMenu>
    </Menubar>
  )
}

Application Style Menubar

<Menubar className="max-w-max">
  <MenubarMenu>
    <MenubarTrigger>Application</MenubarTrigger>
    <MenubarContent>
      <MenubarItem>About Application</MenubarItem>
      <MenubarSeparator />
      <MenubarItem>
        Preferences... <MenubarShortcut>⌘,</MenubarShortcut>
      </MenubarItem>
      <MenubarSeparator />
      <MenubarItem>
        Hide Application <MenubarShortcut>⌘H</MenubarShortcut>
      </MenubarItem>
      <MenubarItem>
        Quit Application <MenubarShortcut>⌘Q</MenubarShortcut>
      </MenubarItem>
    </MenubarContent>
  </MenubarMenu>
  <MenubarMenu>
    <MenubarTrigger>Help</MenubarTrigger>
    <MenubarContent>
      <MenubarItem>Documentation</MenubarItem>
      <MenubarItem>Keyboard Shortcuts</MenubarItem>
      <MenubarSeparator />
      <MenubarItem>Report Issue</MenubarItem>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

Components

Menubar

The root container component.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

MenubarMenu

A container for each menu in the menubar.

MenubarTrigger

The button that toggles the menu dropdown.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
childrenReact.ReactNode-Menu trigger content

MenubarContent

The dropdown content container.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
align"start" | "end""start"Alignment relative to trigger
alignOffsetnumber-4Offset from alignment position
sideOffsetnumber8Distance from trigger

MenubarItem

A menu item component.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
insetbooleanfalseAdds left padding
disabledbooleanfalseDisables the item
onSelectfunction-Called when item selected

MenubarCheckboxItem

A checkbox menu item.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
checkedbooleanfalseCheckbox state
onCheckedChangefunction-Called when checked changes

MenubarRadioGroup

Groups radio items together.

PropTypeDefaultDescription
valuestring-Current selected value
onValueChangefunction-Called when value changes

MenubarRadioItem

A radio menu item.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
valuestring-Radio item value

MenubarSub

Container for submenu functionality.

MenubarSubTrigger

Trigger for opening a submenu.

PropTypeDefaultDescription
classNamestring-Additional CSS classes
insetbooleanfalseAdds left padding

MenubarSubContent

Container for submenu content.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

MenubarSeparator

Visual separator between menu items.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

MenubarShortcut

Displays keyboard shortcuts in menu items.

PropTypeDefaultDescription
classNamestring-Additional CSS classes

Accessibility

  • Full keyboard navigation support
  • Screen reader accessible with proper ARIA attributes
  • Focus management between menu items
  • Supports escape key to close menus
  • Proper focus trapping within menu content
  • Arrow key navigation for menu items

Styling

The Menubar components use DarkSnow UI design tokens:

  • Container: border-theme-mark-light bg-theme-surface shadow-theme-sm
  • Triggers: Focus states with focus:bg-theme-accent focus:text-theme-accent-content
  • Content: Animated dropdown with theme-appropriate shadows and borders
  • Items: Hover and focus states with proper contrast
  • Disabled: Reduced opacity and pointer events disabled

Best Practices

  1. Consistent structure: Use similar menu structures across your application
  2. Keyboard shortcuts: Include shortcuts for frequently used actions
  3. Logical grouping: Use separators to group related menu items
  4. Clear labels: Use descriptive, concise labels for menu items
  5. Disable unavailable actions: Disable menu items when actions are not available
  6. Icon consistency: If using icons, maintain consistent icon usage

Common Patterns

File Menu

<MenubarMenu>
  <MenubarTrigger>File</MenubarTrigger>
  <MenubarContent>
    <MenubarItem>New <MenubarShortcut>⌘N</MenubarShortcut></MenubarItem>
    <MenubarItem>Open <MenubarShortcut>⌘O</MenubarShortcut></MenubarItem>
    <MenubarSeparator />
    <MenubarItem>Save <MenubarShortcut>⌘S</MenubarShortcut></MenubarItem>
    <MenubarItem>Save As <MenubarShortcut>⇧⌘S</MenubarShortcut></MenubarItem>
    <MenubarSeparator />
    <MenubarItem>Print <MenubarShortcut>⌘P</MenubarShortcut></MenubarItem>
  </MenubarContent>
</MenubarMenu>

View Menu with Toggle Options

<MenubarMenu>
  <MenubarTrigger>View</MenubarTrigger>
  <MenubarContent>
    <MenubarCheckboxItem checked={showSidebar} onCheckedChange={setShowSidebar}>
      Show Sidebar
    </MenubarCheckboxItem>
    <MenubarCheckboxItem checked={showToolbar} onCheckedChange={setShowToolbar}>
      Show Toolbar
    </MenubarCheckboxItem>
    <MenubarSeparator />
    <MenubarItem>Zoom In <MenubarShortcut>⌘+</MenubarShortcut></MenubarItem>
    <MenubarItem>Zoom Out <MenubarShortcut>⌘-</MenubarShortcut></MenubarItem>
  </MenubarContent>
</MenubarMenu>

Related Components