Skip to main content

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}