Skip to main content

radio_group_in_form

Function radio_group_in_form 

Source
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""#));