patternfly_yew/components/form/
radio.rs1use crate::ouia;
2use crate::prelude::OuiaComponentType;
3use crate::utils::OuiaSafe;
4use crate::{prelude::use_prop_id, utils::Ouia};
5use std::mem::swap;
6use yew::prelude::*;
7
8const OUIA: Ouia = ouia!("Radio");
9
10#[derive(PartialEq, Properties)]
12pub struct RadioProperties {
13 #[prop_or_default]
15 pub class: Classes,
16
17 #[prop_or_default]
19 pub input_class: Classes,
20
21 #[prop_or_default]
22 pub id: Option<String>,
23
24 #[prop_or_default]
26 pub name: Option<AttrValue>,
27
28 #[prop_or_default]
29 pub value: Option<AttrValue>,
30
31 #[prop_or_default]
33 pub children: Children,
34
35 #[prop_or_default]
36 pub checked: bool,
37
38 #[prop_or_default]
39 pub reversed: bool,
40
41 #[prop_or_default]
42 pub disabled: bool,
43
44 #[prop_or_default]
46 pub description: Option<Html>,
47
48 #[prop_or_default]
50 pub body: Option<Html>,
51
52 #[prop_or_default]
54 pub onchange: Callback<()>,
55
56 #[prop_or_default]
59 pub input_onclick: Option<Callback<MouseEvent>>,
60
61 #[prop_or_default]
63 pub force_label: bool,
64
65 #[prop_or_default]
67 pub ouia_id: Option<String>,
68 #[prop_or(OUIA.component_type())]
70 pub ouia_type: OuiaComponentType,
71 #[prop_or(OuiaSafe::TRUE)]
73 pub ouia_safe: OuiaSafe,
74}
75
76#[function_component(Radio)]
86pub fn radio(props: &RadioProperties) -> Html {
87 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
88 id.clone().unwrap_or(OUIA.generated_id())
89 });
90 let class = classes!("pf-v6-c-radio", props.class.clone());
91
92 let id = use_prop_id(props.id.clone());
93
94 let mut input_class = classes!(props.input_class.clone(), "pf-v6-c-radio__input");
95
96 if props.children.is_empty() && !props.force_label {
97 input_class.extend(classes!("pf-m-standalone"));
98 }
99
100 let onchange = use_callback(props.onchange.clone(), |_, onchange| {
101 onchange.emit(());
102 });
103
104 let mut first = html!(
105 <input
106 class={input_class}
107 type="radio"
108 id={(*id).clone()}
109 name={&props.name}
110 checked={props.checked}
111 disabled={props.disabled}
112 value={&props.value}
113 {onchange}
114 onclick={props.input_onclick.clone()}
115 data-ouia-component-id={(*ouia_id).clone()}
116 data-ouia-component-type={props.ouia_type}
117 data-ouia-safe={props.ouia_safe}
118 />
119 );
120
121 let mut label_class = classes!("pf-v6-c-radio__label");
122 if props.disabled {
123 label_class.extend(classes!("pf-m-disabled"));
124 }
125
126 let mut second = html!(
127 <>
128 if !props.children.is_empty() || props.force_label {
129 <label class={label_class} for={(*id).clone()}>{ props.children.clone() }</label>
130 }
131 </>
132 );
133
134 if props.reversed {
135 swap(&mut first, &mut second);
136 }
137
138 html!(
139 <div {class}>
140 { first }
141 { second }
142 if let Some(description) = &props.description {
143 <span class="pf-v6-c-radio__description">{ description.clone() }</span>
144 }
145 if let Some(body) = &props.body {
146 <span class="pf-v6-c-radio__body">{ body.clone() }</span>
147 }
148 </div>
149 )
150}