YaVendio Registry
Components

YA Dropdown Menu

A dropdown menu component for displaying a list of actions or options

The YaDropdownMenu is a floating menu in the YaVendio Design System. It supports text items, checkbox items, radio items, submenus, labels, separators, and keyboard navigation. Built on top of Radix UI primitives for full accessibility.

Quick Start

pnpm dlx shadcn@latest add @yavendio/ya-dropdown-menu
npx shadcn@latest add @yavendio/ya-dropdown-menu
yarn dlx shadcn@latest add @yavendio/ya-dropdown-menu
import {
  YaDropdownMenu,
  YaDropdownMenuTrigger,
  YaDropdownMenuContent,
  YaDropdownMenuItem,
} from '@/components/ui/ya-dropdown-menu'
import { YaButton } from '@/components/ui/ya-button'

export default function Example() {
  return (
    <YaDropdownMenu>
      <YaDropdownMenuTrigger asChild>
        <YaButton variant="secondary">Open Menu</YaButton>
      </YaDropdownMenuTrigger>
      <YaDropdownMenuContent>
        <YaDropdownMenuItem>Choose service</YaDropdownMenuItem>
        <YaDropdownMenuItem>Add promotion</YaDropdownMenuItem>
        <YaDropdownMenuItem>View details</YaDropdownMenuItem>
      </YaDropdownMenuContent>
    </YaDropdownMenu>
  )
}

Basic Dropdown Menu

Item Types

Text Item with Icons

Items can include icons on the left for better visual hierarchy.

import { User, Settings, Folder, LogOut } from 'lucide-react'

<YaDropdownMenuItem icon={<User className="size-[14px]" />}>Profile</YaDropdownMenuItem>
<YaDropdownMenuItem icon={<Settings className="size-[14px]" />}>Settings</YaDropdownMenuItem>
<YaDropdownMenuItem icon={<Folder className="size-[14px]" />}>Documents</YaDropdownMenuItem>
<YaDropdownMenuItem icon={<LogOut className="size-[14px]" />}>Logout</YaDropdownMenuItem>

Item with Description

Items can have a secondary description text for additional context.

<YaDropdownMenuItem
  icon={<Folder className="size-[14px]" />}
  description="View all your documents"
>
  Documents
</YaDropdownMenuItem>

Selected Item

Items can show a selected state with a checkmark.

<YaDropdownMenuItem selected>Selected option</YaDropdownMenuItem>
<YaDropdownMenuItem>Other option</YaDropdownMenuItem>

Checkbox Items

For multi-select options within the menu.

import { useState } from 'react'
import {
  YaDropdownMenu,
  YaDropdownMenuTrigger,
  YaDropdownMenuContent,
  YaDropdownMenuCheckboxItem,
} from '@/components/ui/ya-dropdown-menu'

export default function CheckboxExample() {
  const [showStatus, setShowStatus] = useState(true)
  const [showActivity, setShowActivity] = useState(false)
  const [showPanel, setShowPanel] = useState(false)

  return (
    <YaDropdownMenu>
      <YaDropdownMenuTrigger asChild>
        <YaButton variant="tertiary">View Options</YaButton>
      </YaDropdownMenuTrigger>
      <YaDropdownMenuContent>
        <YaDropdownMenuCheckboxItem
          checked={showStatus}
          onCheckedChange={setShowStatus}
        >
          Show Status Bar
        </YaDropdownMenuCheckboxItem>
        <YaDropdownMenuCheckboxItem
          checked={showActivity}
          onCheckedChange={setShowActivity}
        >
          Show Activity Panel
        </YaDropdownMenuCheckboxItem>
        <YaDropdownMenuCheckboxItem
          checked={showPanel}
          onCheckedChange={setShowPanel}
        >
          Show Side Panel
        </YaDropdownMenuCheckboxItem>
      </YaDropdownMenuContent>
    </YaDropdownMenu>
  )
}

Radio Items

For single-select options within a group.

import { useState } from 'react'
import {
  YaDropdownMenu,
  YaDropdownMenuTrigger,
  YaDropdownMenuContent,
  YaDropdownMenuRadioGroup,
  YaDropdownMenuRadioItem,
} from '@/components/ui/ya-dropdown-menu'

export default function RadioExample() {
  const [position, setPosition] = useState('center')

  return (
    <YaDropdownMenu>
      <YaDropdownMenuTrigger asChild>
        <YaButton variant="tertiary">Position: {position}</YaButton>
      </YaDropdownMenuTrigger>
      <YaDropdownMenuContent>
        <YaDropdownMenuRadioGroup value={position} onValueChange={setPosition}>
          <YaDropdownMenuRadioItem value="top">Top</YaDropdownMenuRadioItem>
          <YaDropdownMenuRadioItem value="center">Center</YaDropdownMenuRadioItem>
          <YaDropdownMenuRadioItem value="bottom">Bottom</YaDropdownMenuRadioItem>
        </YaDropdownMenuRadioGroup>
      </YaDropdownMenuContent>
    </YaDropdownMenu>
  )
}

Groups and Labels

Organize items into logical groups with labels and separators.

<YaDropdownMenuContent>
  <YaDropdownMenuLabel>Categories</YaDropdownMenuLabel>
  <YaDropdownMenuSeparator />
  <YaDropdownMenuItem icon={<Folder />} description="All active projects">
    Projects
  </YaDropdownMenuItem>
  <YaDropdownMenuItem icon={<Folder />} description="Archived items">
    Archive
  </YaDropdownMenuItem>

  <YaDropdownMenuLabel>Time Period</YaDropdownMenuLabel>
  <YaDropdownMenuSeparator />
  <YaDropdownMenuItem>Last 7 days</YaDropdownMenuItem>
  <YaDropdownMenuItem>Last 30 days</YaDropdownMenuItem>
</YaDropdownMenuContent>

Create nested menus for hierarchical navigation.

import {
  YaDropdownMenu,
  YaDropdownMenuTrigger,
  YaDropdownMenuContent,
  YaDropdownMenuItem,
  YaDropdownMenuSub,
  YaDropdownMenuSubTrigger,
  YaDropdownMenuSubContent,
} from '@/components/ui/ya-dropdown-menu'
import { Folder } from 'lucide-react'

export default function SubmenuExample() {
  return (
    <YaDropdownMenu>
      <YaDropdownMenuTrigger asChild>
        <YaButton variant="secondary">Open Menu</YaButton>
      </YaDropdownMenuTrigger>
      <YaDropdownMenuContent>
        <YaDropdownMenuItem icon={<Folder className="size-[14px]" />}>
          New File
        </YaDropdownMenuItem>
        <YaDropdownMenuSub>
          <YaDropdownMenuSubTrigger
            icon={<Folder className="size-[14px]" />}
            description="Open recent files"
          >
            Recent Files
          </YaDropdownMenuSubTrigger>
          <YaDropdownMenuSubContent>
            <YaDropdownMenuItem icon={<Folder className="size-[14px]" />}>
              document.pdf
            </YaDropdownMenuItem>
            <YaDropdownMenuItem icon={<Folder className="size-[14px]" />}>
              report.xlsx
            </YaDropdownMenuItem>
          </YaDropdownMenuSubContent>
        </YaDropdownMenuSub>
        <YaDropdownMenuItem icon={<Folder className="size-[14px]" />}>
          Save
        </YaDropdownMenuItem>
      </YaDropdownMenuContent>
    </YaDropdownMenu>
  )
}

Disabled Items

Items can be disabled to prevent interaction.

<YaDropdownMenuItem>Edit</YaDropdownMenuItem>
<YaDropdownMenuItem>Duplicate</YaDropdownMenuItem>
<YaDropdownMenuItem disabled>Archive (unavailable)</YaDropdownMenuItem>
<YaDropdownMenuItem disabled>Delete (no permission)</YaDropdownMenuItem>

Examples

Context Menu Actions

<YaDropdownMenuContent>
  <YaDropdownMenuItem icon={<Edit className="size-[14px]" />}>Edit</YaDropdownMenuItem>
  <YaDropdownMenuItem icon={<Copy className="size-[14px]" />}>Duplicate</YaDropdownMenuItem>
  <YaDropdownMenuSeparator />
  <YaDropdownMenuItem icon={<Trash className="size-[14px]" />}>Delete</YaDropdownMenuItem>
</YaDropdownMenuContent>

User Account Menu

import { User, Settings, CreditCard, LogOut } from 'lucide-react'

<YaDropdownMenu>
  <YaDropdownMenuTrigger asChild>
    <YaButton variant="secondary" buttonType="icon">
      <User />
    </YaButton>
  </YaDropdownMenuTrigger>
  <YaDropdownMenuContent align="end">
    <YaDropdownMenuLabel>My Account</YaDropdownMenuLabel>
    <YaDropdownMenuSeparator />
    <YaDropdownMenuItem icon={<User className="size-[14px]" />}>Profile</YaDropdownMenuItem>
    <YaDropdownMenuItem icon={<CreditCard className="size-[14px]" />}>Billing</YaDropdownMenuItem>
    <YaDropdownMenuItem icon={<Settings className="size-[14px]" />}>Settings</YaDropdownMenuItem>
    <YaDropdownMenuSeparator />
    <YaDropdownMenuItem icon={<LogOut className="size-[14px]" />}>Log out</YaDropdownMenuItem>
  </YaDropdownMenuContent>
</YaDropdownMenu>

Props

YaDropdownMenu

PropTypeDefaultDescription
openboolean-Controlled open state
onOpenChange(open: boolean) => void-Callback when open state changes
defaultOpenbooleanfalseDefault open state (uncontrolled)
modalbooleantrueWhether the dropdown should be modal

YaDropdownMenuContent

PropTypeDefaultDescription
sideOffsetnumber4Distance from the trigger in pixels
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side of the trigger
align'start' | 'center' | 'end''start'Preferred alignment against the trigger
classNamestring-Additional CSS classes

YaDropdownMenuItem

PropTypeDefaultDescription
iconReact.ReactNode-Icon on the left side
descriptionstring-Secondary text below the label
selectedbooleanfalseShows a checkmark
insetbooleanfalseAdds left padding for alignment
disabledbooleanfalseDisables the item
onSelect() => void-Callback when selected

YaDropdownMenuCheckboxItem

PropTypeDefaultDescription
checkedboolean-Whether checked
onCheckedChange(checked: boolean) => void-Callback when checked changes
iconReact.ReactNode-Optional icon
descriptionstring-Secondary description

YaDropdownMenuRadioItem

PropTypeDefaultDescription
valuestringrequiredValue of the radio item
iconReact.ReactNode-Optional icon
descriptionstring-Secondary description

YaDropdownMenuSubTrigger

PropTypeDefaultDescription
iconReact.ReactNode-Icon on the left side
descriptionstring-Secondary description
insetbooleanfalseAdds left padding

YaDropdownMenuLabel

PropTypeDefaultDescription
insetbooleanfalseAdds left padding

Accessibility

Best Practices

DoDon't
Limit menu items to 7-10 optionsOverload with too many options
Use submenus for hierarchical contentNest more than 2 levels deep
Group related items with labelsMix unrelated actions together
Use checkbox for toggleable optionsUse checkbox for navigation
Use radio for mutually exclusive choicesMix checkboxes and radios in same group
Use clear action verbs (Edit, Delete)Use vague labels (OK, Click Here)
Add icons for better scannabilityUse icons inconsistently

TypeScript

import { type VariantProps } from 'class-variance-authority'
import {
  yaDropdownMenuContentVariants,
  yaDropdownMenuItemVariants,
} from '@/components/ui/ya-dropdown-menu'

type ContentVariants = VariantProps<typeof yaDropdownMenuContentVariants>
type ItemVariants = VariantProps<typeof yaDropdownMenuItemVariants>

On this page