Skip to main content

dioxus_bootstrap_css/
breadcrumb.rs

1use dioxus::prelude::*;
2
3/// Bootstrap Breadcrumb component.
4///
5/// # Bootstrap HTML → Dioxus
6///
7/// | HTML | Dioxus |
8/// |---|---|
9/// | `<nav><ol class="breadcrumb"><li class="breadcrumb-item"><a href="/">Home</a></li>...` | `Breadcrumb { BreadcrumbItem { href: "/", "Home" } ... }` |
10/// | `<li class="breadcrumb-item active" aria-current="page">Current</li>` | `BreadcrumbItem { active: true, "Current" }` |
11///
12/// ```rust,no_run
13/// # use dioxus::prelude::*;
14/// # use dioxus_bootstrap_css::prelude::*;
15/// # fn _doctest() -> Element {
16/// rsx! {
17///     Breadcrumb {
18///         BreadcrumbItem { href: "/", "Home" }
19///         BreadcrumbItem { href: "/products", "Products" }
20///         BreadcrumbItem { active: true, "Current Page" }
21///     }
22/// }
23/// # }
24/// ```
25#[derive(Clone, PartialEq, Props)]
26pub struct BreadcrumbProps {
27    /// Additional CSS classes.
28    #[props(default)]
29    pub class: String,
30    /// Child elements (BreadcrumbItem components).
31    pub children: Element,
32}
33
34#[component]
35pub fn Breadcrumb(props: BreadcrumbProps) -> Element {
36    let full_class = if props.class.is_empty() {
37        "breadcrumb".to_string()
38    } else {
39        format!("breadcrumb {}", props.class)
40    };
41
42    rsx! {
43        nav { "aria-label": "breadcrumb",
44            ol { class: "{full_class}", {props.children} }
45        }
46    }
47}
48
49/// A single item in a Breadcrumb.
50#[derive(Clone, PartialEq, Props)]
51pub struct BreadcrumbItemProps {
52    /// Link href. Not rendered if active.
53    #[props(default)]
54    pub href: String,
55    /// Active (current page) state — renders as plain text instead of link.
56    #[props(default)]
57    pub active: bool,
58    /// Additional CSS classes.
59    #[props(default)]
60    pub class: String,
61    /// Child elements.
62    pub children: Element,
63}
64
65#[component]
66pub fn BreadcrumbItem(props: BreadcrumbItemProps) -> Element {
67    let mut classes = vec!["breadcrumb-item".to_string()];
68    if props.active {
69        classes.push("active".to_string());
70    }
71    if !props.class.is_empty() {
72        classes.push(props.class.clone());
73    }
74    let full_class = classes.join(" ");
75
76    if props.active {
77        rsx! {
78            li {
79                class: "{full_class}",
80                "aria-current": "page",
81                {props.children}
82            }
83        }
84    } else {
85        rsx! {
86            li { class: "{full_class}",
87                a { href: "{props.href}", {props.children} }
88            }
89        }
90    }
91}