yew_nav_link/
nav_link.rs

1// Import necessary modules from Yew and Yew Router
2use std::marker::PhantomData;
3use yew::prelude::*;
4use yew_router::prelude::*;
5
6/// Props for NavLink component.
7/// R: Routable - A trait bound to ensure that this component can only be used with routable types.
8#[derive(Properties, PartialEq)]
9pub struct NavLinkProps<R: Routable + PartialEq + Clone + 'static> {
10    /// The destination route for the link.
11    pub to: R,
12    /// Children of this component (usually text or other elements to be rendered within the link).
13    pub children: Children,
14    /// Marker for the generic type R. It does not hold any value.
15    #[prop_or_default]
16    pub(crate) _marker: PhantomData<R>,
17}
18
19/// NavLink component for Yew applications using Yew Router.
20///
21/// This component creates a navigational link that is aware of its active state,
22/// based on the current route in the application.
23///
24/// The component is generic over `R`, where `R` must implement the `Routable` trait.
25/// This allows the NavLink to be used with any set of routable types.
26///
27/// # Example
28///
29/// ```rust
30/// #[function_component(App)]
31/// pub fn app() -> Html {
32///     html! {
33///         <nav>
34///             <NavLink<AppRoute> to={AppRoute::Home}>{ "Home" }</NavLink<AppRoute>>
35///             <NavLink<AppRoute> to={AppRoute::About}>{ "About" }</NavLink<AppRoute>>
36///             // ... other NavLinks
37///         </nav>
38///     }
39/// }
40/// ```
41#[function_component(NavLink)]
42pub fn nav_link<R: Routable + PartialEq + Clone + 'static>(props: &NavLinkProps<R>) -> Html {
43    // use_route hook is used to get the current route of the application.
44    let current_route = use_route::<R>();
45
46    // Determine if the NavLink's route matches the current route.
47    // If they match, the link is considered 'active'.
48    let is_active = if let Some(route) = current_route {
49        route == props.to
50    } else {
51        false
52    };
53
54    // CSS class for the NavLink.
55    // The 'active' class is conditionally added based on the active state.
56    let class = format!("nav-link {}", if is_active { "active" } else { "" });
57
58    // Render the NavLink using the Yew's Link component.
59    // The Link component is responsible for handling the navigation.
60    html! {
61        <Link<R> to={props.to.clone()} classes={classes!(class)}>
62            // Rendering children elements passed to the NavLink.
63            { for props.children.iter() }
64        </Link<R>>
65    }
66}
67
68/// Creates a NavLink component for the specified route with the provided children.
69///
70/// This function creates a NavLink component for Yew applications using Yew Router.
71/// It takes a route (`R`) and children text, and returns a NavLink component.
72///
73/// # Arguments
74///
75/// * `to` - The destination route for the link.
76/// * `children` - The text or other elements to be rendered within the link.
77///
78/// # Example
79///
80/// ```rust
81/// // Creating a NavLink for the Home route with the text "Home Page"
82/// <li class="nav-item">
83///     { nav_link(HomeRoute::IntroPage, "Home Page") }
84/// </li>
85/// ```
86///
87/// # Generic Type
88///
89/// * `R` - The route type that implements the `Routable` trait.
90///
91/// # Returns
92///
93/// An HTML representation of the NavLink component.
94///
95/// # Note
96///
97/// The `to` parameter must be of a type that implements the `Routable` trait.
98pub fn nav_link<R: Routable + PartialEq + Clone + 'static>(to: R, children: &str) -> Html {
99    html! {
100        <NavLink<R> to={to}>{ children }</NavLink<R>>
101    }
102}