Inputs
RadioGroup A compound component for single-selection radio button groups.
npm pnpm yarn bun
npm install @morphos/inputs
import { RadioGroup, Radio } from '@morphos/inputs'
Component Description RadioGroupRoot container that manages selection state and renders role="radiogroup" RadioIndividual radio option within the group
@ Component ()
class MyComponent extends StatefulComponent {
@ State () group = new RadioGroup ({ defaultValue: 'monthly' , orientation: 'vertical' })
render () {
return (
< fieldset >
< legend >Billing cycle</ legend >
< RadioGroup class = "morphos-radio-group" orientation = "vertical" aria-label = "Billing cycle" >
< Radio group = { this .group} value = "monthly" class = "morphos-radio" >Monthly</ Radio >
< Radio group = { this .group} value = "quarterly" class = "morphos-radio" >Quarterly</ Radio >
< Radio group = { this .group} value = "annually" class = "morphos-radio" >Annually</ Radio >
</ RadioGroup >
</ fieldset >
)
}
}
Each Radio reads selection state from the group prop and calls group.select(value) on change — it must be given the same RadioGroup instance backing the rendered <RadioGroup> root so the two stay in sync.
@ Component ()
class MyComponent extends StatefulComponent {
@ State () group = new RadioGroup ({ orientation: 'vertical' })
applyTheme ( theme : string ) {
document.documentElement.dataset.theme = theme
}
render () {
return (
< fieldset >
< legend >Theme</ legend >
< RadioGroup
class = "morphos-radio-group"
value = {() => this .group.selectedValue}
orientation = "vertical"
onValueChange = {( value ) => this . applyTheme (value)}
>
< Radio group = { this .group} value = "light" class = "morphos-radio" >Light</ Radio >
< Radio group = { this .group} value = "dark" class = "morphos-radio" >Dark</ Radio >
< Radio group = { this .group} value = "system" class = "morphos-radio" >System</ Radio >
</ RadioGroup >
</ fieldset >
)
}
}
@ Component ()
class MyComponent extends StatefulComponent {
@ State () group = new RadioGroup ({ defaultValue: 's' , orientation: 'horizontal' })
render () {
return (
< fieldset >
< legend >Size</ legend >
< RadioGroup class = "morphos-radio-group" orientation = "horizontal" aria-label = "Size" >
< Radio group = { this .group} value = "s" class = "morphos-radio" >S</ Radio >
< Radio group = { this .group} value = "m" class = "morphos-radio" >M</ Radio >
< Radio group = { this .group} value = "l" class = "morphos-radio" >L</ Radio >
< Radio group = { this .group} value = "xl" class = "morphos-radio" >XL</ Radio >
</ RadioGroup >
</ fieldset >
)
}
}
Prop Type Default Description valuestring— Controlled selected value defaultValuestring— Uncontrolled initial selected value namestring— Shared name attribute intended for radios in the group disabledbooleanfalseDisables all radios in the group requiredbooleanfalseMarks the group as required (aria-required) orientation"vertical" | "horizontal""vertical"Sets aria-orientation and data-orientation onValueChange(value: string) => void— Fires when the selected value changes classstring— Additional CSS classes idstring— HTML id attribute childrenChildren— The Radio items aria-labelstring— Accessible label when no <legend> is present aria-labelledbystring— ID of an element that labels the group
Method Description select(value: string)Sets the group's selected value. Emits onValueChange with the new value.
Prop Type Default Description groupRadioGroup— The parent RadioGroup instance (required) valuestring— The value this radio represents (required) disabledboolean— Overrides the group's disabled for this radio only childrenChildren— Label content rendered beside the input, inside the same <label> classstring— Additional CSS classes on the <label> idstring— HTML id attribute on the <label> aria-labelstring— Accessible label for this individual radio's <input> aria-labelledbystring— ID of an element that labels this individual radio's <input>
Attribute Element When present data-disabledGroup root disabled is truedata-orientationGroup root Always — value is "vertical" or "horizontal" data-checkedRadio <label> This radio's value matches the group's selected value data-disabledRadio <label> Group's disabled or this radio's own disabled is true
RadioGroup renders a <div role="radiogroup"> with aria-orientation, aria-required, and aria-disabled. Each Radio renders a native <input type="radio"> wrapped in a <label>; all radios sharing the same group reuse the name from RadioGroup.name. Wrap the group in a <fieldset> with a <legend> to provide context to assistive technologies — RadioGroup does not render its own <fieldset>.
RadioGroup and Radio do not implement roving-tabindex or arrow-key navigation — each radio input is independently focusable via Tab, and selection changes with the native change event on click. If you need custom keyboard navigation between options, wire it up yourself.
.morphos-radio-group [ data-orientation = "horizontal" ] {
flex-direction : row ;
gap : var ( --morphos-space-4 );
}
.morphos-radio [ data-checked ] input [ type = "radio" ] {
border-color : var ( --morphos-color-accent );
}
.morphos-radio [ data-disabled ] {
opacity : 0.5 ;
cursor : not-allowed ;
}