Skip to main content

edc_web_components/components/
multi_state_selector.rs

1use patternfly_yew::prelude::*;
2use yew::prelude::*;
3
4#[derive(Clone, Debug, PartialEq, Properties)]
5pub struct MultiStateSelectorProps {
6  pub selectable_items: Vec<(String, bool)>,
7  pub on_selected: Callback<Vec<(String, bool)>>,
8}
9
10#[component]
11pub fn MultiStateSelector(props: &MultiStateSelectorProps) -> Html {
12  let onclick = use_callback(
13    (props.selectable_items.clone(), props.on_selected.clone()),
14    |index, (selectable_items, on_selected)| {
15      let mut selectable_items = selectable_items.clone();
16
17      let item: &mut (String, bool) = selectable_items.get_mut(index).unwrap();
18      item.1 = !item.1;
19
20      on_selected.emit(selectable_items.clone());
21    },
22  );
23
24  let actions = props
25    .selectable_items
26    .iter()
27    .enumerate()
28    .map(|(index, (label, selected))| {
29      html_nested!(
30        <MenuAction onclick={onclick.reform(move |_| index)} {selected}>{ &label }</MenuAction>
31      )
32    });
33
34  let text = if props.selectable_items.iter().all(|(_, selected)| *selected)
35    || props
36      .selectable_items
37      .iter()
38      .all(|(_, selected)| !*selected)
39  {
40    "All".to_string()
41  } else {
42    props
43      .selectable_items
44      .iter()
45      .filter_map(|(label, selected)| if *selected { Some(label.clone()) } else { None })
46      .collect::<Vec<String>>()
47      .join(", ")
48  };
49
50  html!(<Dropdown {text}>{ for actions }</Dropdown>)
51}