dioxus_tw_components/components/
radio.rs1use dioxus::prelude::*;
2
3#[derive(Clone)]
4struct RadioGroupCtx {
5 value: Signal<String>,
6 default_value: String,
7 onchange: EventHandler<MouseEvent>,
8}
9
10#[derive(Clone, PartialEq, Props)]
11pub struct RadioGroupProps {
12 #[props(extends = div, extends = GlobalAttributes)]
13 attributes: Vec<Attribute>,
14 children: Element,
15
16 #[props(optional)]
17 default_value: String,
18
19 #[props(optional)]
20 value: Signal<String>,
21
22 #[props(optional)]
23 onchange: EventHandler<MouseEvent>,
24}
25
26#[component]
27pub fn RadioGroup(mut props: RadioGroupProps) -> Element {
28 use_context_provider(|| RadioGroupCtx {
29 value: props.value,
30 default_value: props.default_value.clone(),
31 onchange: props.onchange,
32 });
33
34 let default_classes = "radio";
35 crate::setup_class_attribute(&mut props.attributes, default_classes);
36
37 rsx! {
38 div { ..props.attributes, {props.children} }
39 }
40}
41
42#[derive(Clone, PartialEq, Props)]
43pub struct RadioItemProps {
44 #[props(extends = input, extends = GlobalAttributes)]
45 attributes: Vec<Attribute>,
46 value: String,
47}
48
49#[component]
50pub fn RadioItem(mut props: RadioItemProps) -> Element {
51 let mut state = use_context::<RadioGroupCtx>();
52
53 let default_classes = "radio-input";
54 crate::setup_class_attribute(&mut props.attributes, default_classes);
55
56 let value = props.value.clone();
57 let checked = use_memo(move || {
58 if state.value.read().is_empty() {
59 state.default_value == value
60 } else {
61 (state.value)() == value
62 }
63 });
64
65 rsx! {
66 input {
67 r#type: "radio",
68 checked,
69 onclick: move |event| {
70 state.value.set(props.value.clone());
71 state.onchange.call(event);
72 },
73 ..props.attributes,
74 }
75 }
76}