patternfly_yew/components/tabs/
router.rs1use super::TabTitle;
2use crate::ouia;
3use crate::prelude::{AsClasses, Inset, OuiaComponentType};
4use crate::utils::{Ouia, OuiaSafe};
5use std::fmt::Debug;
6use yew::prelude::*;
7use yew_nested_router::{components::Link, prelude::*};
8
9const OUIA_TABS: Ouia = ouia!("Tabs");
10
11#[derive(Clone, Debug, PartialEq, Properties)]
15pub struct TabsRouterProperties<T>
16where
17 T: Target + 'static,
18{
19 #[prop_or_default]
20 pub r#box: bool,
21 #[prop_or_default]
22 pub vertical: bool,
23 #[prop_or_default]
24 pub filled: bool,
25
26 #[prop_or_default]
27 pub inset: Option<Inset>,
28
29 #[prop_or_default]
30 pub children: ChildrenWithProps<TabRouterItem<T>>,
31
32 #[prop_or_default]
34 pub ouia_id: Option<String>,
35 #[prop_or(OUIA_TABS.component_type())]
37 pub ouia_type: OuiaComponentType,
38 #[prop_or(OuiaSafe::TRUE)]
40 pub ouia_safe: OuiaSafe,
41}
42
43#[function_component(TabsRouter)]
44pub fn tabs_router<T>(props: &TabsRouterProperties<T>) -> Html
45where
46 T: Target,
47{
48 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
49 id.clone().unwrap_or(OUIA_TABS.generated_id())
50 });
51 let mut classes = classes!("pf-v6-c-tabs");
52
53 if props.r#box {
54 classes.push("pf-m-box");
55 }
56
57 if props.vertical {
58 classes.push("pf-m-vertical");
59 }
60
61 if props.filled {
62 classes.push("pf-m-fill");
63 }
64
65 if let Some(inset) = &props.inset {
66 inset.extend_classes(&mut classes);
67 }
68
69 html! (
70 <div
71 class={classes}
72 data-ouia-component-id={(*ouia_id).clone()}
73 data-ouia-component-type={props.ouia_type}
74 data-ouia-safe={props.ouia_safe}
75 >
76 <ul class="pf-v6-c-tabs__list">{ for props.children.iter() }</ul>
77 </div>
78 )
79}
80
81const OUIA_ITEM: Ouia = ouia!("TabsItem");
83
84#[derive(Properties, Clone, PartialEq)]
86pub struct TabRouterItemProperties<T>
87where
88 T: Target,
89{
90 pub title: TabTitle,
92 pub to: T,
94 #[prop_or(false)]
96 pub disabled: bool,
97
98 #[prop_or_default]
100 pub ouia_id: Option<String>,
101 #[prop_or(OUIA_ITEM.component_type())]
103 pub ouia_type: OuiaComponentType,
104 #[prop_or(OuiaSafe::TRUE)]
106 pub ouia_safe: OuiaSafe,
107}
108
109#[function_component(TabRouterItem)]
110pub fn tab_router_item<T>(props: &TabRouterItemProperties<T>) -> Html
111where
112 T: Target,
113{
114 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
115 id.clone().unwrap_or(OUIA_ITEM.generated_id())
116 });
117 let router = use_router::<T>().expect("Must be used below a Router or Nested component");
118
119 let mut classes = Classes::from("pf-v6-c-tabs__item");
120
121 if router.is_same(&props.to) {
122 classes.push("pf-m-current");
123 }
124
125 let mut link_classes = Classes::from("pf-v6-c-tabs__link");
126
127 if props.disabled {
128 link_classes.push("pf-m-disabled");
129 }
130
131 html! (
132 <li
133 class={classes}
134 data-ouia-component-id={(*ouia_id).clone()}
135 data-ouia-component-type={props.ouia_type}
136 data-ouia-safe={props.ouia_safe}
137 >
138 <Link<T> element="button" class={link_classes} to={props.to.clone()}>
139 <span class="pf-v6-c-tabs__item-text">{ props.title.clone() }</span>
140 </Link<T>>
141 </li>
142 )
143}