patternfly_yew/components/select/
mod.rs1use crate::prelude::*;
4use yew::prelude::*;
5
6#[derive(PartialEq, Properties)]
8pub struct SimpleSelectProperties<T>
9where
10 T: Clone + Eq + SelectItemRenderer,
11{
12 #[prop_or_default]
13 pub placeholder: Option<String>,
14
15 #[prop_or_default]
16 pub entries: Vec<T>,
17
18 #[prop_or_default]
19 pub selected: Option<T>,
20
21 #[prop_or_default]
22 pub onselect: Callback<T>,
23}
24
25pub trait SelectItemRenderer {
27 type Item;
28
29 fn label(&self) -> String;
30}
31
32impl<T> SelectItemRenderer for T
33where
34 T: std::fmt::Display,
35{
36 type Item = T;
37
38 fn label(&self) -> String {
39 self.to_string()
40 }
41}
42
43#[function_component(SimpleSelect)]
50pub fn simple_select<T>(props: &SimpleSelectProperties<T>) -> Html
51where
52 T: Clone + Eq + SelectItemRenderer + 'static,
53{
54 let text = props
55 .selected
56 .as_ref()
57 .map(|s| s.label())
58 .or_else(|| props.placeholder.clone());
59
60 html!(
61 <Dropdown text={html!{text.clone().unwrap_or_default()}}>
62 { for props.entries.iter().map(|entry| {
63 html_nested!(
64 <Raw>
65 <SimpleSelectItem<T>
66 entry={entry.clone()}
67 selected={props.selected.as_ref() == Some(entry)}
68 onselect={props.onselect.clone()}
69 />
70 </Raw>
71 )
72 }) }
73 </Dropdown>
74 )
75}
76
77#[derive(PartialEq, Properties)]
78struct SimpleSelectItemProperties<T>
79where
80 T: Eq + SelectItemRenderer + 'static,
81{
82 entry: T,
83 selected: bool,
84 onselect: Callback<T>,
85}
86
87#[function_component(SimpleSelectItem)]
89fn simple_select_item<T>(props: &SimpleSelectItemProperties<T>) -> Html
90where
91 T: Clone + Eq + SelectItemRenderer + 'static,
92{
93 let onclick = use_callback(
94 (props.entry.clone(), props.onselect.clone()),
95 |_, (entry, onselect)| {
96 log::info!("Emit: {}", entry.label());
97 onselect.emit(entry.clone());
98 },
99 );
100
101 html!(<MenuAction {onclick} selected={props.selected}>{ props.entry.label() }</MenuAction>)
102}