Dropdown
Dropdown mantém um conjunto curto de ações ligado a um controle. Escolha-o para comandos no contexto atual; escolha CommandPalette quando as pessoas precisarem buscar no produto inteiro, de qualquer lugar.
Exemplos
Ações agrupadas
Rótulos e separadores revelam a estrutura de um conjunto de comandos antes de alguém ler cada
item. Marque como danger apenas a ação que altera ou remove dados.
Menu alinhado ao fim
align="end" mantém a borda direita deste menu junto ao gatilho. defaultOpen inicia um menu
aberto para demos visuais; deixe-o de fora de exemplos e fluxos normais da aplicação.
Quando usar
Use Dropdown para uma lista pequena e contextual de comandos que não precisa permanecer visível.
Prefira outro componente quando:
- A pessoa escolhe o workspace atual — use WorkspaceSwitcher, um listbox que informa a seleção.
- A pessoa precisa encontrar um comando em todo o produto — use CommandPalette e seu índice buscável.
- A pessoa alterna entre visualizações pares — use Tabs, que representa visualizações, não ações.
Acessibilidade
- O elemento que você passa em
triggervira o gatilho: ele receberole="button", a parada de tabulação,aria-haspopup="menu",aria-expandedearia-controls, e nenhum embrulhador é criado em volta dele. Assim umButtoncomo gatilho é um controle com uma parada de Tab, e o elemento que a pessoa foca é o que anuncia que abre um menu. Só um gatilho de texto puro ganha um span próprio. - Props que já estão no seu elemento vencem a fusão, então um gatilho que carrega o próprio
aria-label— um botão só de ícone, por exemplo — mantém esse nome. - O popup é um
role="menu"; os comandos sãorole="menuitem". Enter, Espaço e ArrowDown o abrem no primeiro comando, enquanto ArrowUp o abre no último. - Dentro do menu, ArrowDown e ArrowUp dão a volta, Home e End vão às pontas, Escape fecha e devolve o foco ao gatilho, e Tab fecha sem bloquear a navegação sequencial normal.
- O foco vai para elementos DOM
menuitemreais, diferente do descendente ativo virtual de CommandPalette. Perto da borda inferior de um celular, o popup vira para cima em vez de rolar a página.
API e código
| Nome | Tipo | Obrigatória | Descrição |
|---|---|---|---|
trigger | ReactNode | Obrigatória | Content that opens the action menu — a Button, IconButton, Avatar, icon or plain text. When it is an element, it receives the trigger semantics itself (role, tab stop, and the menu ARIA) instead of being wrapped, so one control is one tab stop. |
items | DropdownItem[] | Obrigatória | Commands, separators, and labels rendered by the menu. |
align | 'start' | 'end' | — | Popup alignment. Default: `"start"`. |
defaultOpen | boolean | — | Whether the menu starts open. Useful for demos. |
<Dropdown
align="end"
trigger={<Button variant="secondary">Ações do projeto</Button>}
items={[
{ type: 'label', label: 'Projeto' },
{ label: 'Renomear projeto' },
{ type: 'separator' },
{ label: 'Arquivar projeto', danger: true },
]}
/>x-data="lyraDropdown({ … })"
| Opção | Tipo | Obrigatória | Descrição |
|---|---|---|---|
defaultOpen | boolean | — | Whether the menu starts open. Default: `false`. |
align | 'start' | 'end' | — | Popup alignment. Default: `"start"`. |
A estrutura abaixo é o HTML puro: ela vem inteira no markup servido e fica inerte até o Alpine
bootar. Acrescentar o x-data e os três nomes de x-bind é toda a diferença entre um menu estático
e um menu que funciona.
<div class="lyra-dropdown" x-data="lyraDropdown({ align: 'end' })">
<span
class="lyra-btn lyra-btn--secondary lyra-btn--md lyra-dropdown__trigger"
role="button"
tabindex="0"
aria-haspopup="menu"
aria-expanded="false"
x-bind="trigger"
>
Ações do projeto
</span>
<div class="lyra-menu lyra-menu--end" role="menu" x-bind="menu" x-cloak>
<span class="lyra-menu__label">Projeto</span>
<button class="lyra-menu__item" type="button" role="menuitem" x-bind="item">
Renomear projeto
</button>
<hr class="lyra-menu__sep" />
<button
class="lyra-menu__item lyra-menu__item--danger"
type="button"
role="menuitem"
x-bind="item"
>
Arquivar projeto
</button>
</div>
</div>Sem Alpine, um elemento continua sendo o gatilho. Ponha a semântica de menu no próprio controle — um span embrulhando um botão daria duas paradas de Tab para a mesma afordância:
<div class="lyra-dropdown">
<button
class="lyra-btn lyra-btn--secondary lyra-btn--md lyra-dropdown__trigger"
type="button"
aria-haspopup="menu"
aria-expanded="true"
aria-controls="project-actions"
>
Ações do projeto
</button>
<div class="lyra-menu lyra-menu--start" id="project-actions" role="menu">
<span class="lyra-menu__label">Projeto</span>
<button class="lyra-menu__item" type="button" role="menuitem">Renomear projeto</button>
<hr class="lyra-menu__sep" />
<button class="lyra-menu__item lyra-menu__item--danger" type="button" role="menuitem">
Arquivar projeto
</button>
</div>
</div><lyra:dropdown> Gerado do lyra-ds/blade v0.10.0.
O comportamento vem de lyraDropdown() — instale @lyra-ds/alpine e veja a aba HTML + Alpine.
| Prop | Padrão | Obrigatória | Valores de exemplo |
|---|---|---|---|
items | — | Obrigatória | — |
align | 'start' | — | — |
defaultOpen | false | — | — |
<lyra:dropdown align="end" :items="[
['type' => 'label', 'label' => 'Project'],
['label' => 'Rename project'],
['type' => 'separator'],
['label' => 'Archive project', 'danger' => true],
]">
<x-slot:trigger>Project actions</x-slot:trigger>
</lyra:dropdown>