Capítulo 52 de 108

Dropdown Menu

Core Idea

Exibe um menu de ações/funções disparado por um botão trigger. É o componente mais completo da família de menus (compartilha padrão com Context Menu e Menubar). Built on Base UI Menu.

Key Concepts

  • DropdownMenuGroup: agrupa itens relacionados; combina com DropdownMenuLabel para título de seção.
  • DropdownMenuCheckboxItem: item toggle, controlado (checked/onCheckedChange); checked recebe boolean, callback recebe checked === true para normalizar.
  • DropdownMenuRadioGroup / DropdownMenuRadioItem: seleção exclusiva controlada (value/onValueChange).
  • DropdownMenuSub / DropdownMenuSubTrigger / DropdownMenuSubContent: submenu; DropdownMenuSubContent deve ser envolvido em DropdownMenuPortal (diferente do Context Menu, que dispensa portal explícito nos exemplos).
  • DropdownMenuShortcut: hint de atalho alinhado à direita do item.
  • variant="destructive": em DropdownMenuItem, para ações irreversíveis.
  • align: "start" | "center" | "end" em DropdownMenuContent; em RTL, inverter (dir === "rtl" ? "end" : "start").
  • Submenus podem ser aninhados em múltiplos níveis (visto no exemplo "Complex": File → Open Recent → More Projects).

Code Examples

<DropdownMenu>
  <DropdownMenuTrigger render={<Button variant="outline" />}>Open</DropdownMenuTrigger>
  <DropdownMenuContent className="w-40" align="start">
    <DropdownMenuGroup>
      <DropdownMenuLabel>My Account</DropdownMenuLabel>
      <DropdownMenuItem>
        Profile
        <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
      </DropdownMenuItem>
    </DropdownMenuGroup>
    <DropdownMenuSeparator />
    <DropdownMenuGroup>
      <DropdownMenuItem>Team</DropdownMenuItem>
      <DropdownMenuSub>
        <DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
        <DropdownMenuPortal>
          <DropdownMenuSubContent>
            <DropdownMenuItem>Email</DropdownMenuItem>
            <DropdownMenuItem>Message</DropdownMenuItem>
          </DropdownMenuSubContent>
        </DropdownMenuPortal>
      </DropdownMenuSub>
    </DropdownMenuGroup>
  </DropdownMenuContent>
</DropdownMenu>
  • O que demonstra: grupo com label+shortcut, separador, e submenu obrigatoriamente envolto em DropdownMenuPortal.
<DropdownMenuTrigger
  render={<Button variant="ghost" size="icon" className="rounded-full" />}
>
  <Avatar>
    <AvatarImage src="https://github.com/shadcn.png" alt="shadcn" />
    <AvatarFallback>LR</AvatarFallback>
  </Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">...</DropdownMenuContent>
  • O que demonstra: padrão "account switcher" com Avatar como trigger e align="end" (menu abre alinhado à direita, comum em headers).

Reference Tables

Composição:

DropdownMenu
├── DropdownMenuTrigger
└── DropdownMenuContent
    ├── DropdownMenuGroup (Label + Items)
    ├── DropdownMenuSeparator
    ├── DropdownMenuGroup (CheckboxItems)
    ├── DropdownMenuSeparator
    ├── DropdownMenuGroup (RadioGroup)
    └── DropdownMenuSub
        ├── DropdownMenuSubTrigger
        └── DropdownMenuSubContent (dentro de DropdownMenuPortal)

Anti-patterns

  • Omitir DropdownMenuPortal ao redor de DropdownMenuSubContent: os exemplos oficiais sempre envolvem submenus em portal explícito, diferente do padrão simplificado do Context Menu.
  • Passar checked direto sem normalizar em onCheckedChange: usar checked === true no callback evita estados indeterminados incorretos.

Key Takeaways

  1. DropdownMenuSubContent deve estar dentro de DropdownMenuPortal (padrão consistente em todos os exemplos oficiais, inclusive aninhados em múltiplos níveis).
  2. align="end" é o padrão para triggers de avatar/ícone no canto direito de um header.
  3. Compartilha praticamente toda a API com Context Menu (Group, CheckboxItem, RadioGroup, Sub, Shortcut, variant="destructive") — a diferença é só o gatilho (clique vs. clique-direito).
  4. Submenus suportam aninhamento profundo (3+ níveis) sem limitação especial, como no exemplo "Complex" (File → Open Recent → More Projects).
  5. Instalação manual requer npm install @base-ui/react.

Connects To

  • Context Menu: mesma família de subcomponentes; trocar apenas o prefixo DropdownContext e a forma de disparo.
  • Menubar: reaproveita os mesmos conceitos (Group, Radio, Checkbox, Sub) numa barra de menus sempre visível.
  • Avatar: usado como trigger no padrão "account switcher".