Menu

The Menu component provides a dropdown interface for navigation links, actions, and contextual options.

Basics

Pair a trigger with MenuDropdown to show primary actions and separators in a compact surface.

Loading demo…

import { Button, Icon, Menu, MenuDivider, MenuDropdown, MenuItem } from '@plocks/ui'; export function Demo() { return ( <Menu> <Button size="sm" variant="outline"> Open menu </Button> <MenuDropdown> <MenuItem startSection={<Icon name="user" size="sm" />}> Profile </MenuItem> <MenuItem startSection={<Icon name="settings" size="sm" />}> Settings </MenuItem> <MenuItem startSection={<Icon name="info" size="sm" />}> Help & Support </MenuItem> <MenuDivider /> <MenuItem startSection={<Icon name="arrow-left" size="sm" />}> Logout </MenuItem> </MenuDropdown> </Menu> ); }

Context Trigger

Enable trigger="contextmenu" to surface a menu when users right-click or long-press a target.

Loading demo…

import { Card, Icon, Menu, MenuDivider, MenuDropdown, MenuItem, Text } from '@plocks/ui'; export function Demo() { return ( <Menu trigger="contextmenu"> <Card variant="outline" p="xl"> <Text>Right-click or long-press here</Text> </Card> <MenuDropdown> <MenuItem startSection={<Icon name="copy" size="sm" />}> Copy link </MenuItem> <MenuItem startSection={<Icon name="edit" size="sm" />}> Rename </MenuItem> <MenuItem startSection={<Icon name="share" size="sm" />}> Share </MenuItem> <MenuDivider /> <MenuItem startSection={<Icon name="trash" size="sm" />}> Delete </MenuItem> </MenuDropdown> </Menu> ); }

Placement Presets

Adjust the position prop to pin dropdown content to any edge of the trigger.

Loading demo…

import { Button, Menu, MenuDropdown, MenuItem, Row } from '@plocks/ui'; const POSITIONS = [ { label: 'Bottom start', position: 'bottom-start' }, { label: 'Bottom', position: 'bottom' }, { label: 'Bottom end', position: 'bottom-end' }, { label: 'Top start', position: 'top-start' }, { label: 'Top', position: 'top' }, { label: 'Top end', position: 'top-end' }, ] as const; export function Demo() { return ( <Row gap="md" justify="center" wrap="wrap"> {POSITIONS.map(({ label, position }) => ( <Menu key={position} position={position}> <Button size="sm" variant="outline"> {label} </Button> <MenuDropdown> <MenuItem>Duplicate</MenuItem> <MenuItem>Archive</MenuItem> </MenuDropdown> </Menu> ))} </Row> ); }

Checkbox and Radio Items

Choice items keep the menu open while their state changes.

Loading demo…

import { Button, Menu } from '@plocks/ui'; export function Demo() { return ( <Menu> <Button>View options</Button> <Menu.Dropdown> <Menu.CheckboxItem defaultChecked>Show grid</Menu.CheckboxItem> <Menu.RadioGroup defaultValue="comfortable"> <Menu.RadioItem value="comfortable">Comfortable</Menu.RadioItem> <Menu.RadioItem value="compact">Compact</Menu.RadioItem> </Menu.RadioGroup> </Menu.Dropdown> </Menu> ); }

Loading demo…

import { Button, Icon, Menu, MenuDropdown, MenuItem, MenuSub } from '@plocks/ui'; export function Demo() { return ( <Menu w={220}> <Button size="sm" variant="outline"> Actions </Button> <MenuDropdown> <MenuItem startSection={<Icon name="edit" size="sm" />}>Rename</MenuItem> <MenuSub label="Share" startSection={<Icon name="share" size="sm" />}> <MenuItem startSection={<Icon name="link" size="sm" />}>Copy link</MenuItem> <MenuItem startSection={<Icon name="mail" size="sm" />}>Email</MenuItem> <MenuSub label="Social"> <MenuItem>Twitter / X</MenuItem> <MenuItem>LinkedIn</MenuItem> <MenuItem>Reddit</MenuItem> </MenuSub> </MenuSub> <MenuSub label="Move to" startSection={<Icon name="folder" size="sm" />}> <MenuItem>Projects</MenuItem> <MenuItem>Archive</MenuItem> <MenuItem>Trash</MenuItem> </MenuSub> </MenuDropdown> </Menu> ); }
Scan to open this page on your phoneplocks.dev/ui/Menu