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