Przejdź do treści

Toggle

Dwustanowy przycisk, który włącza lub wyłącza jedną opcję i pokazuje jej bieżący stan.

Kod źródłowyBase UIRejestr
import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"

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

export default function ToggleDemo() {
  return (
    <div className="flex items-center gap-1 rounded-xl border bg-card p-1 shadow-raised">
      <Toggle aria-label="Pogrubienie" defaultPressed>
        <BoldIcon />
      </Toggle>
      <Toggle aria-label="Kursywa">
        <ItalicIcon />
      </Toggle>
      <Toggle aria-label="Podkreślenie">
        <UnderlineIcon />
      </Toggle>
    </div>
  )
}

Instalacja

$ pnpm dlx shadcn@latest add https://www.prfct.dev/r/toggle.json

Użycie

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

Przykłady

Wariant konturowy

Wariant outline nadaje każdemu przyciskowi widoczną krawędź. Używaj go, gdy przyciski przełączające stoją na stronie samodzielnie, a nie na pasku narzędzi.

import { EyeOffIcon, LockIcon, PinIcon } from "lucide-react"

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

export default function ToggleOutline() {
  return (
    <div className="flex items-center gap-2">
      <Toggle variant="outline" aria-label="Przypnij do paska bocznego" defaultPressed>
        <PinIcon />
      </Toggle>
      <Toggle variant="outline" aria-label="Zablokuj warstwę">
        <LockIcon />
      </Toggle>
      <Toggle variant="outline" aria-label="Ukryj warstwę">
        <EyeOffIcon />
      </Toggle>
    </div>
  )
}

Z tekstem

Dodaj do ikony etykietę, gdy sama ikona mogłaby być niejednoznaczna albo gdy przycisk jest jedyną kontrolką tego rodzaju na stronie.

import { BellIcon, StarIcon } from "lucide-react"

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

export default function ToggleWithText() {
  return (
    <div className="flex items-center gap-2">
      <Toggle variant="outline" defaultPressed>
        <StarIcon data-icon="inline-start" />
        Z gwiazdką
      </Toggle>
      <Toggle variant="outline">
        <BellIcon data-icon="inline-start" />
        Obserwuj
      </Toggle>
    </div>
  )
}

Rozmiary

Przyciski przełączające mają te same wysokości co przyciski i pola tekstowe — sm 32, default 36, lg 40 — więc równo się układają na każdym pasku narzędzi.

import { BookmarkIcon } from "lucide-react"

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

export default function ToggleSizes() {
  return (
    <div className="flex items-center gap-3">
      <Toggle variant="outline" size="sm" aria-label="Dodaj do zakładek">
        <BookmarkIcon />
      </Toggle>
      <Toggle variant="outline" aria-label="Dodaj do zakładek">
        <BookmarkIcon />
      </Toggle>
      <Toggle variant="outline" size="lg" aria-label="Dodaj do zakładek">
        <BookmarkIcon />
      </Toggle>
    </div>
  )
}

Tryb kontrolowany

Steruj stanem przez pressed i onPressedChange, gdy zależy od niego coś innego na stronie. Tutaj za stanem podążają ikona i tekst pomocniczy.

Powiadomimy cię o nowych komentarzach.

"use client"

import * as React from "react"
import { BellIcon, BellOffIcon } from "lucide-react"

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

export default function ToggleControlled() {
  const [subscribed, setSubscribed] = React.useState(true)

  return (
    <div className="flex flex-col items-center gap-3">
      <Toggle
        variant="outline"
        pressed={subscribed}
        onPressedChange={setSubscribed}
      >
        {subscribed ? (
          <BellIcon data-icon="inline-start" />
        ) : (
          <BellOffIcon data-icon="inline-start" />
        )}
        Powiadomienia
      </Toggle>
      <p className="text-sm text-muted-foreground" aria-live="polite">
        {subscribed
          ? "Powiadomimy cię o nowych komentarzach."
          : "Nie będziesz otrzymywać powiadomień z tego wątku."}
      </p>
    </div>
  )
}
const [subscribed, setSubscribed] = React.useState(true)

<Toggle pressed={subscribed} onPressedChange={setSubscribed}>
  {subscribed ? <BellIcon data-icon="inline-start" /> : <BellOffIcon data-icon="inline-start" />}
  Notifications
</Toggle>

Wyłączony

import { ItalicIcon } from "lucide-react"

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

export default function ToggleDisabled() {
  return (
    <div className="flex items-center gap-2">
      <Toggle aria-label="Kursywa" disabled>
        <ItalicIcon />
      </Toggle>
      <Toggle variant="outline" aria-label="Kursywa" disabled defaultPressed>
        <ItalicIcon />
      </Toggle>
    </div>
  )
}

Wytyczne

Kiedy używać

  • Do opcji formatowania i widoku, które działają od razu: pogrubienie, kursywa, zawijanie wierszy, linie siatki.
  • Do oznaczania czegoś: Oznacz gwiazdką, Przypnij, Obserwuj — gdy informacją jest sam stan wciśnięcia.

Kiedy nie używać

  • Do ustawień, które działają jak preferencja — użyj Switch, który odbiera się jako włączony lub wyłączony, a nie wciśnięty.
  • Do wyboru jednej opcji spośród kilku — użyj Toggle Group.
  • Do wywołania akcji, która nie ma trwałego stanu — użyj Button.

Nazwij opcję, nie akcję

Etykieta przycisku przełączającego nazywa to, czym on steruje, i jest taka sama w obu stanach. Stan pokazuje styl wciśnięcia; jeśli dodatkowo zmienia się tekst, trudno powiedzieć, na który stan się patrzy.

DobrzeEtykieta nazywa opcję, a styl wciśnięcia pokazuje, że jest włączona.
ŹleCzasownik akcji, który zmienia się razem ze stanem, jest niejednoznaczny: to włączone czy wyłączone?

Dostępność

  • Renderuje natywny <button> z aria-pressed, więc czytniki ekranu przedstawiają go jako przycisk przełączający razem z bieżącym stanem.
  • Przyciski z samą ikoną potrzebują aria-label. Nie umieszczaj stanu w etykiecie — Pogrubienie, a nie Pogrubienie włączone — bo przekazuje go już aria-pressed.
  • Stan wciśnięcia pokazują wypełnienie i ciemniejsza etykieta, a nie sam kolor; w trybie wymuszonych kolorów rolę tę przejmuje systemowy kolor wyróżnienia.
KlawiszDziałanie
Tab
Przenosi fokus na przycisk.
SpacjaEnter
Przełącza stan wciśnięcia.

Dokumentacja API

Toggle

Renderuje <button>. Przyjmuje wszystkie propsy komponentu Toggle z Base UI.

PropTypDomyślnie
variant

Styl wizualny. Outline dodaje obramowanie i wyniesione wypełnienie.

"default" | "outline""default"
size

Wysokość i wewnętrzne odstępy, zgodne z przyciskami i polami tekstowymi.

"sm" | "default" | "lg""default"
pressed

Kontrolowany stan wciśnięcia.

booleanBrak wartości domyślnej
defaultPressed

Początkowy stan wciśnięcia w trybie niekontrolowanym.

booleanfalse
onPressedChange

Wywoływana, gdy zmienia się stan wciśnięcia.

(pressed: boolean, eventDetails) => voidBrak wartości domyślnej
disabled

Blokuje interakcję.

booleanfalse
value

Identyfikuje przycisk wewnątrz Toggle Group.

stringBrak wartości domyślnej
render

Podmienia renderowany element, zachowując działanie i style.

ReactElement | (props, state) => ReactElementBrak wartości domyślnej

toggleVariants

Generator klas, eksportowany, żeby inne elementy — na przykład elementy Toggle Group — miały te same style.