1use stylist::yew::{styled_component, use_style};
2use yew::prelude::*;
3#[cfg(feature = "with-yew-router")]
4use yew_router::prelude::*;
5
6use crate::prelude::*;
7
8#[derive(PartialEq, Clone, Properties)]
9pub struct CosmoMainMenuProps {
10 #[prop_or_default]
11 pub children: Children,
12}
13
14#[styled_component(CosmoMainMenu)]
15pub fn main_menu(props: &CosmoMainMenuProps) -> Html {
16 let main_menu_style = use_style!(
17 r#"
18grid-row: main-menu;
19 "#
20 );
21
22 html!(
23 <div class={main_menu_style}>
24 {for props.children.iter()}
25 </div>
26 )
27}
28
29#[derive(PartialEq, Clone, Properties)]
30pub struct CosmoMenuBarProps {
31 #[prop_or_default]
32 pub children: Children,
33}
34
35#[styled_component(CosmoMenuBar)]
36pub fn menu_bar(props: &CosmoMenuBarProps) -> Html {
37 let menu_bar_style = use_style!(
38 r#"
39grid-row: main-menu;
40display: grid;
41position: relative;
42grid-template-columns:
43 [left-touch] var(--menu-left-touch-width) [spacing1] 1rem [backbutton] var(--back-button-width)
44 [spacing2] calc(
45 var(--page-side-spacing) - var(--menu-left-touch-width) - 1rem - var(--back-button-width)
46 )
47 [content] 1fr;
48
49&::before {
50 content: '';
51 position: absolute;
52 width: var(--menu-left-touch-width);
53 height: 100%;
54 background: var(--primary-color);
55 border-bottom-right-radius: var(--border-radius);
56 border-top-right-radius: var(--border-radius);
57}
58 "#
59 );
60
61 html!(
62 <div class={menu_bar_style}>
63 <CosmoBackButton />
64 <CosmoMenuCollection>
65 {for props.children.iter()}
66 </CosmoMenuCollection>
67 </div>
68 )
69}
70
71#[derive(PartialEq, Clone, Properties)]
72struct CosmoMenuCollectionProps {
73 #[prop_or_default]
74 pub children: Children,
75}
76
77#[styled_component(CosmoMenuCollection)]
78fn menu_collection(props: &CosmoMenuCollectionProps) -> Html {
79 let menu_collection_style = use_style!(
80 r#"
81display: grid;
82grid-column: content;
83grid-template-rows: [main-menu] var(--main-menu-height) [sub-menu] var(--sub-menu-height);
84grid-row-gap: var(--menu-gap);
85 "#
86 );
87
88 html!(
89 <nav class={menu_collection_style}>
90 {for props.children.iter()}
91 </nav>
92 )
93}
94
95#[cfg(feature = "with-yew-router")]
96#[derive(PartialEq, Clone, Properties)]
97pub struct CosmoMainMenuItemLinkProps<Route>
98where
99 Route: Routable + 'static,
100{
101 pub label: AttrValue,
102 pub to: Route,
103 pub is_active: bool,
104}
105
106#[hook]
107fn use_main_menu_item_style(is_active: bool) -> Classes {
108 let item_style = use_style!(
109 r#"
110text-decoration: none;
111font-weight: var(--font-weight-menu);
112font-family: var(--font-family-menu);
113text-transform: lowercase;
114font-size: var(--font-size-main-menu);
115line-height: var(--font-size-main-menu);
116vertical-align: text-top;
117color: var(--menu-text-color);
118margin-right: calc(var(--font-size-main-menu) / 2);
119 "#
120 );
121 let mut active_style = Some(use_style!(
122 r#"
123color: var(--menu-text-selected-color);
124 "#
125 ));
126 if !is_active {
127 active_style = None;
128 }
129
130 classes!(item_style, active_style)
131}
132
133#[cfg(feature = "with-yew-router")]
134#[styled_component(CosmoMainMenuItemLink)]
135pub fn main_menu_item_link<Route>(props: &CosmoMainMenuItemLinkProps<Route>) -> Html
136where
137 Route: Routable + 'static,
138{
139 let style = use_main_menu_item_style(props.is_active);
140
141 html!(
142 <Link<Route> to={props.to.clone()} classes={style}>{props.label.clone()}</Link<Route>>
143 )
144}
145
146#[derive(PartialEq, Clone, Properties)]
147pub struct CosmoMainMenuItemProps {
148 pub label: AttrValue,
149 pub is_active: bool,
150}
151
152#[styled_component(CosmoMainMenuItem)]
153pub fn main_menu_item(props: &CosmoMainMenuItemProps) -> Html {
154 let style = use_main_menu_item_style(props.is_active);
155
156 html!(
157 <span class={style}>{props.label.clone()}</span>
158 )
159}
160
161#[derive(PartialEq, Clone, Properties)]
162pub struct CosmoSubMenuBarProps {
163 #[prop_or_default]
164 pub children: Children,
165}
166
167#[styled_component(CosmoSubMenuBar)]
168pub fn sub_menu_bar(props: &CosmoSubMenuBarProps) -> Html {
169 let sub_menu_style = use_style!(
170 r#"
171grid-row: sub-menu;
172 "#
173 );
174
175 html!(
176 <div class={sub_menu_style}>
177 {for props.children.iter()}
178 </div>
179 )
180}
181
182#[hook]
183fn use_sub_menu_item_style(is_active: bool) -> Classes {
184 let item_style = use_style!(
185 r#"
186text-decoration: none;
187font-weight: var(--font-weight-menu);
188font-family: var(--font-family-menu);
189text-transform: uppercase;
190font-size: var(--font-size-sub-menu);
191line-height: var(--font-size-sub-menu);
192vertical-align: text-top;
193margin-right: var(--font-size-sub-menu);
194color: var(--black);
195 "#
196 );
197 let mut active_style = Some(use_style!(
198 r#"
199font-weight: var(--font-weight-sub-menu-active);
200 "#
201 ));
202 if !is_active {
203 active_style = None;
204 }
205
206 classes!(item_style, active_style)
207}
208
209#[cfg(feature = "with-yew-router")]
210#[derive(PartialEq, Clone, Properties)]
211pub struct CosmoSubMenuItemLinkProps<Route>
212where
213 Route: Routable + 'static,
214{
215 pub label: AttrValue,
216 pub to: Route,
217 pub is_active: bool,
218}
219
220#[cfg(feature = "with-yew-router")]
221#[styled_component(CosmoSubMenuItemLink)]
222pub fn sub_menu_item_link<Route>(props: &CosmoSubMenuItemLinkProps<Route>) -> Html
223where
224 Route: Routable + 'static,
225{
226 let style = use_sub_menu_item_style(props.is_active);
227
228 html!(
229 <Link<Route> to={props.to.clone()} classes={style}>{props.label.clone()}</Link<Route>>
230 )
231}
232
233#[derive(PartialEq, Clone, Properties)]
234pub struct CosmoSubMenuItemProps {
235 pub label: AttrValue,
236 pub is_active: bool,
237}
238
239#[styled_component(CosmoSubMenuItem)]
240pub fn sub_menu_item(props: &CosmoSubMenuItemProps) -> Html {
241 let style = use_sub_menu_item_style(props.is_active);
242
243 html!(
244 <span class={style}>{props.label.clone()}</span>
245 )
246}