Skip to content
Destyler UI Destyler UI Destyler UI

Radio

A radio group allows users to make a single choice from a select number of option.

Features

Install

Install the component from your command line.

Terminal window
      
        
npm install @destyler/{radio,vue}
Terminal window
      
        
npm install @destyler/{radio,react}
Terminal window
      
        
npm install @destyler/{radio,svelte}
Terminal window
      
        
npm install @destyler/{radio,solid}

Anatomy

Import all parts and piece them together.

<script setup lang="ts">
import * as radio from '@destyler/radio'
import { normalizeProps, useMachine } from '@destyler/vue'
import { computed, useId } from 'vue'
const [state, send] = useMachine(radio.machine({
id: useId(),
}))
const api = computed(() => radio.connect(state.value, send, normalizeProps))
</script>
<template>
<div v-bind="api.getRootProps()">
<label v-bind="api.getItemProps({ value: '0' })">
<input v-bind="api.getItemHiddenInputProps({ value: '0' })">
<div v-bind="api.getItemControlProps({ value: '0' })"/>
<span v-bind="api.getItemTextProps({ value: '0' })" />
</label>
</div>
</template>
import * as radio from '@destyler/radio'
import { normalizeProps, useMachine } from '@destyler/react'
import { useId } from 'react'
export default function Radio() {
const [state, send] = useMachine(radio.machine({
id: useId(),
}))
const api = radio.connect(state, send, normalizeProps)
return (
<div {...api.getRootProps()} >
<label {...api.getItemProps({ value: '0' })} >
<input {...api.getItemHiddenInputProps({ value: '0' })} />
<div {...api.getItemControlProps({ value: '0' })} />
<span {...api.getItemTextProps({ value: '0' })}></span>
</label>
</div>
)
}
<script lang="ts">
import * as radio from '@destyler/radio'
import { normalizeProps, useMachine } from '@destyler/svelte'
const id = $props.id()
const [state, send] = useMachine(radio.machine({
id,
}))
const api = $derived(radio.connect(state, send, normalizeProps))
</script>
<div {...api.getRootProps()}>
<label {...api.getItemProps({ value: '0' })} >
<input {...api.getItemHiddenInputProps({ value: '0' })}>
<div {...api.getItemControlProps({ value: '0' })}></div>
<span {...api.getItemTextProps({ value: '0' })} ></span>
</label>
</div>
import * as radio from '@destyler/radio'
import { normalizeProps, useMachine } from '@destyler/solid'
import { createMemo, createUniqueId } from 'solid-js'
export default function Radio() {
const [state, send] = useMachine(radio.machine({
id: createUniqueId(),
}))
const api = createMemo(() => radio.connect(state, send, normalizeProps))
return (
<div {...api().getRootProps()} >
<label {...api().getItemProps({ value: '0' })}>
<input {...api().getItemHiddenInputProps({ value: '0' })} />
<div {...api().getItemControlProps({ value: '0' })} />
<span {...api().getItemTextProps({ value: '0' })} ></span>
</label>
</div>
)
}

Disabling the radio group

To make a radio disabled, set the context’s disabled property to true

const [state, send] = useMachine(
radio.machine({
disabled: true,
}),
)

Setting the initial value

To set the radio initial value, set the context’s value property to the value of the radio item to be selected by default

const [state, send] = useMachine(
radio.machine({
value: "apple",
}),
)

Listening for changes

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

const [state, send] = useMachine(
radio.machine({
onValueChange(details) {
// details => { value: string }
console.log("radio value is:", details.value)
},
}),
)

Usage within forms

To use radio group within forms, use the exposed inputProps from the connect function and ensure you pass name value to the destyler’s context. It will render a hidden input and ensure the value changes get propagated to the form correctly.

const [state, send] = useMachine(
radio.machine({
name: "fruits",
}),
)

Styling guide

Earlier, we mentioned that each Radio part has a data-part attribute added to them to select and style them in the DOM.

Checked State

When the radio input is checked, the data-state attribute is added to the

[data-part="radio"][data-state="checked"] {
/* styles for radio checked or unchecked state */
}
[data-part="radio-control"][data-state="checked"] {
/* styles for radio checked or unchecked state */
}
[data-part="radio-label"][data-state="checked"] {
/* 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 otp input machine exposes the following context properties:

ids
Partial<{ 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.
value
string
The value of the checked radio
name
string
The name of the input fields in the radio (Useful for form submission).
form
string
The associate form of the underlying input.
disabled
boolean
If `true`, the radio will be disabled
readOnly
boolean
Whether the checkbox is read-only
onValueChange
(details: ValueChangeDetails) => void
Function called once a radio is checked
orientation
"horizontal" | "vertical"
Orientation of the radio
dir
"ltr" | "rtl"
The document's text/writing direction.
id
string
The unique identifier of the machine.
getRootNode
() => ShadowRoot | Node | Document
A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The radio api exposes the following methods:

value
string
The current value of the radio
setValue
(value: string) => void
Function to set the value of the radio
clearValue
() => void
Function to clear the value of the radio
focus
() => void
Function to focus the radio
getItemState
(props: ItemProps) => ItemState
Returns the state details of a radio input

Accessibility

Keyboard Interaction

name
desc
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.