Skip to main content

A radio group lets users select one option from a set.

Loading...

Features

  • Syncs with disabled state of fieldset
  • Syncs with form reset events
  • Can programmatically set radio group value
  • Can programmatically focus and blur radio items

Installation

Install the radio package:

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

Anatomy

To set up the radio 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.

Usage

Import the radio group package:

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

The radio package exports two key functions:

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

Pass a unique id to useMachine so generated element ids stay predictable.

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 = [ { id: "apple", label: "Apples" }, { id: "orange", label: "Oranges" }, { id: "mango", label: "Mangoes" }, { id: "grape", label: "Grapes" }, ] const service = useMachine(radio.machine, { id: "1" }) const api = computed(() => radio.connect(service, normalizeProps)) </script> <template> <div v-bind="api.getRootProps()"> <h3 v-bind="api.getLabelProps()">Fruits</h3> <div v-for="opt in items" :key="opt.id"> <label v-bind="api.getItemProps({ value: opt.id })"> <span v-bind="api.getItemTextProps({ value: opt.id })" >{{ opt.label }}</span > <input v-bind="api.getItemHiddenInputProps({ value: opt.id })" /> <div v-bind="api.getItemControlProps({ value: opt.id })" /> </label> </div> </div> </template>

Disabling the radio group

Set disabled to true to disable all radio items.

const service = useMachine(radio.machine, { disabled: true, })

Setting the initial value

Use the defaultValue property to set the radio group's initial value.

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

Controlled value

Use value and onValueChange to control selection externally.

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

Listening for changes

When the radio group value changes, the onValueChange callback is invoked.

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

Usage within forms

To use radio group in forms, set name.

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

Set form if the radio inputs should submit with a form outside the current DOM subtree.

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

Vertical orientation

Set orientation when you need a vertical layout.

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

Read-only and required state

Use readOnly and required to control form behavior.

const service = useMachine(radio.machine, { readOnly: true, required: true, })

Invalid state

Set invalid to style and expose invalid form state.

const service = useMachine(radio.machine, { invalid: true, })

Styling guide

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

Checked State

When the radio input is checked, the data-state attribute is added to the item, control, and label parts.

[data-part="radio"][data-state="checked|unchecked"] { /* styles for radio checked or unchecked state */ } [data-part="radio-control"][data-state="checked|unchecked"] { /* styles for radio checked or unchecked state */ } [data-part="radio-label"][data-state="checked|unchecked"] { /* styles for radio checked or unchecked state */ }

Focused State

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

[data-part="radio"][data-focus] { /* styles for radio focus state */ } [data-part="radio-control"][data-focus] { /* styles for radio control 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, control and label parts.

[data-part="radio"][data-disabled] { /* styles for radio disabled state */ } [data-part="radio-control"][data-disabled] { /* styles for radio control 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, control and label parts.

[data-part="radio"][data-invalid] { /* styles for radio invalid state */ } [data-part="radio-control"][data-invalid] { /* styles for radio control 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

Accessibility

Adheres to the Radio Group WAI-ARIA design pattern

Keyboard Interactions

  • Tab
    Moves focus to either the checked radio item or the first radio item in the group.
  • Space
    When focus is on an unchecked radio item, checks it.
  • ArrowDown
    Moves focus and checks the next radio item in the group.
  • ArrowRight
    Moves focus and checks the next radio item in the group.
  • ArrowUp
    Moves focus to the previous radio item in the group.
  • ArrowLeft
    Moves focus to the previous radio item in the group.
Edit this page on GitHub