Toggle Group

Groups multiple toggle controls, allowing users to enable one or multiple options.

	<script lang="ts">
  import { ToggleGroup } from "bits-ui";
  import TextB from "phosphor-svelte/lib/TextB";
  import TextItalic from "phosphor-svelte/lib/TextItalic";
  import TextStrikethrough from "phosphor-svelte/lib/TextStrikethrough";
 
  let value: string[] = $state(["bold"]);
</script>
 
<ToggleGroup.Root
  bind:value
  type="multiple"
  class="flex h-input items-center gap-x-0.5 rounded-card-sm border border-border bg-background-alt px-[4px] py-1 shadow-mini"
>
  <ToggleGroup.Item
    aria-label="toggle bold"
    value="bold"
    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"
  >
    <TextB class="size-6" />
  </ToggleGroup.Item>
  <ToggleGroup.Item
    aria-label="toggle italic"
    value="italic"
    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"
  >
    <TextItalic class="size-6" />
  </ToggleGroup.Item>
  <ToggleGroup.Item
    aria-label="toggle strikethrough"
    value="strikethrough"
    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"
  >
    <TextStrikethrough class="size-6" />
  </ToggleGroup.Item>
</ToggleGroup.Root>

Structure

	<script lang="ts">
	import { ToggleGroup } from "bits-ui";
</script>
 
<ToggleGroup.Root>
	<ToggleGroup.Item value="bold">bold</ToggleGroup.Item>
	<ToggleGroup.Item value="italic">italic</ToggleGroup.Item>
</ToggleGroup.Root>

Single & Multiple

The ToggleGroup component supports two type props, 'single' and 'multiple'. When the type is set to 'single', the ToggleGroup will only allow a single item to be selected at a time, and the type of the value prop will be a string.

When the type is set to 'multiple', the ToggleGroup will allow multiple items to be selected at a time, and the type of the value prop will be an array of strings.

Managing Value State

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

1. Two-Way Binding

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

	<script lang="ts">
	import { ToggleGroup } from "bits-ui";
	let myValue = $state("");
</script>
 
<button onclick={() => (myValue = "item-1")}> Press item 1 </button>
 
<ToggleGroup.Root type="single" bind:value={myValue}>
	<!-- -->
</ToggleGroup.Root>

Key Benefits

  • Simplifies state management
  • Automatically updates myValue when the internal state changes (e.g., via clicking on an item)
  • Allows external control (e.g., toggling an item via a separate button)

2. Change Handler

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

	<script lang="ts">
	import { ToggleGroup } from "bits-ui";
	let myValue = $state("");
</script>
 
<ToggleGroup.Root
	type="single"
	value={myValue}
	onValueChange={(v) => {
		myValue = v;
		// additional logic here.
	}}
>
	<!-- ... -->
</ToggleGroup.Root>

Use Cases

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

3. Fully Controlled

For complete control over the component's value state, use the controlledValue prop. This approach requires you to manually manage the value state, giving you full control over when and how the component responds to value change events.

To implement controlled state:

  1. Set the controlledValue prop to true on the ToggleGroup.Root component.
  2. Provide a value prop to ToggleGroup.Root, which should be a variable holding the current state.
  3. Implement an onValueChange handler to update the state when the internal state changes.
	<script lang="ts">
	import { ToggleGroup } from "bits-ui";
	let myValue = $state("");
</script>
 
<ToggleGroup.Root
	type="single"
	controlledValue
	value={myValue}
	onValueChange={(v) => (myValue = v)}
>
	<!-- ... -->
</ToggleGroup.Root>

When to Use

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

API Reference

ToggleGroup.Root

The root component which contains the toggle group items.

Property Type Description
type required
enum

The type of toggle group.

Default: undefined
value $bindable
union

The value of the toggle group. If the type is 'multiple', this will be an array of strings, otherwise it will be a string.

Default: undefined
onValueChange
function

A callback function called when the value of the toggle group changes. The type of the value is dependent on the type of the toggle group.

Default: undefined
controlledValue
boolean

Whether or not the value is controlled or not. If true, the component will not update the value state internally, instead it will call onValueChange when it would have otherwise, and it is up to you to update the value prop that is passed to the component.

Default: false
disabled
boolean

Whether or not the switch is disabled.

Default: false
loop
boolean

Whether or not the toggle group should loop when navigating.

Default: true
orientation
enum

The orientation of the toggle group.

Default: horizontal
rovingFocus
boolean

Whether or not the toggle group should use roving focus when navigating.

Default: true
ref $bindable
HTMLDivElement

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-orientation
enum

The orientation of the toggle group.

data-toggle-group-root
''

Present on the root element.

ToggleGroup.Item

An individual toggle item within the group.

Property Type Description
value
string

The value of the item.

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

Default: undefined
Data Attribute Value Description
data-state
enum

Whether the toggle item is in the on or off state.

data-value
''

The value of the toggle item.

data-orientation
enum

The orientation of the toggle group.

data-disabled
''

Present when the toggle item is disabled.

data-toggle-group-item
''

Present on the toggle group item.