Skip to content

Dropdown Menu

Displays a menu to the user, such as a set of actions or functions, triggered by a button.

Anatomy

<DropdownMenu>
<DropdownMenuTrigger />
<DropdownMenuContent>
<DropdownMenuLabel />
<DropdownMenuSeparator />
<DropdownMenuItem />
<DropdownMenuSub>
<DropdownMenuSubTrigger />
<DropdownMenuSubContent>
<DropdownMenuItem />
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>

Usage

To display a dropdown menu, compose <DropdownMenu>, <DropdownMenuTrigger>, <DropdownMenuContent>, and one or more of <DropdownMenuItem>.

import { Button } from "stylus-ui/Button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
} from "stylus-ui/DropdownMenu";
import { faAngleDown } from "@fortawesome/pro-regular-svg-icons";
export default () => (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" icon={faAngleDown} iconPosition="right">
Settings
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);

Checkboxes

To display a multiselect dropdown with checkboxes, use <DropdownMenuCheckboxItem> instead of <DropdownMenuItem>.

import { Button } from "stylus-ui/Button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuCheckboxItem,
} from "stylus-ui/DropdownMenu";
import { useState } from "react";
import { faAngleDown } from "@fortawesome/pro-regular-svg-icons";
export default () => {
const [isHighContrastChecked, setIsHighContrastChecked] = useState(true);
const [isReduceMotionChecked, setIsReduceMotionChecked] = useState(false);
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" icon={faAngleDown} iconPosition="right">
Accessibility
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuCheckboxItem
checked={isHighContrastChecked}
onCheckedChange={setIsHighContrastChecked}
>
Enable High Contrast
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={isReduceMotionChecked}
onCheckedChange={setIsReduceMotionChecked}
>
Reduce Motion
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
);
};

Radio group

To display a radio button group, use <DropdownMenuRadioItem> and wrap the items in <DropdownMenuRadioGroup>.

import { Button } from "stylus-ui/Button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
} from "stylus-ui/DropdownMenu";
import { useState } from "react";
import { faAngleDown } from "@fortawesome/pro-regular-svg-icons";
export default () => {
const [selectedValue, setSelectedValue] = useState("default");
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" icon={faAngleDown} iconPosition="right">
Density
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuRadioGroup
value={selectedValue}
onValueChange={setSelectedValue}
>
<DropdownMenuRadioItem value="default">Default</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="comfortable">
Comfortable
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="compact">Compact</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
);
};

To display a nested menu, compose <DropdownMenuSub>, <DropdownMenuSubTrigger>, <DropdownMenuSubContent>, and one or more of <DropdownMenuItem> within <DropdownMenuContent>.

import { Button } from "stylus-ui/Button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
} from "stylus-ui/DropdownMenu";
import { faAngleDown } from "@fortawesome/pro-regular-svg-icons";
export default () => (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" icon={faAngleDown} iconPosition="right">
Settings
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Theme</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuItem>Light</DropdownMenuItem>
<DropdownMenuItem>Dark</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>
);

API Reference

Basics

Contains all the parts of the menu.

Prop
Type
Default
children ReactNode
defaultOpen boolean
dir "ltr""rtl"
modal boolean true
onOpenChange (open: boolean) => void
open boolean

The button that, when clicked, toggles the menu.

Inherits properties from HTMLButtonElement.

Prop
Type
Default
asChild boolean false
children ReactNode

The element that pops out when the menu is open.

Prop
Type
Default
align "start""center""end" "center"
alignOffset number 0
arrowPadding number 0
asChild boolean false
avoidCollisions boolean false
children ReactNode
className string
collisionBoundary Boundary []
collisionPadding number | Padding 0
container HTMLElement document.body
forceMount boolean
hideWhenDetached boolean false
isLoading boolean
loop boolean false
onCloseAutoFocus (event: Event) => void
onEscapeKeyDown (event: KeyboardEvent) => void
onFocusOutside (event: FocusOutsideEvent) => void
onInteractOutside (event: PointerDownOutsideEvent | FocusOutsideEvent) => void
onPointerDownOutside (event: PointerDownOutsideEvent) => void
side "top""right""bottom""left" "bottom"
sideOffset number 0
sticky "partial""always" "center"
theme "light""dark" "dark"

A non-interactive label to provide a heading for a section of the DropdownMenu.

Prop
Type
Default
className string
theme "light""dark" "dark"
variant "title""label" "label"

A horizontal line to separate sections within the DropdownMenu.

Prop
Type
Default
theme "light""dark"

Items

Used to group multiple DropdownMenuItems

Prop
Type
Default
asChild boolean false
children ReactNode
theme "light""dark"

A single item within the dropdown menu.

Prop
Type
Default
asChild boolean false
avatarProps React.ComponentProps<typeof Avatar>
children React.ReactNode
childrenClassName string
className string
disabled boolean
icon IconDefinition
onSelect (event: Event) => void
shortcutText string
showAvatar boolean
showShortcut boolean
showTag boolean
subtext string
textValue string
theme "light""dark"

Checkboxes

A single checkbox item within the dropdown menu.

Prop
Type
Default
asChild boolean false
avatarProps React.ComponentProps<typeof Avatar>
checked boolean
children React.ReactNode
childrenClassName string
className string
disabled boolean
icon IconDefinition
onCheckedChange (checked: boolean) => void
onSelect (event: Event) => void
showAvatar boolean
showTag boolean
subtext string
tagComponent ReactNode
textValue string
theme "light""dark"

Radios

Used to group multiple DropdownMenuRadioItems

Prop
Type
Default
asChild boolean false
children ReactNode
className string
onValueChange (value: string) => void
theme "light""dark"
value string

A single radio item within the dropdown menu.

Prop
Type
Default
asChild boolean false
avatarProps React.ComponentProps<typeof Avatar>
children React.ReactNode
childrenClassName string
className string
disabled boolean
icon IconDefinition
onSelect (event: Event) => void
showAvatar boolean
subtext string
textValue string
theme "light""dark"
value string

Contains all the parts of a sub menu.

Prop
Type
Default
children ReactNode
defaultOpen boolean
onOpenChange (open: boolean) => void
open boolean
theme "light""dark"

The button that, when clicked, toggles the dropdown sub menu.

Inherits properties from HTMLDivElement.

Prop
Type
Default
asChild boolean false
disabled boolean
icon IconDefinition
textValue string
theme "light""dark"

The element that pops out when sub menu is open.

Prop
Type
Default
alignOffset number 0
arrowPadding number 0
asChild boolean false
avoidCollisions boolean false
children ReactNode
className string
collisionBoundary Boundary []
collisionPadding number | Padding 0
forceMount boolean
hideWhenDetached boolean false
loop boolean false
onEscapeKeyDown (event: KeyboardEvent) => void
onFocusOutside (event: FocusOutsideEvent) => void
onInteractOutside (event: PointerDownOutsideEvent | FocusOutsideEvent) => void
onPointerDownOutside (event: PointerDownOutsideEvent) => void
sideOffset number 0
sticky "partial""always" "center"
theme "light""dark" "dark"

Other

When used, portals the content part into the body.

Prop
Type
Default
children ReactNode
container HTMLElement document.body
forceMount boolean
theme "light""dark" "dark"