Menu
A short list of actions under the control that opened it, on the floating glass of a Select's list, one wash gliding between its rows. Built on the vendored Base UI menu: arrow keys move, Enter acts, Escape or a press outside closes it. On a phone it opens as a bottom sheet.
StudioMenu
The studio at the end of the app's header: its mark, its name and a chevron; on a phone the mark alone. It opens what's the owner's.
import { MenuItem, MenuSeparator } from "@/components/shared/menu";
import { StudioMenu } from "@/components/shared/studio-menu";
<StudioMenu name={venue.name} logo={venue.logo}>
<MenuItem render={<Link href={`/${locale}/settings`} />}>
<Settings aria-hidden />
{t("settings")}
</MenuItem>
<MenuSeparator />
<MenuItem onClick={() => void signOut()}>
<LogOut aria-hidden />
{t("signOut")}
</MenuItem>
</StudioMenu>On a phone, a sheet
Under sm the list rises from the screen's foot as a bottom sheet (Sheet), as a Select's list does: the full width, the page dimmed, rows 44px tall, a handle to drag it down by. The same MenuItems, nothing to pass. Narrow this window to see it.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| Menu, MenuTrigger | Base UI Menu.Root, Menu.Trigger | — | As vendored. Style the trigger as a plain button. |
| MenuContent | align, side, sideOffset, children | align "end", 8px off | The list: 12rem wide at least, padded so its rows sit concentric inside. |
| MenuItem | Menu.Item props | — | One action, a 32px row, its icon first. A link through render={<Link href=… />}. |
| MenuSeparator | — | — | A hairline between groups of actions. |
| StudioMenu | { name, logo?, children } | — | The studio's mark (28px), name and chevron as the trigger; the name and chevron from 1024px. |
Guidelines
- For actions, not choices: picking a value is a Select's job.
- A few rows at most, grouped with a separator; what leaves the app (signing out) comes last.