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
71 base={props.base.clone()}
72 onchange={onchange.clone()}
73 checked={*checked}
74 />
75 },
76 Variant::Click { onclick } => html! {
77 <ClickableInput base={props.base.clone()} onclick={onclick.clone()} />
78 },
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Properties)]
83struct SingleSelectActionRadioProperties {
84 base: CardSelectableActionsObjectBase,
85 onchange: Option<Callback<()>>,
86}
87
88struct CommonProps {
89 id: Option<String>,
90 name: Option<AttrValue>,
91 disabled: bool,
92 base_class: &'static str,
93}
94
95fn get_common_props(base: &CardSelectableActionsObjectBase, context: &CardContext) -> CommonProps {
96 CommonProps {
97 base_class: "pf-m-standalone",
98 id: base.id.as_ref().map(|s| s.to_string()),
99 name: base.name.as_ref().cloned(),
100 disabled: context.disabled,
101 }
102}
103
104#[function_component(SingleSelectActionRadio)]
105fn single_select_action_radio(props: &SingleSelectActionRadioProperties) -> Html {
106 let context: CardContext = use_context().expect("Couldn't find card context");
107 let onchange = {
108 let onchange = props.onchange.clone();
109 Callback::from(move |_| {
110 if let Some(f) = onchange.clone() {
111 f.emit(())
112 }
113 })
114 };
115 let common = get_common_props(&props.base, &context);
116 html! {
117 <Radio
118 class={common.base_class}
119 id={common.id}
120 name={common.name}
121 disabled={common.disabled}
122 {onchange}
123 force_label=true
124 />
125 }
126}
127
128#[derive(Debug, Clone, PartialEq, Properties)]
129struct MultiSelectActionCheckboxProperties {
130 base: CardSelectableActionsObjectBase,
131 onchange: Callback<CheckboxState>,
132 checked: CheckboxState,
133}
134
135#[function_component(MultiSelectActionCheckbox)]
136fn multi_select_action_checkbox(props: &MultiSelectActionCheckboxProperties) -> Html {
137 let context: CardContext = use_context().expect("Couldn't find card context");
138 let common = get_common_props(&props.base, &context);
139 html! {
140 <Checkbox
141 class={common.base_class}
142 id={common.id}
143 name={common.name}
144 disabled={common.disabled}
145 onchange={props.onchange.clone()}
146 checked={props.checked}
147 label={html!()}
148 />
149 }
150}
151
152#[derive(Debug, Clone, PartialEq, Properties)]
153struct ClickableInputProperties {
154 base: CardSelectableActionsObjectBase,
155 onclick: Option<Callback<MouseEvent>>,
156}
157
158#[function_component(ClickableInput)]
159fn clickable_input_action_radio(props: &ClickableInputProperties) -> Html {
160 let context: CardContext = use_context().expect("Couldn't find card context");
161 if context.selectable {
162 log::warn!(
163 "Using a click action for an entire tile in a selectable card doesn't work. Set `selectable` to `false` in card `{}`",
164 context.card_id
165 );
166 }
167 let common = get_common_props(&props.base, &context);
168 html! {
169 <Radio
170 class={common.base_class}
171 id={common.id}
172 name={common.name}
173 disabled={common.disabled}
174 input_class="pf-v6-screen-reader"
175 input_onclick={props.onclick.clone()}
176 force_label=true
177 />
178 }
179}