Components
Component
productdevbook/ui

Stable in React

Context Menu

A menu that appears at the pointer on right click or long press.

Loading React 19.3.1…
Hover a part or use it. The code follows. · Loading React…
80Tests passing in React · 0 failing
71.3 KiBSize
5.10 msOpen
6.80 msClose
1.25 MiBMemory
productdevbook and 15 upstream authors10 commits · last

Install#

One package per framework. Context Menu's parts come from it; the anatomy tab at the top shows how they nest.

bun add @▢▢▢▢/react

19 parts. The example uses six of them; the data does not say which are required.

  • ContextMenu.RootA component that creates a context menu activated by right clicking or long pressing.
  • ContextMenu.TriggerAn area that opens the menu on right click or long press.
  • ContextMenu.PortalA portal element that moves the popup to a different part of the DOM.
  • ContextMenu.PositionerPositions the context menu popup against the pointer or a custom anchor.
  • ContextMenu.PopupA container for the menu items.
  • ContextMenu.ItemAn individual interactive item in the menu.
  • ContextMenu.ArrowDisplays an element positioned against the menu anchor. Not in the example.
  • ContextMenu.BackdropAn overlay displayed beneath the menu popup. Not in the example.
  • ContextMenu.CheckboxItemA menu item that toggles a setting on or off. Not in the example.
  • ContextMenu.CheckboxItemIndicatorIndicates whether the checkbox item is ticked. Not in the example.
  • ContextMenu.GroupGroups related menu items with the corresponding label. Not in the example.
  • ContextMenu.GroupLabelAn accessible label that is automatically associated with its parent group. Not in the example.
  • ContextMenu.LinkItemA link in the menu that can be used to navigate to a different page or section. Not in the example.
  • ContextMenu.RadioGroupGroups related radio items. Not in the example.
  • ContextMenu.RadioItemA menu item that works like a radio button in a given group. Not in the example.
  • ContextMenu.RadioItemIndicatorIndicates whether the radio item is selected. Not in the example.
  • ContextMenu.SeparatorA separator element accessible to screen readers. Not in the example.
  • ContextMenu.SubmenuRootGroups all parts of a submenu. Not in the example.
  • ContextMenu.SubmenuTriggerA menu item that opens a submenu. Not in the example.

Examples#

Common ways to put it to work. Each one runs live.

SubmenuRoot and SubmenuTrigger open a nested menu from an item.

ContextMenuSubmenu.tsx

Styling and accessibility#

The parts ship no styles. Style their states with these attributes; the CSS tab at the top has a sheet. The same CSS works in all five frameworks.

  • [data-popup-open]Present when the corresponding context menu is open. On Trigger, SubmenuTrigger.
  • [data-pressed]Present when the corresponding context menu is open. On Trigger.
  • [data-open]Present when the menu popup is open. On Positioner, Popup, Arrow, Backdrop.
  • [data-closed]Present when the menu popup is closed. On Positioner, Popup, Arrow, Backdrop.
  • [data-anchor-hidden]Present when the anchor is hidden. On Positioner.
  • [data-side]Indicates which side the popup is positioned relative to the anchor. On Positioner, Popup, Arrow.
  • [data-align]Indicates how the popup is aligned relative to the specified side. On Positioner, Popup, Arrow.
  • --available-widthThe available width between the anchor and the edge of the viewport. On Positioner.
  • --available-heightThe available height between the anchor and the edge of the viewport. On Positioner.
  • --anchor-widthThe anchor's width. On Positioner.
  • --anchor-heightThe anchor's height. On Positioner.
  • --transform-originThe coordinates that this element is anchored to. Used for animations and transitions. On Positioner.
  • --positioner-widthThe width of the menu's positioner. It is important to set width to this value when using CSS to animate size changes. On Positioner.
  • --positioner-heightThe height of the menu's positioner. It is important to set height to this value when using CSS to animate size changes. On Positioner.
  • [data-starting-style]Present when the menu begins animating in. On Popup, Backdrop, CheckboxItemIndicator, RadioItemIndicator.
  • [data-ending-style]Present when the menu is animating out. On Popup, Backdrop, CheckboxItemIndicator, RadioItemIndicator.
  • [data-instant]Present if animations should be instant. On Popup.
  • [data-highlighted]Present when the menu item is highlighted. On Item, CheckboxItem, LinkItem, RadioItem, SubmenuTrigger.
  • [data-disabled]Present when the menu item is disabled. On Item, CheckboxItem, CheckboxItemIndicator, RadioItem, RadioItemIndicator, SubmenuTrigger.
  • [data-uncentered]Present when the menu arrow is uncentered. On Arrow.
  • [data-checked]Present when the menu checkbox item is checked. On CheckboxItem, CheckboxItemIndicator, RadioItem, RadioItemIndicator.
  • [data-unchecked]Present when the menu checkbox item is not checked. On CheckboxItem, CheckboxItemIndicator, RadioItem, RadioItemIndicator.
  • [data-orientation]Indicates the orientation of the separator. On Separator.

Keyboard

  • ShiftTabCloses the menu and returns focus to the area it was opened on On Popup.

Set for you

  • role="menu"the popup is announced as a menuPopup
  • role="menuitem"each action is read as a menu itemItem
  • role="menuitemcheckbox", aria-checkeda setting is read with its on or off stateCheckboxItem
  • role="menuitemradio", aria-checkedthe chosen option of a set is readRadioItem
  • role="group", aria-labelledby to its GroupLabelrelated items are read under their labelGroup
  • aria-controls to the submenua screen reader knows the item opens another menuSubmenuTrigger
  • role="separator"groups are divided for screen readers tooSeparator
  • aria-hidden="true"the decorative arrow is not readArrow

API reference#

75 props across 19 parts, in React syntax, and className, style, render once for every part. Open a row to try it.

ContextMenu · all parts
Shared propsEvery part that renders an element takes these.
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Use it in React#

What differs from the React API. Switch the framework at the top of the page.

@▢▢▢▢/react is the React 19 package. Its parts, props, data attributes and error messages are upstream Base UI's, and upstream's own tests run against it.

  • Parts

    Each component is its own entry point and exports one namespace named after it.

    import { Switch } from '@base-ui-next/react/switch'
    
    export function Example() {
      return (
        <Switch.Root>
          <Switch.Thumb />
        </Switch.Root>
      )
    }

    A part renders the element its API reference names, such as a <span> for Switch.Root.

  • Props and events

    Props and callbacks have upstream's names and signatures: onCheckedChange(checked, details), onOpenChange(open, details), onValueChange(value, details). details carries reason, event, cancel() and allowPropagation(). Native handlers are React's (onClick, onKeyDown), and event.preventBaseUIHandler() stops a part's own handler.

  • Styling

    className takes a string or a function (state) => string; style takes an object or a function (state) => object. The state's data-* attributes are on the element for CSS.

  • render

    render takes an element (render={<a href="/docs" />}) or a function (props, state) => element that spreads props on what it returns.

  • Refs

    ref reaches the part's element. Imperative handles are ref props, as upstream: inputRef, and actionsRef ({ validate } on Field and Form, { unmount, close } on Dialog).

  • Binding

    A part is controlled when its value prop (checked, open, value) is set, and uncontrolled with the default form (defaultChecked, defaultOpen, defaultValue). React has no two-way binding: pair the value with its change callback.

  • From @base-ui/react
    Change the import from @base-ui/react/<component> to @▢▢▢▢/react/<component>.
  • From @base-ui/react
    Nothing else changes: props, parts, data attributes and errors are the same.