Shadwire
Componentes

Dropdown Menu

Um menu de ações ou opções disparado por um botão.

Instalação

O Shadwire segue o modelo open-code do shadcn/ui: o código-fonte do componente é copiado para a sua aplicação e passa a ser seu. Instale com a CLI:

shadwire add dropdown-menu --yes

O item dropdown-menu do registry instala estes arquivos:

  • app/components/ui_component.rb
  • app/components/ui/dropdown_menu_component.rb
  • app/components/ui/dropdown_menu/trigger_component.rb
  • app/components/ui/dropdown_menu/content_component.rb
  • app/components/ui/dropdown_menu/item_component.rb
  • app/components/ui/dropdown_menu/label_component.rb
  • app/components/ui/dropdown_menu/separator_component.rb
  • app/components/ui/dropdown_menu/group_component.rb
  • app/components/ui/dropdown_menu/shortcut_component.rb
  • app/components/ui/button_component.rb
  • app/helpers/ui/dropdown_menu_helper.rb
  • app/helpers/ui/button_helper.rb
  • app/javascript/controllers/ui_dropdown_menu_controller.js
  • vendor/shadwire/shadwire.css

Este componente usa Stimulus: a aplicação precisa de importmap-rails e stimulus-rails com carregamento automático de controllers.

Ainda não instalou a CLI? gem install shadwire e depois shadwire init.

Uso

O controller ui-dropdown-menu implementa o padrão WAI-ARIA de menu: foco rotativo entre os itens, / com wrap, Home/End, busca por digitação (typeahead) e fechamento por Esc, Tab ou clique fora.

<%= ui_dropdown_menu do %>
  <%= ui_dropdown_menu_trigger(variant: :outline) { "Abrir" } %>
  <%= ui_dropdown_menu_content do %>
    <%= ui_dropdown_menu_label { "Minha conta" } %>
    <%= ui_dropdown_menu_separator %>
    <%= ui_dropdown_menu_item do %>
      Perfil
      <%= ui_dropdown_menu_shortcut { "⇧⌘P" } %>

Ou renderize os componentes diretamente:

<%= render Ui::DropdownMenuComponent.new do %>
  <%= render Ui::DropdownMenu::TriggerComponent.new do %>
    Abrir
  <% end %>
  <%= render Ui::DropdownMenu::ContentComponent.new do %>
    <%= render Ui::DropdownMenu::ItemComponent.new(variant: :destructive) do %>
      Excluir
    <% end %>

Composição

DropdownMenu (data-controller="ui-dropdown-menu")
|-- DropdownMenu::Trigger (Button, aria-haspopup="menu")
`-- DropdownMenu::Content (role="menu")
    |-- DropdownMenu::Label
    |-- DropdownMenu::Separator
    |-- DropdownMenu::Group
    |   `-- DropdownMenu::Item (button/link) > DropdownMenu::Shortcut
    `-- DropdownMenu::Item (variant: :destructive)

Exemplos

Padrão

Label, grupos, itens com atalhos. Setas navegam, typeahead busca por prefixo, Esc fecha.

<%= ui_dropdown_menu do %>
  <%= ui_dropdown_menu_trigger(variant: :outline) { "Abrir" } %>
  <%= ui_dropdown_menu_content(class: "w-56") do %>
    <%= ui_dropdown_menu_label { "Minha conta" } %>
    <%= ui_dropdown_menu_separator %>
    <%= ui_dropdown_menu_group do %>
      <%= ui_dropdown_menu_item do %>
        Perfil

Inset, links e destrutivo

inset: alinha com itens que têm ícone; tag: :a vira link; variant: :destructive destaca ações perigosas.

<%= ui_dropdown_menu do %>
  <%= ui_dropdown_menu_trigger(variant: :outline) { "Ações" } %>
  <%= ui_dropdown_menu_content(class: "w-56") do %>
    <%= ui_dropdown_menu_label(inset: true) { "Aplicação" } %>
    <%= ui_dropdown_menu_item(inset: true) { "Duplicar" } %>
    <%= ui_dropdown_menu_item(disabled: true, inset: true) { "Indisponível" } %>
    <%= ui_dropdown_menu_separator %>
    <%= ui_dropdown_menu_item(tag: :a, href: "#docs", inset: true) { "Documentação" } %>

Referência da API

Todas as partes aceitam class / class_name e **attrs.

Componente Argumento Padrão Descrição
DropdownMenu::Content side, align :bottom, :start Posicionamento do menu por utilitários.
DropdownMenu::Item variant :default :destructive destaca ações perigosas.
DropdownMenu::Item inset, disabled false Recuo para alinhar com ícones; desabilitado é pulado na navegação.
DropdownMenu::Item tag :button Use :a com href para itens de link.