Toggle Group
A toggle group is used to toggle either one option or multiple options.
Features
- Fully managed keyboard navigation.
- Supports horizontal and vertical orientation.
- Support for multiple selection.
Installation
To use the toggle group machine in your project, run the following command in your command line:
npm install @zag-js/toggle-group @zag-js/react # or yarn add @zag-js/toggle-group @zag-js/react
npm install @zag-js/toggle-group @zag-js/vue # or yarn add @zag-js/toggle-group @zag-js/vue
npm install @zag-js/toggle-group @zag-js/vue # or yarn add @zag-js/toggle-group @zag-js/vue
npm install @zag-js/toggle-group @zag-js/solid # or yarn add @zag-js/toggle-group @zag-js/solid
This command will install the framework agnostic toggle group logic and the reactive utilities for your framework of choice.
Anatomy
To set up the toggle group correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
On a high level, the toggle group consists of:
- Root: The root container for the toggle group
- Toggle: The individual toggle button
Usage
First, import the toggle group package into your project
import * as toggle from "@zag-js/toggle-group"
The toggle group package exports two key functions:
machine
— The state machine logic for the toggle group widget as described in the WAI-ARIA spec.connect
— The function that translates the machine's state to JSX attributes and event handlers.
You'll need to provide a unique
id
to theuseMachine
hook. This is used to ensure that every part has a unique identifier.
Next, import the required hooks and functions for your framework and use the toggle group machine in your project 🔥
import { normalizeProps, useMachine } from "@zag-js/react" import * as toggle from "@zag-js/toggle-group" import { useId } from "react" export function ToggleGroup() { const [state, send] = useMachine(toggle.machine({ id: useId() })) const api = toggle.connect(state, send, normalizeProps) return ( <div {...api.rootProps}> <button {...api.getToggleProps({ value: "bold" })}>B</button> <button {...api.getToggleProps({ value: "italic" })}>I</button> <button {...api.getToggleProps({ value: "underline" })}>U</button> </div> ) }
import * as toggle from "@zag-js/toggle-group" import { normalizeProps, useMachine } from "@zag-js/vue" import { defineComponent, computed, h, Fragment } from "vue" export default defineComponent({ name: "ToggleGroup", setup() { const [state, send] = useMachine(toggle.machine({ id: "1" })) const apiRef = computed(() => toggle.connect(state.value, send, normalizeProps), ) return () => { const api = apiRef.value return ( <div {...api.rootProps}> <button {...api.getToggleProps({ value: "bold" })}>B</button> <button {...api.getToggleProps({ value: "italic" })}>I</button> <button {...api.getToggleProps({ value: "underline" })}>U</button> </div> ) } }, })
<script setup> import * as toggle from "@zag-js/toggle-group" import { normalizeProps, useMachine } from "@zag-js/vue"; import { computed } from "vue"; const [state, send] = useMachine(toggle.machine({ id: createUniqueId() })) const api = computed(() => toggle.connect(state.value, send, normalizeProps)) </script> <template> <div v-bind="api.rootProps"> <button v-bind="api.getToggleProps({ value: 'bold' })">B</button> <button v-bind="api.getToggleProps({ value: 'italic' })">I</button> <button v-bind="api.getToggleProps({ value: 'underline' })">U</button> </div> </template>
import { normalizeProps, useMachine } from "@zag-js/solid" import * as toggle from "@zag-js/toggle-group" import { createMemo, createUniqueId } from "solid-js" export function ToggleGroup() { const [state, send] = useMachine(toggle.machine({ id: createUniqueId() })) const api = createMemo(() => toggle.connect(state, send, normalizeProps)) return ( <div {...api().rootProps}> <button {...api().getToggleProps({ value: "bold" })}>B</button> <button {...api().getToggleProps({ value: "italic" })}>I</button> <button {...api().getToggleProps({ value: "underline" })}>U</button> </div> ) }
Changing the orientation
By default, the toggle group is assumed to be horizontal. To change the
orientation to vertical, set the orientation
property in the machine's context
to vertical
.
const [state, send] = useMachine( toggle.machine({ orientation: "vertical", }), )
Listening for value changes
When the pressed toggle in the group changes, onValueChange
callback is
invoked.
const [state, send] = useMachine( toggle.machine({ onValueChange(details) { // details => { value: string[] } console.log(details.value) }, }), )
Allowing multiple selection
Set the multiple
property in the machine's context to true
to allow multiple
options to be toggled.
const [state, send] = useMachine( toggle.machine({ multiple: true, }), )
Disabling the toggle group
Set the disabled
property in the machine's context to true
to disable the
toggle group.
const [state, send] = useMachine( toggle.machine({ disabled: true, }), )
Disabling a toggle
Set the disabled
property in the getToggleProps
function to true
to
disable a toggle.
//... <div {...api.rootProps}> <button {...api.getToggleProps({ value: "bold", disabled: true })}>B</button> </div> //...
Disabling focus loop
The toggle group loops keyboard navigation by default. To disable this, set the
loop
property in the machine's context to false
.
const [state, send] = useMachine( toggle.machine({ loop: false, }), )
Disabling roving focus management
The toggle group uses roving focus management by default. To disable this, set
the rovingFocus
property in the machine's context to false
.
const [state, send] = useMachine( toggle.machine({ rovingFocus: false, }), )
Styling Guide
Earlier, we mentioned that each toggle group part has a data-part
attribute
added to them to select and style them in the DOM.
Pressed State
The toggle is pressed, the data-state
attribute is applied to the toggle
button with on
or off
values.
[data-part="toggle"][data-state="on|off"] { /* styles for toggle button */ }
Focused State
When a toggle button is focused, the data-focus
is applied to the root and
matching toggle button.
[data-part="root"][data-focus] { /* styles for the root */ } [data-part="toggle"][data-focus] { /* styles for the toggle */ }
Disabled State
When a toggle button is disabled, the data-disabled
is applied to the root and
matching toggle button.
[data-part="root"][data-disabled] { /* styles for the root */ } [data-part="toggle"][data-disabled] { /* styles for the toggle */ }
Methods and Properties
The toggle group's api
provides properties and methods you can use to
programmatically read and set the toggle group's value.
value
string[]
The value of the toggle group.setValue
(values: string[]) => void
Function to set the value of the toggle group.
Edit this page on GitHub