Toggle
A two-state button that can be pressed on or off.
Installation
Included in poetry-ui — available as
poetry_toggle
the moment you've installed Poetry,
with no per-component step. To own the source and edit it, copy it into your app:
bin/rails g poetry:add toggle
Default
<%# Upstream's toggle-demo: a small outline bookmark toggle whose ICON
fills when pressed - the icon reads the root's group/toggle marker
(group-aria-pressed/toggle:fill-foreground). label: stays
state-invariant per APG. %>
<%= poetry_toggle(label: "Toggle bookmark", size: :sm, variant: :outline) do %>
<%= poetry_icon(name: :bookmark, class: "group-aria-pressed/toggle:fill-foreground") %>
Bookmark
<% end %>
Outline
<%# Upstream's toggle-outline pair: visible text is the accessible name. %>
<div class="flex flex-wrap items-center gap-2">
<%= poetry_toggle(variant: :outline, label: "Toggle italic") do %>
<%= poetry_icon(name: :italic) %>
Italic
<% end %>
<%= poetry_toggle(variant: :outline, label: "Toggle bold") do %>
<%= poetry_icon(name: :bold) %>
Bold
<% end %>
</div>
Sizes
<div class="flex flex-wrap items-center gap-2">
<%= poetry_toggle(size: :sm, variant: :outline, label: "Italic") do %>
<%= poetry_icon(name: :italic) %>
<% end %>
<%= poetry_toggle(variant: :outline, label: "Italic") do %>
<%= poetry_icon(name: :italic) %>
<% end %>
<%= poetry_toggle(size: :lg, variant: :outline, label: "Italic") do %>
<%= poetry_icon(name: :italic) %>
<% end %>
</div>
States
<%# aria-pressed carries the state - the label stays "Bold" whether
pressed or not. %>
<div class="flex flex-wrap items-center gap-2">
<%= poetry_toggle(pressed: true, label: "Bold") do %>
<%= poetry_icon(name: :bold) %>
<% end %>
<%= poetry_toggle(disabled: true, variant: :outline, label: "Underline") do %>
<%= poetry_icon(name: :underline) %>
<% end %>
<%= poetry_toggle(disabled: true, pressed: true, label: "Bold") do %>
<%= poetry_icon(name: :bold) %>
<% end %>
</div>
With text
<%# Upstream's toggle-text: the DEFAULT variant with icon + text
(visible text is the accessible name - no label: needed). %>
<%= poetry_toggle do %>
<%= poetry_icon(name: :italic) %>
Italic
<% end %>
API
Poetry::Ui::Toggle::Component — options are
constructor keywords (the poetry_* helper forwards them);
slots are composed inside the block. Generated from the gem's source documentation.
| Option | Type | Details | Description |
|---|---|---|---|
| size: | Symbol | one of: default, sm, lg; defaults to :default |
The control's size axis. |
| variant: | Symbol | one of: default, outline; defaults to :default |
The visual treatment; :outline adds a border for standalone use. |
| disabled: | Boolean | defaults to false |
Disables the control and forwards to the native button. |
| label: | String | REQUIRED when icon-only; must be state-INVARIANT (APG: aria-pressed carries the state - a flipping name makes SRs announce nonsense). | |
| pressed: | Boolean | defaults to false |
The server-rendered pressed state. |
Styling
Every part carries a stable data-slot attribute — target
[data-slot=…] from your own CSS to restyle it. State rides
data attributes on the parts below. This contract is verified against rendered DOM in CI.
| Part | Description |
|---|---|
| [data-slot=toggle] | The pressed-state <button> - the whole component; aria-pressed carries the state and the controller flips both together |
State attributes
| Part | Attribute | Condition | Values |
|---|---|---|---|
| toggle | data-pressed | pressed (bare presence boolean - absent when unpressed, never data-pressed=false) | — |
| toggle | data-disabled | disabled (rendered alongside native disabled for styling-hook parity) | — |
| toggle | data-variant | the visual variant | default · outline |
| toggle | data-size | the size | default · sm · lg |
Wiring
The Stimulus surface each element carries — declared in the component, verified against rendered DOM in CI. Bare actions fire on the element's default event.
| Element | Controller | Wiring |
|---|---|---|
| root | poetry--core--pressed | registers · toggle on click |