Radio
Introduction
Section titled “Introduction”Radio stores a single selected key from a fixed option set — plans, statuses, or any exclusive choice that should stay visible rather than hidden in a dropdown. Prefer Select for long lists, and Checkbox list when users may pick more than one.
Each variation below includes a short explanation, the fluent API to paste into your schema, and light/dark screenshots of the rendered control.
Basic radio
Section titled “Basic radio”.options() maps values to labels. Exactly one radio in the group may be selected; state is that key (or empty when none is chosen).
Radio.make('plan') .label('Plan') .options({ 'starter': 'Starter', 'pro': 'Pro', 'enterprise': 'Enterprise', })

Option descriptions
Section titled “Option descriptions”.descriptions() adds secondary copy under each matching option. Keys must align with .options() so the right helper sits under the right label.
Radio.make('plan') .label('Plan') .options({ 'starter': 'Starter', 'pro': 'Pro', 'enterprise': 'Enterprise', }) .descriptions({ 'starter': 'For side projects and prototypes.', 'pro': 'For growing teams shipping weekly.', 'enterprise': 'SSO, audit logs, and dedicated support.', })

Multi-column layout
Section titled “Multi-column layout”.options_columns(n) arranges radios in a grid. Two or three columns work well for short plan names; keep descriptions concise so cells do not collide.
Radio.make('plan') .label('Plan') .options({ 'starter': 'Starter', 'pro': 'Pro', 'enterprise': 'Enterprise', 'custom': 'Custom', }) .options_columns(2)

Boolean options
Section titled “Boolean options”.boolean() swaps custom options for Yes / No (1 / 0) — a radio-group alternative to Checkbox when you want both answers explicit and equally weighted.
Radio.make('feedback') .label('Like this post?') .boolean()

Disabling specific options
Section titled “Disabling specific options”.disable_option_when() greys out individual radios when their value should not be choosable — for example a published status reserved for another workflow.
Radio.make('status') .label('Status') .options({ 'draft': 'Draft', 'scheduled': 'Scheduled', 'published': 'Published', }) .disable_option_when(lambda value, **_: value == 'published')

Closures work on .label(), .helper_text(), .placeholder(), .visible(), .disabled(), and .required() where applicable — see Form closures.