patternfly_yew/components/card/header/
selectable.rs1use super::*;
2
3#[derive(Debug, Clone, PartialEq)]
5pub enum CardSelectableActionsVariant {
6 Click {
13 onclick: Option<Callback<MouseEvent>>,
14 },
15 SingleSelect { onchange: Option<Callback<()>> },
24 MultiSelect {
28 onchange: Callback<CheckboxState>,
29 checked: CheckboxState,
30 },
31}
32
33#[derive(Debug, Clone, PartialEq, Properties)]
35pub struct CardSelectableActionsObjectProperties {
36 pub action: CardSelectableActionsVariant,
38 #[prop_or_default]
40 pub base: CardSelectableActionsObjectBase,
41}
42
43#[derive(Debug, Clone, PartialEq, Properties, Default)]
45pub struct CardSelectableActionsObjectBase {
46 #[prop_or_default]
49 pub has_no_offset: bool,
50 #[prop_or_default]
52 pub class: Classes,
53 #[prop_or_default]
55 pub id: Option<AttrValue>,
56 #[prop_or_default]
59 pub name: Option<AttrValue>,
60}
61
62#[function_component(CardSelectableActionsObject)]
63pub fn selectable_actions_object(props: &CardSelectableActionsObjectProperties) -> Html {
64 type Variant = CardSelectableActionsVariant;
65 match &props.action {
66 Variant::SingleSelect { onchange } => html! {
67 <SingleSelectActionRadio base={props.base.clone()} onchange={onchange.clone()} />
68 },
69 Variant::MultiSelect { onchange, checked } => html! {
70 <MultiSelectActionCheckbox base={props.base.clone()} onchange={onchange.clone()} checked={*checked} />
71 },
72 Variant::Click { onclick } => html! {
73 <ClickableInput base={props.base.clone()} onclick={onclick.clone()} />
74 },
75 }
76}
77
78#[derive(Debug, Clone, PartialEq, Properties)]
79struct SingleSelectActionRadioProperties {
80 base: CardSelectableActionsObjectBase,
81 onchange: Option<Callback<()>>,
82}
83
84struct CommonProps {
85 id: Option<String>,
86 name: Option<AttrValue>,
87 disabled: bool,
88 base_class: &'static str,
89}
90
91fn get_common_props(base: &CardSelectableActionsObjectBase, context: &CardContext) -> CommonProps {
92 CommonProps {
93 base_class: "pf-m-standalone",
94 id: base.id.as_ref().map(|s| s.to_string()),
95 name: base.name.as_ref().cloned(),
96 disabled: context.disabled,
97 }
98}
99
100#[function_component(SingleSelectActionRadio)]
101fn single_select_action_radio(props: &SingleSelectActionRadioProperties) -> Html {
102 let context: CardContext = use_context().expect("Couldn't find card context");
103 let onchange = {
104 let onchange = props.onchange.clone();
105 Callback::from(move |_| {
106 if let Some(f) = onchange.clone() {
107 f.emit(())
108 }
109 })
110 };
111 let common = get_common_props(&props.base, &context);
112 html! {
113 <Radio
114 class={common.base_class}
115 id={common.id}
116 name={common.name}
117 disabled={common.disabled}
118 {onchange}
119 force_label=true
120 />
121 }
122}
123
124#[derive(Debug, Clone, PartialEq, Properties)]
125struct MultiSelectActionCheckboxProperties {
126 base: CardSelectableActionsObjectBase,
127 onchange: Callback<CheckboxState>,
128 checked: CheckboxState,
129}
130
131#[function_component(MultiSelectActionCheckbox)]
132fn multi_select_action_checkbox(props: &MultiSelectActionCheckboxProperties) -> Html {
133 let context: CardContext = use_context().expect("Couldn't find card context");
134 let common = get_common_props(&props.base, &context);
135 html! {
136 <Checkbox
137 class={common.base_class}
138 id={common.id}
139 name={common.name}
140 disabled={common.disabled}
141 onchange={props.onchange.clone()}
142 checked={props.checked}
143 label={html!()}
144 />
145 }
146}
147
148#[derive(Debug, Clone, PartialEq, Properties)]
149struct ClickableInputProperties {
150 base: CardSelectableActionsObjectBase,
151 onclick: Option<Callback<MouseEvent>>,
152}
153
154#[function_component(ClickableInput)]
155fn clickable_input_action_radio(props: &ClickableInputProperties) -> Html {
156 let context: CardContext = use_context().expect("Couldn't find card context");
157 if context.selectable {
158 log::warn!("Using a click action for an entire tile in a selectable card doesn't work. Set `selectable` to `false` in card `{}`", context.card_id);
159 }
160 let common = get_common_props(&props.base, &context);
161 html! {
162 <Radio
163 class={common.base_class}
164 id={common.id}
165 name={common.name}
166 disabled={common.disabled}
167 input_class="pf-v5-screen-reader"
168 input_onclick={props.onclick.clone()}
169 force_label=true
170 />
171 }
172}