yew_nav_link/components/header.rs
1//! # `NavHeader`
2//!
3//! Section header for labeling groups within a navigation list.
4//! Renders a `<li>` with `role="presentation"` and the `nav-header` class.
5//!
6//! # Example
7//!
8//! ```rust
9//! use yew::prelude::*;
10//! use yew_nav_link::{NavHeader, NavItem, NavLink, NavList};
11//! use yew_router::prelude::*;
12//!
13//! # #[derive(Clone, PartialEq, Routable)]
14//! # enum Route {
15//! # #[at("/")]
16//! # Home,
17//! # #[at("/about")]
18//! # About,
19//! # }
20//! #[component]
21//! fn Nav() -> Html {
22//! html! {
23//! <NavList>
24//! <NavHeader text="Main" />
25//! <NavItem><NavLink<Route> to={Route::Home}>{ "Home" }</NavLink<Route>></NavItem>
26//! <NavHeader text="Info" />
27//! <NavItem><NavLink<Route> to={Route::About}>{ "About" }</NavLink<Route>></NavItem>
28//! </NavList>
29//! }
30//! }
31//! ```
32//!
33//! # CSS Classes
34//!
35//! | Class | Condition |
36//! |-------|-----------|
37//! | `nav-header` | Always applied |
38//! | `nav-header-text` | Inner text span |
39//!
40//! # Props
41//!
42//! | Prop | Type | Default | Description |
43//! |------|------|---------|-------------|
44//! | `text` | `Option<&'static str>` | `None` | Header text label |
45//! | `classes` | `Classes` | — | Additional CSS classes |
46//! | `children` | `Children` | — | Content when `text` is `None` |
47
48use yew::prelude::*;
49
50/// Properties for the [`NavHeader`] component.
51///
52/// | Prop | Type | Default | Description |
53/// |------|------|---------|-------------|
54/// | `text` | `Option<&'static str>` | `None` | Header text label |
55/// | `classes` | `Classes` | — | Additional CSS classes |
56/// | `children` | `Children` | — | Content when `text` is `None` |
57#[derive(Properties, Clone, PartialEq, Debug)]
58pub struct NavHeaderProps {
59 /// Additional CSS classes applied to the header.
60 #[prop_or_default]
61 pub classes: Classes,
62
63 /// Text label displayed in the header. If set, overrides `children`.
64 #[prop_or_default]
65 pub text: Option<&'static str>,
66
67 /// Content rendered inside the header when `text` is `None`.
68 #[prop_or_default]
69 pub children: Children
70}
71
72/// Header component for labeling sections within a navigation list.
73///
74/// Renders a `<li>` with `role="presentation"` and the `nav-header` class.
75#[function_component]
76pub fn NavHeader(props: &NavHeaderProps) -> Html {
77 let mut classes = props.classes.clone();
78 classes.push("nav-header");
79
80 if let Some(text) = props.text {
81 html! {
82 <li {classes} role="presentation">
83 <span class="nav-header-text">{ text }</span>
84 </li>
85 }
86 } else {
87 html! {
88 <li {classes} role="presentation">
89 { for props.children.iter() }
90 </li>
91 }
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn nav_header_props_with_text() {
101 let props = NavHeaderProps {
102 classes: Classes::default(),
103 text: Some("Header"),
104 children: Children::new(vec![])
105 };
106
107 assert_eq!(props.text, Some("Header"));
108 }
109
110 #[test]
111 fn nav_header_clone() {
112 let props1 = NavHeaderProps {
113 classes: Classes::default(),
114 text: Some("Header"),
115 children: Children::new(vec![])
116 };
117
118 let props2 = props1.clone();
119 assert_eq!(props1.text, props2.text);
120 }
121}