Menubar

Menubar wraps the existing Menu dropdowns and keeps only one menu open at a time.

Basics

Open a menu by pressing its target, then hover or use arrow keys to switch menus.

Loading demo…

import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <Menubar> <Menubar.Menu> <Menubar.Target>File</Menubar.Target> <Menubar.Dropdown> <Menu.Item>New</Menu.Item> <Menu.Item>Open</Menu.Item> <Menu.Divider /> <Menu.Item>Exit</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> <Menubar.Menu> <Menubar.Target>Edit</Menubar.Target> <Menubar.Dropdown> <Menu.Item>Undo</Menu.Item> <Menu.Item>Redo</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> <Menubar.Menu> <Menubar.Target>Help</Menubar.Target> <Menubar.Dropdown> <Menu.Item>Documentation</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }

Hover Trigger

With trigger="hover", moving across targets switches menus.

Loading demo…

import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <Menubar trigger="hover"> <Menubar.Menu> <Menubar.Target>File</Menubar.Target> <Menubar.Dropdown> <Menu.Item>New</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> <Menubar.Menu> <Menubar.Target>Edit</Menubar.Target> <Menubar.Dropdown> <Menu.Item>Undo</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }

Checkbox and Radio Items

Top-level dropdowns can contain persistent menu choices.

Loading demo…

import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <Menubar> <Menubar.Menu> <Menubar.Target>View</Menubar.Target> <Menubar.Dropdown> <Menu.CheckboxItem>Show grid</Menu.CheckboxItem> <Menu.RadioGroup defaultValue="list"> <Menu.RadioItem value="list">List</Menu.RadioItem> <Menu.RadioItem value="grid">Grid</Menu.RadioItem> </Menu.RadioGroup> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }

Menubar dropdowns reuse nested Menu.Sub groups.

Loading demo…

import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <Menubar> <Menubar.Menu> <Menubar.Target>File</Menubar.Target> <Menubar.Dropdown> <Menu.Sub label="Share"> <Menu.Item>Email</Menu.Item> <Menu.Item>Copy link</Menu.Item> </Menu.Sub> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }

A menu can override the default bottom-start placement.

Loading demo…

import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <Menubar> <Menubar.Menu position="bottom-end"> <Menubar.Target>Options</Menubar.Target> <Menubar.Dropdown> <Menu.Item>Settings</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }

Controlled State

openIndex and onOpenChange let a parent own the open menu.

Loading demo…

import { useState } from 'react'; import { Block, Menu, Menubar } from '@plocks/ui'; export function Demo() { const [openIndex, setOpenIndex] = useState<number | null>(null); return ( <Block fullWidth> <Menubar openIndex={openIndex} onOpenChange={setOpenIndex}> <Menubar.Menu> <Menubar.Target>File</Menubar.Target> <Menubar.Dropdown> <Menu.Item>New</Menu.Item> <Menu.Item>Open</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> <Menubar.Menu> <Menubar.Target>Edit</Menubar.Target> <Menubar.Dropdown> <Menu.Item>Undo</Menu.Item> <Menu.Item>Redo</Menu.Item> </Menubar.Dropdown> </Menubar.Menu> </Menubar> </Block> ); }
Scan to open this page on your phoneplocks.dev/ui/Menubar