Y2K UI

Dropdown Menu

A flat dropdown panel with a thick navy border and pink highlight on hover. Wraps @radix-ui/react-dropdown-menu with Y2K styling — perfect for action menus, settings, and navigation.

dropdown-menu-demo.app

Installation

terminal.sh
npx y2kui@latest add dropdown-menu

Usage

import {
  DropdownMenu,
  DropdownMenuCheckboxItem,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuPortal,
  DropdownMenuRadioGroup,
  DropdownMenuRadioItem,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
  DropdownMenuSub,
  DropdownMenuSubContent,
  DropdownMenuSubTrigger,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

Basic menu

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="pink">Actions</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>Actions</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Edit</DropdownMenuItem>
    <DropdownMenuItem>Duplicate</DropdownMenuItem>
    <DropdownMenuItem>Delete</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

With checkboxes

const [items, setItems] = React.useState<string[]>([])

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="mint">Filter</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuCheckboxItem
      checked={items.includes("a")}
      onCheckedChange={(checked) => {
        setItems(checked ? [...items, "a"] : items.filter((i) => i !== "a"))
      }}
    >
      Option A
    </DropdownMenuCheckboxItem>
    <DropdownMenuCheckboxItem
      checked={items.includes("b")}
      onCheckedChange={(checked) => {
        setItems(checked ? [...items, "b"] : items.filter((i) => i !== "b"))
      }}
    >
      Option B
    </DropdownMenuCheckboxItem>
  </DropdownMenuContent>
</DropdownMenu>

With radio group

const [value, setValue] = React.useState("asc")

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="lilac">Sort</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>Sort order</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuRadioGroup value={value} onValueChange={setValue}>
      <DropdownMenuRadioItem value="asc">Ascending</DropdownMenuRadioItem>
      <DropdownMenuRadioItem value="desc">Descending</DropdownMenuRadioItem>
    </DropdownMenuRadioGroup>
  </DropdownMenuContent>
</DropdownMenu>

With sub-menus

<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="blue">More</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuSub>
      <DropdownMenuSubTrigger>Share</DropdownMenuSubTrigger>
      <DropdownMenuPortal>
        <DropdownMenuSubContent>
          <DropdownMenuItem>Copy link</DropdownMenuItem>
          <DropdownMenuItem>Email</DropdownMenuItem>
        </DropdownMenuSubContent>
      </DropdownMenuPortal>
    </DropdownMenuSub>
    <DropdownMenuItem>Report</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Props

PropTypeDefaultDescription
openbooleanControlled open state of the dropdown.
defaultOpenbooleanInitial open state (uncontrolled).
onOpenChange(open: boolean) => voidFired when open state changes.
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side relative to the trigger.
align'start' | 'center' | 'end''center'Alignment along the chosen side.
sideOffsetnumber6Distance between the trigger and the panel.
disabledbooleanfalseDisable the menu trigger.

On this page