Skip to main content

Dropdown Menu

Displays a menu to the user with a list of actions or functions triggered by a button.

1'use client';
2
3import {
4 KeyboardIcon,
5 Logout02Icon,
6 Notification03Icon,
7 Settings01Icon,
8 Shield02Icon,
9 UserIcon,
10} from '@hugeicons/core-free-icons';
11import { HugeiconsIcon } from '@hugeicons/react';
12import { Button } from '@/components/ui/button';
13import { DropdownMenu } from '@/components/ui/dropdown-menu';
14
15export function Default() {
16 return (
17 <DropdownMenu>
18 <DropdownMenu.Trigger asChild>
19 <Button variant="outline">Account</Button>
20 </DropdownMenu.Trigger>
21 <DropdownMenu.Content className="w-56" align="start">
22 <DropdownMenu.Label>Account</DropdownMenu.Label>
23 <DropdownMenu.Item>
24 <HugeiconsIcon icon={UserIcon} className="mr-2 size-4" />
25 Profile
26 </DropdownMenu.Item>
27 <DropdownMenu.Item>
28 <HugeiconsIcon icon={Notification03Icon} className="mr-2 size-4" />
29 Notifications
30 </DropdownMenu.Item>
31 <DropdownMenu.Item>
32 <HugeiconsIcon icon={Settings01Icon} className="mr-2 size-4" />
33 Settings
34 </DropdownMenu.Item>
35 <DropdownMenu.Separator />
36 <DropdownMenu.Label>Security</DropdownMenu.Label>
37 <DropdownMenu.Item>
38 <HugeiconsIcon icon={Shield02Icon} className="mr-2 size-4" />
39 Privacy & Security
40 </DropdownMenu.Item>
41 <DropdownMenu.Item>
42 <HugeiconsIcon icon={KeyboardIcon} className="mr-2 size-4" />
43 Keyboard shortcuts
44 </DropdownMenu.Item>
45 <DropdownMenu.Separator />
46 <DropdownMenu.Item className="text-destructive focus:text-destructive">
47 <HugeiconsIcon icon={Logout02Icon} className="mr-2 size-4" />
48 Sign out
49 </DropdownMenu.Item>
50 </DropdownMenu.Content>
51 </DropdownMenu>
52 );
53}

Installation

pnpm dlx mateui add dropdown-menu

Anatomy

1import { DropdownMenu } from '@/components/ui/dropdown-menu';
1<DropdownMenu>
2 <DropdownMenu.Trigger asChild>
3 <Button variant="outline">Open Menu</Button>
4 </DropdownMenu.Trigger>
5 <DropdownMenu.Content>
6 <DropdownMenu.Label>My Account</DropdownMenu.Label>
7 <DropdownMenu.Item>Profile</DropdownMenu.Item>
8 <DropdownMenu.Item>Settings</DropdownMenu.Item>
9 <DropdownMenu.Separator />
10 <DropdownMenu.Item variant="destructive">Logout</DropdownMenu.Item>
11 </DropdownMenu.Content>
12</DropdownMenu>

Variants

Checkboxes

1'use client';
2
3import { Tick02Icon } from '@hugeicons/core-free-icons';
4import { HugeiconsIcon } from '@hugeicons/react';
5import * as React from 'react';
6import { Button } from '@/components/ui/button';
7import { DropdownMenu } from '@/components/ui/dropdown-menu';
8
9export function Checkboxes() {
10 const [showStatusBar, setShowStatusBar] = React.useState(true);
11 const [showActivityBar, setShowActivityBar] = React.useState(false);
12 const [showPanel, setShowPanel] = React.useState(false);
13
14 return (
15 <DropdownMenu>
16 <DropdownMenu.Trigger asChild>
17 <Button variant="outline">View Options</Button>
18 </DropdownMenu.Trigger>
19 <DropdownMenu.Content className="w-56" align="start">
20 <DropdownMenu.Label>Appearance</DropdownMenu.Label>
21 <DropdownMenu.Separator />
22 <DropdownMenu.Item onClick={() => setShowStatusBar(!showStatusBar)}>
23 <span className="flex w-6 items-center justify-center">
24 {showStatusBar && <HugeiconsIcon icon={Tick02Icon} size={16} />}
25 </span>
26 Status Bar
27 </DropdownMenu.Item>
28 <DropdownMenu.Item onClick={() => setShowActivityBar(!showActivityBar)}>
29 <span className="flex w-6 items-center justify-center">
30 {showActivityBar && <HugeiconsIcon icon={Tick02Icon} size={16} />}
31 </span>
32 Activity Bar
33 </DropdownMenu.Item>
34 <DropdownMenu.Item onClick={() => setShowPanel(!showPanel)}>
35 <span className="flex w-6 items-center justify-center">
36 {showPanel && <HugeiconsIcon icon={Tick02Icon} size={16} />}
37 </span>
38 Panel
39 </DropdownMenu.Item>
40 </DropdownMenu.Content>
41 </DropdownMenu>
42 );
43}

Radio Group

1'use client';
2
3import * as React from 'react';
4import { Button } from '@/components/ui/button';
5import { DropdownMenu } from '@/components/ui/dropdown-menu';
6
7export function RadioGroup() {
8 const [position, setPosition] = React.useState('bottom');
9
10 return (
11 <DropdownMenu>
12 <DropdownMenu.Trigger asChild>
13 <Button variant="outline">Panel Position</Button>
14 </DropdownMenu.Trigger>
15 <DropdownMenu.Content className="w-56" align="start">
16 <DropdownMenu.Label>Panel Position</DropdownMenu.Label>
17 <DropdownMenu.Separator />
18 {['Top', 'Bottom', 'Right', 'Left'].map((pos) => {
19 const value = pos.toLowerCase();
20 const isSelected = position === value;
21 return (
22 <DropdownMenu.Item key={value} onClick={() => setPosition(value)}>
23 <span className="flex w-6 items-center justify-center">
24 {isSelected && <div className="bg-foreground size-2 rounded-full" />}
25 </span>
26 {pos}
27 </DropdownMenu.Item>
28 );
29 })}
30 </DropdownMenu.Content>
31 </DropdownMenu>
32 );
33}

API Reference

PropTypeDefaultDescription
defaultOpenbooleanfalseInitial open state
onOpenChange(open: boolean) => void-Callback when open state changes
classNamestring-Additional CSS classes
PropTypeDefaultDescription
asChildbooleanfalseRender as child element
classNamestring-Additional CSS classes
PropTypeDefaultDescription
align'start' | 'center' | 'end''start'Horizontal alignment
sideOffsetnumber6Distance from trigger
classNamestring-Additional CSS classes
PropTypeDefaultDescription
disabledbooleanfalseDisable the item
variant'default' | 'destructive''default'Visual style
onSelect() => void-Callback when selected
classNamestring-Additional CSS classes
PropTypeDefaultDescription
childrenReactNode-Label text
Visual separator between menu items.
No props - renders a horizontal line.