1import { Button } from "@/components/ui/pxl/button";2import {3 DropdownMenu,4 DropdownMenuContent,5 DropdownMenuGroup,6 DropdownMenuItem,7 DropdownMenuLabel,8 DropdownMenuPortal,9 DropdownMenuSeparator,10 DropdownMenuShortcut,11 DropdownMenuSub,12 DropdownMenuSubContent,13 DropdownMenuSubTrigger,14 DropdownMenuTrigger,15} from "@/components/ui/pxl/dropdown-menu";16
17export default function DropdownMenuDemo() {18 return (19 <DropdownMenu>20 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />21 <DropdownMenuContent className="w-40" align="start">22 <DropdownMenuGroup>23 <DropdownMenuLabel>My Account</DropdownMenuLabel>24 <DropdownMenuItem>25 Profile26 <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>27 </DropdownMenuItem>28 <DropdownMenuItem>29 Billing30 <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>31 </DropdownMenuItem>32 <DropdownMenuItem>33 Settings34 <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>35 </DropdownMenuItem>36 </DropdownMenuGroup>37 <DropdownMenuSeparator />38 <DropdownMenuGroup>39 <DropdownMenuItem>Team</DropdownMenuItem>40 <DropdownMenuSub>41 <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>42 <DropdownMenuPortal>43 <DropdownMenuSubContent>44 <DropdownMenuItem>Email</DropdownMenuItem>45 <DropdownMenuItem>Message</DropdownMenuItem>46 <DropdownMenuSeparator />47 <DropdownMenuItem>More...</DropdownMenuItem>48 </DropdownMenuSubContent>49 </DropdownMenuPortal>50 </DropdownMenuSub>51 <DropdownMenuItem>52 New Team53 <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>54 </DropdownMenuItem>55 </DropdownMenuGroup>56 <DropdownMenuSeparator />57 <DropdownMenuGroup>58 <DropdownMenuItem>GitHub</DropdownMenuItem>59 <DropdownMenuItem>Support</DropdownMenuItem>60 <DropdownMenuItem disabled>API</DropdownMenuItem>61 </DropdownMenuGroup>62 <DropdownMenuSeparator />63 <DropdownMenuGroup>64 <DropdownMenuItem>65 Log out66 <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>67 </DropdownMenuItem>68 </DropdownMenuGroup>69 </DropdownMenuContent>70 </DropdownMenu>71 );72}Installation
Section titled “Installation”pnpm dlx shadcn@latest add pxl-ui/registry/dropdown-menu
Install the following dependencies:
pnpm add @base-ui/react
Copy and paste the following code into your project.
1import { Menu as MenuPrimitive } from "@base-ui/react/menu";2import type { ComponentProps } from "react";3
4import { cn } from "@/lib/utils";5
6function DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {7 return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;8}9
10function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {11 return <MenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;12}13
14function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {15 return <MenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;16}17
18function DropdownMenuContent({19 align = "start",20 alignOffset = 0,21 side = "bottom",22 sideOffset = 4,23 className,24 ...props25}: MenuPrimitive.Popup.Props &26 Pick<27 MenuPrimitive.Positioner.Props,28 "align" | "alignOffset" | "side" | "sideOffset"29 >) {30 return (31 <MenuPrimitive.Portal>32 <MenuPrimitive.Positioner33 className="isolate z-50 outline-none"34 align={align}35 alignOffset={alignOffset}36 side={side}37 sideOffset={sideOffset}38 >39 <MenuPrimitive.Popup40 data-slot="dropdown-menu-content"41 className={cn(42 "z-50 p-1.5 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden oveflow-y-auto pixel-rounded pixel-border pixel-size-md pixel-color-[color-mix(in_oklab,var(--foreground)_10%,transparent)] bg-popover text-popover-foreground duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",43 className,44 )}45 {...props}46 />47 </MenuPrimitive.Positioner>48 </MenuPrimitive.Portal>49 );50}51
52function DropdownMenuGroup({ className, ...props }: MenuPrimitive.Group.Props) {53 return (54 <MenuPrimitive.Group55 className={className}56 data-slot="dropdown-menu-group"57 {...props}58 />59 );60}61
62function DropdownMenuLabel({63 className,64 inset,65 ...props66}: MenuPrimitive.GroupLabel.Props & {67 inset?: boolean;68}) {69 return (70 <MenuPrimitive.GroupLabel71 data-slot="dropdown-menu-label"72 data-inset={inset}73 className={cn(74 "px-2 py-1.5 text-xs font-heading text-muted-foreground data-inset:pl-7",75 className,76 )}77 {...props}78 />79 );80}81
82function DropdownMenuItem({83 className,84 inset,85 variant = "default",86 ...props87}: MenuPrimitive.Item.Props & {88 inset?: boolean;89 variant?: "default" | "destructive";90}) {91 return (92 <MenuPrimitive.Item93 data-slot="dropdown-menu-item"94 data-inset={inset}95 data-variant={variant}96 className={cn(97 "group/dropdown-menu-item relative flex cursor-default items-center gap-2 pixel-rounded px-2 py-1.5 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",98 className,99 )}100 {...props}101 />102 );103}104
105function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {106 return <MenuPrimitive.SubmenuRoot data-slot="dropdown-menu-sub" {...props} />;107}108
109function DropdownMenuSubTrigger({110 className,111 inset,112 children,113 ...props114}: MenuPrimitive.SubmenuTrigger.Props & {115 inset?: boolean;116}) {117 return (118 <MenuPrimitive.SubmenuTrigger119 data-slot="dropdown-menu-sub-trigger"120 data-inset={inset}121 className={cn(122 "flex cursor-default items-center gap-2 pixel-rounded px-2 py-1.5 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",123 className,124 )}125 {...props}126 >127 {children}128 <svg129 className="ml-auto"130 xmlns="http://www.w3.org/2000/svg"131 fill="currentColor"132 viewBox="0 0 24 24"133 >134 <path d="M16 13v-2h-2v2h2Zm-2-2V9h-2v2h2Zm0 4v-2h-2v2h2Zm-2-6V7h-2v2h2Zm0 8v-2h-2v2h2ZM10 7V5H8v2h2Zm0 12v-2H8v2h2Z" />135 </svg>136 </MenuPrimitive.SubmenuTrigger>137 );138}139
140function DropdownMenuSubContent({141 align = "start",142 alignOffset = -3,143 side = "right",144 sideOffset = 0,145 className,146 ...props147}: ComponentProps<typeof DropdownMenuContent>) {148 return (149 <DropdownMenuContent150 data-slot="dropdown-menu-sub-content"151 className={cn(152 "w-auto min-w-24 rounded-none bg-popover text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",153 className,154 )}155 align={align}156 alignOffset={alignOffset}157 side={side}158 sideOffset={sideOffset}159 {...props}160 />161 );162}163
164function DropdownMenuCheckboxItem({165 className,166 children,167 checked,168 inset,169 ...props170}: MenuPrimitive.CheckboxItem.Props & {171 inset?: boolean;172}) {173 return (174 <MenuPrimitive.CheckboxItem175 data-slot="dropdown-menu-checkbox-item"176 data-inset={inset}177 className={cn(178 "relative flex cursor-default items-center gap-2 pixel-rounded py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",179 className,180 )}181 checked={checked}182 {...props}183 >184 <span185 className="pointer-events-none absolute right-2 flex items-center justify-center"186 data-slot="dropdown-menu-checkbox-item-indicator"187 >188 <MenuPrimitive.CheckboxItemIndicator>189 <svg190 xmlns="http://www.w3.org/2000/svg"191 fill="currentColor"192 viewBox="0 0 24 24"193 >194 <path d="M10 18H8v-2h2v2Zm-2-2H6v-2h2v2Zm4-2v2h-2v-2h2Zm-6 0H4v-2h2v2Zm8 0h-2v-2h2v2Zm2-2h-2v-2h2v2Zm2-2h-2V8h2v2Zm2-2h-2V6h2v2Z" />195 </svg>196 </MenuPrimitive.CheckboxItemIndicator>197 </span>198 {children}199 </MenuPrimitive.CheckboxItem>200 );201}202
203function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {204 return (205 <MenuPrimitive.RadioGroup206 data-slot="dropdown-menu-radio-group"207 {...props}208 />209 );210}211
212function DropdownMenuRadioItem({213 className,214 children,215 inset,216 ...props217}: MenuPrimitive.RadioItem.Props & {218 inset?: boolean;219}) {220 return (221 <MenuPrimitive.RadioItem222 data-slot="dropdown-menu-radio-item"223 data-inset={inset}224 className={cn(225 "relative flex cursor-default items-center gap-2 pixel-rounded py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",226 className,227 )}228 {...props}229 >230 <span231 className="pointer-events-none absolute right-2 flex items-center justify-center"232 data-slot="dropdown-menu-radio-item-indicator"233 >234 <MenuPrimitive.RadioItemIndicator>235 <svg236 xmlns="http://www.w3.org/2000/svg"237 fill="currentColor"238 viewBox="0 0 24 24"239 >240 <path d="M10 18H8v-2h2v2Zm-2-2H6v-2h2v2Zm4-2v2h-2v-2h2Zm-6 0H4v-2h2v2Zm8 0h-2v-2h2v2Zm2-2h-2v-2h2v2Zm2-2h-2V8h2v2Zm2-2h-2V6h2v2Z" />241 </svg>242 </MenuPrimitive.RadioItemIndicator>243 </span>244 {children}245 </MenuPrimitive.RadioItem>246 );247}248
249function DropdownMenuSeparator({250 className,251 ...props252}: MenuPrimitive.Separator.Props) {253 return (254 <MenuPrimitive.Separator255 data-slot="dropdown-menu-separator"256 className={cn("-mx-1 my-1 h-px bg-border", className)}257 {...props}258 />259 );260}261
262function DropdownMenuShortcut({ className, ...props }: ComponentProps<"span">) {263 return (264 <span265 data-slot="dropdown-menu-shortcut"266 className={cn(267 "ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground",268 className,269 )}270 {...props}271 />272 );273}274
275export {276 DropdownMenu,277 DropdownMenuCheckboxItem,278 DropdownMenuContent,279 DropdownMenuGroup,280 DropdownMenuItem,281 DropdownMenuLabel,282 DropdownMenuPortal,283 DropdownMenuRadioGroup,284 DropdownMenuRadioItem,285 DropdownMenuSeparator,286 DropdownMenuShortcut,287 DropdownMenuSub,288 DropdownMenuSubContent,289 DropdownMenuSubTrigger,290 DropdownMenuTrigger,291};Update the import paths to match your project setup.
import { Button } from "@/components/ui/pxl/button"import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger,} from "@/components/ui/pxl/dropdown-menu"<DropdownMenu> <DropdownMenuTrigger render={<Button variant="outline" />}> Open </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuGroup> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuItem>Profile</DropdownMenuItem> <DropdownMenuItem>Billing</DropdownMenuItem> </DropdownMenuGroup> <DropdownMenuSeparator /> <DropdownMenuGroup> <DropdownMenuItem>Team</DropdownMenuItem> <DropdownMenuItem>Subscription</DropdownMenuItem> </DropdownMenuGroup> </DropdownMenuContent></DropdownMenu>Composition
Section titled “Composition”Use the following composition to build a DropdownMenu:
DropdownMenu├── DropdownMenuTrigger└── DropdownMenuContent ├── DropdownMenuGroup │ ├── DropdownMenuLabel │ ├── DropdownMenuItem │ └── DropdownMenuItem ├── DropdownMenuSeparator ├── DropdownMenuGroup │ ├── DropdownMenuLabel │ ├── DropdownMenuCheckboxItem │ └── DropdownMenuCheckboxItem ├── DropdownMenuSeparator ├── DropdownMenuGroup │ ├── DropdownMenuLabel │ └── DropdownMenuRadioGroup │ ├── DropdownMenuRadioItem │ └── DropdownMenuRadioItem └── DropdownMenuSub ├── DropdownMenuSubTrigger └── DropdownMenuSubContent └── DropdownMenuGroup ├── DropdownMenuLabel ├── DropdownMenuItem └── DropdownMenuItemSubmenu
Section titled “Submenu”Use DropdownMenuSub to nest secondary actions.
1import { Button } from "@/components/ui/pxl/button";2import {3 DropdownMenu,4 DropdownMenuContent,5 DropdownMenuGroup,6 DropdownMenuItem,7 DropdownMenuPortal,8 DropdownMenuSeparator,9 DropdownMenuShortcut,10 DropdownMenuSub,11 DropdownMenuSubContent,12 DropdownMenuSubTrigger,13 DropdownMenuTrigger,14} from "@/components/ui/pxl/dropdown-menu";15
16export default function DropdownMenuSubmenuExample() {17 return (18 <DropdownMenu>19 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />20 <DropdownMenuContent>21 <DropdownMenuGroup>22 <DropdownMenuItem>Team</DropdownMenuItem>23 <DropdownMenuSub>24 <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>25 <DropdownMenuPortal>26 <DropdownMenuSubContent>27 <DropdownMenuItem>Email</DropdownMenuItem>28 <DropdownMenuItem>Message</DropdownMenuItem>29 <DropdownMenuSub>30 <DropdownMenuSubTrigger>More options</DropdownMenuSubTrigger>31 <DropdownMenuPortal>32 <DropdownMenuSubContent>33 <DropdownMenuItem>Calendly</DropdownMenuItem>34 <DropdownMenuItem>Slack</DropdownMenuItem>35 <DropdownMenuSeparator />36 <DropdownMenuItem>Webhook</DropdownMenuItem>37 </DropdownMenuSubContent>38 </DropdownMenuPortal>39 </DropdownMenuSub>40 <DropdownMenuSeparator />41 <DropdownMenuItem>Advanced...</DropdownMenuItem>42 </DropdownMenuSubContent>43 </DropdownMenuPortal>44 </DropdownMenuSub>45 <DropdownMenuItem>46 New Team47 <DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>48 </DropdownMenuItem>49 </DropdownMenuGroup>50 </DropdownMenuContent>51 </DropdownMenu>52 );53}Shortcuts
Section titled “Shortcuts”Add DropdownMenuShortcut to show keyboard hints.
1import { Button } from "@/components/ui/pxl/button";2import {3 DropdownMenu,4 DropdownMenuContent,5 DropdownMenuGroup,6 DropdownMenuItem,7 DropdownMenuLabel,8 DropdownMenuSeparator,9 DropdownMenuShortcut,10 DropdownMenuTrigger,11} from "@/components/ui/pxl/dropdown-menu";12
13export default function DropdownMenuShortcutsExample() {14 return (15 <DropdownMenu>16 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />17 <DropdownMenuContent>18 <DropdownMenuGroup>19 <DropdownMenuLabel>My Account</DropdownMenuLabel>20 <DropdownMenuItem>21 Profile22 <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>23 </DropdownMenuItem>24 <DropdownMenuItem>25 Billing26 <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>27 </DropdownMenuItem>28 <DropdownMenuItem>29 Settings30 <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>31 </DropdownMenuItem>32 </DropdownMenuGroup>33 <DropdownMenuSeparator />34 <DropdownMenuItem>35 Log out36 <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>37 </DropdownMenuItem>38 </DropdownMenuContent>39 </DropdownMenu>40 );41}Combine icons with labels for quick scanning.
1import { Button } from "@/components/ui/pxl/button";2import {3 DropdownMenu,4 DropdownMenuContent,5 DropdownMenuItem,6 DropdownMenuSeparator,7 DropdownMenuTrigger,8} from "@/components/ui/pxl/dropdown-menu";9
10export default function DropdownMenuIconsExample() {11 return (12 <DropdownMenu>13 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />14 <DropdownMenuContent>15 <DropdownMenuItem>16 <svg17 xmlns="http://www.w3.org/2000/svg"18 fill="currentColor"19 viewBox="0 0 24 24"20 >21 <path d="M6 22H4v-4h2v4Zm14 0h-2v-4h2v4ZM8 18H6v-2h2v2Zm10 0h-2v-2h2v2Zm-2-2H8v-2h8v2Zm-1-4H9v-2h6v2Zm-6-2H7V4h2v6Zm8 0h-2V4h2v6Zm-2-6H9V2h6v2Z" />22 </svg>23 Profile24 </DropdownMenuItem>25 <DropdownMenuItem>26 <svg27 xmlns="http://www.w3.org/2000/svg"28 fill="currentColor"29 viewBox="0 0 24 24"30 >31 <path d="M20 20H4v-2h16v2ZM4 8h16V6h2v12h-2v-6H4v6H2V6h2v2Zm8 8H6v-2h6v2Zm8-10H4V4h16v2Z" />32 </svg>33 Billing34 </DropdownMenuItem>35 <DropdownMenuItem>36 <svg37 xmlns="http://www.w3.org/2000/svg"38 fill="currentColor"39 viewBox="0 0 24 24"40 >41 <path d="M4 20h3v-2h4v4h2v-4h4v2h-2v4H9v-4H7v2H2v-5h2v3Zm18 2h-5v-2h3v-3h2v5ZM6 11H2v2h4v4H4v-2H0V9h4V7h2v4Zm14-2h4v6h-4v2h-2v-4h4v-2h-4V7h2v2Zm-6 7h-4v-2h4v2Zm-4-2H8v-4h2v4Zm6 0h-2v-4h2v4Zm-2-4h-4V8h4v2ZM7 4H4v3H2V2h5v2Zm8 0h2V2h5v5h-2V4h-3v2h-4V2h-2v4H7V4h2V0h6v4Z" />42 </svg>43 Settings44 </DropdownMenuItem>45 <DropdownMenuSeparator />46 <DropdownMenuItem variant="destructive">47 <svg48 xmlns="http://www.w3.org/2000/svg"49 fill="currentColor"50 viewBox="0 0 24 24"51 >52 <path d="M18 22H6v-2h12v2ZM6 20H4V4h2v16Zm14 0h-2v-3h2v3ZM16 9h2v2h2v2h-2v2h-2v2h-2v-4H8v-2h6V7h2v2Zm4-2h-2V4h2v3Zm-2-3H6V2h12v2Z" />53 </svg>54 Log out55 </DropdownMenuItem>56 </DropdownMenuContent>57 </DropdownMenu>58 );59}Checkboxes
Section titled “Checkboxes”Use DropdownMenuCheckboxItem for toggles.
1import { useState } from "react";2
3import { Button } from "@/components/ui/pxl/button";4import {5 DropdownMenu,6 DropdownMenuCheckboxItem,7 DropdownMenuContent,8 DropdownMenuGroup,9 DropdownMenuLabel,10 DropdownMenuTrigger,11} from "@/components/ui/pxl/dropdown-menu";12
13export default function DropdownMenuCheckboxesExample() {14 const [showStatusBar, setShowStatusBar] = useState(true);15 const [showActivityBar, setShowActivityBar] = useState(false);16 const [showPanel, setShowPanel] = useState(false);17
18 return (19 <DropdownMenu>20 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />21 <DropdownMenuContent className="w-40">22 <DropdownMenuGroup>23 <DropdownMenuLabel>Appearance</DropdownMenuLabel>24 <DropdownMenuCheckboxItem25 checked={showStatusBar ?? false}26 onCheckedChange={setShowStatusBar}27 >28 Status Bar29 </DropdownMenuCheckboxItem>30 <DropdownMenuCheckboxItem31 checked={showActivityBar}32 onCheckedChange={setShowActivityBar}33 disabled34 >35 Activity Bar36 </DropdownMenuCheckboxItem>37 <DropdownMenuCheckboxItem38 checked={showPanel}39 onCheckedChange={setShowPanel}40 >41 Panel42 </DropdownMenuCheckboxItem>43 </DropdownMenuGroup>44 </DropdownMenuContent>45 </DropdownMenu>46 );47}Radio Group
Section titled “Radio Group”Use DropdownMenuRadioGroup for exclusive choices.
1import { useState } from "react";2
3import { Button } from "@/components/ui/pxl/button";4import {5 DropdownMenu,6 DropdownMenuContent,7 DropdownMenuGroup,8 DropdownMenuLabel,9 DropdownMenuRadioGroup,10 DropdownMenuRadioItem,11 DropdownMenuTrigger,12} from "@/components/ui/pxl/dropdown-menu";13
14export default function DropdownMenuRadioGroupExample() {15 const [position, setPosition] = useState("bottom");16
17 return (18 <DropdownMenu>19 <DropdownMenuTrigger render={<Button variant="outline">Open</Button>} />20 <DropdownMenuContent className="w-32">21 <DropdownMenuGroup>22 <DropdownMenuLabel>Panel Position</DropdownMenuLabel>23 <DropdownMenuRadioGroup value={position} onValueChange={setPosition}>24 <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>25 <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>26 <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>27 </DropdownMenuRadioGroup>28 </DropdownMenuGroup>29 </DropdownMenuContent>30 </DropdownMenu>31 );32}Complex
Section titled “Complex”A richer example combining groups, icons, and submenus.
1import { useState } from "react";2
3import { Button } from "@/components/ui/pxl/button";4import {5 DropdownMenu,6 DropdownMenuCheckboxItem,7 DropdownMenuContent,8 DropdownMenuGroup,9 DropdownMenuItem,10 DropdownMenuLabel,11 DropdownMenuPortal,12 DropdownMenuRadioGroup,13 DropdownMenuRadioItem,14 DropdownMenuSeparator,15 DropdownMenuShortcut,16 DropdownMenuSub,17 DropdownMenuSubContent,18 DropdownMenuSubTrigger,19 DropdownMenuTrigger,20} from "@/components/ui/pxl/dropdown-menu";21
22export default function DropdownMenuComplexExample() {23 const [notifications, setNotifications] = useState({24 email: true,25 sms: false,26 push: true,27 });28 const [theme, setTheme] = useState("light");29
30 return (31 <DropdownMenu>32 <DropdownMenuTrigger33 render={<Button variant="outline">Complex Menu</Button>}34 />35 <DropdownMenuContent className="w-44">36 <DropdownMenuGroup>37 <DropdownMenuLabel>File</DropdownMenuLabel>38 <DropdownMenuItem>39 <svg40 xmlns="http://www.w3.org/2000/svg"41 fill="currentColor"42 viewBox="0 0 24 24"43 >44 <path d="M18 22H6v-2h12v2ZM6 20H4V4h2v16ZM16 4h-2v4h4V6h2v14h-2V10h-6V4H6V2h10v2Zm2 2h-2V4h2v2Z" />45 </svg>46 New File47 <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>48 </DropdownMenuItem>49 <DropdownMenuItem>50 <svg51 xmlns="http://www.w3.org/2000/svg"52 fill="currentColor"53 viewBox="0 0 24 24"54 >55 <path d="M20 20H4v-2h16v2ZM4 18H2V6h2v12Zm18 0h-2V8h2v10ZM20 8H10V6H4V4h8v2h8v2Z" />56 </svg>57 New Folder58 <DropdownMenuShortcut>⇧⌘N</DropdownMenuShortcut>59 </DropdownMenuItem>60 <DropdownMenuSub>61 <DropdownMenuSubTrigger>62 <svg63 xmlns="http://www.w3.org/2000/svg"64 fill="currentColor"65 viewBox="0 0 24 24"66 >67 <path d="M9 22H7v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2Zm3-4H4v-2h16v2ZM4 16H2V4h2v12Zm18 0h-2V6h2v10ZM12 4h8v2H10V4H4V2h8v2Z"></path>68 </svg>69 Open Recent70 </DropdownMenuSubTrigger>71 <DropdownMenuPortal>72 <DropdownMenuSubContent>73 <DropdownMenuGroup>74 <DropdownMenuLabel>Recent Projects</DropdownMenuLabel>75 <DropdownMenuItem>76 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5h2v2H8V5ZM6 7h2v2H6V7ZM4 9h2v2H4V9Zm-2 2h2v2H2v-2Zm2 2h2v2H4v-2Zm2 2h2v2H6v-2Zm2 2h2v2H8v-2Zm8-12h-2v2h2V5Zm2 2h-2v2h2V7Zm2 2h-2v2h2V9Zm2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Z"/></svg>77 Project Alpha78 </DropdownMenuItem>79 <DropdownMenuItem>80 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5h2v2H8V5ZM6 7h2v2H6V7ZM4 9h2v2H4V9Zm-2 2h2v2H2v-2Zm2 2h2v2H4v-2Zm2 2h2v2H6v-2Zm2 2h2v2H8v-2Zm8-12h-2v2h2V5Zm2 2h-2v2h2V7Zm2 2h-2v2h2V9Zm2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Z"/></svg>81 Project Beta82 </DropdownMenuItem>83 <DropdownMenuSub>84 <DropdownMenuSubTrigger>85 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M5 15H3v-2h2v2Zm8 0h-2v-2h2v2Zm8 0h-2v-2h2v2ZM3 13H1v-2h2v2Zm4 0H5v-2h2v2Zm4 0H9v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2ZM5 11H3V9h2v2Zm8 0h-2V9h2v2Zm8 0h-2V9h2v2Z"/></svg>86 More Projects87 </DropdownMenuSubTrigger>88 <DropdownMenuPortal>89 <DropdownMenuSubContent>90 <DropdownMenuItem>91 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5h2v2H8V5ZM6 7h2v2H6V7ZM4 9h2v2H4V9Zm-2 2h2v2H2v-2Zm2 2h2v2H4v-2Zm2 2h2v2H6v-2Zm2 2h2v2H8v-2Zm8-12h-2v2h2V5Zm2 2h-2v2h2V7Zm2 2h-2v2h2V9Zm2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Z"/></svg>92 Project Gamma93 </DropdownMenuItem>94 <DropdownMenuItem>95 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5h2v2H8V5ZM6 7h2v2H6V7ZM4 9h2v2H4V9Zm-2 2h2v2H2v-2Zm2 2h2v2H4v-2Zm2 2h2v2H6v-2Zm2 2h2v2H8v-2Zm8-12h-2v2h2V5Zm2 2h-2v2h2V7Zm2 2h-2v2h2V9Zm2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Zm-2 2h-2v2h2v-2Z"/></svg>96 Project Delta97 </DropdownMenuItem>98 </DropdownMenuSubContent>99 </DropdownMenuPortal>100 </DropdownMenuSub>101 </DropdownMenuGroup>102 <DropdownMenuSeparator />103 <DropdownMenuGroup>104 <DropdownMenuItem>105 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M22 22h-2v-2h2v2Zm-2-2h-2v-2h2v2Zm-6-2H6v-2h8v2Zm4 0h-2v-2h2v2ZM6 16H4v-2h2v2Zm10 0h-2v-2h2v2ZM4 14H2V6h2v8Zm14 0h-2V6h2v8ZM6 6H4V4h2v2Zm10 0h-2V4h2v2Zm-2-2H6V2h8v2Z"/></svg>106 Browse...107 </DropdownMenuItem>108 </DropdownMenuGroup>109 </DropdownMenuSubContent>110 </DropdownMenuPortal>111 </DropdownMenuSub>112 <DropdownMenuSeparator />113 <DropdownMenuItem>114 <svg115 xmlns="http://www.w3.org/2000/svg"116 fill="currentColor"117 viewBox="0 0 24 24"118 >119 <path d="M20 22H4v-2h2v-6h2v6h8v-6h2v6h2v2ZM4 20H2V4h2v16Zm18 0h-2V6h2v14Zm-6-6H8v-2h8v2Zm-4-4H6V6h6v4Zm8-4h-2V4h2v2Zm-2-2H4V2h14v2Z" />120 </svg>121 Save122 <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>123 </DropdownMenuItem>124 <DropdownMenuItem>125 <svg126 xmlns="http://www.w3.org/2000/svg"127 fill="currentColor"128 viewBox="0 0 24 24"129 >130 <path d="M19 21H5v-2h14v2ZM5 19H3v-4h2v4Zm16 0h-2v-4h2v4Zm-8-8h4v2h-2v2h-2v2h-2v-2H9v-2H7v-2h4V3h2v8Z" />131 </svg>132 Export133 <DropdownMenuShortcut>⇧⌘E</DropdownMenuShortcut>134 </DropdownMenuItem>135 </DropdownMenuGroup>136 <DropdownMenuSeparator />137 <DropdownMenuGroup>138 <DropdownMenuLabel>View</DropdownMenuLabel>139 <DropdownMenuCheckboxItem140 checked={notifications.email}141 onCheckedChange={(checked) =>142 setNotifications({ ...notifications, email: checked === true })143 }144 >145 <svg146 xmlns="http://www.w3.org/2000/svg"147 fill="currentColor"148 viewBox="0 0 24 24"149 >150 <path d="M16 20H8v-2h8v2Zm-8-2H4v-2h4v2Zm12 0h-4v-2h4v2ZM4 16H2v-2h2v2Zm10 0h-4v-2h4v2Zm8 0h-2v-2h2v2ZM2 14H0v-4h2v4Zm8 0H8v-4h2v4Zm6 0h-2v-4h2v4Zm8 0h-2v-4h2v4ZM4 10H2V8h2v2Zm10 0h-4V8h4v2Zm8 0h-2V8h2v2ZM8 8H4V6h4v2Zm12 0h-4V6h4v2Zm-4-2H8V4h8v2Z"></path>151 </svg>152 Show Sidebar153 </DropdownMenuCheckboxItem>154 <DropdownMenuCheckboxItem155 checked={notifications.sms}156 onCheckedChange={(checked) =>157 setNotifications({ ...notifications, sms: checked === true })158 }159 >160 <svg161 xmlns="http://www.w3.org/2000/svg"162 fill="currentColor"163 viewBox="0 0 24 24"164 >165 <path d="M20 20H4v-2h4v-8H4v8H2V6h2v2h16V6h2v12h-2v-8H10v8h10v2Zm0-14H4V4h16v2Z" />166 </svg>167 Show Status Bar168 </DropdownMenuCheckboxItem>169 <DropdownMenuSub>170 <DropdownMenuSubTrigger>171 <svg172 xmlns="http://www.w3.org/2000/svg"173 fill="currentColor"174 viewBox="0 0 24 24"175 >176 <path d="M14 20h6v2H4v-2h8v-4H4v-2h2v-2h2v2h4v-4h-2V8h2V4h2v16ZM4 20H2v-4h2v4Zm18 0h-2V4h2v16Zm-4-2h-2v-2h2v2ZM6 12H4V8h2v4Zm4-4H6V6h4v2Zm10-4h-6V2h6v2Z" />177 </svg>178 Theme179 </DropdownMenuSubTrigger>180 <DropdownMenuPortal>181 <DropdownMenuSubContent>182 <DropdownMenuGroup>183 <DropdownMenuLabel>Appearance</DropdownMenuLabel>184 <DropdownMenuRadioGroup185 value={theme}186 onValueChange={setTheme}187 >188 <DropdownMenuRadioItem value="light">189 <svg190 xmlns="http://www.w3.org/2000/svg"191 fill="currentColor"192 viewBox="0 0 24 24"193 >194 <path d="M13 22h-2v-3h2v3Zm-6-3H5v-2h2v2Zm12 0h-2v-2h2v2Zm-4-2H9v-2h6v2Zm-6-2H7V9h2v6Zm8 0h-2V9h2v6ZM5 13H2v-2h3v2Zm17 0h-3v-2h3v2Zm-7-4H9V7h6v2ZM7 7H5V5h2v2Zm12 0h-2V5h2v2Zm-6-2h-2V2h2v3Z" />195 </svg>196 Light197 </DropdownMenuRadioItem>198 <DropdownMenuRadioItem value="dark">199 <svg200 xmlns="http://www.w3.org/2000/svg"201 fill="currentColor"202 viewBox="0 0 24 24"203 >204 <path d="M18 22H8v-2h10v2ZM8 20H6v-2h2v2Zm12 0h-2v-2h2v2ZM6 18H4v-2h2v2Zm16 0h-2v-4h-2v-2h2v-2h2v8ZM4 16H2V6h2v10Zm14 0h-6v-2h6v2Zm-6-2h-2v-2h2v2Zm-2-2H8V6h2v6ZM6 6H4V4h2v2Zm8-2h-2v2h-2V4H6V2h8v2Z" />205 </svg>206 Dark207 </DropdownMenuRadioItem>208 <DropdownMenuRadioItem value="system">209 <svg210 xmlns="http://www.w3.org/2000/svg"211 fill="currentColor"212 viewBox="0 0 24 24"213 >214 <path d="M16 22H8v-2h3v-2H4v-2h16v2h-7v2h3v2ZM4 16H2V4h2v12Zm18 0h-2V4h2v12ZM20 4H4V2h16v2Z" />215 </svg>216 System217 </DropdownMenuRadioItem>218 </DropdownMenuRadioGroup>219 </DropdownMenuGroup>220 </DropdownMenuSubContent>221 </DropdownMenuPortal>222 </DropdownMenuSub>223 </DropdownMenuGroup>224 <DropdownMenuSeparator />225 <DropdownMenuGroup>226 <DropdownMenuLabel>Account</DropdownMenuLabel>227 <DropdownMenuItem>228 <svg229 xmlns="http://www.w3.org/2000/svg"230 fill="currentColor"231 viewBox="0 0 24 24"232 >233 <path d="M6 22H4v-4h2v4Zm14 0h-2v-4h2v4ZM8 18H6v-2h2v2Zm10 0h-2v-2h2v2Zm-2-2H8v-2h8v2Zm-1-4H9v-2h6v2Zm-6-2H7V4h2v6Zm8 0h-2V4h2v6Zm-2-6H9V2h6v2Z" />234 </svg>235 Profile236 <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>237 </DropdownMenuItem>238 <DropdownMenuItem>239 <svg240 xmlns="http://www.w3.org/2000/svg"241 fill="currentColor"242 viewBox="0 0 24 24"243 >244 <path d="M20 20H4v-2h16v2ZM4 8h16V6h2v12h-2v-6H4v6H2V6h2v2Zm8 8H6v-2h6v2Zm8-10H4V4h16v2Z" />245 </svg>246 Billing247 </DropdownMenuItem>248 <DropdownMenuSub>249 <DropdownMenuSubTrigger>250 <svg251 xmlns="http://www.w3.org/2000/svg"252 fill="currentColor"253 viewBox="0 0 24 24"254 >255 <path d="M4 20h3v-2h4v4h2v-4h4v2h-2v4H9v-4H7v2H2v-5h2v3Zm18 2h-5v-2h3v-3h2v5ZM6 11H2v2h4v4H4v-2H0V9h4V7h2v4Zm14-2h4v6h-4v2h-2v-4h4v-2h-4V7h2v2Zm-6 7h-4v-2h4v2Zm-4-2H8v-4h2v4Zm6 0h-2v-4h2v4Zm-2-4h-4V8h4v2ZM7 4H4v3H2V2h5v2Zm8 0h2V2h5v5h-2V4h-3v2h-4V2h-2v4H7V4h2V0h6v4Z" />256 </svg>257 Settings258 </DropdownMenuSubTrigger>259 <DropdownMenuPortal>260 <DropdownMenuSubContent>261 <DropdownMenuGroup>262 <DropdownMenuLabel>Preferences</DropdownMenuLabel>263 <DropdownMenuItem>264 <svg265 xmlns="http://www.w3.org/2000/svg"266 fill="currentColor"267 viewBox="0 0 24 24"268 >269 <path d="M21 21H3v-2h18v2ZM3 19H1V5h2v14Zm20 0h-2V5h2v14Zm-5-2H6v-2h12v2Zm-9-4H7v-2h2v2Zm4 0h-2v-2h2v2Zm4 0h-2v-2h2v2ZM7 9H5V7h2v2Zm4 0H9V7h2v2Zm4 0h-2V7h2v2Zm4 0h-2V7h2v2Zm2-4H3V3h18v2Z" />270 </svg>271 Keyboard Shortcuts272 </DropdownMenuItem>273 <DropdownMenuItem>274 <svg275 xmlns="http://www.w3.org/2000/svg"276 fill="currentColor"277 viewBox="0 0 24 24"278 >279 <path d="M15 17h5v-2h2v7h-2v-3h-5v3h-2v-7h2v2Zm-8-2H5v-2h2v2Zm4 0H9v-2h2v2Zm9 0h-5v-2h5v2ZM9 13H7v-2h2v2Zm-2-2H5V9h2v2Zm4 0H9V9h2v2Zm5-4h-3v2h-2V7H2V5h14v2Zm-5-3H7V2h4v2Z" />280 </svg>281 Language282 </DropdownMenuItem>283 <DropdownMenuSub>284 <DropdownMenuSubTrigger>285 <svg286 xmlns="http://www.w3.org/2000/svg"287 fill="currentColor"288 viewBox="0 0 24 24"289 >290 <path d="M9 2h6v2H9zM7 4h2v2H7zm8 0h2v2h-2zM5 6h2v7H5zm12 0h2v7h-2zM3 13h2v4H3zm16 0h2v4h-2z" />291 <path d="M3 15h18v2H3zm5 3h2v2H8zm6 0h2v2h-2zm-4 2h4v2h-4z" />292 </svg>293 Notifications294 </DropdownMenuSubTrigger>295 <DropdownMenuPortal>296 <DropdownMenuSubContent>297 <DropdownMenuGroup>298 <DropdownMenuLabel>299 Notification Types300 </DropdownMenuLabel>301 <DropdownMenuCheckboxItem302 checked={notifications.push}303 onCheckedChange={(checked) =>304 setNotifications({305 ...notifications,306 push: checked === true,307 })308 }309 >310 <svg311 xmlns="http://www.w3.org/2000/svg"312 fill="currentColor"313 viewBox="0 0 24 24"314 >315 <path d="M9 2h6v2H9zM7 4h2v2H7zm8 0h2v2h-2zM5 6h2v7H5zm12 0h2v7h-2zM3 13h2v4H3zm16 0h2v4h-2z" />316 <path d="M3 15h18v2H3zm5 3h2v2H8zm6 0h2v2h-2zm-4 2h4v2h-4z" />317 </svg>318 Push Notifications319 </DropdownMenuCheckboxItem>320 <DropdownMenuCheckboxItem321 checked={notifications.email}322 onCheckedChange={(checked) =>323 setNotifications({324 ...notifications,325 email: checked === true,326 })327 }328 >329 <svg330 xmlns="http://www.w3.org/2000/svg"331 fill="currentColor"332 viewBox="0 0 24 24"333 >334 <path d="M20 20H4v-2h16v2ZM4 18H2V6h2v12Zm18 0h-2V6h2v12Zm-8-4h-4v-2h4v2Zm-4-2H8v-2h2v2Zm6 0h-2v-2h2v2Zm-8-2H6V8h2v2Zm10 0h-2V8h2v2Zm2-4H4V4h16v2Z" />335 </svg>336 Email Notifications337 </DropdownMenuCheckboxItem>338 </DropdownMenuGroup>339 </DropdownMenuSubContent>340 </DropdownMenuPortal>341 </DropdownMenuSub>342 </DropdownMenuGroup>343 <DropdownMenuSeparator />344 <DropdownMenuGroup>345 <DropdownMenuItem>346 <svg347 xmlns="http://www.w3.org/2000/svg"348 fill="currentColor"349 viewBox="0 0 24 24"350 >351 <path d="M14 22h-4v-2h4v2Zm-4-4v2H8v-2h2Zm6 2h-2v-2h2v2Zm-8-2H6v-2h2v2Zm10 0h-2v-2h2v2ZM6 16H4v-2h2v2Zm14 0h-2v-2h2v2ZM4 14H2V4h2v10Zm18 0h-2V4h2v10ZM20 4H4V2h16v2Z" />352 </svg>353 Privacy & Security354 </DropdownMenuItem>355 </DropdownMenuGroup>356 </DropdownMenuSubContent>357 </DropdownMenuPortal>358 </DropdownMenuSub>359 </DropdownMenuGroup>360 <DropdownMenuSeparator />361 <DropdownMenuGroup>362 <DropdownMenuItem>363 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M18 22H6V20H18V22ZM6 20H4V18H6V20ZM20 20H18V18H20V20ZM4 18H2V6H4V18ZM13 18H11V16H13V18ZM22 18H20V6H22V18ZM15 13H13V15H11V11H15V13ZM17 11H15V8H17V11ZM9 10H7V8H9V10ZM15 8H9V6H15V8ZM6 6H4V4H6V6ZM20 6H18V4H20V6ZM18 4H6V2H18V4Z"/></svg>364 Help & Support365 </DropdownMenuItem>366 <DropdownMenuItem>367 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M18 22H6v-2h12v2ZM6 20H4V4h2v16ZM16 4h-2v4h4V6h2v14h-2V10h-6V4H6V2h10v2Zm0 14H8v-2h8v2Zm0-4H8v-2h8v2Zm-6-4H8V8h2v2Zm8-4h-2V4h2v2Z"/></svg>368 Documentation369 </DropdownMenuItem>370 </DropdownMenuGroup>371 <DropdownMenuSeparator />372 <DropdownMenuGroup>373 <DropdownMenuItem variant="destructive">374 <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path d="M18 22H6v-2h12v2ZM6 20H4V4h2v16Zm14 0h-2v-3h2v3ZM16 9h2v2h2v2h-2v2h-2v2h-2v-4H8v-2h6V7h2v2Zm4-2h-2V4h2v3Zm-2-3H6V2h12v2Z"/></svg>375 Sign Out376 <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>377 </DropdownMenuItem>378 </DropdownMenuGroup>379 </DropdownMenuContent>380 </DropdownMenu>381 );382}API Reference
Section titled “API Reference”See the Base UI documentation for the full API reference.