Skip to main content

patternfly_yew/components/breadcrumb/
mod.rs

1//! Navigation breadcrumbs
2use crate::ouia;
3use crate::prelude::OuiaComponentType;
4use crate::utils::{Ouia, OuiaSafe};
5use variant::BreadcrumbItemVariant;
6use yew::{html::ChildrenRenderer, prelude::*};
7
8#[cfg(feature = "yew-nested-router")]
9mod router;
10mod variant;
11
12#[cfg(feature = "yew-nested-router")]
13pub use router::*;
14
15const OUIA: Ouia = ouia!("Breadcrumb");
16
17/// Properties for [`Breadcrumb`]
18#[derive(Clone, Debug, PartialEq, Properties)]
19pub struct BreadcrumbProperties {
20    #[prop_or_default]
21    pub children: ChildrenRenderer<BreadcrumbItemVariant>,
22
23    /// OUIA Component id
24    #[prop_or_default]
25    pub ouia_id: Option<String>,
26    /// OUIA Component Type
27    #[prop_or(OUIA.component_type())]
28    pub ouia_type: OuiaComponentType,
29    /// OUIA Component Safe
30    #[prop_or(OuiaSafe::TRUE)]
31    pub ouia_safe: OuiaSafe,
32}
33
34/// Breadcrumb component
35///
36/// > A **breadcrumb** provides page context to help users navigate more efficiently and understand where they are in the application hierarchy.
37///
38/// See: <https://www.patternfly.org/components/breadcrumb>
39///
40/// ## Properties
41///
42/// Defined by [`BreadcrumbProperties`].
43///
44#[function_component(Breadcrumb)]
45pub fn breadcrumb(props: &BreadcrumbProperties) -> Html {
46    let ouia_id = use_memo(props.ouia_id.clone(), |id| {
47        id.clone().unwrap_or(OUIA.generated_id())
48    });
49    let last = props.children.len() - 1;
50
51    html!(
52        <nav
53            class="pf-v6-c-breadcrumb"
54            aria-label="breadcrumb"
55            data-ouia-component-id={(*ouia_id).clone()}
56            data-ouia-component-type={props.ouia_type}
57            data-ouia-safe={props.ouia_safe}
58        >
59            <ol class="pf-v6-c-breadcrumb__list" role="list">
60                { for props.children.iter().enumerate().map(|(n,c)|item(c, n == last)) }
61            </ol>
62        </nav>
63    )
64}
65
66fn item(mut child: BreadcrumbItemVariant, last: bool) -> Html {
67    child.set_current(last);
68
69    html!(
70        <li class="pf-v6-c-breadcrumb__item">
71            <span class="pf-v6-c-breadcrumb__item-divider">
72                <i class="fas fa-angle-right" aria-hidden="true" />
73            </span>
74            { child }
75        </li>
76    )
77}
78
79/// Properties for [`BreadcrumbItem`]
80#[derive(Clone, Debug, PartialEq, Properties)]
81pub struct BreadcrumbItemProperties {
82    #[prop_or_default]
83    pub href: AttrValue,
84    #[prop_or_default]
85    pub target: AttrValue,
86    #[prop_or_default]
87    pub children: Html,
88    #[prop_or_default]
89    current: bool,
90}
91
92#[function_component(BreadcrumbItem)]
93pub fn breadcrumb_item(props: &BreadcrumbItemProperties) -> Html {
94    let mut class = Classes::from("pf-v6-c-breadcrumb__link");
95    let mut aria_current = AttrValue::default();
96
97    if props.current {
98        class.push("pf-m-current");
99        aria_current = AttrValue::from("page")
100    }
101
102    if props.href.is_empty() {
103        props.children.clone()
104    } else {
105        html!(
106            <a {class} href={&props.href} target={&props.target} aria-current={aria_current}>
107                { props.children.clone() }
108            </a>
109        )
110    }
111}