Radio Group
Anatomy
Mutually exclusive set of radio buttons grouped under a semantic <fieldset> with a <legend>. Supports vertical/horizontal layout, density variants, and native form validation.
maud_ui::primitives::radio_group
Props
Generated from public Rust fields. Defaults are evaluated from the implementation.
| Prop | Type | Default | Description |
|---|---|---|---|
name | String | "" | No description |
label | String | "" | No description |
options | Vec<RadioOption> | [] | No description |
selected | Option<String> | None | No description |
orientation | Orientation | Vertical | No description |
disabled | bool | false | No description |
required | bool | false | Marks each underlying <input type="radio"> as required so native form validation blocks submit until one option is chosen. |
variant | Variant | Default | Density variant — see Variant. |
Examples
Vertical (default)
Horizontal
Disabled
Required + Comfortable
required: true propagates to each input; variant: Comfortable opens spacing.
Compact
variant: Compact — tighter rows for admin/settings panels.
Usage and composition
Import
use maud_ui::primitives::radio_group::{self, Props, RadioOption, Orientation, Variant};
Example
use maud::html;
use maud_ui::primitives::radio_group;
html! {
(radio_group::render(radio_group::Props {
name: "plan".to_string(),
label: "Select a plan".to_string(),
options: vec![
radio_group::RadioOption { value: "free".to_string(), label: "Free".to_string(), description: Some("Up to 3 projects".to_string()) },
radio_group::RadioOption { value: "pro".to_string(), label: "Pro".to_string(), description: Some("Unlimited projects".to_string()) },
],
selected: Some("pro".to_string()),
orientation: radio_group::Orientation::Vertical,
required: true,
variant: radio_group::Variant::Default,
..Default::default()
}))
}
RadioOption Struct
| Field | Type | Description |
|---|---|---|
| value | String | Input value (sent on form submit). |
| label | String | Visible radio label. |
| description | Option | Optional supporting text below the label. |
Orientation Enum
| Value | Description |
|---|---|
| Vertical | Radios stacked vertically (default). |
| Horizontal | Radios laid out inline horizontally. |
Variant Enum
Density axis—mirrors shadcn Base UI "size":
| Value | Class | Description |
|---|---|---|
| Default | — | Default spacing between options. |
| Comfortable | mui-radio-group--comfortable | More breathing room; bigger hit targets. |
| Compact | mui-radio-group--compact | Tighter rows for dense admin UIs. |
Usage Patterns
Vertical (default)
html! {
(radio_group::render(radio_group::Props {
name: "notify".to_string(),
label: "Notifications".to_string(),
options: vec![
radio_group::RadioOption { value: "all".to_string(), label: "All messages".to_string(), description: None },
radio_group::RadioOption { value: "mentions".to_string(), label: "Mentions only".to_string(), description: None },
],
selected: None,
orientation: radio_group::Orientation::Vertical,
..Default::default()
}))
}
Horizontal with Comfortable spacing
html! {
(radio_group::render(radio_group::Props {
name: "size".to_string(),
label: "Size".to_string(),
options: vec![
radio_group::RadioOption { value: "s".to_string(), label: "S".to_string(), description: None },
radio_group::RadioOption { value: "m".to_string(), label: "M".to_string(), description: None },
radio_group::RadioOption { value: "l".to_string(), label: "L".to_string(), description: None },
],
selected: None,
orientation: radio_group::Orientation::Horizontal,
variant: radio_group::Variant::Comfortable,
..Default::default()
}))
}
Required + Compact
html! {
(radio_group::render(radio_group::Props {
name: "priority".to_string(),
label: "Priority".to_string(),
options: vec![
radio_group::RadioOption { value: "low".to_string(), label: "Low".to_string(), description: None },
radio_group::RadioOption { value: "normal".to_string(), label: "Normal".to_string(), description: None },
radio_group::RadioOption { value: "high".to_string(), label: "High".to_string(), description: None },
],
selected: Some("normal".to_string()),
required: true,
variant: radio_group::Variant::Compact,
..Default::default()
}))
}
Related
Radio (single button), Checkbox (independent toggles), Select (long option lists).
Shadcn reference
https://ui.shadcn.com/docs/components/base/radio-group
Accessibility
- Rendered as
<fieldset>with<legend>for semantic grouping. - All radio buttons share the same
nameattribute (mutually exclusive at form level). - Each radio has unique
id="{name}-{value}"and is labeled by<label for="{id}">. requiredattribute enables native form validation (one must be selected before submit).- Descriptions are wrapped in
<span class="mui-radio__description">for visual distinction. aria-disablednot set (nativedisabledattribute sufficient; fieldset-level disable affects all).