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}