Toggle

A control element that switches between two states, providing a binary choice.

••••
	<script lang="ts">
  import { Toggle } from "bits-ui";
  import LockKeyOpen from "phosphor-svelte/lib/LockKeyOpen";
 
  let unlocked = $state(false);
  const code = $derived(unlocked ? "B1T5" : "••••");
</script>
 
<div
  class="min-h-input flex h-full w-[176px] items-center gap-2 rounded-card-sm border border-border bg-background-alt py-1 pl-[18px] pr-1.5 shadow-mini"
>
  <div
    class="text-end font-alt text-[19px] tracking-[13.87px] {unlocked
      ? 'text-foreground'
      : 'text-muted-foreground'}"
  >
    {code}
  </div>
  <Toggle.Root
    aria-label="toggle code visibility"
    class="inline-flex size-10 items-center justify-center rounded-[9px] bg-background-alt transition-all hover:bg-muted active:scale-98 active:bg-dark-10 data-[state=on]:bg-muted data-[state=off]:text-foreground-alt data-[state=on]:text-foreground active:data-[state=on]:bg-dark-10"
    bind:pressed={unlocked}
  >
    <LockKeyOpen class="size-6" />
  </Toggle.Root>
</div>

Structure

	<script lang="ts">
	import { Toggle } from "bits-ui";
</script>
 
<Toggle.Root />

Managing Pressed State

Bits UI offers several approaches to manage and synchronize the Toggle's pressed state, catering to different levels of control and integration needs.

1. Two-Way Binding

For seamless state synchronization, use Svelte's bind:pressed directive. This method automatically keeps your local state in sync with the component's internal state.

	<script lang="ts">
	import { Toggle } from "bits-ui";
	let myPressed = $state(true);
</script>
 
<button onclick={() => (myPressed = false)}> un-press </button>
 
<Toggle.Root bind:pressed={myPressed} />

Key Benefits

  • Simplifies state management
  • Automatically updates myPressed when the switch changes (e.g., via clicking on the toggle)
  • Allows external control (e.g., pressing/toggling via a separate button/programmatically)

2. Change Handler

For more granular control or to perform additional logic on state changes, use the onPressedChange prop. This approach is useful when you need to execute custom logic alongside state updates.

	<script lang="ts">
	import { Toggle } from "bits-ui";
	let myPressed = $state(false);
</script>
 
<Toggle.Root
	checked={myPressed}
	onPressedChange={(p) => {
		myPressed = p;
		// additional logic here.
	}}
/>

Use Cases

  • Implementing custom behaviors on pressed/unpressed
  • Integrating with external state management solutions
  • Triggering side effects (e.g., logging, data fetching)

3. Fully Controlled

For complete control over the component's state, use a Function Binding to manage the value state externally.

	<script lang="ts">
	import { Toggle } from "bits-ui";
	let myPressed = $state(false);
</script>
 
<Toggle.Root bind:pressed={() => myPressed, (newPressed) => (myPressed = newPressed)}>
	<!-- ... -->
</Toggle.Root>

When to Use

  • Implementing complex checked/unchecked logic
  • Coordinating multiple UI elements
  • Debugging state-related issues

API Reference

Toggle.Root

The toggle button.

Property Type Description
pressed $bindable
boolean

Whether or not the toggle button is pressed.

Default: false
onPressedChange
function

A callback function called when the pressed state of the toggle changes.

Default: undefined
disabled
boolean

Whether or not the switch is disabled.

Default: false
ref $bindable
HTMLButtonElement

The underlying DOM element being rendered. You can bind to this to get a reference to the element.

Default: undefined
children
Snippet

The children content to render.

Default: undefined
child
Snippet

Use render delegation to render your own element. See Child Snippet docs for more information.

Default: undefined
Data Attribute Value Description
data-state
enum

Whether the toggle is in the on or off state.

data-disabled
''

Present when the toggle is disabled.

data-toggle-root
''

Present on the root element.