Prototyper UI

Switch

A toggle switch built on Base UI

Loading...

Installation

pnpm dlx shadcn@latest add https://prototyper-ui.com/r/switch.json
npx shadcn@latest add https://prototyper-ui.com/r/switch.json
yarn dlx shadcn@latest add https://prototyper-ui.com/r/switch.json
bunx --bun shadcn@latest add https://prototyper-ui.com/r/switch.json

This will add the following files to your project:

  • components/ui/switch.tsx

Usage

import {
  Switch,
  SwitchTrack,
  SwitchThumb,
} from "@/components/ui/switch"

<Switch>
  <SwitchTrack>
    <SwitchThumb />
  </SwitchTrack>
  Airplane Mode
</Switch>

Anatomy

<Switch>
  <SwitchTrack>
    <SwitchThumb>
      <SwitchIcon /> {/* optional */}
    </SwitchThumb>
  </SwitchTrack>
  {/* label text */}
</Switch>
Sub-componentdata-slotPurposeRequired
SwitchswitchRoot component with label and switch controlYes
SwitchTrackswitch-trackThe sliding track backgroundYes
SwitchThumbswitch-thumbThe draggable thumb indicatorYes
SwitchIconswitch-iconOptional icon wrapper inside the thumbNo

Examples

Sizes

Loading...

With Icon

Loading...

Label Left

Loading...

Disabled

Loading...

Read Only

Loading...

Styling

Data Slots

Use data-slot attributes to target specific parts of the switch:

Slot nameElement
switchRoot wrapper (label + track)
switch-trackThe sliding track background
switch-thumbThe circular thumb indicator

Customization Examples

/* Make the switch track wider */
[data-slot="switch-track"] {
  @apply w-12 h-6;
}

/* Custom checked track color */
[data-slot="switch"] [data-slot="switch-track"] {
  @apply group-data-checked:bg-green-600;
}
{/* Override styles via className */}
<Switch className="gap-4">Wide gap label</Switch>

API Reference

Switch

Root component that manages on/off state and renders a track with thumb.

Prop

Type

All Base UI Switch.Root props are forwarded via ...props.

SwitchTrack

The sliding track background container that holds the thumb.

Prop

Type

All standard HTML div props are supported via ...props.

SwitchThumb

The circular thumb indicator that slides inside the track.

Prop

Type

All Base UI Switch.Thumb props are forwarded via ...props.

SwitchIcon

Optional icon wrapper for displaying icons inside the thumb.

Prop

Type

All standard HTML span props are supported via ...props. The component automatically hides from screen readers with aria-hidden="true".

Accessibility

Keyboard Interactions

KeyAction
SpaceToggles the switch on/off
TabMoves focus to / away from the switch

ARIA Attributes

  • Renders with role="switch" via Base UI.
  • aria-checked is set to true or false based on the switch state.
  • aria-disabled is set when the switch is disabled.
  • aria-readonly is set when the switch is read-only.
  • Screen readers announce the label and the on/off state.

Stream UI

This component is available in @prototyperai/stream-ui.

Catalog Definition

switch.catalog.ts
import { z } from "zod"
import { defineComponent } from "@prototyperai/stream-ui/catalog"

export default defineComponent({
  description: "A toggle switch for on/off states",
  props: z.object({
    label: z.string().optional().describe("Label displayed next to the switch"),
    checked: z.boolean().optional().describe("Whether the switch is on"),
    disabled: z.boolean().optional().describe("Whether the switch is disabled"),
    size: z
      .enum(["sm", "md", "lg"])
      .optional()
      .describe("Switch size variant"),
  }),
  events: ["change"],
  example: { label: "Enable notifications", checked: false, size: "md" },
})

Example Spec

{
  "root": "notifSwitch",
  "elements": {
    "notifSwitch": {
      "type": "Switch",
      "props": {
        "label": "Enable notifications",
        "checked": false,
        "size": "md"
      },
      "$bindState": { "path": "/notificationsEnabled", "event": "change" }
    }
  }
}

Learn more in the Stream UI documentation.

On this page