Playground
Every control sets a real prop of RadioProps. The JSX below updates as you go.
Web
iOS
Android
JSX · RadioProps
Variants
3 examples from src/atoms/radio/radio.md, each rendered live from its own JSX.
Sizes
States
Hover, focus and press are pinned so they can be compared side by side; the rest are real props.
Anatomy
1
Ring
2
Dot
3
Label
4
Description
Dimmed parts appear only in some states or variants.
Props
15 props on RadioProps, grouped as they are declared in source. Required props are marked *.
Accessibility and keyboard
Keyboard
Tab
Enters the group on the checked option
ArrowDown
ArrowRight
Checks the next option
ArrowUp
ArrowLeft
Checks the previous option
Space
Checks the focused option
Semantics
Roles
radio
States
checked
disabled
ARIA on web
aria-checked
aria-hidden
aria-label
Below the platform minimum, the touch area grows to 44 pt on iOS and 48 dp on Android without moving the layout.
From the docs
Pass ref to access the interactive radio row, preserving group navigation. Use useRef<ComponentRef<typeof Radio>>(null) from React, or useRef<View>(null) with React Native's View type. Object and callback refs are supported and detach on unmount. Calling ref.current?.focus() or .blur() delegates to the host without activating the control. Browser focus is supported; native focus depends on the platform and React Native version, and is separate from accessibility focus.
On the web, Space activates the focused control on key release, and Enter also activates it. Holding Space does not repeat the change. Moving focus away, disabling the control, or composing text cancels a pending Space press. RadioGroup arrow keys continue to move focus and selection.
Platform skins
The playground's props on each platform: same tree, native shapes, type and touch sizes.
Usage
One job, a platform's own control: iOS has no radio button, so there a single choice is a checkmark list, the inline picker of a grouped form. Each option's label leads and the chosen option carries a trailing check, and a RadioGroup's options form one inset-grouped section with a hairline between two rows. The web and Android keep the ring, and the role is radio on every platform: on the web an 18 px ring (16 small, 22 large) whose edge thickens in the accent around a hollow center when chosen, on Android Material 3's 20dp ring around an accent dot. In glass mode the ring keeps its solid look on every platform: a ring is a small mark inside content, not a surface, so it draws with no pane and no rim. A card option is a content-layer pane, as a selectable Card is. On iOS the list stays vertical when the group asks for a row (a list has no row form), and card options stay tiles that mark the choice with the same trailing check.
Pass ref to access the interactive radio row, preserving group navigation. Use useRef<ComponentRef<typeof Radio>>(null) from React, or useRef<View>(null) with React Native's View type. Object and callback refs are supported and detach on unmount. Calling ref.current?.focus() or .blur() delegates to the host without activating the control. Browser focus is supported; native focus depends on the platform and React Native version, and is separate from accessibility focus.
On the web, Space activates the focused control on key release, and Enter also activates it. Holding Space does not repeat the change. Moving focus away, disabling the control, or composing text cancels a pending Space press. RadioGroup arrow keys continue to move focus and selection.
Tokens
Read from the playground render. Values follow the scheme and the ion hue.
--fd
--ft
--ion
--ln2
--tx3