Dropdown menu
Um menu de ações e opções atrás de um botão, com grupos, submenus, itens de checkbox e de rádio e atalhos.
pnpm dlx shadcn@latest add https://hextaui.com/r/dropdown-menu.jsonAdiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.
Adicione os tokens de tema ao seu CSS global, se ainda não o fez.
Instale as dependências.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopie e cole o código a seguir no seu projeto.
components/ui/dropdown-menu.tsx Atualize os caminhos de importação para corresponder à configuração do seu projeto.
Área segura
Mover-se na diagonal de um gatilho de submenu em direção ao seu submenu cruza gatilhos vizinhos. A área segura mantém o submenu aberto enquanto o ponteiro se dirige a ele. Ative showSafeArea para vê-la ao vivo: o ponto fica verde dentro da área e vermelho onde o submenu trocaria.
Checkboxes
<DropdownMenuCheckboxItem /> alterna uma configuração e mantém o menu aberto, para que várias possam ser alteradas em sequência. A marca é desenhada e apagada em vez de surgir de repente.
Radio group
Envolva <DropdownMenuRadioItem /> em um <DropdownMenuRadioGroup /> para escolher uma opção. Um rótulo dentro do grupo dá nome a ele para os leitores de tela.
Marca à direita
Defina indicator="end" em itens de checkbox e radio para mostrar a marca depois do rótulo em vez de recuá-la, o que combina com seletores que têm uma descrição sob cada opção.
Estilo select
O menu nunca fica mais estreito que seu gatilho. Defina closeOnClick em itens radio quando escolher um também deve fechar o menu.
Ações de linha
Um menu atende todas as linhas. Crie um handle com createDropdownMenuHandle, passe-o a cada gatilho com um payload e leia o payload no menu. Delete passa a um alert dialog.
Controlado
Passe open e onOpenChange. O segundo argumento diz por que o menu mudou, como um toque no gatilho, em um item ou Escape. Itens com closeOnClick={false} o mantêm aberto.
Abrir ao passar o mouse
openOnHover no gatilho abre o menu após delay e o fecha após closeDelay. O clique e o teclado continuam funcionando, então usuários de toque e de teclado não ficam de fora.
Desabilitado
Um gatilho desativado nunca abre. Itens desativados continuam visíveis e são ignorados pelas teclas de seta.
Conteúdo longo
Os rótulos quebram de linha em vez de esticar o menu além de 20rem, strings sem quebra se partem em qualquer ponto e os atalhos permanecem na primeira linha.
Rolagem
Quando não há espaço para todos os itens, o menu rola dentro do viewport e o item destacado rola para a vista.
Dentro de uma sheet
O menu fica acima do sheet. Escape fecha primeiro o menu e depois o sheet.
Da direita para a esquerda
O menu, o chevron do submenu e o lado do submenu seguem a direção do gatilho. Os atalhos mantêm a ordem da esquerda para a direita.
| Tecla | Ação |
|---|---|
| EnterSpace↓ | No gatilho, abre o menu e destaca o primeiro item. |
| ↓ | Destaca o próximo item, voltando ao início no fim. |
| ↑ | Destaca o item anterior, voltando ao fim no início. |
| Home | Destaca o primeiro item. |
| End | Destaca o último item. |
| EnterSpace | Executa o item destacado. Itens de checkbox e radio alternam e mantêm o menu aberto. |
| → | Abre o submenu destacado e entra nele. ← em layouts da direita para a esquerda. |
| ← | Fecha o submenu atual e volta ao seu gatilho. → em layouts da direita para a esquerda. |
| Esc | Fecha o menu atual e devolve o foco ao seu gatilho. Em um submenu, apenas esse submenu fecha. |
| A–Z | Destaca o próximo item que começa com aquela letra. |
- O gatilho é anunciado como um botão de menu, e o foco volta a ele quando o menu fecha.
- Dê aos gatilhos só com ícone um
aria-label, como faz o exemplo de ações de linha. <DropdownMenuShortcut />é apenas um rótulo visual. Associe as teclas você mesmo.- Com movimento reduzido ativado, o menu aparece com fade, sem escala, e o piscar do item é ignorado.
Construído sobre o menu do Base UI. Cada parte aceita as props da primitiva que envolve.
| Prop | Tipo | Padrão |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
showSafeAreaDesenha a área segura do submenu enquanto o menu está aberto. Para depuração e demonstrações. | boolean | false |
onOpenChangedetails.reason informa o que causou a mudança. | (open: boolean, details) => void | – |
modalBloqueia a rolagem da página e os cliques externos enquanto aberto. | boolean | true |
loopFocusVolta ao início nas duas pontas das teclas de seta. | boolean | true |
handleConecta gatilhos desanexados a este menu. | DropdownMenuHandle<Payload> | – |
childrenUse a forma de função para ler o payload do gatilho que abriu o menu. | ReactNode | ({ payload }) => ReactNode | – |
disabled | boolean | false |
| Prop | Tipo | Padrão |
|---|---|---|
openOnHover | boolean | false |
delayMilissegundos antes de o hover abrir o menu. | number | 100 |
closeDelayMilissegundos antes de um menu aberto por hover fechar. | number | 0 |
handle | DropdownMenuHandle<Payload> | – |
payloadRepassado ao menu quando este gatilho o abre. | Payload | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-trigger" | Selecione o gatilho no CSS. |
data-popup-open | Presente enquanto o menu está aberto. |
data-pressed | Presente enquanto o gatilho está pressionado. |
data-disabled | Presente quando o gatilho está desativado. |
| Prop | Tipo | Padrão |
|---|---|---|
side | "top" | "bottom" | "left" | "right" | "inline-start" | "inline-end" | "bottom" |
align | "start" | "center" | "end" | "start" |
sideOffset | number | 4 |
alignOffset | number | 0 |
collisionPaddingEspaço mantido entre o menu e a borda do viewport. | number | Rect | 8 |
anchorPosiciona em relação a outro elemento em vez do gatilho. | Element | RefObject | VirtualElement | – |
sticky | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-content" | Seleciona o menu no CSS. |
data-open | Presente enquanto o menu está aberto. |
data-starting-style | Presente enquanto o menu anima a entrada. |
data-ending-style | Presente enquanto o menu anima a saída. |
data-side | O lado em que o menu se fixou após o tratamento de colisões. |
data-align | O alinhamento em que ele se fixou. |
data-chosen | Presente depois que um item é clicado, então o menu espera o piscar de confirmação do item antes de fechar. |
--anchor-width | A largura do gatilho. O menu tem pelo menos essa largura. |
--available-height | Espaço restante no viewport. Menus longos rolam dentro dele. |
--transform-origin | De onde a animação de escala cresce, ao lado do gatilho. |
| Prop | Tipo | Padrão |
|---|---|---|
variant | "default" | "destructive" | "default" |
insetRecua o item para alinhá-lo aos itens com checkbox. | boolean | false |
closeOnClick | boolean | true |
onClick | (event) => void | – |
labelTexto usado na busca por digitação quando os children não são texto simples. | string | – |
disabled | boolean | false |
renderRenderize um link com render={<a href="…" />}. | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-item" | Selecione itens no CSS. |
data-variant | A variante atual. |
data-highlighted | Presente enquanto o item está destacado pelo ponteiro ou pelo teclado. |
data-disabled | Presente quando o item está desabilitado. |
data-chosen | Presente no item que acabou de ser clicado, enquanto ele pisca. |
data-inset | Presente quando inset está definido. |
| Prop | Tipo | Padrão |
|---|---|---|
checked | boolean | – |
defaultChecked | boolean | false |
onCheckedChange | (checked: boolean, details) => void | – |
closeOnClick | boolean | false |
inset | boolean | false |
indicator | "start" | "end" | "start" |
disabled | boolean | false |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-checkbox-item" | Seleciona os itens com checkbox no CSS. |
data-checked | Presente quando marcado. |
data-unchecked | Presente quando não marcado. |
data-highlighted | Presente enquanto o item está destacado pelo ponteiro ou pelo teclado. |
data-disabled | Presente quando o item está desabilitado. |
data-chosen | Presente no item que acabou de ser clicado, enquanto ele pisca. |
data-inset | Presente quando inset está definido. |
| Prop | Tipo | Padrão |
|---|---|---|
value | Value | – |
defaultValue | Value | – |
onValueChange | (value: Value, details) => void | – |
disabled | boolean | false |
| Prop | Tipo | Padrão |
|---|---|---|
value | Value | – |
closeOnClick | boolean | false |
inset | boolean | false |
indicator | "start" | "end" | "start" |
disabled | boolean | false |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-radio-item" | Seleciona os itens radio no CSS. |
data-checked | Presente no item selecionado. |
data-unchecked | Presente nos outros itens. |
data-highlighted | Presente enquanto o item está destacado pelo ponteiro ou pelo teclado. |
data-disabled | Presente quando o item está desabilitado. |
data-chosen | Presente no item que acabou de ser clicado, enquanto ele pisca. |
data-inset | Presente quando inset está definido. |
Agrupa itens relacionados. Um <DropdownMenuLabel /> dentro dele se torna o nome acessível do grupo.
| Prop | Tipo | Padrão |
|---|---|---|
inset | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
Um divisor entre grupos, anunciado como separator.
| Prop | Tipo | Padrão |
|---|---|---|
dirOs atalhos mantêm a ordem das teclas em menus da direita para a esquerda. | "ltr" | "rtl" | "ltr" |
| Prop | Tipo | Padrão |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
closeParentOnEscFecha o menu inteiro, não apenas este submenu, com Escape. | boolean | false |
| Prop | Tipo | Padrão |
|---|---|---|
inset | boolean | false |
disabled | boolean | false |
delayMilissegundos antes de o hover abrir o submenu. | number | 100 |
closeDelay | number | 0 |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-sub-trigger" | Seleciona os gatilhos de submenu no CSS. |
data-popup-open | Presente enquanto o seu submenu está aberto. |
data-highlighted | Presente enquanto destacado. |
| Prop | Tipo | Padrão |
|---|---|---|
sideOffset | number | 0 |
alignOffset | number | -4 |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descrição |
|---|---|
data-slot="dropdown-menu-sub-content" | Seleciona os submenus no CSS. |
data-open | Presente enquanto o menu está aberto. |
data-starting-style | Presente enquanto o menu anima a entrada. |
data-ending-style | Presente enquanto o menu anima a saída. |
data-side | O lado em que o menu se fixou após o tratamento de colisões. |
data-align | O alinhamento em que ele se fixou. |
data-chosen | Presente depois que um item é clicado, então o menu espera o piscar de confirmação do item antes de fechar. |
--available-height | Espaço restante no viewport. Menus longos rolam dentro dele. |
--transform-origin | De onde a animação de escala cresce, ao lado do gatilho. |
- Alert dialogUm diálogo de confirmação para ações destrutivas ou importantes que aguarda trabalho assíncrono e vira um bottom sheet no celular.
- CommandUma lista pesquisável de ações, inline ou como paleta ⌘K, com páginas, atalhos e correspondências destacadas.
- Context menuUm menu de ações ao clicar com o botão direito ou pressionar e segurar, com submenus, itens de checkbox e de rádio e feedback de pressão no toque.
- DialogUma janela sobre a página para formulários e tarefas focadas, com cabeçalho e rodapé fixos, aninhamento e um bottom sheet com deslize no celular.
- DrawerUm painel que desliza a partir de qualquer borda e acompanha o seu dedo, com pontos de ancoragem, uma alça funcional e drawers aninhados que se empilham.
- Hover cardUm card de prévia que abre quando um link recebe hover ou foco, para conteúdo que usuários que enxergam podem conferir rapidamente.
Usado em blocos
Blocos que se baseiam em Dropdown menu.
- Prompt InputUm campo de conversa que começa como uma linha discreta, cresce até virar um card conforme você escreve e desce quando a conversa começa. Enter envia, de forma segura com entrada em japonês e chinês. Cole, solte ou escolha arquivos com prévias, progresso e nova tentativa. @ adiciona arquivos e / executa comandos a partir de um menu no cursor. Um seletor de modelo com teclas numéricas, um slider de esforço que ganha vida no Max, um anel de contexto, ditado com forma de onda ao vivo, chips de ferramentas, uma fila para mensagens digitadas enquanto uma resposta é transmitida e rascunhos que sobrevivem a um recarregamento.
- API keysA página de chaves de API de um produto de IA, como nos consoles da OpenAI e da Anthropic. Crie chaves com permissões restritas e uma expiração, veja o segredo uma única vez com uma cópia que confirma, revogue com desfazer, renomeie no próprio lugar, faça a rotação com um período de tolerância e veja o uso por chave.
- ArtifactO painel ao lado de um chat de IA que mostra o que o modelo criou. Páginas web, SVGs, documentos e código chegam em streaming ao vivo e depois passam para uma prévia isolada em sandbox, com versões que você pode comparar e restaurar, uma divisão redimensionável e um bottom sheet no celular.
- Chat SidebarA barra lateral de um app de chat. Logo, busca e Novo chat no topo, seus próprios links abaixo, chats fixados, projetos que se expandem para mostrar seus chats, recentes agrupados por dia e linhas com menus de hover e de clique direito, renomeação inline, exclusão com desfazer e estados de resposta ao vivo.