Skip to main content

dioxus_bootstrap/
dropdown.rs

1use dioxus::prelude::*;
2use dioxus_router::navigation::NavigationTarget;
3use dioxus_router::components::Link;
4
5#[derive(Clone, Props, PartialEq)]
6pub struct DropdownProps {
7    #[props(optional)]
8    id: String,
9    #[props(optional, default = "".to_string())]
10    class: String,
11    children: Element,
12}
13
14#[component]
15pub fn Dropdown(props: DropdownProps) -> Element {
16    let mut class_list = vec!["dropdown".to_string()];
17    
18    if !props.class.is_empty() {
19        class_list.push(props.class.clone());
20    }
21    
22    let class_list = class_list.join(" ");
23    
24    rsx! {
25        div {
26            id: props.id,
27            class: class_list,
28            {props.children}
29        }
30    }
31}
32
33#[derive(Clone, Props, PartialEq)]
34pub struct DropdownMenuProps {
35    #[props(optional)]
36    id: String,
37    #[props(optional, default = "".to_string())]
38    class: String,
39    #[props(optional, default = false)]
40    dark: bool,
41    children: Element,
42}
43
44#[component]
45pub fn DropdownMenu(props: DropdownMenuProps) -> Element {
46    let mut class_list = vec!["dropdown-menu".to_string()];
47    
48    if props.dark {
49        class_list.push("dropdown-menu-dark".to_string());
50    }
51    
52    if !props.class.is_empty() {
53        class_list.push(props.class.clone());
54    }
55    
56    let class_list = class_list.join(" ");
57    
58    rsx! {
59        ul {
60            id: props.id,
61            class: class_list,
62            {props.children}
63        }
64    }
65}
66
67#[derive(Clone, Props, PartialEq)]
68pub struct DropdownItemProps {
69    #[props(optional)]
70    id: String,
71    #[props(optional, default = "".to_string())]
72    class: String,
73    #[props(optional, default = false)]
74    active: bool,
75    #[props(optional, default = false)]
76    disabled: bool,
77    #[props(optional)]
78    href: Option<String>,
79    #[props(optional)]
80    link_to: Option<NavigationTarget>,
81    #[props(optional)]
82    onclick: EventHandler<MouseEvent>,
83    children: Element,
84}
85
86#[component]
87pub fn DropdownItem(props: DropdownItemProps) -> Element {
88    let mut class_list = vec!["dropdown-item".to_string()];
89    
90    if props.active {
91        class_list.push("active".to_string());
92    }
93    
94    if props.disabled {
95        class_list.push("disabled".to_string());
96    }
97    
98    if !props.class.is_empty() {
99        class_list.push(props.class.clone());
100    }
101    
102    let class_list = class_list.join(" ");
103    
104    rsx! {
105        li {
106            match props.link_to {
107                Some(to) if !props.disabled => rsx! {
108                    Link {
109                        id: props.id,
110                        class: class_list,
111                        to: to,
112                        onclick: props.onclick,
113                        {props.children}
114                    }
115                },
116                None if !props.disabled => rsx! {
117                    a {
118                        id: props.id,
119                        class: class_list,
120                        href: props.href.unwrap_or("#".to_string()),
121                        onclick: props.onclick,
122                        {props.children}
123                    }
124                },
125                _ => rsx! {
126                    span {
127                        id: props.id,
128                        class: class_list,
129                        {props.children}
130                    }
131                }
132            }
133        }
134    }
135}
136
137#[derive(Clone, Props, PartialEq)]
138pub struct DropdownHeaderProps {
139    #[props(optional)]
140    id: String,
141    #[props(optional, default = "".to_string())]
142    class: String,
143    children: Element,
144}
145
146#[component]
147pub fn DropdownHeader(props: DropdownHeaderProps) -> Element {
148    let mut class_list = vec!["dropdown-header".to_string()];
149    
150    if !props.class.is_empty() {
151        class_list.push(props.class.clone());
152    }
153    
154    let class_list = class_list.join(" ");
155    
156    rsx! {
157        li {
158            h6 {
159                id: props.id,
160                class: class_list,
161                {props.children}
162            }
163        }
164    }
165}
166
167#[derive(Clone, Props, PartialEq)]
168pub struct DropdownDividerProps {
169    #[props(optional)]
170    id: String,
171    #[props(optional, default = "".to_string())]
172    class: String,
173}
174
175#[component]
176pub fn DropdownDivider(props: DropdownDividerProps) -> Element {
177    let mut class_list = vec!["dropdown-divider".to_string()];
178    
179    if !props.class.is_empty() {
180        class_list.push(props.class.clone());
181    }
182    
183    let class_list = class_list.join(" ");
184    
185    rsx! {
186        li {
187            hr {
188                id: props.id,
189                class: class_list,
190            }
191        }
192    }
193}