pub fn radio_group_in_form<S, T: Validate, U: Serialize + PartialEq, L: Into<String>>(
title: impl Into<String>,
form: Sig<S, Form<T>>,
field: Sig<T, U>,
options: impl IntoIterator<Item = (U, L)>,
) -> El<S>Expand description
A group of radio buttons with title in its <legend>, bound to field
of form.
It is radio_group with the form’s error for field
under it. ARIA allows aria-invalid on a radio group but not on a plain
group, so the <fieldset> takes role="radiogroup", is named by its
legend through aria-labelledby, and carries aria-describedby and
aria-invalid. The field is marked touched when focus leaves the group,
and not while the arrow keys move it between the radios.
use hypersig::{Form, Rules, Sig, Signals, Validate};
use hypersig_ui::radio_group_in_form;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Default)]
enum Plan {
#[default]
Unset,
Free,
Pro,
}
#[derive(Signals, Serialize, Deserialize, Clone)]
struct Signup {
plan: Plan,
}
impl Validate for Signup {
fn rules<S>(form: Sig<S, Self>, rules: &mut Rules<S, Self>) {
let chosen = !form.at(Signup::plan()).equals(&Plan::Unset);
rules.check(Signup::plan(), chosen, "Choose a plan.");
}
}
#[derive(Signals, Serialize, Deserialize)]
struct Join {
signup: Form<Signup>,
}
let plans = radio_group_in_form(
"Plan",
Join::signup(),
Signup::plan(),
[(Plan::Free, "Free"), (Plan::Pro, "Pro")],
);
let html = plans.render();
assert!(html.contains(r#"role="radiogroup""#));
assert!(html.contains(r#"aria-describedby="ui-signup-value-plan-error""#));