Menu
Menu displays a list of actions in a popup anchored to a trigger. It supports size, variant, color, side, align, and integrates with the sl styling system.
Demo
Alignment and sides
Usage
- TypeScript
- JavaScript
import React from 'react';
import {
MenuRoot,
MenuTrigger,
MenuBackdrop,
MenuPositioner,
MenuPopup,
MenuArrow,
MenuItem,
MenuSeparator,
MenuGroup,
MenuGroupLabel,
} from '@libdev-ui/base';
export default function Example() {
return (
<MenuRoot>
<MenuTrigger
sl={{ px: 12, py: 8, bgcolor: 'background.level2', color: 'text', borderRadius: 'md', boxShadow: 'sm' }}
>
Open menu
</MenuTrigger>
<MenuBackdrop />
<MenuPositioner side="bottom" align="start" offset={6}>
<MenuPopup sl={{ p: 8, minWidth: 220 }}>
<MenuArrow />
<MenuItem>New File</MenuItem>
<MenuItem>Open…</MenuItem>
<MenuSeparator />
<MenuGroup>
<MenuGroupLabel>Views</MenuGroupLabel>
<MenuItem>Explorer</MenuItem>
<MenuItem>Search</MenuItem>
</MenuGroup>
</MenuPopup>
</MenuPositioner>
</MenuRoot>
);
}
import React from 'react';
import {
MenuRoot,
MenuTrigger,
MenuBackdrop,
MenuPositioner,
MenuPopup,
MenuArrow,
MenuItem,
MenuSeparator,
MenuGroup,
MenuGroupLabel,
} from '@libdev-ui/base';
export default function Example() {
return (
<MenuRoot>
<MenuTrigger
sl={{ px: 12, py: 8, bgcolor: 'background.level2', color: 'text', borderRadius: 'md', boxShadow: 'sm' }}
>
Open menu
</MenuTrigger>
<MenuBackdrop />
<MenuPositioner side="bottom" align="start" offset={6}>
<MenuPopup sl={{ p: 8, minWidth: 220 }}>
<MenuArrow />
<MenuItem>New File</MenuItem>
<MenuItem>Open…</MenuItem>
<MenuSeparator />
<MenuGroup>
<MenuGroupLabel>Views</MenuGroupLabel>
<MenuItem>Explorer</MenuItem>
<MenuItem>Search</MenuItem>
</MenuGroup>
</MenuPopup>
</MenuPositioner>
</MenuRoot>
);
}
Props
MenuRoot
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | Controls open state | |
| defaultOpen | boolean | Uncontrolled initial open state | |
| onClose | () => void | Called when menu requests close | |
| onOpenChange | (open: boolean) => void | Called when open changes | |
| side | 'top' | 'bottom' | 'left' | 'right' | 'bottom' | Popup side relative to trigger |
| align | 'start' | 'center' | 'end' | 'start' | Popup alignment on the chosen side |
| offset | number | 6 | Gap between trigger and popup |
| disablePortal | boolean | false | Render under parent hierarchy |
| keepMounted | boolean | false | Keep popup in DOM when closed |
| size | 'sm' | 'md' | 'lg' | string | 'md' | Size token forwarded to popup |
| variant | 'outlined' | 'plain' | 'soft' | 'solid' | string | 'outlined' | Variant token |
| color | 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | string | 'neutral' | Color token |
| sl | SlProp | System styles for the root wrapper |
MenuTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
| as | 'button' | 'div' | 'button' | Element used for the trigger |
| sl | SlProp | System styles | |
| ...buttonProps | ButtonHTMLAttributes | Native button props when as='button' | |
| ...divProps | HTMLAttributes | Native div props when as='div' |
MenuPositioner
| Prop | Type | Default |
|---|---|---|
| side | 'top' | 'bottom' | 'left' | 'right' | 'bottom' |
| align | 'start' | 'center' | 'end' | 'start' |
| offset | number | 6 |
| sl | SlProp |
MenuPopup
| Prop | Type | Default |
|---|---|---|
| size | 'sm' | 'md' | 'lg' | string | 'md' |
| variant | 'outlined' | 'plain' | 'soft' | 'solid' | string | 'outlined' |
| color | 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | string | 'neutral' |
| instant | boolean | false |
| sl | SlProp |
MenuItem
| Prop | Type | Default |
|---|---|---|
| role | 'menuitem' | 'menuitemradio' | 'menuitemcheckbox' | 'menuitem' |
| disabled | boolean | false |
| sl | SlProp |
Utilities
Use sl tokens like bgcolor: 'background.level2', color: 'text', borderRadius: 'md', boxShadow: 'sm', p: 8, px: 12, py: 8 to style the trigger and the popup.