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.
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 without taking ownership of state, use defaultValue (the value of the radio item to select). Prefer this over seeding with value (presence-controlled after Phase 2).
const [state, send] = useMachine( radio.machine({ defaultValue: "apple", }),)Controlled usage
Radio group value can be uncontrolled or controlled. Prefer defaultValue for an uncontrolled seed. Passing value into machine(...) is presence-controlled — sync with onValueChange and adapter context. See Controllable State.
const value = "apple" // your reactive stateradio.machine({ id: "1", value, onValueChange(details) { // details => { value: string | null } },})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-partattribute 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:
Partial<{ root: string; label: string; indicator: string; item: (value: string) => string; itemLabel: (value: string) => string; itemControl: (value: string) => string; itemHiddenInput: (value: string) => string; }>stringstringstringstringbooleanboolean(details: ValueChangeDetails) => void"horizontal" | "vertical""ltr" | "rtl"string() => ShadowRoot | Node | DocumentMachine API
The radio api exposes the following methods:
string(value: string) => void() => void() => void(props: ItemProps) => ItemStateData Attributes
Root
data-scopedata-partdata-orientationdata-disabledLabel
data-scopedata-partdata-orientationdata-disabledItem Control
data-scopedata-partdata-activeIndicator
data-scopedata-partdata-disableddata-orientationAccessibility
Keyboard Interaction
TabSpaceArrowDownArrowRightArrowUpArrowLeft