use super::navbar_container::NavbarContainer;
use super::navbar_item::NavbarItem;
use crate::layouts::container::{Direction, JustifyContent, Mode};
use crate::styles::{get_palette, get_style, Palette, Style};
use crate::utils::create_style;
use stylist::{css, StyleSource};
use yew::prelude::*;
use yew::Children;
use yew_assets::ux_assets::{UxAssets, UxIcon};
pub struct Navbar {
pub link: ComponentLink<Self>,
pub props: NavbarProps,
pub display_menu: bool,
}
struct NavbarModel;
#[derive(Clone, Properties, PartialEq)]
pub struct Props {
#[prop_or(Palette::Standard)]
pub navbar_palette: Palette,
#[prop_or(false)]
pub hide_navbar_items_mobile: bool,
#[prop_or(Style::Regular)]
pub navbar_style: Style,
#[prop_or_default]
pub code_ref: NodeRef,
#[prop_or_default]
pub key: String,
#[prop_or_default]
pub class_name: String,
#[prop_or_default]
pub id: String,
#[prop_or(Fixed::Top)]
pub fixed: Fixed,
#[prop_or_default]
pub branch: Html,
#[prop_or(css!(""))]
pub styles: StyleSource<'static>,
pub children: Children,
}
#[derive(Clone, PartialEq)]
pub struct NavbarProps {
pub navbar_palette: String,
pub navbar_style: String,
pub hide_navbar_items_mobile: bool,
pub key: String,
pub code_ref: NodeRef,
pub id: String,
pub class_name: String,
pub fixed: Fixed,
pub branch: Html,
pub styles: StyleSource<'static>,
pub children: Children,
}
impl From<Props> for NavbarProps {
fn from(props: Props) -> Self {
NavbarProps {
navbar_palette: get_palette(props.navbar_palette),
navbar_style: get_style(props.navbar_style),
hide_navbar_items_mobile: props.hide_navbar_items_mobile,
key: props.key,
code_ref: props.code_ref,
id: props.id,
class_name: props.class_name,
fixed: props.fixed,
branch: props.branch,
children: props.children,
styles: props.styles,
}
}
}
#[derive(Clone, PartialEq)]
pub enum Fixed {
None,
Top,
Bottom,
}
pub enum Msg {
TroggleMenu,
}
impl Component for Navbar {
type Message = Msg;
type Properties = Props;
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
Navbar {
link,
props: NavbarProps::from(props),
display_menu: false,
}
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::TroggleMenu => {
self.display_menu = !self.display_menu;
}
};
true
}
fn rendered(&mut self, first_render: bool) {
if first_render {
NavbarModel.init(self.props.clone());
}
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
if self.props != NavbarProps::from(props.clone()) {
NavbarModel.init(self.props.clone());
self.props = NavbarProps::from(props);
if self.props.hide_navbar_items_mobile && self.display_menu {
self.display_menu = false;
}
return true;
}
false
}
fn view(&self) -> Html {
html! {
<>
<div
class=classes!("navbar-mobile", self.props.navbar_style.clone(), self.props.navbar_palette.clone(), self.props.class_name.clone(), self.props.styles.clone())
id=self.props.id.clone()
key=self.props.key.clone()
ref=self.props.code_ref.clone()
>
<div class="navbar-collapse">
<NavbarContainer justify_content=JustifyContent::FlexStart(Mode::NoMode)
direction=Direction::Row
class_name="navbar-container-mobile">
{get_branch(self.props.branch.clone())}
</NavbarContainer>
<NavbarContainer justify_content=JustifyContent::FlexEnd(Mode::NoMode)
direction=Direction::Row
class_name="navbar-container-mobile">
<NavbarItem
onclick_signal=self.link.callback(move |_| Msg::TroggleMenu)
class_name="navbar-menu-item"
>
<UxAssets
icon=UxIcon::Menu
size=(String::from("30"), String::from("30"))
class_name="navbar-menu"
/>
</NavbarItem>
</NavbarContainer>
</div>
{if self.display_menu {
self.props.children.clone()
} else {
Children::new(vec![])
}}
</div>
<div
class=format!("navbar {} {} {}", self.props.navbar_style, self.props.navbar_palette, self.props.class_name)
>
<NavbarContainer justify_content=JustifyContent::Start(Mode::NoMode)
direction=Direction::Row
class_name="navbar-container-mobile">
{get_branch(self.props.branch.clone())}
</NavbarContainer>
{if !self.display_menu {
self.props.children.clone()
} else {
Children::new(vec![])
} }
</div>
</>
}
}
}
impl NavbarModel {
fn init(self, props: NavbarProps) {
self.set_fixed(props.fixed);
}
fn set_fixed(self, fixed: Fixed) {
create_style(
String::from("position"),
if fixed == Fixed::None {
String::from("inherit")
} else {
String::from("fixed")
},
String::from("navbar"),
);
if fixed != Fixed::None {
create_style(
if fixed == Fixed::Top {
String::from("top")
} else {
String::from("bottom")
},
String::from("0"),
String::from("navbar"),
);
}
}
}
fn get_branch(branch: Html) -> Html {
if branch != html! {} {
html! {
<div class="branch">
{branch}
</div>
}
} else {
html! {}
}
}