Tessina UI
ConfiguratorGitHubIntroduction
InstallationUsageTheming
ComponentsAccordionAction SheetAlertAlertDialogArea ChartAspectRatioAvatarBadgeBannerBar ChartBottom NavBreadcrumbButtonButtonGroupCalendarCardCarouselChartChatBubbleCheckboxChipCodeBlockCollapsibleColor PickerComboboxCommandContainerContextMenuDate PickerDividerDrawerDropdown MenuEmptyStateFABFieldFieldsetFile UploadFile Upload 2FlexFormGridHoverCardIconButtonLabelLine ChartLinkMenubarMeterModalNavigation MenuNumberFieldOTP InputPaginationPie ChartPopoverProgressPromptInputRadar ChartRadial ChartRadioRatingScroll AreaSearchSegmentedControlSelectShortcutSidebarSkeletonSliderSpacerSpinnerSplit ButtonStackStatusStepperSurfaceSwitchTableTabsTextareaTime PickerToastToggleButtonToggleGroupToolbarTooltipTop Header DesktopTop Header Mobile
Contributing
Components

Dropdown Menu

A contextual menu that opens from a trigger, built on Radix UI. Supports grouped items, leading/trailing icons, keyboard shortcuts, descriptions, submenus, checkboxes, radio groups, and full RTL layout.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
} from "@tessinaui/ui";
import { Button } from "@tessinaui/ui";
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">Open</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent>
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Profile</DropdownMenuItem>
    <DropdownMenuItem>Settings</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem intent="error">Sign out</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Examples

Default

A basic menu with a label, items, and a destructive sign-out action.

Sizes

Five sizes from xs to xl, each scaling padding, text, and icons.

With Icons & Shortcuts

Items with leading icons and keyboard shortcut badges.

Checkbox Items

Toggleable checkbox items that hold their own checked state.

Radio Group

Mutually exclusive options grouped in a radio group.

Submenu

Nested submenus for grouping related actions behind a trigger.

API Reference

DropdownMenuContent

The panel that contains menu items. Pass size and width here — they propagate automatically to all child items via React context.

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Controls panel padding, item padding, text size, and icon size
width"narrow" | "default" | "wide""default"Controls minimum width of the panel
side"top" | "right" | "bottom" | "left""bottom"Preferred side to open on (Radix)
align"start" | "center" | "end""start"Alignment relative to the trigger (Radix)
sideOffsetnumber4Gap in px between trigger and panel (Radix)
dir"ltr" | "rtl"—Text direction — flips icon order and submenu side

All other Radix Content props are forwarded.

DropdownMenuItem

PropTypeDefaultDescription
leadingIconReact.ReactNode—Icon on the start side
trailingIconReact.ReactNode—Icon on the end side
shortcutstring—Keyboard shortcut badge (e.g. "⌘K")
descriptionstring—Secondary description line below the label
intent"none" | "error""none""error" applies destructive (red) styling to text and icons
insetbooleanfalseAdds start padding for alignment when some items have icons and others don't
disabledbooleanfalseDisables the item and mutes its appearance

All native Radix Item props are forwarded.

DropdownMenuLabel

Section heading inside the menu. Automatically sized to match the content size.

PropTypeDefaultDescription
insetbooleanfalseAdds start padding to align with inset items

DropdownMenuSeparator

Horizontal divider between groups. No props needed.

DropdownMenuShortcut

Standalone keyboard badge. Used internally by DropdownMenuItem but can be composed manually.

<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>

DropdownMenuSub / SubTrigger / SubContent

Three-part pattern for nested submenus:

<DropdownMenuSub>
  <DropdownMenuSubTrigger leadingIcon={<Share />}>Share</DropdownMenuSubTrigger>
  <DropdownMenuSubContent>
    <DropdownMenuItem>Email</DropdownMenuItem>
    <DropdownMenuItem>Copy link</DropdownMenuItem>
  </DropdownMenuSubContent>
</DropdownMenuSub>

DropdownMenuSubTrigger accepts leadingIcon and inset. DropdownMenuSubContent inherits size from parent context.

DropdownMenuCheckboxItem

Checkbox-style item that maintains checked state:

const [checked, setChecked] = useState(false);

<DropdownMenuCheckboxItem checked={checked} onCheckedChange={setChecked}>
  Show toolbar
</DropdownMenuCheckboxItem>

DropdownMenuRadioGroup / RadioItem

Radio-group for mutually exclusive selection:

const [theme, setTheme] = useState("system");

<DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
  <DropdownMenuRadioItem value="light">Light</DropdownMenuRadioItem>
  <DropdownMenuRadioItem value="dark">Dark</DropdownMenuRadioItem>
  <DropdownMenuRadioItem value="system">System</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>

Sizes

All five sizes scale item padding, text size, icon size, and panel padding proportionally. Pass size once to DropdownMenuContent:

<DropdownMenuContent size="sm">
  <DropdownMenuItem>Profile</DropdownMenuItem>
</DropdownMenuContent>

Width Variants

{/* Compact narrow panel */}
<DropdownMenuContent width="narrow">...</DropdownMenuContent>

{/* Default width (min-w-[12rem]) */}
<DropdownMenuContent width="default">...</DropdownMenuContent>

{/* Wide panel — useful for items with descriptions */}
<DropdownMenuContent width="wide">...</DropdownMenuContent>

With Icons, Shortcut & Description

<DropdownMenuItem
  leadingIcon={<Settings />}
  shortcut="⌘,"
  description="Manage your preferences"
>
  Settings
</DropdownMenuItem>

Destructive Items

<DropdownMenuItem intent="error" leadingIcon={<Trash />} shortcut="⌫">
  Delete
</DropdownMenuItem>

RTL

Pass dir="rtl" to DropdownMenuContent. The layout, icon positions, and submenu open direction all flip automatically:

<DropdownMenuContent dir="rtl">
  <DropdownMenuItem leadingIcon={<User />}>الملف الشخصي</DropdownMenuItem>
</DropdownMenuContent>

Accessibility

  • Built on Radix UI @radix-ui/react-dropdown-menu — full keyboard navigation out of the box
  • Arrow keys move focus between items; Enter/Space activates; Escape closes
  • Tab dismisses the menu and returns focus to the trigger
  • Each item is a focusable [role="menuitem"]
  • Disabled items have [data-disabled] and pointer-events-none
  • Color contrast: all intent states meet WCAG 2.1 AA
  • Submenus open on ArrowRight (LTR) / ArrowLeft (RTL)

Drawer

An accessible slide-in panel built on Base UI Dialog. Compound component pattern with Header, Body, Footer, Title, and Description. Four sides (right, left, top, bottom). Five sizes. Five corner-rounding options. Auto-stacking footer for sheets. LTR and RTL support.

EmptyState

Centered surface for "no data here" — empty lists, search results, tables, dashboards, inboxes, 404s, first-run / onboarding moments. Three variants, four sizes, six intents tinting the icon tile, primary + secondary actions, optional footer, LTR/RTL.

On this page

PlaygroundInstallationUsageExamplesDefaultSizesWith Icons & ShortcutsCheckbox ItemsRadio GroupSubmenuAPI ReferenceDropdownMenuContentDropdownMenuItemDropdownMenuLabelDropdownMenuSeparatorDropdownMenuShortcutDropdownMenuSub / SubTrigger / SubContentDropdownMenuCheckboxItemDropdownMenuRadioGroup / RadioItemSizesWidth VariantsWith Icons, Shortcut & DescriptionDestructive ItemsRTLAccessibility