HextaUI

Switch

Ein Ein/Aus-Schalter, den du antippen, drücken oder ziehen kannst, mit einem Thumb, der sich unter deinem Finger streckt, und einem optionalen Pending-Zustand für Speichervorgänge.

import { Switch } from "@/components/ui/switch"

const settings = [
  {
    id: "wifi",
    title: "Wi-Fi",
    description: "Join known networks automatically.",
    on: true,
  },
  {
    id: "bluetooth",
    title: "Bluetooth",
    description: "Connect to headphones and keyboards.",
    on: false,
  },
  {
    id: "airdrop",
    title: "Nearby sharing",
    description: "Let people around you send files.",
    on: true,
  },
]

export function SwitchDemo() {
  return (
    <div className="flex w-full max-w-sm flex-col divide-y rounded-xl border">
      {settings.map((setting) => (
        <label
          key={setting.id}
          className="flex items-center justify-between gap-4 p-4 text-sm"
        >
          <span className="flex flex-col gap-0.5">
            <span className="font-medium">{setting.title}</span>
            <span className="text-muted-foreground">{setting.description}</span>
          </span>
          <Switch defaultChecked={setting.on} />
        </label>
      ))}
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/switch.json

Fügt die Komponente, die HextaUI-Theme-Tokens und alle HextaUI-Komponenten hinzu, von denen sie abhängt.

import { Switch } from "@/components/ui/switch"
<label className="flex items-center gap-3">
  <Switch defaultChecked />
  Wi-Fi
</label>

Beim Drücken streckt sich der Thumb zur anderen Seite, bevor er hinüberfedert, sodass du den Druck spürst. Du kannst den Thumb auch greifen und ziehen: Über die Mitte hinaus kippt er um, davor schnappt er zurück.

iOS

variant="ios" nutzt eine höhere Spur, einen kapselförmigen Thumb und Grün im eingeschalteten Zustand. Drücken, Ziehen und Speichern funktionieren gleich.

import { Switch } from "@/components/ui/switch"

export function SwitchIos() {
  return (
    <div className="flex flex-col gap-4 text-sm">
      <label className="flex items-center gap-3">
        <Switch variant="ios" />
        Airplane mode
      </label>
      <label className="flex items-center gap-3">
        <Switch variant="ios" defaultChecked />
        Wi-Fi
      </label>
      <div className="flex items-center gap-4">
        <Switch variant="ios" size="sm" aria-label="Small" defaultChecked />
        <Switch variant="ios" size="lg" aria-label="Large" defaultChecked />
      </div>
    </div>
  )
}

Speichern

Gib aus onCheckedChange ein Promise zurück, und der Switch kippt sofort um, auch wenn er kontrolliert ist. Ein Spinner erscheint im Thumb nur, wenn das Speichern länger als 400ms dauert. Wird es abgelehnt, kippt der Switch zurück und wackelt.

"use client"

import { Switch } from "@/components/ui/switch"

function save(succeed: boolean) {
  return new Promise<void>((resolve, reject) =>
    setTimeout(() => (succeed ? resolve() : reject(new Error("Offline"))), 1200)
  )
}

export function SwitchAsync() {
  return (
    <div className="flex flex-col gap-4 text-sm">
      <label className="flex items-center gap-3">
        <Switch onCheckedChange={() => save(true)} />
        Sync to cloud (saves)
      </label>
      <label className="flex items-center gap-3">
        <Switch defaultChecked onCheckedChange={() => save(false)} />
        Public profile (fails and flips back)
      </label>
    </div>
  )
}

Ein- und Aus-Markierungen

icons fügt der Spur ein Häkchen und einen Ring hinzu, damit der Zustand nicht von Farbe abhängt.

import { Switch } from "@/components/ui/switch"

export function SwitchIcons() {
  return (
    <div className="flex flex-col gap-4 text-sm">
      <label className="flex items-center gap-3">
        <Switch icons defaultChecked />
        Captions
      </label>
      <label className="flex items-center gap-3">
        <Switch icons size="lg" />
        Reduce transparency
      </label>
    </div>
  )
}

Größen

sm, default und lg.

import { Switch } from "@/components/ui/switch"

export function SwitchSizes() {
  return (
    <div className="flex items-center gap-6">
      <Switch size="sm" aria-label="Small" defaultChecked />
      <Switch aria-label="Default" defaultChecked />
      <Switch size="lg" aria-label="Large" defaultChecked />
    </div>
  )
}

In einem Field

Mit Field sind Label und Beschreibung mit dem Switch verknüpft.

import {
  Field,
  FieldContent,
  FieldDescription,
  FieldLabel,
} from "@/components/ui/field"
import { Switch } from "@/components/ui/switch"

export function SwitchField() {
  return (
    <Field orientation="horizontal" className="w-full max-w-sm">
      <FieldContent>
        <FieldLabel>Marketing emails</FieldLabel>
        <FieldDescription>
          Product news and offers, about once a month.
        </FieldDescription>
      </FieldContent>
      <Switch name="marketing" />
    </Field>
  )
}

Deaktiviert und schreibgeschützt

readOnly hält den Wert sichtbar und fokussierbar, ändert ihn aber nicht.

import { Switch } from "@/components/ui/switch"

export function SwitchStates() {
  return (
    <div className="flex flex-col gap-4 text-sm">
      <label className="flex items-center gap-3">
        <Switch disabled />
        Disabled
      </label>
      <label className="flex items-center gap-3">
        <Switch disabled defaultChecked />
        Disabled and on
      </label>
      <label className="flex items-center gap-3">
        <Switch readOnly defaultChecked />
        Read-only (managed by your admin)
      </label>
    </div>
  )
}

Kontrolliert

Übergib checked und onCheckedChange.

"use client"

import * as React from "react"

import { Switch } from "@/components/ui/switch"

export function SwitchControlled() {
  const [dark, setDark] = React.useState(false)

  return (
    <label className="flex items-center gap-3 text-sm">
      <Switch checked={dark} onCheckedChange={setDark} />
      Dark mode is {dark ? "on" : "off"}
    </label>
  )
}

Rechts nach links

Der Thumb startet rechts und gleitet nach links, und das Ziehen folgt.

import { Switch } from "@/components/ui/switch"

export function SwitchRtl() {
  return (
    <div dir="rtl" className="flex flex-col gap-4 text-sm">
      <label className="flex items-center gap-3">
        <Switch defaultChecked icons />
        الإشعارات
      </label>
      <label className="flex items-center gap-3">
        <Switch />
        الوضع الداكن
      </label>
    </div>
  )
}
TasteAktion
SpaceEnterSchaltet den fokussierten Switch ein oder aus.
  • Der Switch hat die Rolle switch, benannt durch sein Label. Umschließe ihn mit einem <label> oder nutze Field.
  • Beim Speichern ist er aria-busy und ignoriert neue Betätigungen.
  • Die Trefferfläche ist größer als der Switch und auf Touch noch größer.
  • Bei reduzierter Bewegung bewegt sich der Thumb sofort, und nichts wackelt.
PropTypStandard
checked
boolean–
defaultChecked
booleanfalse
onCheckedChangeGib ein Promise zurück, um den Speicherzustand zu zeigen. Bei Ablehnung kippt ein unkontrollierter Switch zurück.
(checked, details) => void | Promise–
variant
"default" | "ios""default"
size
"sm" | "default" | "lg""default"
iconsZeige Ein- und Aus-Markierungen in der Spur.
booleanfalse
name
string–
value
string–
disabled
booleanfalse
readOnly
booleanfalse
required
booleanfalse
render
ReactElement | (props, state) => ReactElement<span>
AttributBeschreibung
data-slot="switch"Die Spur, mit data-size und data-variant.
data-slot="switch-thumb"Der Thumb.
data-checked / data-uncheckedOb der Switch an ist.
data-draggingVorhanden, solange der Thumb gezogen wird.
data-pendingVorhanden, solange ein zurückgegebenes Promise aussteht.
--switch-w / --switch-h / --switch-thumb / --switch-thumb-wGrößen von Spur und Thumb, über size gesetzt.

In Blocks verwendet

Blocks, die auf Switch aufbauen.