dioxus_bootstrap/
sidebar.rs1use 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 #[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}