use leptos::prelude::*; use leptos_router::components::{Outlet, A}; use leptos_router::hooks::use_location; use crate::common::{SubTabInfo, TabInfo}; /// # Tab Sidebar Component /// /// This component creates a list of tabs that correspond to the given `Vec`. /// There are a few things to note: /// /// - This component defines an [`Outlet`], meaning that it is designed to display the route /// information on its own. If you intend to use this on a page, the page should not also contain /// an `Outlet` component unless it needs to render its own nested children. /// - The "selected" appearance for the individual tabs work best when their paths are at the same /// depth. For example: /// ``` /// let good_list = vec! [ /// TabInfo { /// ..., /// path: "/default/path" /// }, /// TabInfo { /// ..., /// path: "/good/path" /// } /// ]; /// /// let bad_list = vec! [ /// TabInfo { /// ..., /// path: "/default/path" /// }, /// TabInfo { /// ..., /// path: "/bad/path/here" /// } /// ] /// ``` /// /// Example usage in a view (assuming the good list from above): /// ``` /// view! { /// /// // Remember, no Outlets! /// } /// ``` #[component] pub fn TabSidebarList( #[prop(into)] base_path: Signal, #[prop(into)] tabs: Signal>, ) -> impl IntoView { // Create a series of tabs based on a given list of names and paths. view! {
} } #[component] fn SidebarTab( #[prop(into)] base_path: Signal, #[prop(into)] text: Signal, #[prop(into)] path: Signal, #[prop(into)] sub_paths: Signal>, ) -> impl IntoView { let location = use_location(); let full_path = Memo::new(move |_| { format!("/{}/{}", base_path.get(), path.get()) }); let selected = Memo::new(move |_| { let current_path = location.pathname.get(); // There's extra logic here as well, but for now this works. current_path.starts_with(&full_path.get()) }); view! { } } #[component] fn SidebarSubTab( #[prop(into)] parent_path: Signal, #[prop(into)] text: Signal, #[prop(into)] path: Signal, ) -> impl IntoView { let full_path = Memo::new(move |_| { format!("{}/{}", parent_path.get(), path.get()) }); view! { {text} } }