Skip to main content

An accessible dropdown and context menu that displays a list of actions or options.

Read more about installing Components and Primitives.

Wrap related items in a menu.itemGroup and name it with a menu.itemGroupLabel. A menu.separator divides the groups.

Set asChild="{true}" on a menu.item to put its attributes on your <a href>. The item navigates like a regular link, also from the keyboard.

Use menu.checkboxItem for options that switch on and off independently. The root sets closeOnSelect="{false}", so the menu stays open while you check several.

Radio items that share a name are mutually exclusive: choosing one unchecks the others.

Link a submenu to its parent by id: give its menu.root a rootId and a parentId that is the parent's rootId, then add a menu.triggerItem with a matching childId to the parent's content. Open Share or Export below.

Wrap an area in a menu.contextTrigger to open the menu on right-click. Add a regular menu.trigger as well to open the same menu from a button.

Right-click this area

Give each menu.trigger its own value and they open the same menu. onTriggerValueChange tells you which one opened it, so an item can act on what its trigger belongs to.

The trigger sits apart from the menu and links to a menu.provider with provider, a contextTrigger takes it too. The provider takes the props of the menu: here positioning, which aligns the menu to the end of the trigger. Its id is the rootId of the menu, so a submenu names it in parentId. See Providers.

Meeting notes

Menus portal to the end of the <body>. Set portalled="{false}" on menu.content inside a dialog, or another focus-trapped element, to keep the menu in its DOM subtree.

The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.

Provides shared menu state to the rest of the parts. Renders no element of its own.

NameDescriptionRequiredDefault
closeOnSelectboolean
Whether to close the menu when an option is selected.
No
true
compositeboolean
Whether the menu is composed with other composite widgets like a combobox or tabs.
No
true
typeaheadboolean
Whether pressing printable characters should trigger typeahead navigation.
No
true
loopFocusboolean
Whether to loop the keyboard navigation.
No
false
positioningarray
The options used to dynamically position the menu.
No
{
    "placement": "bottom-start",
    "gutter": 8
}
defaultOpenboolean
The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu.
No
false
defaultHighlightedValuestring
The initial highlighted value of the menu item when rendered.
No
-
defaultTriggerValuestring
The initial trigger value when rendered, for a menu with multiple triggers.
No
-
ariaLabelstring
The accessibility label for the menu. Forwarded to the machine as `aria-label`.
No
-
parentIdstring
The `rootId` of the parent menu this menu is a submenu of. Must match a `menu.triggerItem`'s `childId` on that parent, pointing back at this menu's own `rootId` - see the Nested Menu docs example.
No
-
rootIdstring
The root ID of the component, used for hydration and identification.
No
-
idsarray
The IDs of of the component parts for composition.
No
[]
autoMountboolean
Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()`
No
true
providerstring
The `id` of the `.provider` this root takes its `rootId` and props from.
No
-

Opens and closes the menu. Renders a <button> element.

NameDescriptionRequiredDefault
providerstring
The `id` of the `<component>.provider` this part belongs to, when it renders outside its root.
No
-
valuestring
The value that identifies this specific trigger, for a menu with multiple triggers.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-menu-trigger<uid>
data-disabledPresent when disabled
data-placementThe placement of the trigger
data-sideThe side of the trigger that the trigger is positioned on
data-valueThe value of the item
data-currentPresent when current
data-controls
data-state"open" | "closed"

Opens the menu at the cursor position on right-click. Renders a <div> element.

NameDescriptionRequiredDefault
providerstring
The `id` of the `<component>.provider` this part belongs to, when it renders outside its root.
No
-
valuestring
The value that identifies this specific context trigger, for a menu with multiple context triggers.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-menu-context-trigger<uid>
data-valueThe value of the item
data-currentPresent when current
data-state"open" | "closed"

Contains the menu items. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-menu-content<uid>
data-state"open" | "closed"
data-instant
data-placementThe placement of the content
data-sideThe side of the trigger that the content is positioned on
data-nestedmenu
data-has-nestedmenu

A selectable menu action. Renders a <div> element.

NameDescriptionRequiredDefault
valuestring
The unique value of the menu item.
Yes
-
disabledboolean
Whether the menu item is disabled.
No
-
valueTextstring
The textual value of the item, used for typeahead navigation. Falls back to the item's text content when omitted.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Rendered data attributes

AttributeDescription
data-menu-item<uid>
data-disabledPresent when disabled
data-highlightedPresent when highlighted
data-valueThe value of the item
data-valuetextThe human-readable value

A menu item that toggles independently of other items. Renders a <div> element.

NameDescriptionRequiredDefault
valuestring
The unique value of the checkbox item.
Yes
-
checkedboolean
Whether the checkbox item is checked when rendered.
No
false
disabledboolean
Whether the checkbox item is disabled.
No
-
valueTextstring
The textual value of the item, used for typeahead navigation. Falls back to the item's text content when omitted.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

A menu item that's mutually exclusive with other radio items sharing the same name. Renders a <div> element.

NameDescriptionRequiredDefault
valuestring
The unique value of the radio item.
Yes
-
checkedboolean
Whether the radio item is checked when rendered.
No
false
disabledboolean
Whether the radio item is disabled.
No
-
valueTextstring
The textual value of the item, used for typeahead navigation. Falls back to the item's text content when omitted.
No
-
namestring
Groups radio items so selecting one unchecks the others sharing the same `name`.
No
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Groups related items together. Renders a <div> element.

NameDescriptionRequiredDefault
valuestring
The value identifier of the item group. Picked up automatically by a `menu.itemGroupLabel` nested inside it.
Yes
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Labels an itemGroup. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

A visual divider between items. Renders a <div> element.

NameDescriptionRequiredDefault
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-

Opens a nested submenu from within another menu's content. Renders a <div> element.

NameDescriptionRequiredDefault
childIdstring
The `rootId` of the submenu (its `menu.root`'s `rootId`) that this item opens. That submenu's own `parentId` must point back at this menu's `rootId`.
Yes
-
attributesarray
Additional attributes that should be rendered on the component where ui:attributes is used.
No
[]
asChildboolean
If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props.
No
-
classstring
The CSS class(es) to be applied to the component.
No
-
NameTypeDescription
openbooleanWhether the menu is open
setOpen(open: boolean) => voidFunction to open or close the menu
triggerValuestring | nullThe trigger value
setTriggerValue(value: string | null) => voidFunction to set the trigger value
highlightedValuestring | nullThe id of the currently highlighted menuitem
setHighlightedValue(value: string) => voidFunction to set the highlighted menuitem
setParent(parent: MenuService) => voidFunction to register a parent menu. This is used for submenus
setChild(child: MenuService) => voidFunction to register a child menu. This is used for submenus
reposition(options?: Partial<PositioningOptions>) => voidFunction to reposition the popover
getOptionItemState(props: OptionItemProps) => OptionItemStateReturns the state of the option item
getItemState(props: ItemProps) => ItemStateReturns the state of the menu item
addItemListener(props: ItemListenerProps) => VoidFunction | undefinedSetup the custom event listener for item selection event
getTriggerState(props?: TriggerProps) => TriggerStateReturns the state of a specific trigger, including whether it's the currently active one
getPositionerState() => PositionerStateReturns the state of the positioner
getContentState() => ContentStateReturns the state of the content
KeyDescription
SpaceActivates/Selects the highlighted item
EnterActivates/Selects the highlighted item
ArrowDownHighlights the next item in the menu
ArrowUpHighlights the previous item in the menu
ArrowRightArrowLeftWhen focus is on trigger, opens or closes the submenu depending on reading direction.
EscCloses the menu and moves focus to the trigger