Skip to main content

shadow_design/
tabs.rs

1use crate::icon::{Icon, IconKind};
2use dioxus::prelude::*;
3
4#[component]
5pub fn TabList(#[props(default)] class: String, children: Element) -> Element {
6    #[cfg(feature = "theme")]
7    let theme_val = crate::theme::use_theme()();
8    #[cfg(feature = "theme")]
9    let base_override = theme_val.resolve_component_base("tabs").unwrap_or("");
10    #[cfg(feature = "theme")]
11    let class_modifiers = theme_val.resolve_class_modifiers("tabs", &class);
12
13    #[cfg(not(feature = "theme"))]
14    let base_override = "";
15    #[cfg(not(feature = "theme"))]
16    let class_modifiers = String::new();
17
18    rsx! {
19        div {
20            class: "sd-tabs-list {base_override} {class_modifiers} {class}",
21            {children}
22        }
23    }
24}
25
26#[component]
27pub fn Tab(
28    value: String,
29    active: Signal<String>,
30    #[props(default)] icon: Option<IconKind>,
31    #[props(default)] badge: Option<String>,
32    #[props(default)] class: String,
33    children: Element,
34) -> Element {
35    let is_active = *active.read() == value;
36    let target = value.clone();
37    let active_class = if is_active { "sd-tab--active" } else { "" };
38
39    #[cfg(feature = "theme")]
40    let theme_val = crate::theme::use_theme()();
41    #[cfg(feature = "theme")]
42    let base_override = theme_val.resolve_component_base("tab").unwrap_or("");
43    #[cfg(feature = "theme")]
44    let class_modifiers = theme_val.resolve_class_modifiers("tab", &class);
45
46    #[cfg(not(feature = "theme"))]
47    let base_override = "";
48    #[cfg(not(feature = "theme"))]
49    let class_modifiers = String::new();
50
51    rsx! {
52        button {
53            r#type: "button",
54            class: "sd-tab {base_override} {active_class} {class_modifiers} {class}",
55            onclick: move |_| *active.write() = target.clone(),
56            if let Some(i) = icon {
57                span { class: "sd-tab__icon",
58                    Icon { kind: i, size: 14 }
59                }
60            }
61            {children}
62            if let Some(b) = badge {
63                span { class: "sd-tab__badge", "{b}" }
64            }
65        }
66    }
67}
68
69#[component]
70pub fn TabPanel(
71    value: String,
72    active: Signal<String>,
73    #[props(default)] class: String,
74    children: Element,
75) -> Element {
76    if *active.read() != value {
77        return rsx! {};
78    }
79
80    #[cfg(feature = "theme")]
81    let theme_val = crate::theme::use_theme()();
82    #[cfg(feature = "theme")]
83    let base_override = theme_val.resolve_component_base("tab-panel").unwrap_or("");
84    #[cfg(feature = "theme")]
85    let class_modifiers = theme_val.resolve_class_modifiers("tab-panel", &class);
86
87    #[cfg(not(feature = "theme"))]
88    let base_override = "";
89    #[cfg(not(feature = "theme"))]
90    let class_modifiers = String::new();
91
92    rsx! {
93        div {
94            class: "sd-tab-panel {base_override} {class_modifiers} {class}",
95            {children}
96        }
97    }
98}