Skip to main content

dioxus_bootstrap/
sidebar.rs

1use dioxus::prelude::*;
2use super::background::*;
3use dioxus_router::navigation::NavigationTarget;
4use dioxus_router::components::Link;
5
6use super::container::*;
7
8#[derive(Clone, Props, PartialEq)]
9pub struct SidebarLayoutProps {
10    #[props(optional)]
11    id: String,
12    sidebar: Element,
13    children: Element,
14}
15
16#[component]
17pub fn SideBarLayout(props: SidebarLayoutProps) -> Element {
18    rsx!{
19        Row {
20            id: props.id,
21            no_wrap: true,
22            {props.sidebar}
23            main {
24                {props.children}
25            }
26        }
27
28    }
29}
30
31#[derive(Clone, Props, PartialEq)]
32pub struct SidebarProps {
33    #[props(optional)]
34    id: String,
35    children: Element,
36    header: Option<Element>,
37    footer: Option<Element>,
38    #[props(optional, default = BackGroundColor::Tertiary)]
39    background_color: BackGroundColor,
40    #[props(optional, default = 0)]
41    flex_shrink: u8,
42    #[props(optional, default = "300px".to_string())]
43    width: String,
44    #[props(optional, default = 3)]
45    pad: u8,
46}
47
48#[component]
49pub fn SideBar(props: SidebarProps) -> Element {
50    let background_color: &str = props.background_color.into();
51    let class_list = vec![
52        "wrapper sidebar flex-column".to_string(),
53        background_color.to_string(),
54        format!("flex-shrink-{}", props.flex_shrink),
55        format!("p-{}", props.pad)
56    ];
57
58    let width_style = format!("width: {}", props.width);
59
60    let class_list = class_list.join(" ");
61    rsx!{
62        aside {
63            style: width_style,
64            class: class_list,
65            id: props.id,
66            match props.header {
67                Some(h) => rsx!{
68                    {h},
69                    hr{}
70                },
71                None => rsx!{}
72            }
73            {props.children}
74            match props.footer {
75                Some(f) => rsx!{
76                    hr{}
77                    {f},
78                },
79                None => rsx!{}
80            }
81        }
82    }
83}
84
85#[derive(Clone, Props, PartialEq)]
86pub struct SidebarMenuProps {
87    #[props(optional)]
88    id: String,
89    children: Element,
90    #[props(optional, default = true)]
91    pills: bool,
92    #[props(optional, default = true)]
93    auto_size: bool,
94}
95
96#[component]
97pub fn SideBarMenu(props: SidebarMenuProps) -> Element {
98    let mut class_list = vec!["nav".to_string(), "flex-column".to_string()];
99
100    if props.pills {class_list.push("nav-pills".to_string())}
101    if props.auto_size {class_list.push("mb-auto".to_string())}
102
103    let class_list = class_list.join(" ");
104    rsx! {
105        ul {
106            class: class_list,
107            {props.children}
108        }
109    }
110}
111
112#[derive(Clone, Props, PartialEq)]
113pub struct SidebarMenuItemProps {
114    #[props(optional)]
115    id: String,
116    children: Element,
117    #[props(optional, default = false)]
118    active: bool,
119    /// Uses the Dioxus Router for the menu item.
120    #[props(optional, default = None)]
121    link_to: Option<NavigationTarget>,
122    #[props(optional)]
123    onclick: EventHandler<MouseEvent>,
124    #[props(optional)]
125    onmounted: EventHandler<MountedEvent>,
126    #[props(optional, default = "".to_string())]
127    style: String,
128}
129
130#[component]
131pub fn SideBarMenuItem(props: SidebarMenuItemProps) -> Element {
132    let mut class_list = vec!["nav-link".to_string()];
133
134    if props.active {class_list.push("active".to_string())}
135    else {class_list.push("link-body-emphasis".to_string())}
136
137    let class_list = class_list.join(" ");
138    rsx!{
139        li {
140            class: "nav-item",
141            match props.link_to {
142                Some(t) => rsx!{
143                    Link {
144                    to: t,
145                    id: props.id,
146                    onclick: props.onclick,
147                    style: props.style,
148                    class: class_list,
149                    {props.children}
150                }},
151                None => rsx! {
152                    a {
153                    id: props.id,
154                    href: "#",
155                    onclick: props.onclick,
156                    style: props.style,
157                    class: class_list,
158                    {props.children}
159                }},
160            }
161        }
162    }
163}