Inputs
Dropdown Menu
List of options or actions presented to the user.
"use client"
import React from "react"import { RiAddCircleLine, RiAddLine, RiArrowUpCircleLine, RiDiscordLine, RiHeartPulseLine, RiIdCardLine, RiLogoutBoxLine, RiMailAddLine, RiMessageLine, RiSettings2Line, RiSlackLine, RiTelegramLine, RiUserSmileLine, RiWhatsappLine,} from "@remixicon/react"
import { Button } from "@/components/Button"import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuIconWrapper, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSubMenu, DropdownMenuSubMenuContent, DropdownMenuSubMenuTrigger, DropdownMenuTrigger,} from "@/components/DropdownMenu"
export const DropdownMenuHero = () => { return ( <div className="flex justify-center"> <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="secondary">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent className="min-w-56"> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuSeparator />
<DropdownMenuGroup> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiArrowUpCircleLine className="size-4 text-blue-500" /> <span className="text-blue-500">Upgrade</span> </span> </DropdownMenuItem> <DropdownMenuItem disabled shortcut="⌘B"> <span className="flex items-center gap-x-2"> <DropdownMenuIconWrapper> <RiIdCardLine className="size-4 text-inherit" /> </DropdownMenuIconWrapper> <span>Billing</span> </span> </DropdownMenuItem> <DropdownMenuItem shortcut="⌘S"> <span className="flex items-center gap-x-2"> <DropdownMenuIconWrapper> <RiSettings2Line className="size-4 text-inherit" /> </DropdownMenuIconWrapper> <span>Account Settings</span> </span> </DropdownMenuItem> </DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup> <DropdownMenuItem hint="Pro"> <span className="flex items-center gap-x-2"> <RiUserSmileLine className="size-4 text-inherit" /> <span>Manage workspace</span> </span> </DropdownMenuItem>
<DropdownMenuSubMenu> <DropdownMenuSubMenuTrigger> <span className="flex items-center gap-x-2"> <RiAddCircleLine className="size-4 text-inherit" /> <span>Invite users</span> </span> </DropdownMenuSubMenuTrigger> <DropdownMenuSubMenuContent> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiMailAddLine className="size-4 text-inherit" /> <span>Email</span> </span> </DropdownMenuItem>
<DropdownMenuSubMenu> <DropdownMenuSubMenuTrigger> <span className="flex items-center gap-x-2"> <RiMessageLine className="size-4 text-inherit" /> <span>Message</span> </span> </DropdownMenuSubMenuTrigger> <DropdownMenuSubMenuContent> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiWhatsappLine className="size-4 text-inherit" /> <span>Whatsapp</span> </span> </DropdownMenuItem> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiTelegramLine className="size-4 text-inherit" /> <span>Telegram</span> </span> </DropdownMenuItem> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiDiscordLine className="size-4 text-inherit" /> <span>Discord</span> </span> </DropdownMenuItem> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiSlackLine className="size-4 text-inherit" /> <span>Slack</span> </span> </DropdownMenuItem> </DropdownMenuSubMenuContent> </DropdownMenuSubMenu> <DropdownMenuSeparator /> <DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiAddCircleLine className="size-4 text-inherit" /> <span>More...</span> </span> </DropdownMenuItem> </DropdownMenuSubMenuContent> </DropdownMenuSubMenu> <DropdownMenuItem shortcut="⌘T"> <span className="flex items-center gap-x-2"> <RiAddLine className="size-4 text-inherit" /> <span>New Workspace</span> </span> </DropdownMenuItem> </DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem> <span className="flex items-center gap-x-2"> <RiHeartPulseLine className="size-4 text-inherit" /> <span>Support</span> </span> </DropdownMenuItem> <DropdownMenuItem shortcut="⇧⌘Q"> <span className="flex items-center gap-x-2"> <RiLogoutBoxLine className="size-4 text-inherit" /> <span>Sign out</span> </span> </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </div> )}
Installation
npm install @radix-ui/react-dropdown-menu @remixicon/react
- Copy and paste the code into your project’s component directory. Do not forget to update the import paths.
// Tremor Dropdown Menu [v0.0.2] "use client" import * as React from "react"import * as DropdownMenuPrimitives from "@radix-ui/react-dropdown-menu"import { RiArrowRightSLine, RiCheckboxBlankCircleLine, RiCheckLine, RiRadioButtonFill,} from "@remixicon/react" import { cx } from "@/lib/utils" const DropdownMenu = DropdownMenuPrimitives.RootDropdownMenu.displayName = "DropdownMenu" const DropdownMenuTrigger = DropdownMenuPrimitives.TriggerDropdownMenuTrigger.displayName = "DropdownMenuTrigger" const DropdownMenuGroup = DropdownMenuPrimitives.GroupDropdownMenuGroup.displayName = "DropdownMenuGroup" const DropdownMenuSubMenu = DropdownMenuPrimitives.SubDropdownMenuSubMenu.displayName = "DropdownMenuSubMenu" const DropdownMenuRadioGroup = DropdownMenuPrimitives.RadioGroupDropdownMenuRadioGroup.displayName = "DropdownMenuRadioGroup" const DropdownMenuSubMenuTrigger = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.SubTrigger>, Omit< React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.SubTrigger>, "asChild" >>(({ className, children, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.SubTrigger ref={forwardedRef} className={cx( // base "relative flex cursor-default select-none items-center rounded py-1.5 pl-2 pr-1 outline-none transition-colors data-[state=checked]:font-semibold sm:text-sm", // text color "text-gray-900 dark:text-gray-50", // disabled "data-[disabled]:pointer-events-none data-[disabled]:text-gray-400 data-[disabled]:hover:bg-none dark:data-[disabled]:text-gray-600", // focus "focus-visible:bg-gray-100 data-[state=open]:bg-gray-100 focus-visible:dark:bg-gray-900 data-[state=open]:dark:bg-gray-900", // hover "hover:bg-gray-100 hover:dark:bg-gray-900", // className, )} {...props} > {children} <RiArrowRightSLine className="ml-auto size-4 shrink-0" aria-hidden="true" /> </DropdownMenuPrimitives.SubTrigger>))DropdownMenuSubMenuTrigger.displayName = "DropdownMenuSubMenuTrigger" const DropdownMenuSubMenuContent = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.SubContent>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.SubContent>>(({ className, collisionPadding = 8, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.Portal> <DropdownMenuPrimitives.SubContent ref={forwardedRef} collisionPadding={collisionPadding} className={cx( // base "relative z-50 overflow-hidden rounded-md border p-1 shadow-xl shadow-black/[2.5%]", // widths "min-w-32", // heights "max-h-[var(--radix-popper-available-height)]", // background color "bg-white dark:bg-gray-950", // text color "text-gray-900 dark:text-gray-50", // border color "border-gray-200 dark:border-gray-800", // transition "will-change-[transform,opacity]", // "data-[state=open]:animate-slideDownAndFade", "data-[state=closed]:animate-hide", "data-[side=bottom]:animate-slideDownAndFade data-[side=left]:animate-slideLeftAndFade data-[side=right]:animate-slideRightAndFade data-[side=top]:animate-slideUpAndFade", className, )} {...props} /> </DropdownMenuPrimitives.Portal>))DropdownMenuSubMenuContent.displayName = "DropdownMenuSubMenuContent" const DropdownMenuContent = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.Content>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.Content>>( ( { className, sideOffset = 8, collisionPadding = 8, align = "center", loop = true, ...props }, forwardedRef, ) => ( <DropdownMenuPrimitives.Portal> <DropdownMenuPrimitives.Content ref={forwardedRef} className={cx( // base "relative z-50 overflow-hidden rounded-md border p-1 shadow-xl shadow-black/[2.5%]", // widths "min-w-48", // heights "max-h-[var(--radix-popper-available-height)]", // background color "bg-white dark:bg-gray-950", // text color "text-gray-900 dark:text-gray-50", // border color "border-gray-200 dark:border-gray-800", // transition "will-change-[transform,opacity]", "data-[state=closed]:animate-hide", "data-[side=bottom]:animate-slideDownAndFade data-[side=left]:animate-slideLeftAndFade data-[side=right]:animate-slideRightAndFade data-[side=top]:animate-slideUpAndFade", className, )} sideOffset={sideOffset} align={align} collisionPadding={collisionPadding} loop={loop} {...props} /> </DropdownMenuPrimitives.Portal> ),)DropdownMenuContent.displayName = "DropdownMenuContent" const DropdownMenuItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.Item>, Omit< React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.Item>, "asChild" > & { shortcut?: string hint?: string }>(({ className, shortcut, hint, children, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.Item ref={forwardedRef} className={cx( // base "group/DropdownMenuItem relative flex cursor-pointer select-none items-center rounded py-1.5 pl-2 pr-1 outline-none transition-colors data-[state=checked]:font-semibold sm:text-sm", // text color "text-gray-900 dark:text-gray-50", // disabled "data-[disabled]:pointer-events-none data-[disabled]:text-gray-400 data-[disabled]:hover:bg-none dark:data-[disabled]:text-gray-600", // focus "focus-visible:bg-gray-100 focus-visible:dark:bg-gray-900", // hover "hover:bg-gray-100 hover:dark:bg-gray-900", className, )} tremor-id="tremor-raw" {...props} > {children} {hint && ( <span className={cx("ml-auto pl-2 text-sm text-gray-400 dark:text-gray-600")} > {hint} </span> )} {shortcut && ( <span className={cx("ml-auto pl-2 text-sm text-gray-400 dark:text-gray-600")} > {shortcut} </span> )} </DropdownMenuPrimitives.Item>))DropdownMenuItem.displayName = "DropdownMenuItem" const DropdownMenuCheckboxItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.CheckboxItem>, Omit< React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.CheckboxItem>, "asChild" > & { shortcut?: string hint?: string }>( ( { className, hint, shortcut, children, checked, ...props }, forwardedRef, ) => ( <DropdownMenuPrimitives.CheckboxItem ref={forwardedRef} className={cx( // base "relative flex cursor-pointer select-none items-center gap-x-2 rounded py-1.5 pl-8 pr-1 outline-none transition-colors data-[state=checked]:font-semibold sm:text-sm", // text color "text-gray-900 dark:text-gray-50", // disabled "data-[disabled]:pointer-events-none data-[disabled]:text-gray-400 data-[disabled]:hover:bg-none dark:data-[disabled]:text-gray-600", // focus "focus-visible:bg-gray-100 focus-visible:dark:bg-gray-900", // hover "hover:bg-gray-100 hover:dark:bg-gray-900", className, )} checked={checked} {...props} > <span className="absolute left-2 flex size-4 items-center justify-center"> <DropdownMenuPrimitives.ItemIndicator> <RiCheckLine aria-hidden="true" className="size-full shrink-0 text-gray-800 dark:text-gray-200" /> </DropdownMenuPrimitives.ItemIndicator> </span> {children} {hint && ( <span className={cx( "ml-auto text-sm font-normal text-gray-400 dark:text-gray-600", )} > {hint} </span> )} {shortcut && ( <span className={cx( "ml-auto text-sm font-normal tracking-widest text-gray-400 dark:border-gray-800 dark:text-gray-600", )} > {shortcut} </span> )} </DropdownMenuPrimitives.CheckboxItem> ),)DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem" const DropdownMenuRadioItem = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.RadioItem>, Omit< React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.RadioItem>, "asChild" > & { shortcut?: string hint?: string }>(({ className, hint, shortcut, children, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.RadioItem ref={forwardedRef} className={cx( // base "group/DropdownMenuRadioItem relative flex cursor-pointer select-none items-center gap-x-2 rounded py-1.5 pl-8 pr-1 outline-none transition-colors data-[state=checked]:font-semibold sm:text-sm", // text color "text-gray-900 dark:text-gray-50", // disabled "data-[disabled]:pointer-events-none data-[disabled]:text-gray-400 data-[disabled]:hover:bg-none dark:data-[disabled]:text-gray-600", // focus "focus-visible:bg-gray-100 focus-visible:dark:bg-gray-900", // hover "hover:bg-gray-100 hover:dark:bg-gray-900", className, )} {...props} > <span className="absolute left-2 flex size-4 items-center justify-center"> <RiRadioButtonFill aria-hidden="true" className="size-full shrink-0 text-blue-500 group-data-[state=checked]/DropdownMenuRadioItem:flex group-data-[state=unchecked]/DropdownMenuRadioItem:hidden dark:text-blue-500" /> <RiCheckboxBlankCircleLine aria-hidden="true" className="size-full shrink-0 text-gray-300 group-data-[state=unchecked]/DropdownMenuRadioItem:flex group-data-[state=checked]/DropdownMenuRadioItem:hidden dark:text-gray-700" /> </span> {children} {hint && ( <span className={cx( "ml-auto text-sm font-normal text-gray-400 dark:text-gray-600", )} > {hint} </span> )} {shortcut && ( <span className={cx( "ml-auto text-sm font-normal tracking-widest text-gray-400 dark:border-gray-800 dark:text-gray-600", )} > {shortcut} </span> )} </DropdownMenuPrimitives.RadioItem>))DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem" const DropdownMenuLabel = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.Label>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.Label>>(({ className, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.Label ref={forwardedRef} className={cx( // base "px-2 py-2 text-xs font-medium tracking-wide", // text color "text-gray-500 dark:text-gray-500", className, )} {...props} />))DropdownMenuLabel.displayName = "DropdownMenuLabel" const DropdownMenuSeparator = React.forwardRef< React.ElementRef<typeof DropdownMenuPrimitives.Separator>, React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitives.Separator>>(({ className, ...props }, forwardedRef) => ( <DropdownMenuPrimitives.Separator ref={forwardedRef} className={cx( "-mx-1 my-1 h-px border-t border-gray-200 dark:border-gray-800", className, )} {...props} />))DropdownMenuSeparator.displayName = "DropdownMenuSeparator" const DropdownMenuIconWrapper = ({ className, ...props}: React.HTMLAttributes<HTMLSpanElement>) => { return ( <div className={cx( // text color "text-gray-600 dark:text-gray-400", // disabled "group-data-[disabled]/DropdownMenuItem:text-gray-400 group-data-[disabled]/DropdownMenuItem:dark:text-gray-700", className, )} {...props} /> )}DropdownMenuIconWrapper.displayName = "DropdownMenuIconWrapper" export { DropdownMenu, DropdownMenuTrigger, DropdownMenuSubMenuTrigger, DropdownMenuSubMenu, DropdownMenuSubMenuContent, DropdownMenuGroup, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuCheckboxItem, DropdownMenuIconWrapper, DropdownMenuLabel, DropdownMenuSeparator,}
import type { Config } from 'tailwindcss';export default { // ... theme: { extend: { keyframes: { hide: { from: { opacity: "1" }, to: { opacity: "0" }, }, slideDownAndFade: { from: { opacity: "0", transform: "translateY(-6px)" }, to: { opacity: "1", transform: "translateY(0)" }, }, slideLeftAndFade: { from: { opacity: "0", transform: "translateX(6px)" }, to: { opacity: "1", transform: "translateX(0)" }, }, slideUpAndFade: { from: { opacity: "0", transform: "translateY(6px)" }, to: { opacity: "1", transform: "translateY(0)" }, }, slideRightAndFade: { from: { opacity: "0", transform: "translateX(-6px)" }, to: { opacity: "1", transform: "translateX(0)" }, }, }, animation: { hide: "hide 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideDownAndFade: "slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideLeftAndFade: "slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideUpAndFade: "slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideRightAndFade: "slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", }, }, }, // ...} satisfies Config;
Example: Simple
"use client"
import React from "react"
import { Button } from "@/components/Button"import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger,} from "@/components/DropdownMenu"
export const DropdownMenuSimpleExample = () => { return ( <div className="flex justify-center"> <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="secondary">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>My Account</DropdownMenuLabel> <DropdownMenuSeparator />
<DropdownMenuGroup> <DropdownMenuItem shortcut="⌘S">Account Settings</DropdownMenuItem> </DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup> <DropdownMenuItem hint="Pro">Manage workspace</DropdownMenuItem>
<DropdownMenuItem shortcut="⌘T">New Workspace</DropdownMenuItem> </DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>Support</DropdownMenuItem> <DropdownMenuItem shortcut="⇧⌘Q">Sign out</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </div> )}
Example: With RadioItem
"use client"
import React from "react"
import { Button } from "@/components/Button"import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger,} from "@/components/DropdownMenu"
export const DropdownMenuRadioExample = () => { const [sort, setSort] = React.useState("alpha") return ( <div className="flex justify-center"> <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="secondary">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>Sorting</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup> <DropdownMenuRadioGroup value={sort} onValueChange={setSort}> <DropdownMenuRadioItem value="alpha" hint="A–Z"> Alphabetical </DropdownMenuRadioItem> <DropdownMenuRadioItem value="alpha-reverse" hint="Z-A"> Reverse Alphabetical </DropdownMenuRadioItem> <DropdownMenuRadioItem value="asc" hint="1-99"> Created At </DropdownMenuRadioItem> </DropdownMenuRadioGroup> </DropdownMenuGroup> </DropdownMenuContent> </DropdownMenu> </div> )}
Example: With CheckboxItem
"use client"
import React from "react"import { DropdownMenuCheckboxItemProps } from "@radix-ui/react-dropdown-menu"
import { Button } from "@/components/Button"import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger,} from "@/components/DropdownMenu"
type Checked = DropdownMenuCheckboxItemProps["checked"]
export const DropdownMenuCheckboxExample = () => { const [showStatusBar, setShowStatusBar] = React.useState<Checked>(true) const [showActivityBar, setShowActivityBar] = React.useState<Checked>(true) const [showPanel, setShowPanel] = React.useState<Checked>(false) return ( <div className="flex justify-center"> <DropdownMenu> <DropdownMenuTrigger asChild> <Button variant="secondary">Open</Button> </DropdownMenuTrigger> <DropdownMenuContent> <DropdownMenuLabel>Layout</DropdownMenuLabel> <DropdownMenuSeparator /> <DropdownMenuCheckboxItem checked={showStatusBar} onCheckedChange={setShowStatusBar} hint="Pro" > Show status bar </DropdownMenuCheckboxItem> <DropdownMenuCheckboxItem checked={showActivityBar} onCheckedChange={setShowActivityBar} > Show activity bar </DropdownMenuCheckboxItem> <DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel} hint="Base" > Show panel </DropdownMenuCheckboxItem> </DropdownMenuContent> </DropdownMenu> </div> )}
API Reference: DropdownMenu
This component uses the Radix UI API.
API Reference: DropdownMenuTrigger
This component uses the Radix UI API.
API Reference: DropdownMenuSubMenuTrigger
This component uses the Radix UI API.
API Reference: DropdownMenuSubMenu
This component uses the Radix UI API.
API Reference: DropdownMenuSubMenuContent
This component uses the Radix UI API.
API Reference: DropdownMenuGroup
This component uses the Radix UI API.
API Reference: DropdownMenuContent
This component uses the Radix UI API.
API Reference: DropdownMenuItem
This component uses the Radix UI API.
Note that asChild is omitted.
- shortcut
- Add a keyboard shortcut.
string
- hint
- Add a hint.
string
API Reference: DropdownMenuRadioGroup
This component uses the Radix UI API.
API Reference: DropdownMenuRadioItem
This component uses the Radix UI API.
Note that asChild is omitted.
- shortcut
- Add a keyboard shortcut.
string
- hint
- Add a hint.
string
API Reference: DropdownMenuCheckboxItem
This component uses the Radix UI API.
Note that asChild is omitted.
- shortcut
- Add a keyboard shortcut.
string
- hint
- Add a hint.
string
API Reference: DropdownMenuIconWrapper
This component extens an HTML "div".
API Reference: DropdownMenuLabel
This component uses the Radix UI API.
API Reference: DropdownMenuSeparator
This component uses the Radix UI API.