Toggle Group

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

Stimulus: shadcn--toggle-group

Installation

Add the component to your project:

rails generate shadcn:component toggle_group

Usage

<%= 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 %>

Examples

Single Selection

Only one item can be selected at a time.

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
<%= 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 %>

<%= 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 %>

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 %>

API Reference

ToggleGroupComponent

API Reference

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

API Reference

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 docs provides interactivity.

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

Installation

Add to your config/importmap.rb:

pin "shadcn-rails", to: "shadcn/index.js"

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

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

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

Or import just this controller:

import DocsController from "shadcn-rails/controllers/docs_controller"

application.register("docs", DocsController)

Targets

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

Values

Name Type Default Description
type String 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 { DocsController } from "shadcn-rails"

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