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-v5-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-v5-c-breadcrumb__list" role="list">
60                {
61                    for props.children.iter().enumerate().map(|(n,c)|item(c, n == last))
62                }
63            </ol>
64        </nav>
65    )
66}
67
68fn item(mut child: BreadcrumbItemVariant, last: bool) -> Html {
69    child.set_current(last);
70
71    html!(
72        <li class="pf-v5-c-breadcrumb__item">
73            <span class="pf-v5-c-breadcrumb__item-divider">
74                <i class="fas fa-angle-right" aria-hidden="true"></i>
75            </span>
76            { child }
77        </li>
78    )
79}
80
81/// Properties for [`BreadcrumbItem`]
82#[derive(Clone, Debug, PartialEq, Properties)]
83pub struct BreadcrumbItemProperties {
84    #[prop_or_default]
85    pub href: AttrValue,
86    #[prop_or_default]
87    pub target: AttrValue,
88    #[prop_or_default]
89    pub children: Html,
90    #[prop_or_default]
91    current: bool,
92}
93
94#[function_component(BreadcrumbItem)]
95pub fn breadcrumb_item(props: &BreadcrumbItemProperties) -> Html {
96    let mut class = Classes::from("pf-v5-c-breadcrumb__link");
97    let mut aria_current = AttrValue::default();
98
99    if props.current {
100        class.push("pf-m-current");
101        aria_current = AttrValue::from("page")
102    }
103
104    if props.href.is_empty() {
105        props.children.clone()
106    } else {
107        html!(
108            <a
109                {class}
110                href={&props.href}
111                target={&props.target}
112                aria-current={aria_current}
113            >
114                    { props.children.clone() }
115            </a>
116        )
117    }
118}