Skip to content
  1. Keyline UI
  2. Menubar
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Menubar

A row of menus in one frame. Each title is a cell; its menu docks to the frame’s bottom edge under it. With one menu open, Left and Right move to the next.

StandardNarrow
010020030040050060070080090010001100120013001400150016001700180019002000

Loading the live example…

"use client"

import { useState } from "react"
import {
  Menubar,
  MenubarCheckboxItem,
  MenubarContent,
  MenubarItem,
  MenubarMenu,
  MenubarRadioGroup,
  MenubarRadioItem,
  MenubarSeparator,
  MenubarTrigger,
} from "@/components/keyline/ui/menubar"

export function SalesReportMenus() {
  const [period, setPeriod] = useState("quarter")
  const [targets, setTargets] = useState(true)
  const [byRep, setByRep] = useState(false)
  const [last, setLast] = useState<string | null>(null)

  return (
    <div className="grid min-w-0 grid-cols-[minmax(0,1fr)] gap-4">
      <Menubar aria-label="Sales report">
        <MenubarMenu>
          <MenubarTrigger>File</MenubarTrigger>
          <MenubarContent>
            <MenubarItem onClick={() => setLast("Saved a copy for David Wallace.")}>Save a copy</MenubarItem>
            <MenubarItem shortcut="⌘P" onClick={() => setLast("Sent to the printer by the annex.")}>
              Print
            </MenubarItem>
          </MenubarContent>
        </MenubarMenu>
        <MenubarMenu>
          <MenubarTrigger>View</MenubarTrigger>
          <MenubarContent>
            <MenubarCheckboxItem checked={targets} onCheckedChange={setTargets}>
              Branch targets
            </MenubarCheckboxItem>
            <MenubarCheckboxItem checked={byRep} onCheckedChange={setByRep}>
              Split by sales rep
            </MenubarCheckboxItem>
            <MenubarSeparator />
            <MenubarRadioGroup value={period} onValueChange={setPeriod}>
              <MenubarRadioItem value="month">This month</MenubarRadioItem>
              <MenubarRadioItem value="quarter">This quarter</MenubarRadioItem>
              <MenubarRadioItem value="year">This year</MenubarRadioItem>
            </MenubarRadioGroup>
          </MenubarContent>
        </MenubarMenu>
        <MenubarMenu>
          <MenubarTrigger>Share</MenubarTrigger>
          <MenubarContent>
            <MenubarItem onClick={() => setLast("Emailed to the Scranton sales team.")}>Email the sales team</MenubarItem>
            <MenubarItem onClick={() => setLast("Posted on the break room board.")}>Post in the break room</MenubarItem>
          </MenubarContent>
        </MenubarMenu>
        <MenubarMenu>
          <MenubarTrigger>Help</MenubarTrigger>
          <MenubarContent>
            <MenubarItem onClick={() => setLast("Ticket opened with IT. Nick will be up shortly.")}>Ask IT</MenubarItem>
          </MenubarContent>
        </MenubarMenu>
      </Menubar>
      <p role="status" className="m-0 min-h-10 text-[14px] text-kl-ink-2">
        Q3 sales, Scranton · {period === "month" ? "this month" : period === "quarter" ? "this quarter" : "this year"}
        {targets ? " · against targets" : ""}
        {byRep ? " · by rep" : ""}
        {last ? ` · ${last}` : ""}
      </p>
    </div>
  )
}

Installation

npx shadcn@latest add @keyline-ui/menubar

Run it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.

Usage

The rows are Menu’s, re-exported under Menubar names: MenubarItem, MenubarCheckboxItem, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator and the submenu parts.

import {
  Menubar,
  MenubarContent,
  MenubarItem,
  MenubarMenu,
  MenubarTrigger,
} from "@/components/keyline/ui/menubar"
<Menubar aria-label="Sales report">
  <MenubarMenu>
    <MenubarTrigger>File</MenubarTrigger>
    <MenubarContent>
      <MenubarItem onClick={print}>Print</MenubarItem>
    </MenubarContent>
  </MenubarMenu>
</Menubar>

Props

PropTypeDefaultDescription
layout"control" | "cell"Default "control"cell drops the frame, for a menubar that is the top row of a Panel or an app shell header.
aria-labelstringDefault —Name the bar for what its menus act on.
loopFocusbooleanDefault trueLeft and Right wrap from the last title to the first.

At narrow widths the titles scroll inside the frame and the hidden edge is shaded. Built on Base UI Menubar.

Sheet 14 of 73PreviousMenuNextContext menu
On this page