Creative Tim UICreative Tim UI

Shadcn Menu

PreviousNext

A versatile dropdown menu component that displays a list of options when triggered, perfect for navigation, actions, and contextual menus.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function MenuDemo() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Open</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem>Add Team</DropdownMenuItem>
        <DropdownMenuItem>Add Project</DropdownMenuItem>
        <DropdownMenuItem>My Profile</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Installation

pnpm dlx @creative-tim/ui@latest add dropdown-menu

Usage

import MenuDemo from "@/components/menu-demo"
<MenuDemo />

Examples

A demonstration of menu placement options showing how dropdown menus can be positioned relative to their trigger, including top, bottom, left, right, and their start/end variations for precise alignment.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function MenuPlacement() {
  return (
    <div className="flex flex-col gap-3">
      <div className="flex gap-3">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Top</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="top">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Top Start</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="top" align="start">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Top End</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="top" align="end">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
      <div className="flex gap-3">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Right</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="right">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Right Start</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="right" align="start">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Right End</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="right" align="end">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
      <div className="flex gap-3">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Bottom</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="bottom">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Bottom Start</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="bottom" align="start">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Bottom End</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="bottom" align="end">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
      <div className="flex gap-3">
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Left</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="left">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Left Start</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="left" align="start">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button>Left End</Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent side="left" align="end">
            <DropdownMenuItem>Add Team</DropdownMenuItem>
            <DropdownMenuItem>Add Project</DropdownMenuItem>
            <DropdownMenuItem>My Profile</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
    </div>
  )
}

A dropdown menu containing checkbox items that allow users to select multiple sorting options, with each checkbox maintaining its own state independently.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function MenuWithCheckbox() {
  const [taskName, setTaskName] = React.useState(false)
  const [dateCreated, setDateCreated] = React.useState(false)
  const [completed, setCompleted] = React.useState(false)

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Sort</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem
          onSelect={(e) => e.preventDefault()}
          className="gap-2 pl-1.5"
        >
          <Checkbox
            id="task-name"
            checked={taskName}
            onCheckedChange={setTaskName}
          />
          <label htmlFor="task-name" className="cursor-pointer">
            Task Name
          </label>
        </DropdownMenuItem>
        <DropdownMenuItem
          onSelect={(e) => e.preventDefault()}
          className="gap-2 pl-1.5"
        >
          <Checkbox
            id="date-created"
            checked={dateCreated}
            onCheckedChange={setDateCreated}
          />
          <label htmlFor="date-created" className="cursor-pointer">
            Date Created
          </label>
        </DropdownMenuItem>
        <DropdownMenuItem
          onSelect={(e) => e.preventDefault()}
          className="gap-2 pl-1.5"
        >
          <Checkbox
            id="completed"
            checked={completed}
            onCheckedChange={setCompleted}
          />
          <label htmlFor="completed" className="cursor-pointer">
            Completed
          </label>
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

A dropdown menu with a visual separator dividing regular menu items from a destructive action, helping to distinguish between safe and potentially dangerous operations.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function MenuWithDivider() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Open</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem>Add Team</DropdownMenuItem>
        <DropdownMenuItem>Add Project</DropdownMenuItem>
        <DropdownMenuItem>My Profile</DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive">Logout</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

A dropdown menu with a maximum height and scrollable content, ideal for displaying long lists of menu items while maintaining a compact interface.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function MenuWithScrollingContent() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Open</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent className="max-h-72 overflow-y-auto">
        <DropdownMenuItem>Menu Item 1</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 2</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 3</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 4</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 5</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 6</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 7</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 8</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 9</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 10</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 11</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 12</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 13</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 14</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 15</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 16</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 17</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 18</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 19</DropdownMenuItem>
        <DropdownMenuItem>Menu Item 20</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

A dropdown menu featuring an integrated search input field at the top, allowing users to filter menu items dynamically for quick access to specific options.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"

export function MenuWithSearch() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Open</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <div className="px-2 py-1.5">
          <Input placeholder="Search..." className="mb-1" />
        </div>
        <DropdownMenuItem>Add Team</DropdownMenuItem>
        <DropdownMenuItem>Add Project</DropdownMenuItem>
        <DropdownMenuItem>My Profile</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

A navigation-style dropdown menu with a featured card section and descriptive menu items, perfect for showcasing product versions or navigation categories with rich content.

import { ChevronDown, Rocket } from "lucide-react"

import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function NavMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="sm" className="flex items-center gap-1">
          Versions <ChevronDown className="h-3.5 w-3.5" />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent className="grid max-w-lg grid-cols-5 gap-1 p-2">
        <Card className="bg-primary text-primary-foreground col-span-2 grid place-items-center rounded-[5px] px-8 py-4 shadow-none">
          <div>
            <Rocket className="mx-auto h-12 w-12" />
            <h6 className="mt-5 text-center text-base leading-snug font-semibold">
              Creative Tim UI PRO
            </h6>
          </div>
        </Card>
        <ul className="col-span-3 m-0 space-y-1">
          <DropdownMenuItem className="flex-col items-start">
            <span className="font-semibold">@creative-tim/ui</span>
            <span className="text-muted-foreground text-xs">
              Learn how to use @creative-tim/ui, packed with rich components and
              widgets.
            </span>
          </DropdownMenuItem>
          <DropdownMenuItem className="flex-col items-start">
            <span className="font-semibold">Creative Tim UI</span>
            <span className="text-muted-foreground text-xs">
              Learn how to use Creative Tim UI, packed with rich components for
              React.
            </span>
          </DropdownMenuItem>
          <DropdownMenuItem className="flex-col items-start">
            <span className="font-semibold">Creative Tim UI PRO</span>
            <span className="text-muted-foreground text-xs">
              A complete set of UI Elements for building faster websites in less
              time.
            </span>
          </DropdownMenuItem>
        </ul>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Nested Menu

A dropdown menu with nested submenus that expand when hovered or clicked, enabling hierarchical menu structures for organizing complex navigation or action sets.

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function NestedMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button>Open</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem>Add Team</DropdownMenuItem>
        <DropdownMenuItem>Add Project</DropdownMenuItem>
        <DropdownMenuSub>
          <DropdownMenuSubTrigger>My Profile</DropdownMenuSubTrigger>
          <DropdownMenuSubContent>
            <DropdownMenuItem>Edit Profile</DropdownMenuItem>
            <DropdownMenuItem>Change Password</DropdownMenuItem>
            <DropdownMenuItem>Upgrade to PRO</DropdownMenuItem>
          </DropdownMenuSubContent>
        </DropdownMenuSub>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Notification Menu

A notification-style dropdown menu displaying a list of notification items with avatars, titles, and timestamps, commonly used in header bars for user notifications.

import { Bell, Clock } from "lucide-react"

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

interface MenuItemProps {
  img: string
  title: string
  date: string
}

function NotificationMenuItem({ img, title, date }: MenuItemProps) {
  return (
    <DropdownMenuItem className="gap-3">
      <Avatar>
        <AvatarImage src={img} alt="profile-picture" />
        <AvatarFallback>U</AvatarFallback>
      </Avatar>
      <div>
        <p className="mb-1 block text-sm font-semibold">{title}</p>
        <p className="text-muted-foreground flex items-center gap-1 text-xs">
          <Clock className="h-3 w-3" />
          {date}
        </p>
      </div>
    </DropdownMenuItem>
  )
}

export function NotificationMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" size="sm">
          <Bell className="h-4 w-4" />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <NotificationMenuItem
          img="https://images.unsplash.com/photo-1574015974293-817f0ebebb74?auto=format&fit=crop&q=80&w=400&h=400"
          title="Tania send you a message"
          date="13 minutes ago"
        />
        <NotificationMenuItem
          img="https://images.unsplash.com/photo-1661327930345-9c6714b603b3?auto=format&fit=crop&q=80&w=400&h=400"
          title="Natali replied to your email."
          date="1 hour ago"
        />
        <NotificationMenuItem
          img="https://images.unsplash.com/photo-1578508637199-240a8f25eff6?auto=format&fit=crop&q=80&w=400&h=400"
          title="You've received a payment."
          date="5 hours ago"
        />
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Profile Menu

A profile dropdown menu triggered by an avatar, containing user-related actions like profile settings, support, and logout, with a visual separator before the destructive logout action.

import { HelpCircle, LogOut, Settings, UserCircle } from "lucide-react"

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export function ProfileMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button className="cursor-pointer outline-none">
          <Avatar>
            <AvatarImage
              src="https://images.unsplash.com/photo-1574015974293-817f0ebebb74?auto=format&fit=crop&q=80&w=400&h=400"
              alt="profile-picture"
            />
            <AvatarFallback>U</AvatarFallback>
          </Avatar>
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuItem>
          <UserCircle className="mr-2 h-[18px] w-[18px]" /> My Profile
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Settings className="mr-2 h-[18px] w-[18px]" /> Edit Profile
        </DropdownMenuItem>
        <DropdownMenuItem>
          <HelpCircle className="mr-2 h-[18px] w-[18px]" /> Support
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive">
          <LogOut className="mr-2 h-[18px] w-[18px]" />
          Logout
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Best Practices

  • Use dropdown menus for actions that don't need to be immediately visible
  • Keep menu items concise and clearly labeled
  • Use dividers to group related menu items
  • Provide visual feedback for destructive actions (like logout)
  • Consider using icons alongside text for better visual recognition
  • Use nested menus sparingly to avoid overwhelming users
  • Ensure keyboard navigation works properly for accessibility
  • Position menus appropriately to avoid viewport overflow
  • Use search functionality for menus with many items
  • Consider scrollable content for long lists

Menu components provide a flexible way to organize actions and navigation options while keeping interfaces clean and uncluttered. They're ideal for header navigation, action buttons, user profiles, notifications, and any interface where space is at a premium.