import {ActionMenu} from '@primer/react'
ActionMenu
ships with ActionMenu.Button
which is an accessible trigger for the overlay. It's recommended to compose ActionList
with ActionMenu.Overlay
<ActionMenu><ActionMenu.Button>Menu</ActionMenu.Button><ActionMenu.Overlay><ActionList><ActionList.Item onSelect={event => console.log('New file')}>New file</ActionList.Item><ActionList.Item>Copy link</ActionList.Item><ActionList.Item>Edit file</ActionList.Item><ActionList.Divider /><ActionList.Item variant="danger">Delete file</ActionList.Item></ActionList></ActionMenu.Overlay></ActionMenu>
You can choose to have a different anchor for the Menu depending on the application's context.
<ActionMenu><ActionMenu.Anchor><IconButton icon={KebabHorizontalIcon} variant="invisible" aria-label="Open column options" /></ActionMenu.Anchor><ActionMenu.Overlay><ActionList><ActionList.Item><ActionList.LeadingVisual><PencilIcon /></ActionList.LeadingVisual>Rename</ActionList.Item><ActionList.Item><ActionList.LeadingVisual><ArchiveIcon /></ActionList.LeadingVisual>Archive all cards</ActionList.Item><ActionList.Item variant="danger"><ActionList.LeadingVisual><TrashIcon /></ActionList.LeadingVisual>Delete</ActionList.Item></ActionList></ActionMenu.Overlay></ActionMenu>
<ActionMenu><ActionMenu.Button>Open column menu</ActionMenu.Button><ActionMenu.Overlay><ActionList showDividers><ActionList.Group title="Live query"><ActionList.Item><ActionList.LeadingVisual><SearchIcon /></ActionList.LeadingVisual>repo:github/memex,github/github</ActionList.Item></ActionList.Group><ActionList.Divider /><ActionList.Group title="Layout" variant="subtle"><ActionList.Item><ActionList.LeadingVisual><NoteIcon /></ActionList.LeadingVisual>Table<ActionList.Description variant="block">Information-dense table optimized for operations across teams</ActionList.Description></ActionList.Item><ActionList.Item role="listitem"><ActionList.LeadingVisual><ProjectIcon /></ActionList.LeadingVisual>Board<ActionList.Description variant="block">Kanban-style board focused on visual states</ActionList.Description></ActionList.Item></ActionList.Group><ActionList.Divider /><ActionList.Group><ActionList.Item><ActionList.LeadingVisual><FilterIcon /></ActionList.LeadingVisual>Save sort and filters to current view</ActionList.Item><ActionList.Item><ActionList.LeadingVisual><FilterIcon /></ActionList.LeadingVisual>Save sort and filters to new view</ActionList.Item></ActionList.Group><ActionList.Divider /><ActionList.Group><ActionList.Item><ActionList.LeadingVisual><GearIcon /></ActionList.LeadingVisual>View settings</ActionList.Item></ActionList.Group></ActionList></ActionMenu.Overlay></ActionMenu>
Use selectionVariant
on ActionList
to create a menu with single or multiple selection.
const fieldTypes = [{icon: TypographyIcon, name: 'Text'},{icon: NumberIcon, name: 'Number'},{icon: CalendarIcon, name: 'Date'},{icon: SingleSelectIcon, name: 'Single select'},{icon: IterationsIcon, name: 'Iteration'}]const Example = () => {const [selectedIndex, setSelectedIndex] = React.useState(1)const selectedType = fieldTypes[selectedIndex]return (<ActionMenu><ActionMenu.Button aria-label="Select field type" leadingIcon={selectedType.icon}>{selectedType.name}</ActionMenu.Button><ActionMenu.Overlay width="medium"><ActionList selectionVariant="single">{fieldTypes.map((type, index) => (<ActionList.Item key={index} selected={index === selectedIndex} onSelect={() => setSelectedIndex(index)}><ActionList.LeadingVisual><type.icon /></ActionList.LeadingVisual>{type.name}</ActionList.Item>))}</ActionList></ActionMenu.Overlay></ActionMenu>)}render(<Example />)
To create an anchor outside of the menu, you need to switch to controlled mode for the menu and pass it as anchorRef
to ActionMenu
. Make sure you add aria-expanded
and aria-haspopup
to the external anchor:
const Example = () => {const [open, setOpen] = React.useState(false)const anchorRef = React.createRef()return (<><Button ref={anchorRef} aria-haspopup="true" aria-expanded={open} onClick={() => setOpen(!open)}>{open ? 'Close Menu' : 'Open Menu'}</Button><ActionMenu open={open} onOpenChange={setOpen} anchorRef={anchorRef}><ActionMenu.Overlay><ActionList><ActionList.Item>Copy link</ActionList.Item><ActionList.Item>Quote reply</ActionList.Item><ActionList.Item>Edit comment</ActionList.Item><ActionList.Divider /><ActionList.Item variant="danger">Delete file</ActionList.Item></ActionList></ActionMenu.Overlay></ActionMenu></>)}render(<Example />)
To create an anchor outside of the menu, you need to switch to controlled mode for the menu and pass it as anchorRef
to ActionMenu
:
const handleEscape = () => alert('you hit escape!')render(<ActionMenu><ActionMenu.Button>Open Actions Menu</ActionMenu.Button><ActionMenu.Overlay width="medium" onEscape={handleEscape}><ActionList><ActionList.Item>Open current Codespace<ActionList.Description variant="block">Your existing Codespace will be opened to its previous state, and you'll be asked to manually switch tonew-branch.</ActionList.Description><ActionList.TrailingVisual>⌘O</ActionList.TrailingVisual></ActionList.Item><ActionList.Item>Create new Codespace<ActionList.Description variant="block">Create a brand new Codespace with a fresh image and checkout this branch.</ActionList.Description><ActionList.TrailingVisual>⌘C</ActionList.TrailingVisual></ActionList.Item></ActionList></ActionMenu.Overlay></ActionMenu>)
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactElement[] | Recommended: ActionMenu.Button or ActionMenu.Anchor with ActionMenu.Overlay | |
open | boolean | false | If defined, will control the open/closed state of the overlay. Must be used in conjuction with onOpenChange . |
onOpenChange | (open: boolean) => void | If defined, will control the open/closed state of the overlay. Must be used in conjuction with open . | |
anchorRef | React.RefObject<HTMLElement> | Useful for defining an external anchor |
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactElement | ||
Additional props are passed to the <Button> element. See Button docs for a list of props accepted by the <Button> element. If an as prop is specified, the accepted props will change accordingly. |
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactElement | Accepts a single child element |
Name | Type | Default | Description |
---|---|---|---|
children Required | React.ReactElement | React.ReactElement[] | ||
align | start | center | end | start | |
Additional props are passed to the <Overlay> element. See Overlay docs for a list of props accepted by the <Overlay> element. |
Interface guidelines: Action List + Menu