import { DropdownMenu, Button } from "@cloudflare/kumo";
import { PlusIcon } from "@phosphor-icons/react";
export function DropdownBasicDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={PlusIcon}>Add</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item>Worker</DropdownMenu.Item>
<DropdownMenu.Item>Pages</DropdownMenu.Item>
<DropdownMenu.Item>KV Namespace</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
} Installation
Barrel
import { DropdownMenu } from "@cloudflare/kumo";Granular
import { DropdownMenu } from "@cloudflare/kumo/components/dropdown"; Usage
import { DropdownMenu, Button } from "@cloudflare/kumo";
export default function Example() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>Menu</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item>Option 1</DropdownMenu.Item>
<DropdownMenu.Item>Option 2</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
} Examples
Basic Dropdown
import { DropdownMenu, Button } from "@cloudflare/kumo";
import { PlusIcon } from "@phosphor-icons/react";
export function DropdownBasicDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={PlusIcon}>Add</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item>Worker</DropdownMenu.Item>
<DropdownMenu.Item>Pages</DropdownMenu.Item>
<DropdownMenu.Item>KV Namespace</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
} Checkbox Items
Use DropdownMenu.CheckboxItem for toggleable options that can be
independently checked or unchecked.
import { useState } from "react";
import { DropdownMenu, Button } from "@cloudflare/kumo";
export function DropdownCheckboxDemo() {
const [showSidebar, setShowSidebar] = useState(true);
const [showLineNumbers, setShowLineNumbers] = useState(false);
const [wordWrap, setWordWrap] = useState(true);
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>View Options</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>Display</DropdownMenu.Label>
<DropdownMenu.CheckboxItem
checked={showSidebar}
onCheckedChange={setShowSidebar}
>
Show sidebar
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem
checked={showLineNumbers}
onCheckedChange={setShowLineNumbers}
>
Show line numbers
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem
checked={wordWrap}
onCheckedChange={setWordWrap}
>
Word wrap
</DropdownMenu.CheckboxItem>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu>
);
} Nested Menu with Radio Selection
Use DropdownMenu.Sub, DropdownMenu.SubTrigger, and
DropdownMenu.SubContent to create nested submenus. For single-selection
lists like language or timezone, use DropdownMenu.RadioGroup and
DropdownMenu.RadioItem.
import { useState } from "react";
import { DropdownMenu, Button } from "@cloudflare/kumo";
import { UserIcon, CreditCardIcon, MoonIcon, SignOutIcon } from "@phosphor-icons/react";
export function DropdownNestedDemo() {
const [language, setLanguage] = useState("en");
const [timezone, setTimezone] = useState("America/Los_Angeles");
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button icon={UserIcon}>Account</Button>} />
<DropdownMenu.Content>
<DropdownMenu.Item icon={UserIcon}>Profile</DropdownMenu.Item>
<DropdownMenu.Item icon={CreditCardIcon}>Billing</DropdownMenu.Item>
<DropdownMenu.Item icon={MoonIcon}>Dark mode</DropdownMenu.Item>
{/* Language submenu with RadioGroup */}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger>Language</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Group>
<DropdownMenu.RadioGroup
value={language}
onValueChange={setLanguage}
>
{languages.map((lang) => (
<DropdownMenu.RadioItem key={lang.code} value={lang.code}>
{lang.label}
<DropdownMenu.RadioItemIndicator />
</DropdownMenu.RadioItem>
))}
</DropdownMenu.RadioGroup>
</DropdownMenu.Group>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
{/* Timezone submenu with RadioGroup */}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger>Set Timezone</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Group>
<DropdownMenu.RadioGroup
value={timezone}
onValueChange={setTimezone}
>
{timezones.map((tz) => (
<DropdownMenu.RadioItem key={tz.value} value={tz.value}>
{tz.label}
<DropdownMenu.RadioItemIndicator />
</DropdownMenu.RadioItem>
))}
</DropdownMenu.RadioGroup>
</DropdownMenu.Group>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Separator />
<DropdownMenu.Item icon={SignOutIcon} variant="danger">
Log out
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
);
} Navigation Links
Use DropdownMenu.LinkItem for menu items that navigate to a URL.
This renders a semantic <a> element with full control over link attributes like target and rel.
import { DropdownMenu, Button } from "@cloudflare/kumo";
import { GearIcon, BookOpenIcon, ArrowSquareOutIcon } from "@phosphor-icons/react";
/**
* Demonstrates the new LinkItem component for navigation links.
* Use LinkItem instead of Item with href for cleaner, more semantic links.
*/
export function DropdownLinkItemDemo() {
return (
<DropdownMenu>
<DropdownMenu.Trigger render={<Button>Resources</Button>} />
<DropdownMenu.Content>
<DropdownMenu.LinkItem href="/settings" icon={GearIcon}>
Settings
</DropdownMenu.LinkItem>
<DropdownMenu.LinkItem href="/docs" icon={BookOpenIcon}>
Documentation
</DropdownMenu.LinkItem>
<DropdownMenu.Separator />
<DropdownMenu.LinkItem
href="https://developers.cloudflare.com"
target="_blank"
icon={ArrowSquareOutIcon}
>
Developer Docs
</DropdownMenu.LinkItem>
</DropdownMenu.Content>
</DropdownMenu>
);
} API Reference
DropdownMenu
Root component that manages the dropdown state.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "danger" | "default" | Visual style of the dropdown item. - `"default"` — Standard item appearance - `"danger"` — Destructive action with red text |
DropdownMenu.Trigger
Button that opens the dropdown when clicked.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.Item
Individual menu item for actions.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.LinkItem
A menu item that navigates to a URL. Renders a semantic <a> element. Use this instead of Item for navigation links.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.CheckboxItem
A menu item that can be toggled on or off. Use for independent boolean options.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.Sub
Root component for a nested submenu. Wrap SubTrigger and SubContent inside this.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.SubTrigger
Menu item that opens a nested submenu when hovered or clicked. Displays a caret icon automatically.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.SubContent
Container for submenu items. Positioned relative to the SubTrigger.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.Separator
A visual divider between menu items.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.RadioGroup
Groups radio items for single-selection behavior. Only one item can be selected at a time.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.RadioItem
A menu item that works like a radio button. Must be used inside a RadioGroup.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.
DropdownMenu.RadioItemIndicator
Shows the selected state for a RadioItem. Displays a checkmark by default.
| Prop | Type | Default |
|---|
No component-specific props. Accepts standard HTML attributes.