Shadwire
Componentes

Sheet

Estende o Dialog para exibir conteúdo complementar deslizando de uma borda da tela.

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

O item sheet do registry instala estes arquivos:

  • app/components/ui_component.rb
  • app/components/ui/sheet_component.rb
  • app/components/ui/sheet/trigger_component.rb
  • app/components/ui/sheet/content_component.rb
  • app/components/ui/sheet/header_component.rb
  • app/components/ui/sheet/footer_component.rb
  • app/components/ui/sheet/title_component.rb
  • app/components/ui/sheet/description_component.rb
  • app/components/ui/sheet/close_component.rb
  • app/components/ui/button_component.rb
  • app/components/ui/icon_component.rb
  • app/helpers/ui/sheet_helper.rb
  • app/helpers/ui/button_helper.rb
  • app/helpers/ui/icon_helper.rb
  • app/javascript/controllers/ui_dialog_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

Mesmo contrato do Dialog (elemento <dialog> + controller ui-dialog), com o painel ancorado em uma borda via side:.

<%= ui_sheet do %>
  <%= ui_sheet_trigger(variant: :outline) { "Abrir" } %>
  <%= ui_sheet_content(side: :right) do %>
    <%= ui_sheet_header do %>
      <%= ui_sheet_title { "Título" } %>
      <%= ui_sheet_description { "Descrição do painel." } %>
    <% end %>
    <%= ui_sheet_footer do %>

Ou renderize os componentes diretamente:

<%= render Ui::SheetComponent.new do %>
  <%= render Ui::Sheet::TriggerComponent.new do %>
    Abrir
  <% end %>
  <%= render Ui::Sheet::ContentComponent.new(side: :left) do %>
    <%= render Ui::Sheet::TitleComponent.new do %>
      Título
    <% end %>

Composição

Sheet (ui-dialog)
|-- Sheet::Trigger (Button)
`-- Sheet::Content (<dialog> ancorado em uma borda, side:)
    |-- Sheet::Header > Sheet::Title + Sheet::Description
    `-- Sheet::Footer > Sheet::Close (Button)

Exemplos

Padrão

Um painel que desliza da direita, com formulário e footer.

Editar perfil

Faça alterações no seu perfil e salve quando terminar.

<%= ui_sheet do %>
  <%= ui_sheet_trigger(variant: :outline) { "Abrir sheet" } %>
  <%= ui_sheet_content do %>
    <%= ui_sheet_header do %>
      <%= ui_sheet_title { "Editar perfil" } %>
      <%= ui_sheet_description { "Faça alterações no seu perfil e salve quando terminar." } %>
    <% end %>
    <div class="grid gap-4 px-4">

Os quatro lados

side: :right, :left, :top ou :bottom controla a borda de origem e a animação.

Sheet: direita

Este painel desliza do lado "right".

Sheet: esquerda

Este painel desliza do lado "left".

Sheet: topo

Este painel desliza do lado "top".

Sheet: base

Este painel desliza do lado "bottom".

<% { right: "Direita", left: "Esquerda", top: "Topo", bottom: "Base" }.each do |side, label| %>
  <%= ui_sheet do %>
    <%= ui_sheet_trigger(variant: :outline) { label } %>
    <%= ui_sheet_content(side: side) do %>
      <%= ui_sheet_header do %>
        <%= ui_sheet_title { "Sheet: #{label.downcase}" } %>
        <%= ui_sheet_description { "Este painel desliza do lado \"#{side}\"." } %>
      <% end %>

Referência da API

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

Componente Argumento Padrão Descrição
Sheet close_on_backdrop true Fecha ao clicar fora do painel.
Sheet::Content side :right :right, :left, :top, :bottom — emite data-side.
Sheet::Content show_close_button true Renderiza o botão X no canto superior direito.
Sheet::Trigger / Sheet::Close variant, size :default / :outline Encapsulam Ui::ButtonComponent.