structyl

Dropdown Menu API

View component

The full prop reference for the Dropdown Menu component. Displays a menu to the user — such as a set of actions or functions — triggered by a button.

Import

tsx
import { DropdownMenu } from '@structyl/styled';

Props

Root

Root container that manages dropdown menu state, dir, and modal behavior

PropTypeDefault
children#React.ReactNode

Child elements (Trigger, Content, etc.)

—
open#boolean

Controlled open state

—
defaultOpen#boolean

Initial open state when uncontrolled

false
onOpenChange#(open: boolean) => void

Callback when open state changes

—
dir#'ltr' | 'rtl'

Text direction

—
modal#boolean

Whether to disable pointer events outside and trap focus

true

Trigger

Button that toggles the dropdown menu; extends native button with aria attributes

PropTypeDefault
asChild#boolean

Render as child element, passing through props

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLButtonElement>

Forward ref to button element

—
...buttonProps#React.ComponentPropsWithoutRef<'button'>

All standard HTML button attributes and event handlers

—

Content

Dropdown menu content portal with positioning, animation, and focus management

PropTypeDefault
container#Element | DocumentFragment | null

Portal container; defaults to document.body

—
sideOffset#number

Offset from trigger button

6
side#'top' | 'right' | 'bottom' | 'left'

Preferred side to display content

—
align#'start' | 'center' | 'end'

Alignment relative to trigger

—
alignOffset#number

Offset from alignment edge

—
avoidCollisions#boolean

Automatically flip side/align to avoid viewport collisions

—
collisionBoundary#Element | Element[] | null

Elements to consider as collision boundaries

—
collisionPadding#number

Padding from collision boundaries

—
strategy#'fixed' | 'absolute'

Positioning strategy

—
sticky#'partial' | 'always'

Whether content sticks to trigger during scroll

—
hideWhenDetached#boolean

Hide when trigger no longer visible

—
updatePositionStrategy#'always' | 'optimized'

Position update frequency

—
loop#boolean

Enable keyboard focus looping

false
forceMount#boolean

Force mount content even when closed

—
onCloseAutoFocus#(event: Event) => void

Callback when auto-focusing on close; returns focus to trigger by default

—
onEscapeKeyDown#(event: KeyboardEvent) => void

Callback when escape key is pressed

—
onPointerDownOutside#(event: PointerDownOutsideEvent) => void

Callback for pointer down outside content

—
onFocusOutside#(event: FocusOutsideEvent) => void

Callback for focus moving outside content

—
onInteractOutside#(event: PointerDownOutsideEvent | FocusOutsideEvent) => void

Callback for any interaction outside content

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to content div

—

Item

Menu item with optional inset padding; supports disabled state and select callback

PropTypeDefault
inset#boolean

Add left padding for visual inset

—
disabled#boolean

Disable item interaction

—
onSelect#(event: Event) => void

Callback when item is selected (click or enter)

—
textValue#string

Text content for typeahead search

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to item div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes and event handlers

—

CheckboxItem

Menu item with checkbox indicator; toggles checked state on select

PropTypeDefault
checked#boolean | 'indeterminate'

Checkbox state

—
onCheckedChange#(checked: boolean) => void

Callback when checked state changes

—
disabled#boolean

Disable item interaction

—
onSelect#(event: Event) => void

Callback when item is selected

—
textValue#string

Text content for typeahead search

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to item div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes and event handlers

—

RadioGroup

Container for radio items that manages exclusive selection

PropTypeDefault
value#string

Currently selected radio item value

—
onValueChange#(value: string) => void

Callback when selected value changes

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to group div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes

—

RadioItem

Radio item within RadioGroup; selects its value when clicked

PropTypeDefault
value#string

Value to select when this item is chosen (required)

—
disabled#boolean

Disable item interaction

—
onSelect#(event: Event) => void

Callback when item is selected

—
textValue#string

Text content for typeahead search

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to item div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes and event handlers

—

Group

Semantic grouping container for menu items

PropTypeDefault
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to group div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes

—

Label

Non-interactive label for menu sections; supports optional inset padding

PropTypeDefault
inset#boolean

Add left padding for visual inset

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to label div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes

—

Separator

Visual divider between menu sections

PropTypeDefault
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to separator div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes

—

Shortcut

Display keyboard shortcut hint text (e.g. '⌘S'); styled as optional child content

PropTypeDefault
className#string

CSS class name

—
...spanProps#React.HTMLAttributes<HTMLSpanElement>

Standard HTML span attributes

—

Sub

Container for nested submenu with independent open/close state

PropTypeDefault
children#React.ReactNode

Child elements (SubTrigger, SubContent)

—
open#boolean

Controlled open state

—
defaultOpen#boolean

Initial open state when uncontrolled

—
onOpenChange#(open: boolean) => void

Callback when submenu open state changes

—

SubTrigger

Item that toggles a submenu; displays chevron icon; supports inset padding

PropTypeDefault
inset#boolean

Add left padding for visual inset

—
disabled#boolean

Disable item interaction

—
onSelect#(event: Event) => void

Callback when item is selected

—
textValue#string

Text content for typeahead search

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to trigger div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes and event handlers

—

SubContent

Submenu content portal; positioned adjacent to SubTrigger

PropTypeDefault
forceMount#boolean

Force mount content even when closed

—
loop#boolean

Enable keyboard focus looping

false
onCloseAutoFocus#(event: Event) => void

Callback when auto-focusing on close

—
onEscapeKeyDown#(event: KeyboardEvent) => void

Callback when escape key is pressed; closes root menu

—
onPointerDownOutside#(event: PointerDownOutsideEvent) => void

Callback for pointer down outside content

—
onFocusOutside#(event: FocusOutsideEvent) => void

Callback for focus moving outside content; closes submenu if target is not trigger

—
onInteractOutside#(event: PointerDownOutsideEvent | FocusOutsideEvent) => void

Callback for any interaction outside content

—
sideOffset#number

Offset from trigger

—
alignOffset#number

Offset from alignment edge

—
avoidCollisions#boolean

Automatically flip side/align to avoid viewport collisions

—
collisionBoundary#Element | Element[] | null

Elements to consider as collision boundaries

—
collisionPadding#number

Padding from collision boundaries

—
strategy#'fixed' | 'absolute'

Positioning strategy

—
sticky#'partial' | 'always'

Whether content sticks to trigger during scroll

—
hideWhenDetached#boolean

Hide when trigger no longer visible

—
updatePositionStrategy#'always' | 'optimized'

Position update frequency

—
className#string

CSS class name

—
ref#React.ForwardedRef<HTMLDivElement>

Forward ref to content div

—
...divProps#React.ComponentPropsWithoutRef<'div'>

Standard HTML div attributes and event handlers (side and align are fixed to 'right'/'start' and 'left'/'start' for RTL)

—

Portal

Portal container for rendering Content outside React tree; exported for advanced use

PropTypeDefault
children#React.ReactNode

Portal content

—
container#Element | DocumentFragment | null

Portal target container; defaults to document.body

—
forceMount#boolean

Force mount portal regardless of open state

—

Keyboard interactions

Adheres to the WAI-ARIA design pattern .

KeyDescription
Space / EnterOpens the menu and focuses the first item.
ArrowDown / ArrowUpMoves focus between items.
ArrowRight / ArrowLeftOpens / closes a submenu.
EscCloses the menu and returns focus to the trigger.

Source code

If you didn't find what you need here, read the component implementation .

structyl — Accessible React Component Library