Toggle Group

A set of two-state buttons that can be toggled on or off.

Stimulus: shadcn--toggle-group
toggle-group/default
<%= render Shadcn::ToggleGroup.new(type: :multiple) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
<% end %>

Installation

Add the component to your project:

rails generate shadcn:add toggle_group

Usage

<%= render Shadcn::ToggleGroup.new(type: :multiple) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
<% end %>

Examples

Single Selection

Only one item can be selected at a time.

<%= render Shadcn::ToggleGroupComponent.new(type: :single) do |group| %>
  <% group.with_item(value: "left", aria_label: "Align left") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "center", aria_label: "Align center") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "right", aria_label: "Align right") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
  <% end %>
<% end %>

Multiple Selection

Multiple items can be selected simultaneously.

<%= render Shadcn::ToggleGroupComponent.new(type: :multiple) do |group| %>
  <% group.with_item(value: "bold", aria_label: "Toggle bold") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"/></svg>
  <% end %>
  <% group.with_item(value: "italic", aria_label: "Toggle italic") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
  <% end %>
  <% group.with_item(value: "underline", aria_label: "Toggle underline") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" x2="20" y1="20" y2="20"/></svg>
  <% end %>
<% end %>

Outline Variant

<%= render Shadcn::ToggleGroupComponent.new(type: :single, variant: :outline) do |group| %>
  <% group.with_item(value: "left", aria_label: "Align left") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "center", aria_label: "Align center") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "right", aria_label: "Align right") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
  <% end %>
<% end %>

Sizes

Small
Large
<div class="flex flex-col gap-4">
  <div class="flex items-center gap-4">
    <span class="w-16 text-sm text-muted-foreground">Small</span>
    <%= render Shadcn::ToggleGroupComponent.new(type: :single, size: :sm) do |group| %>
      <% group.with_item(value: "left", aria_label: "Align left") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
      <% end %>
      <% group.with_item(value: "center", aria_label: "Align center") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
      <% end %>
      <% group.with_item(value: "right", aria_label: "Align right") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
      <% end %>
    <% end %>
  </div>
  <div class="flex items-center gap-4">
    <span class="w-16 text-sm text-muted-foreground">Large</span>
    <%= render Shadcn::ToggleGroupComponent.new(type: :single, size: :lg) do |group| %>
      <% group.with_item(value: "left", aria_label: "Align left") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
      <% end %>
      <% group.with_item(value: "center", aria_label: "Align center") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
      <% end %>
      <% group.with_item(value: "right", aria_label: "Align right") do %>
        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
      <% end %>
    <% end %>
  </div>
</div>

Default Value

Set pressed: true on an item to make it selected by default.

<%= render Shadcn::ToggleGroupComponent.new(type: :single, value: "center") do |group| %>
  <% group.with_item(value: "left", aria_label: "Align left") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "center", pressed: true, aria_label: "Align center") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "right", aria_label: "Align right") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
  <% end %>
<% end %>

Disabled Item

Individual items can be disabled.

<%= render Shadcn::ToggleGroupComponent.new(type: :single) do |group| %>
  <% group.with_item(value: "left", aria_label: "Align left") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="15" x2="3" y1="12" y2="12"/><line x1="17" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "center", disabled: true, aria_label: "Align center (disabled)") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="18" x2="6" y1="12" y2="12"/><line x1="21" x2="3" y1="18" y2="18"/></svg>
  <% end %>
  <% group.with_item(value: "right", aria_label: "Align right") do %>
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="9" y1="12" y2="12"/><line x1="21" x2="7" y1="18" y2="18"/></svg>
  <% end %>
<% end %>

Small Size

toggle-group/small
<%= render Shadcn::ToggleGroup.new(type: :multiple, size: :sm) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
<% end %>

Large Size

toggle-group/large
<%= render Shadcn::ToggleGroup.new(type: :multiple, size: :lg) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
<% end %>

Disabled Items

toggle-group/disabled
<%= render Shadcn::ToggleGroup.new(type: :multiple, disabled: true) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
<% end %>

All Variants

toggle-group/variants
<div class="flex flex-wrap gap-4">
  <%= render Shadcn::ToggleGroup.new(type: :single, variant: :default) do |group| %>
    <% group.with_item(value: "left", aria_label: "Left") { "Left" } %>
    <% group.with_item(value: "center", aria_label: "Center") { "Center" } %>
    <% group.with_item(value: "right", aria_label: "Right") { "Right" } %>
  <% end %>
  
  <%= render Shadcn::ToggleGroup.new(type: :single, variant: :outline) do |group| %>
    <% group.with_item(value: "left", aria_label: "Left") { "Left" } %>
    <% group.with_item(value: "center", aria_label: "Center") { "Center" } %>
    <% group.with_item(value: "right", aria_label: "Right") { "Right" } %>
  <% end %>
</div>

With Text Content

toggle-group/with_text
<%= render(Shadcn::ToggleGroupComponent.new(type: :single, variant: :outline)) do |group| %>
  <% group.with_item(value: "a") { "A" } %>
  <% group.with_item(value: "b") { "B" } %>
  <% group.with_item(value: "c") { "C" } %>
<% end %>

Multiple With Values

toggle-group/multiple_with_values
<%= render Shadcn::ToggleGroup.new(type: :multiple, value: %w[bold italic]) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
  <% group.with_item(value: "strikethrough", aria_label: "S") { "S" } %>
<% end %>

Text Formatting Toolbar

toggle-group/text_formatting_toolbar
<%= render Shadcn::ToggleGroup.new(type: :multiple) do |group| %>
  <% group.with_item(value: "bold", aria_label: "B") { "B" } %>
  <% group.with_item(value: "italic", aria_label: "I") { "I" } %>
  <% group.with_item(value: "underline", aria_label: "U") { "U" } %>
  <% group.with_item(value: "strikethrough", aria_label: "S") { "S" } %>
<% end %>

API Reference

ToggleGroupComponent

Prop Type Default Description
type Symbol :single Selection mode (:single or :multiple)
variant Symbol :default Visual style variant (:default, :outline)
size Symbol :default Size of toggles (:sm, :default, :lg)
value String/Array nil Currently selected value(s)
name String nil Form field name for hidden input

Item Slot

Prop Type Default Description
value String required Unique value for this item
pressed Boolean false Initial pressed/selected state
disabled Boolean false Whether the item is disabled
aria_label String nil Accessibility label

Stimulus Controller

This component requires JavaScript. The Stimulus controller shadcn--toggle-group provides interactivity.

Manages selection state across toggle items, supporting single and multiple selection modes.

Installation

Add to your config/importmap.rb:

pin "shadcn", to: "index.esm.js"

Then in your app/javascript/controllers/index.js:

import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn"

const application = Application.start()
registerShadcnControllers(application)

Or import just this controller:

import ToggleGroupController from "shadcn-rails-stimulus/controllers/toggle_group_controller"

application.register("shadcn--toggle-group", ToggleGroupController)

Targets

Name Description
item Toggle items in the group
input Hidden input for form submission

Values

Name Type Default Description
type String "single" Selection mode ('single' or 'multiple')
value String "" Comma-separated list of selected values

Actions

Action Description
toggle Toggles an item's selected state

TypeScript

Type definitions are included. Import types as needed:

import type { ToggleGroupController } from "shadcn-rails-stimulus"

Accessibility

  • Uses role="group" on the container
  • Each item has aria-pressed reflecting its state
  • Supports keyboard navigation
  • Items use data-state attribute for CSS styling