dioxus_bootstrap/
tab.rs

1use dioxus::prelude::*;
2use dioxus_router::navigation::NavigationTarget;
3use dioxus_router::components::Link;
4
5#[derive(Clone, Copy, PartialEq)]
6pub enum TabSetVarient {
7    /// Tabs look like links, without decoration
8    Basic,
9
10    /// Tabs with a basic tab outline.
11    Tabs,
12
13    /// Pill-shaped tabs
14    Pills,
15
16    /// Tabs are underlined.
17    Underline,
18}
19
20
21#[derive(Clone, Props, PartialEq)]
22pub struct TabSetProps {
23    #[props(optional)]
24    id: String,
25    children: Element,
26    #[props(optional, default = TabSetVarient::Basic)]
27    varient: TabSetVarient,
28    #[props(optional, default = false)]
29    verticle: bool,
30    #[props(optional, default = false)]
31    fill: bool,
32}
33
34#[component]
35pub fn TabSet(props: TabSetProps) -> Element {
36    let mut class_list = String::from("nav");
37
38    if props.verticle {
39        class_list.push_str(" flex-column");
40    }
41
42    match props.varient {
43        TabSetVarient::Tabs => {
44            class_list.push_str(" nav-tabs");
45        },
46        TabSetVarient::Pills => {
47            class_list.push_str(" nav-pills");
48        },
49        TabSetVarient::Underline => {
50            class_list.push_str(" nav-underline");
51        },
52        _ => {}
53    }
54
55    if props.fill {
56        class_list.push_str(" nav-fill");
57    }
58
59    rsx! {
60        ul {
61            class: class_list,
62            {props.children}
63        }
64    }
65}
66
67#[derive(Clone, Props, PartialEq)]
68pub struct TabProps {
69    #[props(optional)]
70    id: String,
71    children: Element,
72    #[props(optional, default = false)]
73    active: bool,
74    #[props(optional, default = None)]
75    link_to: Option<NavigationTarget>,
76    #[props(optional, default = false)]
77    dropdown: bool,
78    #[props(optional, default = false)]
79    disabled: bool,
80    #[props(optional)]
81    onclick: EventHandler<MouseEvent>,
82    #[props(optional)]
83    onmounted: EventHandler<MountedEvent>,
84    #[props(optional, default = String::from(""))]
85    style: String,
86}
87
88#[component]
89pub fn Tab(props: TabProps) -> Element {
90    let mut class_list = String::from("nav-item");
91    if props.active {
92        class_list.push_str(" active");
93    }
94    if props.dropdown {
95        class_list.push_str(" dropdown");
96    }
97
98    rsx! {
99        li {
100            class: class_list,
101            if props.dropdown {
102                ul {
103                    class: "dropdown-menu",
104                    {props.children}
105                }
106            } else {
107                match props.link_to {
108                    Some(link) => {
109                        rsx! {
110                            Link {
111                                to: link,
112                                id: props.id,
113                                onclick: props.onclick,
114                                style: props.style,
115                                class: "nav-link",
116                                aria_disabled: props.disabled,
117                                {props.children}
118                            }
119                        }
120                    }
121                    None => {
122                        rsx! {
123                            a {
124                                class: "nav-link",
125                                style: props.style,
126                                aria_disabled: props.disabled,
127                                onclick: props.onclick,
128                                id: props.id,
129                                {props.children}
130                            }
131                        }
132                    }
133                }
134            }
135        }
136    }
137}