Menu

Dropdown menu for structured actions with grouped items, submenus, checkbox and radio items, and horizontal layouts.

import { Menu } from "@plexui/ui/components/Menu";

Examples

Overview

Natural sizing

Horizontal (icons only)

size

Horizontal (icons with labels)

size

Grouped items

Checkbox items

indicatorPosition
indicatorVariant

Radio items

indicatorPosition

Item actions

Destructive items

API

Note: Menu prevents Tab from advancing focus. For generic popover content use Popover instead.

Menu (root)

PropTypeDefaultDescription
forceOpenboolean—Keep menu open (controlled)
onOpen() => void—Called when menu opens
onClose() => void—Called when menu closes
modalbooleanfalseWhether menu is modal (focus trap)

Menu.Trigger: Renders its child (e.g. a Button) as the element that toggles the menu. Other props (aria-*, handlers, ref) reach the child.

PropTypeDefaultDescription
disabledbooleanfalsePrevent the menu from opening

Menu.Content

PropTypeDefaultDescription
widthnumber | "auto""auto"Panel width in px
minWidthnumber | "auto"300Minimum panel width in px (vertical layout)
maxHeightnumber—Maximum panel height in px
side"top" | "right" | "bottom" | "left""bottom"Preferred placement
sideOffsetnumber5Distance from the trigger in px
align"start" | "center" | "end""center"Alignment relative to trigger
alignOffsetnumber-5Offset from the start or end alignment in px
layout"vertical" | "horizontal""vertical"Layout direction. Use horizontal for icon toolbars
size"sm" | "md" | "lg""md"Size of horizontal menu items (icon size + padding)
onCloseAutoFocus(event: Event) => void—Called before focus returns to the trigger; call event.preventDefault() to keep it from moving there

Menu.Item: List item. Use onSelect or onClick for actions; without either the item is non-interactive content.

PropTypeDefaultDescription
descriptionReactNode—Second line under the label. The label turns semibold on its own
onSelect(event: Event) => void—Called when item is selected; call event.preventDefault() to keep the menu open
onClick(event: MouseEvent) => void—Called when the item is clicked; also makes the item interactive
disabledbooleanfalseDisable the item
dangerbooleanfalseDestructive action: the item is drawn in the danger color
classNamestring—Applied to the item

Menu.Link: Item that navigates. Internal paths render the link component from PlexUIProvider; absolute http(s) URLs open in a new tab. Pass href or to, disabled (a disabled link does not navigate), as and link props; danger marks a destructive destination.

Menu.Separator: Divider between items. No props.

Menu.Group: Groups related items. Wraps Menu.Item, Menu.Link, or Menu.Label. No specific props.

Menu.Label: Non-interactive label for a group. Accepts className.

Menu.Sub / Menu.SubTrigger / Menu.SubContent: Submenu wrapper (with forceOpen, onOpen and onClose), trigger (with disabled), and content panel (with width, minWidth, maxHeight, sideOffset and alignOffset).

Menu.CheckboxItem

PropTypeDefaultDescription
checkedboolean | "indeterminate"—Checked state
onCheckedChange(checked: boolean) => void—When checkbox toggles
onSelect(event: Event) => void—Use with preventDefault() to keep menu open
indicatorPosition"start" | "end""end"Checkbox position
indicatorVariant"solid" | "ghost""solid"Checkbox indicator style
disabledboolean—Disable the item

Menu.RadioGroup / Menu.RadioItem: Radio group: value, onChange and indicatorPosition (default "end"); RadioItem: value, disabled and onSelect.

Menu.ItemActions / Menu.ItemAction: ItemActions wraps hover actions; ItemAction accepts onClick and closes the menu.

Styling

Menu reads these component tokens. Override them at any scope to restyle it:

  • --menu-checkbox-indicator-size: checkbox indicator size (default var(--font-text-lg-size))
  • --menu-font-size: font size (default var(--font-text-sm-size))
  • --menu-gutter: gutter (default spacing(1.5))
  • --menu-item-background-color: item background color (default light-dark(var(--alpha-08), var(--alpha-10)))
  • --menu-item-gap: item gap (default spacing(1.5))
  • --menu-item-padding: item padding (default spacing(1.5) spacing(2))
  • --menu-line-height: line height (default var(--font-text-sm-line-height))
  • --menu-radio-indicator-hole-size: radio indicator hole size (default var(--font-text-3xs-size))
  • --menu-radio-indicator-size: radio indicator size (default var(--font-text-lg-size))
  • --menu-radius: radius (default var(--radius-xl))
  • --menu-separator-background-color: separator background color (default var(--color-border))
  • --menu-separator-gutter: separator gutter (default var(--menu-gutter) calc(-1 * var(--menu-gutter)))
  • --radio-group-indicator-background-color: indicator background color (default var(--color-background-primary-solid))
  • --radio-group-indicator-border-color: indicator border color (default var(--color-border-primary-outline))
  • --radio-group-indicator-border-color-hover: indicator border color hover (default var(--alpha-25))
  • --radio-group-indicator-hole-background-color: indicator hole background color (default var(--color-text-primary-solid))