HextaUI

Toggle

Ein Button, der an oder aus bleibt, mit einer Füllung, die sich beim Drücken setzt, einem klaren Übergang beim Hover zu „an“ und Icons, die sich mit dem Zustand füllen können.

import { IconBold, IconItalic, IconUnderline } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleDemo() {
  return (
    <div className="flex items-center gap-1">
      <Toggle aria-label="Bold" defaultPressed>
        <IconBold />
      </Toggle>
      <Toggle aria-label="Italic">
        <IconItalic />
      </Toggle>
      <Toggle aria-label="Underline">
        <IconUnderline />
      </Toggle>
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/toggle.json

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

import { Toggle } from "@/components/ui/toggle"
<Toggle aria-label="Bold">
  <IconBold />
</Toggle>

Das Hovern eines ausgeschalteten Toggles zeigt eine helle Tönung; das Einschalten setzt eine stärkere Füllung und bringt das Label auf vollen Kontrast, sodass „an“ nie wie Hover aussieht.

Outline

variant="outline" fügt Rahmen und Fläche hinzu, für Toggles, die für sich stehen.

import { IconBookmark } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleOutline() {
  return (
    <div className="flex items-center gap-2">
      <Toggle variant="outline" aria-label="Bookmark">
        <IconBookmark />
      </Toggle>
      <Toggle variant="outline">
        <IconBookmark />
        Bookmark
      </Toggle>
    </div>
  )
}

Mit Text

Icons und Labels stehen nebeneinander. Toggles mit sichtbarem Text brauchen kein aria-label.

import { IconItalic, IconTextWrap } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleText() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Toggle>
        <IconItalic />
        Italic
      </Toggle>
      <Toggle variant="outline" defaultPressed>
        <IconTextWrap />
        Wrap lines
      </Toggle>
      <Toggle variant="outline">Show hidden files</Toggle>
    </div>
  )
}

Gefüllt, wenn an

Füge group-data-pressed/toggle:fill-current zu einem Outline-Icon hinzu, und es füllt sich, wenn der Toggle einschaltet.

import { IconBookmark, IconHeart, IconStar } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleFilledIcon() {
  return (
    <div className="flex items-center gap-1">
      <Toggle aria-label="Like" defaultPressed>
        <IconHeart className="group-data-pressed/toggle:fill-current" />
      </Toggle>
      <Toggle aria-label="Star">
        <IconStar className="group-data-pressed/toggle:fill-current" />
      </Toggle>
      <Toggle aria-label="Save">
        <IconBookmark className="group-data-pressed/toggle:fill-current" />
      </Toggle>
    </div>
  )
}

Größen

sm, default und lg. Toggles nur mit Icon bleiben quadratisch.

import { IconBold } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleSizes() {
  return (
    <div className="flex flex-col gap-4">
      <div className="flex items-center gap-2">
        <Toggle size="sm" aria-label="Bold, small">
          <IconBold />
        </Toggle>
        <Toggle aria-label="Bold">
          <IconBold />
        </Toggle>
        <Toggle size="lg" aria-label="Bold, large">
          <IconBold />
        </Toggle>
      </div>
      <div className="flex items-center gap-2">
        <Toggle size="sm" variant="outline">
          Small
        </Toggle>
        <Toggle variant="outline">Default</Toggle>
        <Toggle size="lg" variant="outline">
          Large
        </Toggle>
      </div>
    </div>
  )
}

Pill

shape="pill" rundet die Enden vollständig ab, für Toggles in abgerundeten Flächen wie einem Chat-Composer.

import { IconSparkles, IconWorld } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function TogglePill() {
  return (
    <div className="flex flex-wrap items-center gap-2">
      <Toggle shape="pill" defaultPressed>
        <IconSparkles />
        Think
      </Toggle>
      <Toggle shape="pill" variant="outline">
        <IconWorld />
        Search
      </Toggle>
    </div>
  )
}

Deaktiviert

Ein deaktivierter Toggle zeigt weiterhin, ob er an ist, kann aber nicht gedrückt oder fokussiert werden.

import { IconBold, IconUnderline } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleDisabled() {
  return (
    <div className="flex items-center gap-2">
      <Toggle disabled aria-label="Bold">
        <IconBold />
      </Toggle>
      <Toggle disabled defaultPressed aria-label="Underline">
        <IconUnderline />
      </Toggle>
      <Toggle disabled variant="outline">
        Read-only mode
      </Toggle>
    </div>
  )
}

Kontrolliert

Übergib pressed und onPressedChange. Das Label bleibt gleich, während das Icon dem Zustand folgt.

"use client"

import * as React from "react"
import { IconMicrophone, IconMicrophoneOff } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleControlled() {
  const [muted, setMuted] = React.useState(false)

  return (
    <div className="flex items-center gap-3 text-sm">
      <Toggle
        variant="outline"
        aria-label="Mute microphone"
        pressed={muted}
        onPressedChange={setMuted}
      >
        {muted ? <IconMicrophoneOff /> : <IconMicrophone />}
      </Toggle>
      <span className="text-muted-foreground">
        Microphone is {muted ? "muted" : "on"}
      </span>
    </div>
  )
}

Rechts nach links

Icons führen das Label von rechts an.

import { IconAlignRight, IconBold, IconItalic } from "@tabler/icons-react"

import { Toggle } from "@/components/ui/toggle"

export function ToggleRtl() {
  return (
    <div dir="rtl" className="flex items-center gap-2">
      <Toggle variant="outline" defaultPressed>
        <IconBold />
        عريض
      </Toggle>
      <Toggle variant="outline">
        <IconItalic />
        مائل
      </Toggle>
      <Toggle variant="outline" aria-label="محاذاة لليمين">
        <IconAlignRight />
      </Toggle>
    </div>
  )
}
TasteAktion
SpaceEnterSchaltet den fokussierten Toggle an oder aus.
TabSetzt den Fokus auf den nächsten Toggle.
  • Der Toggle ist ein button mit aria-pressed, sodass Screenreader ansagen, ob er an ist.
  • Gib Toggles nur mit Icon ein aria-label, das die Aktion benennt („Mikrofon stummschalten“), und behalte es in beiden Zuständen bei. Es zusätzlich zum Pressed-Zustand zu ändern, wirkt wie eine doppelte Verneinung.
  • Auf Touchscreens wächst die Trefferfläche auf mindestens 44px, außer in einer Toggle group, wo sich Nachbarn überlappen würden.
  • Bei reduzierter Bewegung skaliert nichts; die Füllung blendet nur ein.
PropTypStandard
variant
"default" | "outline""default"
size
"default" | "sm" | "lg""default"
shape
"default" | "pill""default"
pressed
boolean–
defaultPressed
booleanfalse
onPressedChange
(pressed, details) => void–
disabled
booleanfalse
valueIdentifiziert den Toggle in einer Toggle group.
string–
className
string | (state) => string–
nativeButton
booleantrue
render
ReactElement | (props, state) => ReactElement<button>
AttributBeschreibung
data-slot="toggle"Der Button, mit data-variant und data-size.
data-pressedVorhanden, wenn der Toggle an ist.
data-disabledVorhanden, wenn der Toggle deaktiviert ist.

In Blocks verwendet

Blocks, die auf Toggle aufbauen.