Skip to content

Radio Group

Picks exactly one option from a short list, as classic radios or as selectable cards with a title and description.

Preview

Statement frequency

Installation

pnpm add @syntara/react @syntara/tokens
import { RadioGroup, Radio } from '@syntara/react';

Usage

import { Radio, RadioGroup } from '@syntara/react';

export function Payout() {
  return (
    <RadioGroup variant="card" label="How should we pay you?" defaultValue="bank">
      <Radio value="bank" description="1–2 working days. No fee.">Bank transfer</Radio>
      <Radio value="instant" description="In minutes. 1% fee.">Instant payout</Radio>
    </RadioGroup>
  );
}

Examples

Cards

variant="card": the whole card is the target; the description is linked, not part of the name.

How should we pay you?
Arrives in 1–2 working days. No fee.
Arrives in minutes. 1% fee, capped at ₹50.
Posted to your registered address.

Cards in a row

Wraps to a column on narrow screens.

Plan
Up to 3 claims a year
Unlimited claims, priority review
Everything in Plus for up to 5 people

Horizontal

Account type

Invalid and disabled

Preferred contact time
Choose a time so we can call you back.
RegionSet by your employer.

Accessibility

KeysAction
TabMoves focus to the selected radio (or the first), then out of the group.
Arrow keysMove to and select the next/previous option, skipping disabled ones.
SpaceSelects the focused radio if nothing is selected.
  • Uses native radio inputs inside a radiogroup.
  • In the card variant the label stretches over the card, so the whole card is clickable, and the focus ring is drawn around the card.
  • Selected cards get a 2px primary edge and a tinted fill, not colour alone.

Guidelines

Do

  • Use for 2–6 mutually exclusive options that should all be visible.
  • Use cards when each option needs a sentence of explanation (fees, timing).
  • Preselect a sensible default when there is one.

Don’t

  • Don't use radios for more than about 7 options; use a Select.
  • Don't put interactive elements inside a card; the whole card is the target.

API reference

RadioGroup

label
ReactNode

Group label. Without one, pass aria-label.

description
ReactNode

Help text under the group label.

errorMessage
string | ((validation: ValidationResult) => string)

Shown with an icon when invalid.

variant
  • defaultdefault
  • card

card renders each Radio as a selectable card (title = children, plus description).

orientation
  • horizontal
  • verticaldefault

Layout. Horizontal cards share the row and wrap when narrow.

value / defaultValue
string | null

Controlled / uncontrolled selected value.

onChange
(value: string) => void

Called when the selection changes.

isRequired / isInvalid / isDisabled
boolean

Validation and disabled state.

Default false

Radio

valueRequired
string

Unique value of this option.

children
ReactNode

The label (the card title in the card variant).

description
ReactNode

Secondary text, linked with aria-describedby.

isDisabled
boolean

Disables this option; arrow keys skip it.

Default false

Tokens

The semantic tokens this component reads, grouped by what they control. Swatches show this site’s theme; change a tenant’s brand and the component follows with no code change.

Colour15
action.primary.bgaction.primary.fgaction.primary.hoverborder.defaultborder.strongborder.subtlefeedback.danger.onSolidfeedback.danger.solidfocus.ringsurface.defaultsurface.selectedsurface.sunkentext.defaulttext.disabledtext.subtle
Type4
font.size.mdfont.size.smfont.weight.mediumline-height.normal
Space and size8
control-heightspace.1space.16space.2space.3space.4space.5space.6
Shape1
radius.field
Depth2
shadow.highlightshadow.raised
Motion5
motion.duration.fastmotion.duration.springmotion.easingmotion.springmotion.duration.normal