dioxus_tw_components/components/
radio.rs1use dioxus::prelude::*;
2
3#[derive(Clone)]
4struct RadioGroupCtx {
5 value: Signal<String>,
6 default_value: Signal<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 let mut default_value = use_signal(|| props.default_value.clone());
29
30 use_context_provider(|| RadioGroupCtx {
31 value: props.value,
32 default_value,
33 onchange: props.onchange,
34 });
35
36 if *default_value.peek() != props.default_value {
39 *default_value.write() = props.default_value.clone();
40 }
41
42 let default_classes = "radio";
43 crate::setup_class_attribute(&mut props.attributes, default_classes);
44
45 rsx! {
46 div { ..props.attributes, {props.children} }
47 }
48}
49
50#[derive(Clone, PartialEq, Props)]
51pub struct RadioItemProps {
52 #[props(extends = input, extends = GlobalAttributes)]
53 attributes: Vec<Attribute>,
54 value: String,
55}
56
57#[component]
58pub fn RadioItem(mut props: RadioItemProps) -> Element {
59 let mut state = use_context::<RadioGroupCtx>();
60
61 let default_classes = "radio-input";
62 crate::setup_class_attribute(&mut props.attributes, default_classes);
63
64 let value = props.value.clone();
65 let checked = use_memo(move || {
66 if state.value.read().is_empty() {
67 *state.default_value.read() == value
68 } else {
69 (state.value)() == value
70 }
71 });
72
73 rsx! {
74 input {
75 r#type: "radio",
76 checked,
77 onclick: move |event| {
78 state.value.set(props.value.clone());
79 state.onchange.call(event);
80 },
81 ..props.attributes,
82 }
83 }
84}