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 /// Click handler for the link. A breadcrumb in a single-page app navigates
59 /// by handler rather than by `href`, and without this the only way to
60 /// intercept it is to hand-write the `<a>` — which is the raw Bootstrap the
61 /// component exists to replace.
62 #[props(default)]
63 pub onclick: Option<EventHandler<MouseEvent>>,
64 /// Additional CSS classes.
65 #[props(default)]
66 pub class: String,
67 /// Child elements.
68 pub children: Element,
69}
70
71#[component]
72pub fn BreadcrumbItem(props: BreadcrumbItemProps) -> Element {
73 let mut classes = vec!["breadcrumb-item".to_string()];
74 if props.active {
75 classes.push("active".to_string());
76 }
77 if !props.class.is_empty() {
78 classes.push(props.class.clone());
79 }
80 let full_class = classes.join(" ");
81
82 if props.active {
83 rsx! {
84 li {
85 class: "{full_class}",
86 "aria-current": "page",
87 {props.children}
88 }
89 }
90 } else {
91 rsx! {
92 li { class: "{full_class}",
93 a {
94 href: "{props.href}",
95 onclick: move |evt| {
96 if let Some(handler) = &props.onclick {
97 handler.call(evt);
98 }
99 },
100 {props.children}
101 }
102 }
103 }
104 }
105}