Skip to main content

A segmented control lets users pick one option from a small set.

Loading...

Features

  • Syncs with disabled state of fieldset
  • Syncs with form reset events
  • Can programmatically set segmented control value
  • Can programmatically focus segmented control items

Installation

Install the radio group package:

npm install @zag-js/radio-group @zag-js/vue # or yarn add @zag-js/radio-group @zag-js/vue

Anatomy

Check the segmented control anatomy and part names.

Each part includes a data-part attribute to help identify them in the DOM.

Usage

Import the radio group package:

import * as radio from "@zag-js/radio-group"

These are the key exports:

  • machine - State machine logic.
  • connect - Maps machine state to JSX props and event handlers.

Then use the framework integration helpers:

<script setup> import * as radio from "@zag-js/radio-group" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed } from "vue" const items = [ { label: "React", value: "react" }, { label: "Angular", value: "ng" }, { label: "Vue", value: "vue" }, { label: "Svelte", value: "svelte" }, ] const service = useMachine(radio.machine, { id: "1" }) const api = computed(() => radio.connect(service, normalizeProps)) </script> <template> <div v-bind="api.getRootProps()"> <div v-bind="api.getIndicatorProps()" /> <div v-for="opt in items" :key="opt.value"> <label v-bind="api.getItemProps({ value: opt.value })"> <span v-bind="api.getItemTextProps({ value: opt.value })" >{{ opt.label }}</span > <input v-bind="api.getItemHiddenInputProps({ value: opt.value })" /> </label> </div> </div> </template>

Setting the initial value

Use the defaultValue property to set the segmented control's initial value.

const service = useMachine(radio.machine, { defaultValue: "apple", })

Controlled segmented value

Use value and onValueChange for controlled usage.

const service = useMachine(radio.machine, { value, onValueChange(details) { setValue(details.value) }, })

Programmatic value control

Use the connected API when you need imperative updates.

api.setValue("orange") api.clearValue()

Focusing from code

Use api.focus() to move focus to the selected item (or first enabled item).

api.focus()

Listening for changes

When the segmented control value changes, the onValueChange callback is invoked.

const service = useMachine(radio.machine, { onValueChange(details) { // details => { value: string | null } console.log("segmented control value is:", details.value) }, })

Usage within forms

To use segmented control in forms, set name and render api.getItemHiddenInputProps({ value }) for each item.

const service = useMachine(radio.machine, { name: "fruits", })

Vertical orientation

Set orientation when you need a vertical layout.

const service = useMachine(radio.machine, { orientation: "vertical", })

Styling guide

Each part includes a data-part attribute you can target in CSS.

Indicator

Style the segmented control Indicator through the indicator part.

[data-part="indicator"] { /* styles for indicator */ }

Focused State

When the radio input is focused, the data-focus attribute is added to the root and label parts.

[data-part="radio"][data-focus] { /* styles for radio focus state */ } [data-part="radio-label"][data-focus] { /* styles for radio label focus state */ }

Disabled State

When the radio is disabled, the data-disabled attribute is added to the root and label parts.

[data-part="radio"][data-disabled] { /* styles for radio disabled state */ } [data-part="radio-label"][data-disabled] { /* styles for radio label disabled state */ }

Invalid State

When the radio is invalid, the data-invalid attribute is added to the root and label parts.

[data-part="radio"][data-invalid] { /* styles for radio invalid state */ } [data-part="radio-label"][data-invalid] { /* styles for radio label invalid state */ }

Methods and Properties

Machine Context

The radio group machine exposes the following context properties:

  • idsPartial<{ root: string; label: string; indicator: string; item: (value: string) => string; itemLabel: (value: string) => string; itemControl: (value: string) => string; itemHiddenInput: (value: string) => string; }>The ids of the elements in the radio. Useful for composition.
  • valuestringThe controlled value of the radio group
  • defaultValuestringThe initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group.
  • namestringThe name of the input fields in the radio (Useful for form submission).
  • formstringThe associate form of the underlying input.
  • disabledbooleanIf `true`, the radio group will be disabled
  • invalidbooleanIf `true`, the radio group is marked as invalid.
  • requiredbooleanIf `true`, the radio group is marked as required.
  • readOnlybooleanWhether the radio group is read-only
  • onValueChange(details: ValueChangeDetails) => voidFunction called once a radio is checked
  • orientation"horizontal" | "vertical"Orientation of the radio group
  • dir"ltr" | "rtl"The document's text/writing direction.
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The radio group api exposes the following methods:

  • valuestringThe current value of the radio group
  • setValue(value: string) => voidFunction to set the value of the radio group
  • clearValueVoidFunctionFunction to clear the value of the radio group
  • focusVoidFunctionFunction to focus the radio group
  • getItemState(props: ItemProps) => ItemStateReturns the state details of a radio input

Data Attributes

Root
data-scope
radio-group
data-part
root
data-orientation
The orientation of the radio-group
data-disabled
Present when disabled
data-invalid
Present when invalid
data-required
Present when required
Label
data-scope
radio-group
data-part
label
data-orientation
The orientation of the label
data-disabled
Present when disabled
data-invalid
Present when invalid
data-required
Present when required
ItemControl
data-scope
radio-group
data-part
item-control
data-active
Present when active or pressed
Indicator
data-scope
radio-group
data-part
indicator
data-disabled
Present when disabled
data-orientation
The orientation of the indicator
Edit this page on GitHub