yew_utils/components/
drop_down_plain.rs1use std::fmt::Display;
2use web_sys::HtmlSelectElement;
3use yew::prelude::*;
4
5pub struct DropDown<T> {
6 selected: T,
7 node: NodeRef,
8}
9
10pub enum Msg {
11 SelectionChanged(usize),
12}
13
14#[derive(PartialEq, Properties)]
15pub struct DropDownProps<T>
16where
17 T: PartialEq,
18{
19 pub initial: T,
20 pub options: Vec<T>,
21 pub selection_changed: Callback<T>,
22}
23
24impl<T> Component for DropDown<T>
25where
26 T: Display + Clone + PartialEq + 'static,
27{
28 type Message = Msg;
29 type Properties = DropDownProps<T>;
30
31 fn create(ctx: &Context<Self>) -> Self {
32 Self {
33 selected: ctx.props().initial.clone(),
34 node: NodeRef::default(),
35 }
36 }
37
38 fn view(&self, ctx: &Context<Self>) -> Html {
39 let node = self.node.clone();
40
41 html! {
42 <select ref={node.clone()} onchange={ctx.link().callback(move |_| {
43 let node2: HtmlSelectElement = node.cast().unwrap();
44 let idx = node2.selected_index() as usize;
45 Msg::SelectionChanged(idx)
46 })}>
47 {
48 for ctx.props().options.iter().map(|opt| {
49 if opt == &self.selected {
50 html! {
51 <option value={opt.to_string()} selected=true>{opt}</option>
52 }
53 } else {
54 html! {
55 <option value={opt.to_string()}>{opt}</option>
56 }
57 }
58 })
59
60 }
61 </select>
62 }
63 }
64
65 fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
66 match msg {
67 Msg::SelectionChanged(idx) => {
68 if let Some(selected) = ctx.props().options.get(idx) {
69 self.selected = selected.clone();
70 ctx.props().selection_changed.emit(selected.clone());
71 }
72 true
73 }
74 }
75 }
76}