Switch

A toggle control enabling users to switch between "on" and "off" states.

	<script lang="ts">
  import { Label, Switch } from "bits-ui";
</script>
 
<div class="flex items-center space-x-3">
  <Switch.Root
    id="dnd"
    name="hello"
    class="peer inline-flex h-[36px] min-h-[36px] w-[60px] shrink-0 cursor-pointer items-center rounded-full px-[3px] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-foreground data-[state=unchecked]:bg-dark-10 data-[state=unchecked]:shadow-mini-inset dark:data-[state=checked]:bg-foreground"
  >
    <Switch.Thumb
      class="pointer-events-none block size-[30px] shrink-0 rounded-full bg-background transition-transform data-[state=checked]:translate-x-6 data-[state=unchecked]:translate-x-0 data-[state=unchecked]:shadow-mini dark:border dark:border-background/30 dark:bg-foreground dark:shadow-popover dark:data-[state=unchecked]:border"
    />
  </Switch.Root>
  <Label.Root for="dnd" class="text-sm font-medium">Do not disturb</Label.Root>
</div>

Structure

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

Reusable Components

It's recommended to use the Switch primitives to create your own custom switch component that can be used throughout your application.

In the example below, we're using the Checkbox and Label components to create a custom switch component.

MySwitch.svelte
	<script lang="ts">
	import { Switch, Label, useId, type WithoutChildrenOrChild } from "bits-ui";
 
	let {
		id = useId(),
		checked = $bindable(false),
		ref = $bindable(null),
		...restProps
	}: WithoutChildrenOrChild<Switch.RootProps> & {
		labelText: string;
	} = $props();
</script>
 
<Switch.Root bind:checked bind:ref {id} {...restProps}>
	<Switch.Thumb />
</Switch.Root>
<Label.Root for={id}>{labelText}</Label.Root>

You can then use the MySwitch component in your application like so:

	<script lang="ts">
	import MySwitch from "$lib/components/MySwitch.svelte";
 
	let notifications = $state(true);
</script>
 
<MySwitch bind:checked={notifications} labelText="Enable notifications" />

Managing Checked State

The checked prop is used to determine whether the switch is in one of two states: checked and unchecked.

Two-Way Binding

Use the bind:checked directive for two-way synchronization between your local state and the switch's internal state.

	<script lang="ts">
	import { Switch } from "bits-ui";
 
	let myChecked = $state(false);
 
	function fetchNotifications() {
		// whatever logic would result in the `myChecked` state being updated
		myChecked = true;
	}
</script>
 
<button onclick={fetchNotifications}> Sync Notifications </button>
 
<Switch.Root bind:checked={myChecked}>
	<!-- ...-->
</Switch.Root>

This setup enables toggling the switch via custom logic and ensures the local myChecked state updates when the switch changes through any internal means (e.g. clicking on the switch).

Change Handler

You can also use the onCheckedChange prop to update local state when the switch's checked state changes. This is useful when you don't want two-way binding for one reason or another, or you want to perform an additional side-effect when the switch's checked state changes.

	<Switch.Root onCheckedChange={(checked) => console.log(checked)}>
	<!-- ...-->
</Switch.Root>

Disabled State

You can disable the switch by setting the disabled prop to true.

	<Switch.Root disabled>
	<!-- ...-->
</Switch.Root>

HTML Forms

If you pass the name prop to Switch.Root, a hidden input element will be rendered to submit the value of the switch to a form.

By default, the checkbox will be submitted with the default checkbox value of 'on' if the switch is checked.

	<Switch.Root name="dnd">
	<!-- ... -->
</Switch.Root>

Custom Input Value

If you'd prefer to submit a different value, you can use the value prop to set the value of the hidden input.

For example, if you wanted to submit a string value, you could do the following:

	<Switch.Root name="dnd" value="hello">
	<!-- ... -->
	<Switch.Thumb />
</Switch.Root>

API Reference

Switch.Root

The root switch component used to set and manage the state of the switch.

Property Type Description
checked $bindable
boolean

Whether or not the switch is checked.

Default: false
onCheckedChange
function

A callback function called when the checked state of the switch changes.

Default: undefined
disabled
boolean

Whether or not the switch is disabled.

Default: false
name
string

The name of the hidden input element, used to identify the input in form submissions.

Default: undefined
required
boolean

Whether or not the switch is required to be checked.

Default: false
value
string

The value of the hidden input element to be used in form submissions when the switch is checked.

Default: undefined
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 delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-state
''

The switch's checked state.

data-checked
''

Present when the switch is checked.

data-disabled
''

Present when the switch is disabled.

data-switch-root
''

Present on the root element.

Switch.Thumb

The thumb on the switch used to indicate the switch's state.

Property Type Description
ref $bindable
HTMLSpanElement

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 delegation docs for more information.

Default: undefined
Data Attribute Value Description
data-state
''

The switch's checked state.

data-checked
''

Present when the switch is checked.

data-switch-thumb
''

Present on the thumb element.