Shadwire
Componentes

Popover

Um painel sobreposto, disparado por um botão, para exibir conteúdo rico.

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 popover --yes

O item popover do registry instala estes arquivos:

  • app/components/ui_component.rb
  • app/components/ui/popover_component.rb
  • app/components/ui/popover/trigger_component.rb
  • app/components/ui/popover/content_component.rb
  • app/components/ui/button_component.rb
  • app/helpers/ui/popover_helper.rb
  • app/helpers/ui/button_helper.rb
  • app/javascript/controllers/ui_popover_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-popover alterna o painel, move o foco para dentro dele ao abrir e o devolve ao gatilho ao fechar por Esc. Clique fora também fecha. O posicionamento usa apenas utilitários (side/align), sem floating-ui.

<%= ui_popover do %>
  <%= ui_popover_trigger(variant: :outline) { "Abrir" } %>
  <%= ui_popover_content do %>
    Conteúdo do popover.
  <% end %>
<% end %>

Ou renderize os componentes diretamente:

<%= render Ui::PopoverComponent.new do %>
  <%= render Ui::Popover::TriggerComponent.new do %>
    Abrir
  <% end %>
  <%= render Ui::Popover::ContentComponent.new(side: :bottom, align: :start) do %>
    Conteúdo
  <% end %>
<% end %>

Composição

Popover (data-controller="ui-popover", relative)
|-- Popover::Trigger (Button, aria-expanded)
`-- Popover::Content (absolute, side: + align:)

Exemplos

Padrão

Painel não-modal: abre no clique, foca o conteúdo e fecha por clique fora ou Esc.

<%= ui_popover do %>
  <%= ui_popover_trigger(variant: :outline) { "Abrir dimensões" } %>
  <%= ui_popover_content do %>
    <div class="grid gap-4">
      <div class="space-y-1">
        <h4 class="font-medium leading-none">Dimensões</h4>
        <p class="text-sm text-muted-foreground">Defina as dimensões da camada.</p>
      </div>

Alinhamento

align: :start, :center ou :end desloca o painel no eixo cruzado.

<% %i[start center end].each do |align| %>
  <%= ui_popover do %>
    <%= ui_popover_trigger(variant: :outline) { "align: #{align}" } %>
    <%= ui_popover_content(side: :bottom, align: align, class: "w-48") do %>
      <p class="text-sm">Alinhado a <strong><%= align %></strong> no eixo horizontal.</p>
    <% end %>
  <% end %>
<% end %>

Referência da API

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

Componente Argumento Padrão Descrição
Popover::Trigger variant, size :outline Button que abre/fecha; mantém aria-expanded.
Popover::Content side :bottom :top, :right, :bottom, :left.
Popover::Content align :center :start, :center, :end no eixo cruzado.