FairGarden Design

Menubar

An application row of menus, for app screens with three or more command groups.

import { Menubar, MenubarMenu } from '@fairgarden-private/design/components/Menubar'
import { MenuItem } from '@fairgarden-private/design/components/Menu'

The bar is 44 px tall with a --border-size-1 rule under it. Each MenubarMenu has a type-button-sm trigger whose label is authored in title case with no tracking ("File", "View Options"); the open trigger takes a --ds-stroke-3 bar. Its items are the Menu's parts, in the Menu's portaled white popup, which never changes with the bar's ground. Below 1024 px the bar collapses into one "Menu" trigger, and each menu becomes a labelled group in its popup. The bar is hidden in print.

Use a menubar only on application screens; menus for one object belong in a Menu, and page navigation belongs in the navigation components.

An application menubar

An application menubar

Narrow the window below 1024 px to see the collapsed "Menu".

No command yet. Grid on, contours off.

MenubarBasic.tsx
'use client'

import * as React from 'react'
import { Menubar, MenubarMenu } from '@fairgarden-private/design/components/Menubar'
import {
  MenuCheckboxItem,
  MenuItem,
  MenuSeparator,
  MenuSubmenu,
  MenuSubmenuTrigger,
  MenuPopup,
} from '@fairgarden-private/design/components/Menu'
import styles from './basic.module.css'

export function MenubarBasic() {
  const [last, setLast] = React.useState('No command yet.')
  const [showGrid, setShowGrid] = React.useState(true)
  const [showContours, setShowContours] = React.useState(false)
  const run = (message: string) => () => setLast(message)

  return (
    <div className={styles.stack}>
      <Menubar>
        <MenubarMenu label="File">
          <MenuItem shortcut="⌘ N" onClick={run('New survey.')}>
            New survey
          </MenuItem>
          <MenuItem shortcut="⌘ O" onClick={run('Opened a survey.')}>
            Open survey
          </MenuItem>
          <MenuSubmenu>
            <MenuSubmenuTrigger icon="download">Export as</MenuSubmenuTrigger>
            <MenuPopup>
              <MenuItem onClick={run('Exported a CSV.')}>CSV table</MenuItem>
              <MenuItem onClick={run('Exported a GPX track.')}>GPX track</MenuItem>
            </MenuPopup>
          </MenuSubmenu>
        </MenubarMenu>
        <MenubarMenu label="Edit">
          <MenuItem shortcut="⌘ Z" onClick={run('Undid the last change.')}>
            Undo
          </MenuItem>
          <MenuItem disabled shortcut="⇧ ⌘ Z">
            Redo (nothing to redo)
          </MenuItem>
          <MenuSeparator />
          <MenuItem destructive onClick={run('Cleared the plot.')}>
            Clear plot
          </MenuItem>
        </MenubarMenu>
        <MenubarMenu label="View Options">
          <MenuCheckboxItem checked={showGrid} onCheckedChange={setShowGrid}>
            Survey grid
          </MenuCheckboxItem>
          <MenuCheckboxItem checked={showContours} onCheckedChange={setShowContours}>
            Contour lines
          </MenuCheckboxItem>
        </MenubarMenu>
      </Menubar>
      <p className={styles.status} aria-live="polite">
        {`${last} Grid ${showGrid ? 'on' : 'off'}, contours ${showContours ? 'on' : 'off'}.`}
      </p>
    </div>
  )
}

API Reference

The bar (Base UI Menubar): --ds-size-hit tall with a --border-size-1 --role-rule under it, holding MenubarMenus. Below --lg-n-above it collapses into one collapsedLabel trigger whose popup lists each menu as a labelled group.

PropTypeDescription
collapsedLabel
string | undefined

The single trigger’s label below --lg-n-above, where the menus collapse into one menu of labelled groups. Title case. Default “Menu”.

collapsedPopupProps
MenuPopupProps | undefined

Props for the collapsed menu’s popup.

primary
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'ruby'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| null
| undefined

Primary Radix scale for the bar: triggers, rule, open bar and ring. Never defaulted [D133].

secondary
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'ruby'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| 'amber'
| 'blue'
| 'cyan'
| 'grass'
| 'green'
| 'jade'
| 'lime'
| 'mint'
| 'orange'
| 'sky'
| 'teal'
| 'yellow'
| null
| undefined

Secondary Radix scale for the bar. Never defaulted.

One menu of the bar: a type-button-sm trigger and a Menu popup of its items. Inside the collapsed “Menu” it renders as a MenuGroup under a MenuGroupLabel of the same label.

PropTypeDescription
label
string | undefined

The trigger’s label, authored in title case with no tracking (“File”, “Edit”, “View Options”) [D160, D165]; the group label when collapsed.

popupProps
MenuPopupProps | undefined

Props for the menu’s popup (placement, color axes).

disabled
boolean | undefined

Disables the trigger.

children
React.ReactNode | undefined

The menu’s items: MenuItem, MenuCheckboxItem, MenuRadioGroup, MenuSubmenu …

Additional types

menubar
MenubarMenuProps
MenubarProps

Specification: DESIGN-SYSTEM.md §9.7 (menu and menubar) and D165 (title-case command triggers).