Skip to main content
In progress

Radio

A Radio Group is a collection of individual Radios that allows users to select one option from a small, clearly defined set.

Preferred contact method
Code example
import { Radio, RadioGroup } from '@yleisradio/yds-components-react';

<RadioGroup
id="contact-pref"
name="contact"
label="Preferred contact method"
selectedValue="email"
onChange={() => {}}
>
<Radio value="email" label="Email" />
<Radio value="sms" label="SMS" />
<Radio value="phone" label="Phone" />
</RadioGroup>

Why to use

Radio Groups provide a structured, accessible, and consistent way for users to make a single choice within forms, settings, or surveys. They make comparisons easy by displaying all options side by side, clarify the selection context through group labels and helper text, and visually communicate that only one option can be active at a time.

When to use

Use a RadioGroup when users must select one option from a small, mutually exclusive set and all choices should be visible for comparison—common in forms, preferences, settings, and survey questions. Use NumericScale when the selection represents a point on a low-to-high range, such as satisfaction, agreement, or rating scales.

Differences between RadioGroup types

TypePurposePlacementUse case
RadioGroupOne mutually exclusive choice from a short list.Mostly vertical; horizontal only for short labels.Form questions, settings, preference selections (e.g., “Sähköposti”, “SMS”, “Puhelu”).
NumericScaleChoosing a point on a defined numerical range.Horizontal with clearly labelled endpoints.Ratings, satisfaction scores, Likert-style scales (e.g., “En pitänyt” – “Pidin erittäin paljon”).
Do
  • Use for single-choice decisions with a small number of options (typically 2–5).
  • Ensure all options are visible and directly comparable.
  • Provide a clear group label (and optional description for context).
  • Prefer vertical layout; use horizontal only for short labels or numeric scales.
  • Use NumericScale for range-based or Likert-style questions.
  • Provide a preselected default when a recommended option exists.
Don’t
  • Don’t use for multiple selections—use Checkboxes instead.
  • Don’t use for binary toggles—use a Switch.
  • Don’t use when the list is long—use Select or Combobox.
  • Don’t hide the group label or mix unrelated answer types.
  • Don’t use long or ambiguous option labels.

Content Guidelines

Radio group labels and option text should be short, comparable, and unambiguous. Users must be able to scan the list quickly and clearly understand the difference between choices.

Do
  • Write a concise group label that reads like a question or heading.(e.g., “Mieluisin yhteydenottotapa”)
  • Keep option labels short and parallel in structure.(e.g., “Sähköposti”, “SMS”, “Puhelu”)
  • Use the group description for brief clarification when needed.
  • For NumericScale, label both ends of the range clearly.(e.g., “En pitänyt” – “Pidin erittäin paljon”)
Don’t
  • Don’t use long sentences as option labels—move explanations to the description.
  • Don’t create overlapping or unclear choices.
  • Don’t repeat label wording in each option.
  • Don’t mix different answer types in one group.

Anatomy

Radio anatomy

  1. Group label – Defines the purpose of the group.
  2. Description – Optional helper text below the label.
  3. Radio control – Circular selector; only one can be active.
  4. Option label – Text linked to each radio choice.

Key Radio Props

Use the following props to customize the Radio component to fit your needs.

variant

ValueExampleDescription
primaryDefault style for most use cases.
secondaryUses highlight color for the control.
Code example
<Radio variant="primary" value="email" label="Email" checked />
<Radio variant="secondary" value="email" label="Email" checked />

isDisabled

Non-interactive, dimmed styling.

TypeExampleDescription
booleanTemporarily prevents user interaction.
Code example
<Radio value="email" label="Email" isDisabled checked />

hideLabel

TypeExampleDescription
booleanVisually hides label but keeps it accessible.
Code example
<Radio value="email" label="Email" hideLabel />

controlAlign

ValueExampleDescription
startPositions the control before the label text.
endPositions the control after the label text.
Code example
<Radio value="email" label="Email" controlAlign="start" />
<Radio value="email" label="Email" controlAlign="end" />

Key RadioGroup Props

Use the following props to customize the RadioGroup component to fit your needs.

label

TypeExampleDescription
string
Contact method
Text label describing the purpose of the group.
Code example
<RadioGroup
id="contact"
name="contact"
label="Contact method"
onChange={() => {}}
>
<Radio label="Email" value="email" />
<Radio label="Phone" value="phone" />
</RadioGroup>

description

Helper guidance placed below the group label.

TypeExampleDescription
string
Contact method
How should we reach you?
Provides additional context or instructions for the group.
Code example
<RadioGroup
id="contact"
name="contact"
label="Contact method"
description="How should we reach you?"
onChange={() => {}}
>
<Radio label="Email" value="email" />
<Radio label="Phone" value="phone" />
</RadioGroup>

errorMessage

TypeExampleDescription
string
Contact method
Shows an error message and applies error styles to the group.
Code example
<RadioGroup
id="contact"
name="contact"
label="Contact method"
errorMessage="Please select a contact method"
onChange={() => {}}
>
<Radio label="Email" value="email" />
<Radio label="Phone" value="phone" />
</RadioGroup>

direction

Layout orientation of the radio options.

ValueExampleDescription
vertical
Contact method
Stacks radios vertically (default).
horizontal
Contact method
Arranges radios horizontally.
Code example
<RadioGroup
id="contact"
name="contact"
label="Contact method"
direction="vertical"
onChange={() => {}}
>
<Radio label="Email" value="email" />
<Radio label="Phone" value="phone" />
</RadioGroup>

<RadioGroup
id="contact"
name="contact"
label="Contact method"
direction="horizontal"
onChange={() => {}}
>
<Radio label="Email" value="email" />
<Radio label="Phone" value="phone" />
</RadioGroup>

RadioGroupNumericScale (Likert / Rating)

Extends RadioGroup with optional semantic boundary labels.

PropTypeDefaultDescription
startLabelstringText describing the low end of the scale (e.g. "Not at all").
endLabelstringText describing the high end (e.g. "Very satisfied").
Code example
<RadioGroupNumericScale
id="satisfaction"
name="satisfaction"
label="Satisfaction"
startLabel="Low"
endLabel="High"
direction="horizontal"
selectedValue="3"
onChange={() => {}}
>
<Radio value="1" label="1" />
<Radio value="2" label="2" />
<Radio value="3" label="3" />
<Radio value="4" label="4" />
<Radio value="5" label="5" />
</RadioGroupNumericScale>

Behavior

  • Only one option can be selected at a time; choosing a new one deselects the previous.
  • Radios in the same group share the same name attribute to ensure correct selection and navigation.
  • The group label defines the question or context for all options.
  • Use vertical layout for readability and horizontal for compact or scale-type choices.
  • Disabled Radios remain visible but non-interactive.
  • Supports both controlled (selectedValue, onChange) and uncontrolled (defaultChecked) usage.
  • Error messages appear below the group and guide users to correct input.

Accessibility

Implementation examples

With description

Preferred learning method
Choose the learning method that best supports your studying.
Code example
<RadioGroup
id="newsletter"
name="newsletter"
label="Preferred learning method"
description=" Choose the learning method that best supports your studying."
selectedValue="weekly"
onChange={() => {}}
>
<Radio value="online" label="Online self-paced courses" />
<Radio value="classroom" label="Instructor-led classroom training" />
<Radio value="hybrid" label="Hybrid sessions" />
<Radio value="group" label="Group discussions" />
<Radio value="independent" label="Independent study" />
</RadioGroup>

With error message

Preferred learning method
Choose the learning method that best supports your studying.
Code example
<RadioGroup
id="newsletter"
name="newsletter"
label="Preferred learning method"
description=" Choose the learning method that best supports your studying."
errorMessage="Please select a preference"
onChange={() => {}}
>
<Radio value="online" label="Online self-paced courses" />
<Radio value="classroom" label="Instructor-led classroom training" />
<Radio value="hybrid" label="Hybrid sessions" />
<Radio value="group" label="Group discussions" />
<Radio value="independent" label="Independent study" />
</RadioGroup>

Numeric scale rating

Did you like this article?
Did not likeLiked a lot
Code example
<RadioGroupNumericScale
id="article"
name="article"
label="Did you like this article?"
startLabel="Did not like"
endLabel="Liked a lot"
direction="horizontal"
selectedValue="3"
onChange={() => {}}
>
<Radio value="1" label="1" />
<Radio value="2" label="2" />
<Radio value="3" label="3" />
<Radio value="4" label="4" />
<Radio value="5" label="5" />
</RadioGroupNumericScale>

See more examples in Storybook

API Reference

Props

Radio

The Radio component accepts all standard HTML <input> attributes in addition to the following props:

PropTypeRequiredDefaultDescription
variantVariantTypeNo'primary'
isDisabledbooleanNofalse
errorbooleanNo
labelReactNodeYes
namestringNo
hideLabelbooleanNofalse
useUnderlaybooleanNofalse
onChange(event: ChangeEvent<HTMLInputElement>) => voidNo
controlAlignInputControlAlignNo'start'

RadioGroup

The RadioGroup component accepts the following props:

PropTypeRequiredDefaultDescription
idstringYes
namestringYes
selectedValuestringNo
errorMessagestringNo
labelstringNo
labelOptionsFormGroupLabelPropsNo
descriptionstringNo
childrenReactNodeYes
directionRadioGroupDirectionNo'vertical'
onChange(event: ChangeEvent<HTMLInputElement>) => voidYes

RadioGroupNumericScale

The RadioGroupNumericScale component extends RadioGroup and accepts the following additional props:

PropTypeRequiredDefaultDescription
startLabelstringNo
endLabelstringNo

Type Definitions

Radio

export type VariantType = 'primary' | 'secondary';
export type InputControlAlign = 'start' | 'end';
export type RadioGroupDirection = 'vertical' | 'horizontal';

export interface RadioDSProps {
variant?: VariantType;
isDisabled?: boolean;
error?: boolean;
label: ReactNode;
name?: string;
hideLabel?: boolean;
useUnderlay?: boolean;
onChange?: (event: ChangeEvent<HTMLInputElement>) => void;
controlAlign?: InputControlAlign;
}

export type RadioProps = InputHTMLAttributes<HTMLInputElement> & RadioDSProps;

RadioGroup

export interface RadioGroupProps {
id: string;
name: string;
selectedValue?: string;
errorMessage?: string;
label?: string;
labelOptions?: FormGroupLabelProps;
description?: string;
children: ReactNode;
direction?: RadioGroupDirection;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
}

RadioGroupNumericScale

export interface RadioGroupNumericScaleProps extends RadioGroupProps {
startLabel?: string;
endLabel?: string;
}
  • Checkbox: For multiple independent selections.
  • Switch: Immediate binary toggles.
  • ChoiceBox: Alternative visual single-choice pattern.