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-v5-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-v5-c-tabs__list">
77 { for props.children.iter() }
78 </ul>
79 </div>
80 )
81}
82
83const OUIA_ITEM: Ouia = ouia!("TabsItem");
85
86#[derive(Properties, Clone, PartialEq)]
88pub struct TabRouterItemProperties<T>
89where
90 T: Target,
91{
92 pub title: TabTitle,
94 pub to: T,
96 #[prop_or(false)]
98 pub disabled: bool,
99
100 #[prop_or_default]
102 pub ouia_id: Option<String>,
103 #[prop_or(OUIA_ITEM.component_type())]
105 pub ouia_type: OuiaComponentType,
106 #[prop_or(OuiaSafe::TRUE)]
108 pub ouia_safe: OuiaSafe,
109}
110
111#[function_component(TabRouterItem)]
112pub fn tab_router_item<T>(props: &TabRouterItemProperties<T>) -> Html
113where
114 T: Target,
115{
116 let ouia_id = use_memo(props.ouia_id.clone(), |id| {
117 id.clone().unwrap_or(OUIA_ITEM.generated_id())
118 });
119 let router = use_router::<T>().expect("Must be used below a Router or Nested component");
120
121 let mut classes = Classes::from("pf-v5-c-tabs__item");
122
123 if router.is_same(&props.to) {
124 classes.push("pf-m-current");
125 }
126
127 let mut link_classes = Classes::from("pf-v5-c-tabs__link");
128
129 if props.disabled {
130 link_classes.push("pf-m-disabled");
131 }
132
133 html! (
134 <li
135 class={classes}
136 data-ouia-component-id={(*ouia_id).clone()}
137 data-ouia-component-type={props.ouia_type}
138 data-ouia-safe={props.ouia_safe}
139 >
140 <Link<T> element="button" class={link_classes} to={props.to.clone()}>
141 <span class="pf-v5-c-tabs__item-text"> { &props.title } </span>
142 </Link<T>>
143 </li>
144 )
145}