ybc/form/
radio.rs

1use wasm_bindgen::UnwrapThrowExt;
2use web_sys::HtmlInputElement;
3use yew::prelude::*;
4
5#[derive(Clone, Debug, Properties, PartialEq)]
6pub struct RadioProps {
7    /// The `name` attribute for this form element.
8    ///
9    /// All members of the same radio group must have the same value for their `name` attribute.
10    pub name: String,
11    /// The `value` attribute for this form element.
12    ///
13    /// This is different from other form elements, as this value does not change. It represents
14    /// the value to be used for the radio group overall when this element is selected.
15    pub value: String,
16    /// The value of the currently selected radio of this radio group.
17    pub checked_value: Option<String>,
18    /// The callback to be used for propagating changes to the selected radio of the radio group.
19    pub update: Callback<String>,
20    #[prop_or_default]
21    pub children: Children,
22    #[prop_or_default]
23    pub classes: Classes,
24    /// Disable this component.
25    #[prop_or_default]
26    pub disabled: bool,
27}
28
29/// The mutually exclusive radio buttons in their native format.
30///
31/// [https://bulma.io/documentation/form/radio/](https://bulma.io/documentation/form/radio/)
32///
33/// All YBC form components are controlled components. This means that the value of the field must
34/// be provided from a parent component, and changes to this component are propagated to the parent
35/// component via callback.
36#[function_component(Radio)]
37pub fn radio(props: &RadioProps) -> Html {
38    let class = classes!("radio", props.classes.clone());
39    let oninput = props.update.reform(|ev: web_sys::InputEvent| {
40        let input: HtmlInputElement = ev.target_dyn_into().expect_throw("event target should be an input");
41        input.value()
42    });
43    html! {
44        <label {class} disabled={props.disabled}>
45            <input
46                type="radio"
47                name={props.name.clone()}
48                value={props.value.clone()}
49                checked={props.checked_value.as_ref().map(|val| val == &props.value).unwrap_or(false)}
50                {oninput}
51                disabled={props.disabled}
52                />
53            {props.children.clone()}
54        </label>
55    }
56}