본문으로 건너뛰기
언어

Dropdown menustandard

버튼을 눌러 여는 메뉴(dropdown menu)입니다. shadcn base-nova 의 `dropdown-menu` 를 그대로 싣습니다. 오른쪽 클릭으로 여는 메뉴는 `context-menu`, 고르는 값이 입력값이면 `select` 를 씁니다.

설치

pnpm
pnpm dlx shadcn@4.23.0 add @uikit/dropdown-menu

Default

dropdown-menu-example.tsx
"use client"
import * as React from "react"
import {  Example,  ExampleWrapper,} from "@/components/example"import {  Avatar,  AvatarFallback,  AvatarImage,} from "@/components/ui/avatar"import { Button } from "@/components/ui/button"import {  Dialog,  DialogContent,  DialogDescription,  DialogHeader,  DialogTitle,  DialogTrigger,} from "@/components/ui/dialog"import {  DropdownMenu,  DropdownMenuCheckboxItem,  DropdownMenuContent,  DropdownMenuGroup,  DropdownMenuItem,  DropdownMenuLabel,  DropdownMenuPortal,  DropdownMenuRadioGroup,  DropdownMenuRadioItem,  DropdownMenuSeparator,  DropdownMenuShortcut,  DropdownMenuSub,  DropdownMenuSubContent,  DropdownMenuSubTrigger,  DropdownMenuTrigger,} from "@/components/ui/dropdown-menu"import { ActivityIcon, ArchiveIcon, ArrowDownIcon, ArrowRightIcon, ArrowUpIcon, BadgeCheckIcon, BellIcon, Building2Icon, ChevronsUpDownIcon, ClipboardPasteIcon, CopyIcon, CreditCardIcon, HelpCircleIcon, LayoutIcon, LogOutIcon, MailIcon, MessageSquareIcon, PanelLeftIcon, PencilIcon, PlusCircleIcon, ScissorsIcon, SettingsIcon, ShareIcon, TrashIcon, UserIcon, UsersIcon, WalletIcon } from "lucide-react"
export default function DropdownMenuExample() {  return (    <ExampleWrapper>      <DropdownMenuBasic />      <DropdownMenuComplex />      <DropdownMenuSides />      <DropdownMenuWithIcons />      <DropdownMenuWithShortcuts />      <DropdownMenuWithSubmenu />      <DropdownMenuWithCheckboxes />      <DropdownMenuWithCheckboxesIcons />      <DropdownMenuWithRadio />      <DropdownMenuWithRadioIcons />      <DropdownMenuWithDestructive />      <DropdownMenuWithAvatar />      <DropdownMenuInDialog />      <DropdownMenuWithInset />    </ExampleWrapper>  )}
function DropdownMenuBasic() {  return (    <Example title="Basic">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="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>  )}
function DropdownMenuSides() {  return (    <Example title="Sides" containerClassName="col-span-2">      <div className="flex flex-wrap justify-center gap-2">        {(          [            "inline-start",            "left",            "top",            "bottom",            "right",            "inline-end",          ] as const        ).map((side) => (          <DropdownMenu key={side}>            <DropdownMenuTrigger              render={<Button variant="outline" className="w-fit capitalize" />}            >              {side.replace("-", " ")}            </DropdownMenuTrigger>            <DropdownMenuContent side={side}>              <DropdownMenuGroup>                <DropdownMenuItem>Profile</DropdownMenuItem>                <DropdownMenuItem>Billing</DropdownMenuItem>                <DropdownMenuItem>Settings</DropdownMenuItem>              </DropdownMenuGroup>            </DropdownMenuContent>          </DropdownMenu>        ))}      </div>    </Example>  )}
function DropdownMenuWithIcons() {  return (    <Example title="With Icons">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Open        </DropdownMenuTrigger>        <DropdownMenuContent>          <DropdownMenuItem>            <UserIcon />            Profile          </DropdownMenuItem>          <DropdownMenuItem>            <CreditCardIcon />            Billing          </DropdownMenuItem>          <DropdownMenuItem>            <SettingsIcon />            Settings          </DropdownMenuItem>          <DropdownMenuSeparator />          <DropdownMenuItem variant="destructive">            <LogOutIcon />            Log out          </DropdownMenuItem>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithShortcuts() {  return (    <Example title="With Shortcuts">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="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>  )}
function DropdownMenuWithSubmenu() {  return (    <Example title="With Submenu">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="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>  )}
function DropdownMenuWithCheckboxes() {  const [showStatusBar, setShowStatusBar] = React.useState(true)  const [showActivityBar, setShowActivityBar] = React.useState(false)  const [showPanel, setShowPanel] = React.useState(false)
  return (    <Example title="With Checkboxes">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Checkboxes        </DropdownMenuTrigger>        <DropdownMenuContent className="min-w-40">          <DropdownMenuGroup>            <DropdownMenuLabel>Appearance</DropdownMenuLabel>            <DropdownMenuCheckboxItem              checked={showStatusBar}              onCheckedChange={setShowStatusBar}            >              <LayoutIcon />              Status Bar            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              checked={showActivityBar}              onCheckedChange={setShowActivityBar}              disabled            >              <ActivityIcon />              Activity Bar            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              checked={showPanel}              onCheckedChange={setShowPanel}            >              <PanelLeftIcon />              Panel            </DropdownMenuCheckboxItem>          </DropdownMenuGroup>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithRadio() {  const [position, setPosition] = React.useState("bottom")
  return (    <Example title="With Radio Group">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Radio Group        </DropdownMenuTrigger>        <DropdownMenuContent>          <DropdownMenuGroup>            <DropdownMenuLabel>Panel Position</DropdownMenuLabel>            <DropdownMenuRadioGroup              value={position}              onValueChange={setPosition}            >              <DropdownMenuRadioItem value="top">                <ArrowUpIcon />                Top              </DropdownMenuRadioItem>              <DropdownMenuRadioItem value="bottom">                <ArrowDownIcon />                Bottom              </DropdownMenuRadioItem>              <DropdownMenuRadioItem value="right" disabled>                <ArrowRightIcon />                Right              </DropdownMenuRadioItem>            </DropdownMenuRadioGroup>          </DropdownMenuGroup>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithCheckboxesIcons() {  const [notifications, setNotifications] = React.useState({    email: true,    sms: false,    push: true,  })
  return (    <Example title="Checkboxes with Icons">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Notifications        </DropdownMenuTrigger>        <DropdownMenuContent className="min-w-56">          <DropdownMenuGroup>            <DropdownMenuLabel>Notification Preferences</DropdownMenuLabel>            <DropdownMenuCheckboxItem              checked={notifications.email}              onCheckedChange={(checked) =>                setNotifications({ ...notifications, email: checked === true })              }            >              <MailIcon />              Email notifications            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              checked={notifications.sms}              onCheckedChange={(checked) =>                setNotifications({ ...notifications, sms: checked === true })              }            >              <MessageSquareIcon />              SMS notifications            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              checked={notifications.push}              onCheckedChange={(checked) =>                setNotifications({ ...notifications, push: checked === true })              }            >              <BellIcon />              Push notifications            </DropdownMenuCheckboxItem>          </DropdownMenuGroup>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithRadioIcons() {  const [paymentMethod, setPaymentMethod] = React.useState("card")
  return (    <Example title="Radio with Icons">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Payment Method        </DropdownMenuTrigger>        <DropdownMenuContent className="min-w-56">          <DropdownMenuGroup>            <DropdownMenuLabel>Select Payment Method</DropdownMenuLabel>            <DropdownMenuRadioGroup              value={paymentMethod}              onValueChange={setPaymentMethod}            >              <DropdownMenuRadioItem value="card">                <CreditCardIcon />                Credit Card              </DropdownMenuRadioItem>              <DropdownMenuRadioItem value="paypal">                <WalletIcon />                PayPal              </DropdownMenuRadioItem>              <DropdownMenuRadioItem value="bank">                <Building2Icon />                Bank Transfer              </DropdownMenuRadioItem>            </DropdownMenuRadioGroup>          </DropdownMenuGroup>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithDestructive() {  return (    <Example title="With Destructive Items">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Actions        </DropdownMenuTrigger>        <DropdownMenuContent>          <DropdownMenuItem>            <PencilIcon />            Edit          </DropdownMenuItem>          <DropdownMenuItem>            <ShareIcon />            Share          </DropdownMenuItem>          <DropdownMenuSeparator />          <DropdownMenuItem>            <ArchiveIcon />            Archive          </DropdownMenuItem>          <DropdownMenuItem variant="destructive">            <TrashIcon />            Delete          </DropdownMenuItem>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuWithAvatar() {  const menuContent = (    <>      <DropdownMenuGroup>        <DropdownMenuItem>          <BadgeCheckIcon />          Account        </DropdownMenuItem>        <DropdownMenuItem>          <CreditCardIcon />          Billing        </DropdownMenuItem>        <DropdownMenuItem>          <BellIcon />          Notifications        </DropdownMenuItem>      </DropdownMenuGroup>      <DropdownMenuSeparator />      <DropdownMenuItem>        <LogOutIcon />        Sign Out      </DropdownMenuItem>    </>  )
  return (    <Example title="With Avatar">      <div className="flex items-center justify-between gap-4">        <DropdownMenu>          <DropdownMenuTrigger            render={              <Button                variant="outline"                className="h-12 justify-start px-2 md:max-w-[200px] style-sera:font-normal style-sera:tracking-normal style-sera:normal-case"              />            }          >            <Avatar>              <AvatarImage src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%208'%3E%3Crect%20width='8'%20height='8'%20fill='%2364748b'/%3E%3C/svg%3E" alt="Shadcn" />              <AvatarFallback className="rounded-lg">CN</AvatarFallback>            </Avatar>            <div className="grid flex-1 text-left text-sm leading-tight">              <span className="truncate font-semibold">shadcn</span>              <span className="truncate text-xs text-muted-foreground">                shadcn@example.com              </span>            </div>            <ChevronsUpDownIcon className="ml-auto text-muted-foreground" />          </DropdownMenuTrigger>          <DropdownMenuContent className="w-(--anchor-width) min-w-56">            {menuContent}          </DropdownMenuContent>        </DropdownMenu>        <DropdownMenu>          <DropdownMenuTrigger            render={              <Button variant="ghost" size="icon" className="rounded-full" />            }          >            <Avatar>              <AvatarImage src="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%208%208'%3E%3Crect%20width='8'%20height='8'%20fill='%2364748b'/%3E%3C/svg%3E" alt="shadcn" />              <AvatarFallback>LR</AvatarFallback>            </Avatar>          </DropdownMenuTrigger>          <DropdownMenuContent align="end" side="top">            {menuContent}          </DropdownMenuContent>        </DropdownMenu>      </div>    </Example>  )}
function DropdownMenuInDialog() {  return (    <Example title="In Dialog">      <Dialog>        <DialogTrigger render={<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              render={<Button variant="outline" className="w-fit" />}            >              Open Menu            </DropdownMenuTrigger>            <DropdownMenuContent>              <DropdownMenuItem>                <CopyIcon />                Copy              </DropdownMenuItem>              <DropdownMenuItem>                <ScissorsIcon />                Cut              </DropdownMenuItem>              <DropdownMenuItem>                <ClipboardPasteIcon />                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">                <TrashIcon />                Delete              </DropdownMenuItem>            </DropdownMenuContent>          </DropdownMenu>        </DialogContent>      </Dialog>    </Example>  )}
function DropdownMenuWithInset() {  const [showBookmarks, setShowBookmarks] = React.useState(true)  const [showUrls, setShowUrls] = React.useState(false)  const [theme, setTheme] = React.useState("system")
  return (    <Example title="With Inset">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Open        </DropdownMenuTrigger>        <DropdownMenuContent className="w-44">          <DropdownMenuGroup>            <DropdownMenuLabel>Actions</DropdownMenuLabel>            <DropdownMenuItem>              <CopyIcon />              Copy            </DropdownMenuItem>            <DropdownMenuItem>              <ScissorsIcon />              Cut            </DropdownMenuItem>            <DropdownMenuItem inset>Paste</DropdownMenuItem>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuGroup>            <DropdownMenuLabel inset>Appearance</DropdownMenuLabel>            <DropdownMenuCheckboxItem              inset              checked={showBookmarks}              onCheckedChange={setShowBookmarks}            >              Bookmarks            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              inset              checked={showUrls}              onCheckedChange={setShowUrls}            >              Full URLs            </DropdownMenuCheckboxItem>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuGroup>            <DropdownMenuLabel inset>Theme</DropdownMenuLabel>            <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>              <DropdownMenuRadioItem inset value="light">                Light              </DropdownMenuRadioItem>              <DropdownMenuRadioItem inset value="dark">                Dark              </DropdownMenuRadioItem>              <DropdownMenuRadioItem inset value="system">                System              </DropdownMenuRadioItem>            </DropdownMenuRadioGroup>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuSub>            <DropdownMenuSubTrigger inset>More Options</DropdownMenuSubTrigger>            <DropdownMenuPortal>              <DropdownMenuSubContent>                <DropdownMenuGroup>                  <DropdownMenuItem>Save Page...</DropdownMenuItem>                  <DropdownMenuItem>Create Shortcut...</DropdownMenuItem>                </DropdownMenuGroup>              </DropdownMenuSubContent>            </DropdownMenuPortal>          </DropdownMenuSub>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}
function DropdownMenuComplex() {  const [showSidebar, setShowSidebar] = React.useState(true)  const [showStatusBar, setShowStatusBar] = React.useState(false)
  return (    <Example title="Complex">      <DropdownMenu>        <DropdownMenuTrigger          render={<Button variant="outline" className="w-fit" />}        >          Complex Menu        </DropdownMenuTrigger>        <DropdownMenuContent className="w-56">          <DropdownMenuGroup>            <DropdownMenuLabel>My Account</DropdownMenuLabel>            <DropdownMenuItem>              <UserIcon />              Profile              <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>            </DropdownMenuItem>            <DropdownMenuItem>              <CreditCardIcon />              Billing              <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>            </DropdownMenuItem>            <DropdownMenuItem>              <SettingsIcon />              Settings              <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>            </DropdownMenuItem>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuGroup>            <DropdownMenuLabel>View</DropdownMenuLabel>            <DropdownMenuCheckboxItem              checked={showSidebar}              onCheckedChange={setShowSidebar}            >              <PanelLeftIcon />              Sidebar            </DropdownMenuCheckboxItem>            <DropdownMenuCheckboxItem              checked={showStatusBar}              onCheckedChange={setShowStatusBar}            >              <LayoutIcon />              Status Bar            </DropdownMenuCheckboxItem>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuGroup>            <DropdownMenuSub>              <DropdownMenuSubTrigger>                <UsersIcon />                Invite Users              </DropdownMenuSubTrigger>              <DropdownMenuPortal>                <DropdownMenuSubContent>                  <DropdownMenuGroup>                    <DropdownMenuItem>                      <MailIcon />                      Email                    </DropdownMenuItem>                    <DropdownMenuItem>                      <MessageSquareIcon />                      Message                    </DropdownMenuItem>                  </DropdownMenuGroup>                  <DropdownMenuSeparator />                  <DropdownMenuGroup>                    <DropdownMenuItem>                      <PlusCircleIcon />                      More...                    </DropdownMenuItem>                  </DropdownMenuGroup>                </DropdownMenuSubContent>              </DropdownMenuPortal>            </DropdownMenuSub>          </DropdownMenuGroup>          <DropdownMenuSeparator />          <DropdownMenuGroup>            <DropdownMenuItem>              <HelpCircleIcon />              Support            </DropdownMenuItem>            <DropdownMenuItem variant="destructive">              <LogOutIcon />              Sign Out              <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>            </DropdownMenuItem>          </DropdownMenuGroup>        </DropdownMenuContent>      </DropdownMenu>    </Example>  )}