Switch

A control that allows the user to toggle between on and off.

Stimulus: shadcn--switch

Installation

Add the component to your project:

rails generate shadcn:add switch

Usage

<div class="flex items-center space-x-2">
  <%= render Shadcn::SwitchComponent.new(id: "default-switch") %>
  <%= render Shadcn::LabelComponent.new(for: "default-switch") { "Enable notifications" } %>
</div>

Examples

Default

<div class="flex items-center space-x-2">
  <%= render Shadcn::SwitchComponent.new(id: "default-switch") %>
  <%= render Shadcn::LabelComponent.new(for: "default-switch") { "Enable notifications" } %>
</div>

Checked

Set checked: true to render in the on state.

<div class="flex items-center space-x-2">
  <%= render Shadcn::SwitchComponent.new(id: "checked-switch-demo", checked: true) %>
  <%= render Shadcn::LabelComponent.new(for: "checked-switch-demo") { "Enabled by default" } %>
</div>

Disabled

<div class="flex flex-col gap-4">
  <div class="flex items-center space-x-2">
    <%= render Shadcn::SwitchComponent.new(id: "disabled-off", disabled: true) %>
    <%= render Shadcn::LabelComponent.new(for: "disabled-off") { "Disabled (off)" } %>
  </div>
  <div class="flex items-center space-x-2">
    <%= render Shadcn::SwitchComponent.new(id: "disabled-on", disabled: true, checked: true) %>
    <%= render Shadcn::LabelComponent.new(for: "disabled-on") { "Disabled (on)" } %>
  </div>
</div>

With Label

Pass label text as the component block to render a clickable label around the switch.

<%= render Shadcn::SwitchComponent.new(name: "airplane_mode", id: "airplane_mode") { "Airplane mode" } %>

Required

Use required: true when a form requires this switch to be checked before submission.

<div class="flex items-center space-x-2">
  <%= render Shadcn::SwitchComponent.new(name: "agreement", id: "agreement", required: true) %>
  <%= render Shadcn::LabelComponent.new(for: "agreement") { "Accept terms and conditions" } %>
</div>

In a Form

Notifications

Configure how you receive notifications.

Receive notifications via email.

Receive push notifications.

Receive notifications via SMS.

<%= render Shadcn::CardComponent.new(class_name: "w-full max-w-md") do |card| %>
  <% card.with_header do |header| %>
    <% header.with_title { "Notifications" } %>
    <% header.with_description { "Configure how you receive notifications." } %>
  <% end %>
  <% card.with_content do %>
    <div class="space-y-4">
      <div class="flex items-center justify-between">
        <div class="space-y-0.5">
          <%= render Shadcn::LabelComponent.new(for: "email-notif") { "Email" } %>
          <p class="text-sm text-muted-foreground">Receive notifications via email.</p>
        </div>
        <%= render Shadcn::SwitchComponent.new(id: "email-notif", name: "notifications[email]", checked: true) %>
      </div>
      <%= render Shadcn::SeparatorComponent.new %>
      <div class="flex items-center justify-between">
        <div class="space-y-0.5">
          <%= render Shadcn::LabelComponent.new(for: "push-notif") { "Push" } %>
          <p class="text-sm text-muted-foreground">Receive push notifications.</p>
        </div>
        <%= render Shadcn::SwitchComponent.new(id: "push-notif", name: "notifications[push]") %>
      </div>
      <%= render Shadcn::SeparatorComponent.new %>
      <div class="flex items-center justify-between">
        <div class="space-y-0.5">
          <%= render Shadcn::LabelComponent.new(for: "sms-notif") { "SMS" } %>
          <p class="text-sm text-muted-foreground">Receive notifications via SMS.</p>
        </div>
        <%= render Shadcn::SwitchComponent.new(id: "sms-notif", name: "notifications[sms]") %>
      </div>
    </div>
  <% end %>
<% end %>

API Reference

Prop Type Default Description
name String nil Input name attribute
id String nil Input id attribute
value String "1" Value when checked
checked Boolean false Whether the switch is on
disabled Boolean false Whether the switch is disabled
required Boolean false Whether the switch is required
unchecked_value String "0" Hidden value submitted when unchecked
include_hidden Boolean true Whether to render the hidden unchecked value input

Stimulus Controller

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

Handles switch toggle state and updates form values.

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 SwitchController from "shadcn-rails-stimulus/controllers/switch_controller"

application.register("shadcn--switch", SwitchController)

Values

Name Type Default Description
checked Boolean false Current checked state

Actions

Action Description
toggle Toggles the switch state

TypeScript

Type definitions are included. Import types as needed:

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

Accessibility

  • Uses role="switch" for proper accessibility
  • Has aria-checked attribute that reflects current state
  • Always pair with a LabelComponent for accessibility
  • Disabled state is properly announced to screen readers
  • Keyboard navigable - can be toggled with Space key