A mutually exclusive choice control for the Quantum Design System.
The qds-radio-group component renders a set of qds-radio options where
exactly one can be selected at a time. It is form-associated and works
standalone or inside qds-field. The group owns everything; qds-radio is a
presentational leaf.
Use it for 2 to 5 mutually exclusive options where seeing all of them at
once helps the choice. Above 5 options, use qds-select.
Arrow-key difference from qds-select: In a radio group, arrow keys
SELECT ON MOVE — the ARIA radio-group pattern. Pressing ArrowDown or ArrowRight
moves to the next option and immediately selects it. In qds-select, arrow
keys only move an active option without selecting it; selection happens on
Enter or click. This difference is intentional: radio groups show all options
at once, and screen reader users expect arrow navigation to immediately select.
<qds-radio-group name="basis" label="Cost basis" value="fifo" required>
<qds-radio value="fifo" label="First in, first out"></qds-radio>
<qds-radio value="lifo" label="Last in, first out"></qds-radio>
<qds-radio value="avg" label="Average cost" hint="Weighted by quantity"></qds-radio>
</qds-radio-group>
options property<qds-radio-group name="basis" label="Cost basis"></qds-radio-group>
<script>
const group = document.querySelector('qds-radio-group');
group.options = [
{ value: 'fifo', label: 'First in, first out' },
{ value: 'lifo', label: 'Last in, first out' },
{ value: 'avg', label: 'Average cost', description: 'Weighted by quantity' },
];
</script>
Property options use the same QdsOption[] shape as qds-select, so data
can move between the two components without reshaping. When both property
options and slotted children are present, property options win and slotted
children are not rendered.
value - String. The selected radio’s value.label - String. Group label text.hint - String. Helper text below the options.error-text - String. Error message shown when invalid is true.name - String. Form field name.orientation - "vertical" | "horizontal". Layout direction. Default "vertical".size - "sm" | "md" | "lg". Control size for all child radios. Default "md".disabled - Boolean. Disables the entire group; cascades to all radios.readonly - Boolean. Blocks selection without dimming.required - Boolean. At least one radio must be selected.invalid - Boolean. Author-forced invalid state.value - String. Synced with the value attribute.options - QdsOption[]. Property only. Renders internal radios; wins over slotted children.label - String.hint - String.errorText - String.name - String.orientation - "vertical" | "horizontal".size - "sm" | "md" | "lg".disabled - Boolean.readonly - Boolean.required - Boolean.invalid - Boolean.validity - Read-only. Returns a QdsValidity object.checkValidity() - Returns boolean.reportValidity() - Returns boolean; also sets the visible error.setCustomValidity(message) - Sets a custom error; empty string clears it.value - String. The value this radio represents.label - String. Label text. Also settable as slotted text content.hint - String. Per-option helper text.disabled - Boolean. Disables this radio. Cannot un-disable inside a disabled group.checked - Boolean. Set by the group, not by authors.container - The outer wrapper.label - The group label.required - The required marker span.options - The options container.hint - The helper text.error - The error message.row - The clickable row.dot - The radio circle.dot-inner - The inner dot of a selected radio.label - The label text.hint - The per-option helper text.change - When selection changes. Detail: { component, value }.input - Same moment as change. Detail: { component, value }.qds-validity-change - When validity transitions. Detail: QdsValidityChangeEventDetail.| Key | Behaviour |
|---|---|
Tab |
Enters the group at the selected radio, then leaves the group entirely |
ArrowDown / ArrowRight |
Next enabled radio, wrapping; selects it and fires change |
ArrowUp / ArrowLeft |
Previous enabled radio, wrapping; selects it |
Space |
Selects the focused radio (no-op if already selected) |
Home / End |
First / last enabled radio, and selects it |
Disabled radios are skipped by arrow navigation entirely.
<form id="settings-form">
<qds-radio-group name="theme" label="Theme" value="light" required>
<qds-radio value="light" label="Light"></qds-radio>
<qds-radio value="dark" label="Dark"></qds-radio>
<qds-radio value="auto" label="System" hint="Follow the OS preference"></qds-radio>
</qds-radio-group>
</form>
<script>
document.querySelector('#settings-form').addEventListener('change', (e) => {
if (e.target.tagName === 'QDS-RADIO-GROUP') {
console.log('Selected:', e.detail.value);
}
});
</script>