app: Add a sidebar component
This commit is contained in:
parent
2bbf35b4e9
commit
141ff9e419
2 changed files with 153 additions and 0 deletions
|
|
@ -6,6 +6,10 @@ use web_sys::HtmlInputElement;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
|
use crate::sidebar::RegaladeSidebar;
|
||||||
|
|
||||||
|
mod sidebar;
|
||||||
|
|
||||||
#[derive(Routable, Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Routable, Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum Route {
|
enum Route {
|
||||||
#[at("/")]
|
#[at("/")]
|
||||||
|
|
|
||||||
149
app/src/sidebar.rs
Normal file
149
app/src/sidebar.rs
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
use crate::Route;
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
struct MenuEntry {
|
||||||
|
icon: &'static str,
|
||||||
|
label: &'static str,
|
||||||
|
page: Route,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Properties, PartialEq)]
|
||||||
|
struct SidebarProps {
|
||||||
|
entries: Vec<MenuEntry>,
|
||||||
|
current: Route,
|
||||||
|
household: AttrValue,
|
||||||
|
children: Children,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
fn Sidebar(props: &SidebarProps) -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class={classes!("row", "flex-nowrap")}>
|
||||||
|
<div class={classes!(
|
||||||
|
"col-auto",
|
||||||
|
"col-md-3",
|
||||||
|
"col-xl-2",
|
||||||
|
"px-sm-2",
|
||||||
|
"px-0",
|
||||||
|
"bg-dark-subtle"
|
||||||
|
)}>
|
||||||
|
<div class={classes!(
|
||||||
|
"d-flex",
|
||||||
|
"flex-column",
|
||||||
|
"align-items-center",
|
||||||
|
"align-items-sm-start",
|
||||||
|
"px-3",
|
||||||
|
"pt-2",
|
||||||
|
"text-white",
|
||||||
|
"min-vh-100"
|
||||||
|
)}>
|
||||||
|
<a href="/" class={classes!(
|
||||||
|
"d-flex",
|
||||||
|
"align-items-center",
|
||||||
|
"pb-3",
|
||||||
|
"mb-md-0",
|
||||||
|
"me-md-auto",
|
||||||
|
"text-white",
|
||||||
|
"text-decoration-none"
|
||||||
|
)}>
|
||||||
|
<span class="fs-5 d-none d-sm-inline">{"Menu"}</span>
|
||||||
|
</a>
|
||||||
|
<hr class={classes!("w-100", "d-none", "d-sm-inline")} />
|
||||||
|
<ul id="menu" class={classes!(
|
||||||
|
"nav",
|
||||||
|
"nav-pills",
|
||||||
|
"flex-column",
|
||||||
|
"mb-sm-auto",
|
||||||
|
"mb-0",
|
||||||
|
"align-items-center",
|
||||||
|
"align-items-sm-start",
|
||||||
|
"w-100",
|
||||||
|
)}>
|
||||||
|
{
|
||||||
|
for props.entries.iter().map(|e| {
|
||||||
|
let active = if e.page == props.current {
|
||||||
|
Some("active")
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<li class="nav-item w-100">
|
||||||
|
<a href="#" class={classes!(
|
||||||
|
"nav-link",
|
||||||
|
"text-white",
|
||||||
|
active,
|
||||||
|
)}>
|
||||||
|
<i class={classes!("fs-4", e.icon)}></i>
|
||||||
|
<span class={classes!("ms-2", "d-none", "d-sm-inline")}>
|
||||||
|
{e.label}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
<hr class="w-100" />
|
||||||
|
<div class={classes!("dropdown")}>
|
||||||
|
<a href="#"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
class={classes!(
|
||||||
|
"d-flex",
|
||||||
|
"align-items-center",
|
||||||
|
"text-white",
|
||||||
|
"text-decoration-none",
|
||||||
|
"dropdown-toggle",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<i class={classes!("fs-4", "bi-house-door-fill")}></i>
|
||||||
|
<strong class={classes!("ms-2", "d-none", "d-sm-inline")}>
|
||||||
|
{&props.household}
|
||||||
|
</strong>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<hr />
|
||||||
|
<li><a class="dropdown-item" href="#">{"New household"}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class={classes!("col", "py-3")}>
|
||||||
|
{ for props.children.iter() }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Properties, PartialEq)]
|
||||||
|
pub(crate) struct RegaladeSidebarProps {
|
||||||
|
pub(crate) current: Route,
|
||||||
|
pub(crate) household: AttrValue,
|
||||||
|
pub(crate) children: Children,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub(crate) fn RegaladeSidebar(props: &RegaladeSidebarProps) -> Html {
|
||||||
|
let entries = vec![
|
||||||
|
MenuEntry {
|
||||||
|
label: "Home",
|
||||||
|
icon: "bi-house",
|
||||||
|
page: Route::Index,
|
||||||
|
},
|
||||||
|
MenuEntry {
|
||||||
|
label: "Ingredients",
|
||||||
|
icon: "bi-egg-fill",
|
||||||
|
page: Route::Ingredients,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<Sidebar {entries} current={props.current} household={props.household.clone()}>
|
||||||
|
{ for props.children.iter() }
|
||||||
|
</Sidebar>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue