DropdownMenu
Display a dropdown menu.
#
Documentation
#
#
Usage
#
Use the DropdownMenu
, DropdownMenuTrigger
, and DropdownMenuContent
components to build out menus.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Controlled
#
Use the open
and defaultOpen
props to toggle between controlled and uncontrolled usage. And combine it with onOpenChange
to listen for changes to the state.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
Flex,
Switch,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
import { useState } from "react";
export function App() {
const [keepOpen, setKeepOpen] = useState(false);
const [open, setOpen] = useState(false);
return (
<Flex flexDirection="row">
<Switch onCheckedChange={setKeepOpen}>Keep menu open</Switch>
<DropdownMenu
modal={false}
onOpenChange={(flag) => setOpen(flag || keepOpen)}
open={open}
>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Flex>
);
}
#
Non modal usage
#
By default scrolling and interactions with outside elements is disabled when menu is open. Set modal
prop to false
in order to render a non-modal dropdown.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu modal={false}>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Trigger
#
#
Customize trigger
#
By default we use the Button
component for the menu trigger which accepts all of the existing button props.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconDots, IconLogout, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger
appearance="subtle"
aria-label="My Account"
icon={<IconDots />}
/>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Composition
#
We can also completely change the trigger by using asChild
and passing our own component.
import {
Avatar,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Avatar asChild colorScheme="brand">
<button>JD</button>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Content
#
#
Menu position
#
Use the align
and side
props on DropdownMenuContent
to change the default position of the dropdown.
import type { ComponentPropsWithRef } from "react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
export function App({
align,
side,
}: Pick<ComponentPropsWithRef<typeof DropdownMenuContent>, "align" | "side">) {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent align={align} side={side}>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Item
#
#
Appearance
#
Use the colorScheme
prop to control the appearance of items.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconPencil, IconTrash } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem addonBefore={<IconPencil />}>Edit</DropdownMenuItem>
<DropdownMenuItem addonBefore={<IconTrash />} colorScheme="danger">
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Description
#
Use the description
prop to add secondary text to items.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Actions</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem description="Create a new task">
New task
</DropdownMenuItem>
<DropdownMenuItem description="Copy this task">
Copy task
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem colorScheme="danger">Delete task</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Disabled items
#
Use the disabled
prop on menu items to disable them.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser, IconUsers } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuItem addonBefore={<IconUsers />} disabled>
Team Management
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Label
#
Use the DropdownMenuLabel
component to render a read-only label.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem addonBefore={<IconLogout />}>Logout</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Selection
#
Use the onSelect
prop to handle selection of items.
Last selected item:
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
Flex,
Text,
} from "@optiaxiom/react";
import { IconLogout, IconUser } from "@tabler/icons-react";
import { useState } from "react";
export function App() {
const [selected, setSelected] = useState("");
return (
<Flex flexDirection="row">
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem
addonBefore={<IconUser />}
onSelect={() => setSelected("view")}
>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
addonBefore={<IconLogout />}
onSelect={() => setSelected("logout")}
>
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Text>Last selected item: {selected}</Text>
</Flex>
);
}
#
Left and right addons
#
Use the addonBefore
and addonAfter
prop to add icons, text, or any other element to the start or end of the menu items.
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
Kbd,
} from "@optiaxiom/react";
import { IconLogout, IconSettings, IconUser } from "@tabler/icons-react";
export function App() {
return (
<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem
addonAfter={
<Kbd keys={["option", "shift"]} variant="subtle">
P
</Kbd>
}
addonBefore={<IconSettings />}
>
Preferences
</DropdownMenuItem>
<DropdownMenuItem addonBefore={<IconUser />}>
View Profile
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
addonAfter={
<Kbd keys={["option", "shift"]} variant="subtle">
Q
</Kbd>
}
addonBefore={<IconLogout />}
>
Logout
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
#
Props
#
#
DropdownMenu
#
Name | Type |
---|---|
defaultOpen |
|
dir |
|
modal |
|
onOpenChange |
|
open |
|
#
DropdownMenuContent
#
Supports all Box props in addition to its own.
Name | Type |
---|---|
align |
|
alignOffset |
|
arrowPadding |
|
asChild |
|
avoidCollisions |
|
collisionBoundary |
|
collisionPadding |
|
forceMount |
Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. |
hideWhenDetached |
|
loop |
Whether keyboard navigation should loop around @defaultValue false |
onCloseAutoFocus |
Event handler called when auto-focusing on close. Can be prevented. |
onEscapeKeyDown |
|
onFocusOutside |
|
onInteractOutside |
|
onPointerDownOutside |
|
side |
|
sideOffset |
|
sticky |
|
updatePositionStrategy |
|
#
DropdownMenuItem
#
Supports all Box props in addition to its own.
Name | Type |
---|---|
asChild |
|
disabled |
|
onSelect |
|
textValue |
|
#
DropdownMenuLabel
#
Supports all Box props in addition to its own.
Name | Type |
---|---|
asChild |
|
#
DropdownMenuSeparator
#
Supports all Box props in addition to its own.
Name | Type |
---|---|
asChild |
|
#
DropdownMenuTrigger
#
Supports all Box props in addition to its own.
Name | Type |
---|---|
asChild |
|
#
Changelog
#
#
0.1.0
#
- Added component