RadioCard
Layer: molecule · Path:
src/molecules/radio_card.rs· Exports:radio_card::RadioCard
A selectable card for single-choice options: an interactive Surface wrapping a display-only Radio plus a label and optional description. Stateless like the Radio atom — it reports clicks via its Response; the consumer owns exclusivity across the set.
Design
- Purpose / when to use — Present a small set of mutually exclusive options as legible cards (plan tiers, modes) instead of bare radio buttons.
- Anatomy —
Surface::new().interactive().selected(selected)paddedSPACE_3→ horizontal row of a displayRadio(.interactive(false)) + a vertical stack of abody_strongTextlabel and an optional muted caption description. - States — selected visual driven by
Surface::selected(selected); hover/press bySurface::interactive(). Selection itself is caller-managed. - Tokens / layout consumed —
core::SPACE_3(pad + radio→text gap). See tokens.
API
| Method | Effect |
|---|---|
RadioCard::new(selected: bool, label: impl Into<String>) -> Self | Set the selected visual + label. Note selected is a plain bool, not a binding. |
.description(description: impl Into<String>) -> Self | Optional muted caption under the label. |
.id_source(id: impl std::hash::Hash) -> Self | Stable surface id (use one per card). |
.show(self, ui: &mut Ui) -> Response | Render; returns the surface Response (check .clicked()). |
Usage
#![allow(unused)]
fn main() {
use ouroboros_ui::molecules::RadioCard;
// realistic — consumer manages exclusivity over a list
let mut sel = 0usize;
for (i, (title, desc)) in [
("Starter", "Up to 10 projects"),
("Pro", "Unlimited projects"),
].iter().enumerate() {
if RadioCard::new(sel == i, *title)
.description(*desc)
.id_source(("rc", i))
.show(ui)
.clicked()
{
sel = i;
}
}
}
Composition
Composes Surface + Radio + Text. It never paints — see the guards.
Notes
- Unlike
CheckboxCard, this takesselected: bool(not&mut) and does not mutate anything — react to.clicked()and update your own selection index. - The inner radio is display-only (
.interactive(false)); the whole card is the click target. - Give each card a distinct
id_source(e.g.("rc", i)) to avoid surface-id collisions.