Zaidan

Command Palette

Search for a command to run...

GitHub43

Dropdown Menu

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

Installation

CLI

Manual

Copy and paste the following code into your project.

import * as DropdownMenuPrimitive from "@kobalte/core/dropdown-menu";
import type { PolymorphicProps } from "@kobalte/core/polymorphic";
import { Check, ChevronRight } from "lucide-solid";
import type { ComponentProps, ValidComponent } from "solid-js";
import { mergeProps, splitProps } from "solid-js";
import { cn } from "~/lib/utils";
type DropdownMenuProps = DropdownMenuPrimitive.DropdownMenuRootProps;
const DropdownMenu = (props: DropdownMenuProps) => {
const mergedProps = mergeProps({ gutter: 4 }, props);
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...mergedProps} />;
};
type DropdownMenuPortalProps = DropdownMenuPrimitive.DropdownMenuPortalProps;
const DropdownMenuPortal = (props: DropdownMenuPortalProps) => {
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
};
type DropdownMenuTriggerProps<T extends ValidComponent = "button"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuTriggerProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuTrigger = <T extends ValidComponent = "button">(
props: DropdownMenuTriggerProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuTriggerProps, ["class"]);
return (
<DropdownMenuPrimitive.Trigger
class={local.class}
data-slot="dropdown-menu-trigger"
{...others}
/>
);
};
type DropdownMenuContentProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuContentProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuContent = <T extends ValidComponent = "div">(
props: DropdownMenuContentProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuContentProps, ["class"]);
return (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.Content
data-slot="dropdown-menu-content"
class={cn(
"z-50 z-dropdown-menu-content z-menu-target max-h-(--kb-popper-available-height) min-w-32 origin-(--kb-menu-content-transform-origin) overflow-y-auto overflow-x-hidden outline-none data-closed:overflow-hidden",
local.class,
)}
{...others}
/>
</DropdownMenuPrimitive.Portal>
);
};
type DropdownMenuGroupProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuGroupProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuGroup = <T extends ValidComponent = "div">(props: DropdownMenuGroupProps<T>) => {
const [local, others] = splitProps(props as DropdownMenuGroupProps, ["class"]);
return (
<DropdownMenuPrimitive.Group class={local.class} data-slot="dropdown-menu-group" {...others} />
);
};
type DropdownMenuLabelProps<T extends ValidComponent = "span"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuGroupLabelProps<T>
> &
Pick<ComponentProps<T>, "class"> & {
inset?: boolean;
};
const DropdownMenuLabel = <T extends ValidComponent = "span">(props: DropdownMenuLabelProps<T>) => {
const [local, others] = splitProps(props as DropdownMenuLabelProps, ["class", "inset"]);
return (
<DropdownMenuPrimitive.GroupLabel
data-slot="dropdown-menu-label"
data-inset={local.inset}
class={cn("z-dropdown-menu-label data-inset:pl-8", local.class)}
{...others}
/>
);
};
type DropdownMenuItemProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuItemProps<T>
> &
Pick<ComponentProps<T>, "class"> & {
inset?: boolean;
variant?: "default" | "destructive";
};
const DropdownMenuItem = <T extends ValidComponent = "div">(rawProps: DropdownMenuItemProps<T>) => {
const props = mergeProps({ variant: "default" } as DropdownMenuItemProps<T>, rawProps);
const [local, others] = splitProps(props as DropdownMenuItemProps, ["class", "inset", "variant"]);
return (
<DropdownMenuPrimitive.Item
data-slot="dropdown-menu-item"
data-inset={local.inset}
data-variant={local.variant}
class={cn(
"group/dropdown-menu-item relative z-dropdown-menu-item flex cursor-default select-none items-center outline-hidden data-disabled:pointer-events-none data-inset:pl-8 data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
local.class,
)}
{...others}
/>
);
};
type DropdownMenuSubProps = DropdownMenuPrimitive.DropdownMenuSubProps;
const DropdownMenuSub = (props: DropdownMenuSubProps) => {
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
};
type DropdownMenuSubTriggerProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuSubTriggerProps<T>
> &
Pick<ComponentProps<T>, "class" | "children"> & {
inset?: boolean;
};
const DropdownMenuSubTrigger = <T extends ValidComponent = "div">(
props: DropdownMenuSubTriggerProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuSubTriggerProps, [
"class",
"inset",
"children",
]);
return (
<DropdownMenuPrimitive.SubTrigger
data-slot="dropdown-menu-sub-trigger"
data-inset={local.inset}
class={cn(
"z-dropdown-menu-sub-trigger flex cursor-default select-none items-center outline-hidden data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
local.class,
)}
{...others}
>
{local.children}
<ChevronRight class="ml-auto" />
</DropdownMenuPrimitive.SubTrigger>
);
};
type DropdownMenuSubContentProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuSubContentProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuSubContent = <T extends ValidComponent = "div">(
props: DropdownMenuSubContentProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuSubContentProps, ["class"]);
return (
<DropdownMenuPrimitive.Portal>
<DropdownMenuPrimitive.SubContent
data-slot="dropdown-menu-sub-content"
class={cn(
"z-50 z-dropdown-menu-sub-content z-menu-target max-h-(--kb-popper-available-height) min-w-32 origin-(--kb-menu-content-transform-origin) overflow-y-auto overflow-x-hidden outline-none data-closed:overflow-hidden",
local.class,
)}
{...others}
/>
</DropdownMenuPrimitive.Portal>
);
};
type DropdownMenuCheckboxItemProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuCheckboxItemProps<T>
> &
Pick<ComponentProps<T>, "class" | "children">;
const DropdownMenuCheckboxItem = <T extends ValidComponent = "div">(
props: DropdownMenuCheckboxItemProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuCheckboxItemProps, ["class", "children"]);
return (
<DropdownMenuPrimitive.CheckboxItem
data-slot="dropdown-menu-checkbox-item"
class={cn(
"relative z-dropdown-menu-checkbox-item flex cursor-default select-none items-center outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
local.class,
)}
{...others}
>
<span
class="pointer-events-none z-dropdown-menu-item-indicator"
data-slot="dropdown-menu-checkbox-item-indicator"
>
<DropdownMenuPrimitive.ItemIndicator>
<Check />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{local.children}
</DropdownMenuPrimitive.CheckboxItem>
);
};
type DropdownMenuRadioGroupProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuRadioGroupProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuRadioGroup = <T extends ValidComponent = "div">(
props: DropdownMenuRadioGroupProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuRadioGroupProps, ["class"]);
return (
<DropdownMenuPrimitive.RadioGroup
class={local.class}
data-slot="dropdown-menu-radio-group"
{...others}
/>
);
};
type DropdownMenuRadioItemProps<T extends ValidComponent = "div"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuRadioItemProps<T>
> &
Pick<ComponentProps<T>, "class" | "children">;
const DropdownMenuRadioItem = <T extends ValidComponent = "div">(
props: DropdownMenuRadioItemProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuRadioItemProps, ["class", "children"]);
return (
<DropdownMenuPrimitive.RadioItem
data-slot="dropdown-menu-radio-item"
class={cn(
"relative z-dropdown-menu-radio-item flex cursor-default select-none items-center outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
local.class,
)}
{...others}
>
<span
class="pointer-events-none z-dropdown-menu-item-indicator"
data-slot="dropdown-menu-radio-item-indicator"
>
<DropdownMenuPrimitive.ItemIndicator>
<Check />
</DropdownMenuPrimitive.ItemIndicator>
</span>
{local.children}
</DropdownMenuPrimitive.RadioItem>
);
};
type DropdownMenuSeparatorProps<T extends ValidComponent = "hr"> = PolymorphicProps<
T,
DropdownMenuPrimitive.DropdownMenuSeparatorProps<T>
> &
Pick<ComponentProps<T>, "class">;
const DropdownMenuSeparator = <T extends ValidComponent = "hr">(
props: DropdownMenuSeparatorProps<T>,
) => {
const [local, others] = splitProps(props as DropdownMenuSeparatorProps, ["class"]);
return (
<DropdownMenuPrimitive.Separator
data-slot="dropdown-menu-separator"
class={cn("z-dropdown-menu-separator", local.class)}
{...others}
/>
);
};
type DropdownMenuShortcutProps = ComponentProps<"span">;
const DropdownMenuShortcut = (props: DropdownMenuShortcutProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<span
data-slot="dropdown-menu-shortcut"
class={cn("z-dropdown-menu-shortcut", local.class)}
{...others}
/>
);
};
export {
DropdownMenu,
DropdownMenuPortal,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
};

Examples

Here are the source code of all the examples from the preview page:

Basic

import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuBasic() {
return (
<Example title="Basic">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>GitHub</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<DropdownMenuItem disabled>API</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Icons

import { CreditCard, LogOut, Settings, User } from "lucide-solid";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithIcons() {
return (
<Example title="With Icons">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<User />
Profile
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<Settings />
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<LogOut />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Shortcuts

import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithShortcuts() {
return (
<Example title="With Shortcuts">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuItem>
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Billing
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Settings
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Keyboard shortcuts
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
Log out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Submenu

import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithSubmenu() {
return (
<Example title="With Submenu">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Open
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Email</DropdownMenuItem>
<DropdownMenuItem>Message</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>More...</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuItem>
New Team
<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Checkboxes

import { Activity, Layout, PanelLeft } from "lucide-solid";
import { createSignal } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithCheckboxes() {
const [showStatusBar, setShowStatusBar] = createSignal(true);
const [showActivityBar, setShowActivityBar] = createSignal(false);
const [showPanel, setShowPanel] = createSignal(false);
return (
<Example title="With Checkboxes">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Checkboxes
</DropdownMenuTrigger>
<DropdownMenuContent class="min-w-40">
<DropdownMenuGroup>
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuCheckboxItem checked={showStatusBar()} onChange={setShowStatusBar}>
<Layout />
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={showActivityBar()}
onChange={setShowActivityBar}
disabled
>
<Activity />
Activity Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem checked={showPanel()} onChange={setShowPanel}>
<PanelLeft />
Panel
</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Radio Group

import { ArrowDown, ArrowRight, ArrowUp } from "lucide-solid";
import { createSignal } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithRadio() {
const [position, setPosition] = createSignal("bottom");
return (
<Example title="With Radio Group">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Radio Group
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
<DropdownMenuRadioGroup value={position()} onChange={setPosition}>
<DropdownMenuRadioItem value="top">
<ArrowUp />
Top
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">
<ArrowDown />
Bottom
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right" disabled>
<ArrowRight />
Right
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

Checkboxes with Icons

import { Bell, Mail, MessageSquare } from "lucide-solid";
import { createSignal } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithCheckboxesIcons() {
const [notifications, setNotifications] = createSignal({
email: true,
sms: false,
push: true,
});
return (
<Example title="Checkboxes with Icons">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Notifications
</DropdownMenuTrigger>
<DropdownMenuContent class="min-w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Notification Preferences</DropdownMenuLabel>
<DropdownMenuCheckboxItem
checked={notifications().email}
onChange={(checked) =>
setNotifications({ ...notifications(), email: checked === true })
}
>
<Mail />
Email notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={notifications().sms}
onChange={(checked) =>
setNotifications({ ...notifications(), sms: checked === true })
}
>
<MessageSquare />
SMS notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={notifications().push}
onChange={(checked) =>
setNotifications({ ...notifications(), push: checked === true })
}
>
<Bell />
Push notifications
</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

Radio with Icons

import { Building2, CreditCard, Wallet } from "lucide-solid";
import { createSignal } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithRadioIcons() {
const [paymentMethod, setPaymentMethod] = createSignal("card");
return (
<Example title="Radio with Icons">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Payment Method
</DropdownMenuTrigger>
<DropdownMenuContent class="min-w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Select Payment Method</DropdownMenuLabel>
<DropdownMenuRadioGroup value={paymentMethod()} onChange={setPaymentMethod}>
<DropdownMenuRadioItem value="card">
<CreditCard />
Credit Card
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="paypal">
<Wallet />
PayPal
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bank">
<Building2 />
Bank Transfer
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Destructive Items

import { Archive, Pencil, Share, Trash } from "lucide-solid";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithDestructive() {
return (
<Example title="With Destructive Items">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Actions
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<Pencil />
Edit
</DropdownMenuItem>
<DropdownMenuItem>
<Share />
Share
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Archive />
Archive
</DropdownMenuItem>
<DropdownMenuItem variant="destructive">
<Trash />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}

With Avatar

import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogOut } from "lucide-solid";
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuWithAvatar() {
return (
<Example title="With Avatar">
<div class="flex items-center justify-between gap-4">
<DropdownMenu placement="top-end">
<DropdownMenuTrigger
as={Button}
variant="outline"
class="h-12 justify-start px-2 md:max-w-[200px]"
>
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="Shadcn" />
<AvatarFallback class="rounded-lg">CN</AvatarFallback>
</Avatar>
<div class="grid flex-1 text-left text-sm leading-tight">
<span class="truncate font-semibold">shadcn</span>
<span class="truncate text-muted-foreground text-xs">shadcn@example.com</span>
</div>
<ChevronsUpDown class="ml-auto text-muted-foreground" />
</DropdownMenuTrigger>
<DropdownMenuContent class="w-(--anchor-width) min-w-56">
<DropdownMenuGroup>
<DropdownMenuItem>
<BadgeCheck />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<Bell />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut />
Sign Out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="ghost" size="icon" class="rounded-full">
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="shadcn" />
<AvatarFallback>LR</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
{" "}
<DropdownMenuGroup>
<DropdownMenuItem>
<BadgeCheck />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<Bell />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<LogOut />
Sign Out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</Example>
);
}

In Dialog

import { ClipboardPaste, Copy, Scissors, Trash } from "lucide-solid";
import { Button } from "~/components/ui/button";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "~/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuInDialog() {
return (
<Example title="In Dialog">
<Dialog>
<DialogTrigger as={Button} variant="outline">
Open Dialog
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dropdown Menu Example</DialogTitle>
<DialogDescription>Click the button below to see the dropdown menu.</DialogDescription>
</DialogHeader>
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Open Menu
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<Copy />
Copy
</DropdownMenuItem>
<DropdownMenuItem>
<Scissors />
Cut
</DropdownMenuItem>
<DropdownMenuItem>
<ClipboardPaste />
Paste
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>More Options</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Save Page...</DropdownMenuItem>
<DropdownMenuItem>Create Shortcut...</DropdownMenuItem>
<DropdownMenuItem>Name Window...</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Developer Tools</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<Trash />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</DialogContent>
</Dialog>
</Example>
);
}

Complex

import {
Bell,
CreditCard,
Download,
Eye,
File,
FileCode,
FileText,
Folder,
FolderOpen,
FolderSearch,
HelpCircle,
Keyboard,
Languages,
Layout,
LogOut,
Mail,
Monitor,
Moon,
MoreHorizontal,
Palette,
Save,
Settings,
Shield,
Sun,
User,
} from "lucide-solid";
import { createSignal } from "solid-js";
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
function DropdownMenuComplex() {
const [notifications, setNotifications] = createSignal({
email: true,
sms: false,
push: true,
});
const [theme, setTheme] = createSignal("light");
return (
<Example title="Complex">
<DropdownMenu>
<DropdownMenuTrigger as={Button} variant="outline" class="w-fit">
Complex Menu
</DropdownMenuTrigger>
<DropdownMenuContent class="style-lyra:w-48 style-maia:w-56 style-mira:w-48 style-nova:w-48 style-vega:w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>File</DropdownMenuLabel>
<DropdownMenuItem>
<File />
New File
<DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Folder />
New Folder
<DropdownMenuShortcut>⇧⌘N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<FolderOpen />
Open Recent
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Recent Projects</DropdownMenuLabel>
<DropdownMenuItem>
<FileCode />
Project Alpha
</DropdownMenuItem>
<DropdownMenuItem>
<FileCode />
Project Beta
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<MoreHorizontal />
More Projects
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<FileCode />
Project Gamma
</DropdownMenuItem>
<DropdownMenuItem>
<FileCode />
Project Delta
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<FolderSearch />
Browse...
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Save />
Save
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Download />
Export
<DropdownMenuShortcut>⇧⌘E</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>View</DropdownMenuLabel>
<DropdownMenuCheckboxItem
checked={notifications().email}
onChange={(checked) =>
setNotifications({ ...notifications(), email: checked === true })
}
>
<Eye />
Show Sidebar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={notifications().sms}
onChange={(checked) =>
setNotifications({ ...notifications(), sms: checked === true })
}
>
<Layout />
Show Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<Palette />
Theme
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuRadioGroup value={theme()} onChange={setTheme}>
<DropdownMenuRadioItem value="light">
<Sun />
Light
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="dark">
<Moon />
Dark
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="system">
<Monitor />
System
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>Account</DropdownMenuLabel>
<DropdownMenuItem>
<User />
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<Settings />
Settings
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Preferences</DropdownMenuLabel>
<DropdownMenuItem>
<Keyboard />
Keyboard Shortcuts
</DropdownMenuItem>
<DropdownMenuItem>
<Languages />
Language
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<Bell />
Notifications
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuGroup>
<DropdownMenuLabel>Notification Types</DropdownMenuLabel>
<DropdownMenuCheckboxItem
checked={notifications().push}
onChange={(checked) =>
setNotifications({
...notifications(),
push: checked === true,
})
}
>
<Bell />
Push Notifications
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={notifications().email}
onChange={(checked) =>
setNotifications({
...notifications(),
email: checked === true,
})
}
>
<Mail />
Email Notifications
</DropdownMenuCheckboxItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<Shield />
Privacy & Security
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<HelpCircle />
Help & Support
</DropdownMenuItem>
<DropdownMenuItem>
<FileText />
Documentation
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
<LogOut />
Sign Out
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</Example>
);
}