jinya_ui/widgets/menu/
bar.rs

1use yew::prelude::*;
2use yew::{Component, ComponentLink, Html};
3
4pub fn get_css<'a>() -> &'a str {
5    // language=CSS
6    "
7.jinya-menu {
8    width: 100%;
9    box-sizing: border-box;
10    box-shadow: 0 4px 6px var(--menu-bar-box-shadown);
11    display: flex;
12    background: var(--white);
13}
14
15.jinya-menu__title {
16    font-weight: var(--font-style-bold);
17    padding-left: 1rem;
18    width: 10vw;
19    box-sizing: border-box;
20    margin-top: auto;
21    margin-bottom: auto;
22}
23
24.jinya-menu__items-container {
25    display: flex;
26    width: 80vw;
27    margin: 0;
28    padding: 0;
29}
30
31.jinya-menu__search-bar {
32    width: 12%;
33    background: var(--input-background-color);
34    margin-right: auto;
35    margin-left: 0;
36    display: flex;
37    justify-content: space-between;
38    padding-left: 1rem;
39    box-sizing: border-box;
40}
41
42.jinya-menu__search-input {
43    height: 100%;
44    width: 100%;
45    background: none;
46    border: none;
47    font-size: 1rem;
48    color: var(--primary-color);
49    font-family: var(--font-family);
50    outline: none;
51}
52
53.jinya-menu__search-button {
54    font-size: 1.5rem;
55    margin-top: auto;
56    margin-bottom: auto;
57    margin-right: 1rem;
58    color: var(--primary-color);
59    background: none;
60    border: none;
61    cursor: pointer;
62    outline: none;
63}
64"
65}
66
67pub enum Msg {
68    Search(FocusEvent),
69    Input(InputData),
70}
71
72pub struct MenuBar {
73    link: ComponentLink<Self>,
74    children: Children,
75    title: String,
76    search_placeholder: Option<String>,
77    search_text: String,
78    on_search: Callback<String>,
79    on_keyword: Callback<String>,
80}
81
82#[derive(Clone, PartialEq, Properties)]
83pub struct MenuBarProps {
84    pub children: Children,
85    pub title: String,
86    #[prop_or(None)]
87    pub search_placeholder: Option<String>,
88    #[prop_or_default]
89    pub on_search: Callback<String>,
90    #[prop_or_default]
91    pub on_keyword: Callback<String>,
92}
93
94impl Component for MenuBar {
95    type Message = Msg;
96    type Properties = MenuBarProps;
97
98    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
99        MenuBar {
100            link,
101            title: props.title,
102            children: props.children,
103            search_placeholder: props.search_placeholder,
104            search_text: "".to_string(),
105            on_search: props.on_search,
106            on_keyword: props.on_keyword,
107        }
108    }
109
110    fn update(&mut self, msg: Self::Message) -> bool {
111        match msg {
112            Msg::Input(data) => {
113                self.search_text = data.value;
114                self.on_keyword.emit(self.search_text.to_string());
115            }
116            Msg::Search(event) => {
117                event.prevent_default();
118                self.on_search.emit(self.search_text.to_string());
119            }
120        }
121
122        true
123    }
124
125    fn change(&mut self, _props: Self::Properties) -> bool {
126        self.children = _props.children;
127        self.title = _props.title;
128        self.search_placeholder = _props.search_placeholder;
129        self.on_search = _props.on_search;
130        self.on_keyword = _props.on_keyword;
131
132        true
133    }
134
135    fn view(&self) -> Html {
136        html! {
137            <div class="jinya-menu">
138                <span class="jinya-menu__title">{&self.title}</span>
139                <ul class="jinya-menu__items-container">
140                    {for self.children.iter().enumerate().map(|(_, mut item)| {
141                        item
142                    })}
143                </ul>
144                {if self.search_placeholder.is_some() {
145                    html! {
146                        <form onsubmit=self.link.callback(|event| Msg::Search(event)) class="jinya-menu__search-bar">
147                            <input value=self.search_text placeholder=self.search_placeholder.as_ref().unwrap() oninput=self.link.callback(|e| Msg::Input(e)) class="jinya-menu__search-input" type="search" />
148                            <button type="submit" class="jinya-menu__search-button">
149                                <span class="mdi mdi-magnify"></span>
150                            </button>
151                        </form>
152                    }
153                } else {
154                    html! {}
155                }}
156            </div>
157        }
158    }
159}