Toggle
Form ControlsLocal guide ↗
import { Toggle } from "bits-ui" Icon toggle
bind:pressed synchronizes the icon, revealed value, status and pressed surface
•••••••••••••• Hidden<script lang="ts">
import { Toggle } from 'bits-ui';
import { Eye, EyeOff } from '@lucide/svelte';
let pressed = $state(false);
const token = $derived(pressed ? 'bk_live_7N4K2X' : '••••••••••••••');
</script>
<div class="panel mx-auto flex max-w-md items-center gap-3 p-3">
<code class="min-w-0 flex-1 truncate px-2 text-sm tracking-wider text-ink-200">{token}</code>
<Toggle.Root
bind:pressed
aria-label={pressed ? 'Hide API token' : 'Show API token'}
class="inline-flex size-10 shrink-0 items-center justify-center rounded-lg border border-ink-700 bg-ink-900 text-ink-400 transition hover:text-ink-50 data-[state=on]:border-brand-500 data-[state=on]:bg-brand-500 data-[state=on]:text-ink-950"
>
{#if pressed}
<EyeOff class="size-5" />
{:else}
<Eye class="size-5" />
{/if}
</Toggle.Root>
<span class="chip">{pressed ? 'Visible' : 'Hidden'}</span>
</div>
Controlled and locked
External controls share the pressed state; a disabled toggle communicates a fixed policy
Alerts: muted
Security alerts are locked on
<script lang="ts">
import { Toggle } from 'bits-ui';
import { Bell, BellOff, ShieldCheck } from '@lucide/svelte';
let muted = $state(true);
</script>
<div class="grid gap-4">
<div class="flex flex-wrap items-center gap-2">
<button class="btn btn-sm" onclick={() => (muted = false)}>Turn sound on</button>
<button class="btn btn-sm" onclick={() => (muted = true)}>Mute</button>
<span class="chip">Alerts: {muted ? 'muted' : 'audible'}</span>
</div>
<div class="flex items-center gap-3">
<Toggle.Root
bind:pressed={muted}
aria-label="Mute alerts"
class="inline-flex size-11 items-center justify-center rounded-lg border border-ink-700 bg-ink-900 text-ink-400 data-[state=on]:border-accent-500 data-[state=on]:bg-accent-500 data-[state=on]:text-ink-950"
>
{#if muted}<BellOff class="size-5" />{:else}<Bell class="size-5" />{/if}
</Toggle.Root>
<Toggle.Root
pressed
disabled
aria-label="Security notifications cannot be disabled"
class="inline-flex size-11 cursor-not-allowed items-center justify-center rounded-lg border border-brand-500 bg-brand-500/20 text-brand-400 opacity-60"
>
<ShieldCheck class="size-5" />
</Toggle.Root>
<span class="muted text-xs">Security alerts are locked on</span>
</div>
</div>
pressed is the bindable boolean state. The root emits data-state="on" or data-state="off", and adds data-disabled when interaction is disabled. Icon-only toggles still need an accessible name such as aria-label.
Unlike Checkbox, Switch, and Radio Group, Toggle has no name, value, or required form props and does not render a hidden input. Mirror its pressed state into your own form field when a toggle must be submitted.