From 5256c9275ce0eae08d5676e52b71f5d82e12b86d Mon Sep 17 00:00:00 2001 From: luoxiao Date: Thu, 1 Aug 2024 17:31:42 +0800 Subject: [PATCH] feat: adds NavCategory --- thaw/src/nav/mod.rs | 2 + thaw/src/nav/nav-drawer.css | 38 ++++++++++++-- thaw/src/nav/nav_category.rs | 99 ++++++++++++++++++++++++++++++++++++ thaw/src/nav/nav_drawer.rs | 20 +++++--- thaw/src/nav/nav_item.rs | 43 +++++++++++++--- 5 files changed, 185 insertions(+), 17 deletions(-) create mode 100644 thaw/src/nav/nav_category.rs diff --git a/thaw/src/nav/mod.rs b/thaw/src/nav/mod.rs index ae2500d..9fabb4d 100644 --- a/thaw/src/nav/mod.rs +++ b/thaw/src/nav/mod.rs @@ -1,5 +1,7 @@ +mod nav_category; mod nav_drawer; mod nav_item; +pub use nav_category::*; pub use nav_drawer::*; pub use nav_item::*; diff --git a/thaw/src/nav/nav-drawer.css b/thaw/src/nav/nav-drawer.css index f9ed9c5..bf05b45 100644 --- a/thaw/src/nav/nav-drawer.css +++ b/thaw/src/nav/nav-drawer.css @@ -38,7 +38,8 @@ z-index: 2; } -.thaw-nav-item { +.thaw-nav-item, +.thaw-nav-category-item { display: flex; text-transform: none; position: relative; @@ -58,11 +59,13 @@ cursor: pointer; } -.thaw-nav-item:hover { +.thaw-nav-item:hover, +.thaw-nav-category-item:hover { background-color: var(--colorNeutralBackground4Hover); } -.thaw-nav-item:active { +.thaw-nav-item:active, +.thaw-nav-category-item:active { background-color: var(--colorNeutralBackground4Pressed); } @@ -75,3 +78,32 @@ border-radius: var(--borderRadiusCircular); margin-inline-start: -18px; } + +.thaw-nav-sub-item-group-enter-from, +.thaw-nav-sub-item-group-enter-to { + opacity: 1; +} + +.thaw-nav-sub-item-group-leave-to, +.thaw-nav-sub-item-group-enter-from { + opacity: 0; + max-height: 0; +} + +.thaw-nav-sub-item-group-leave-active { + overflow: hidden; + transition: max-height 0.15s cubic-bezier(0.4, 0, 0.2, 1) 0s, + opacity 0.15s cubic-bezier(0, 0, 0.2, 1) 0s, + padding-top 0.15s cubic-bezier(0.4, 0, 0.2, 1) 0s; +} + +.thaw-nav-sub-item-group-enter-active { + overflow: hidden; + transition: max-height 0.15s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.15s cubic-bezier(0.4, 0, 1, 1), + padding-top 0.15s cubic-bezier(0.4, 0, 0.2, 1); +} + +.thaw-nav-sub-item { + padding-inline-start: 46px; +} diff --git a/thaw/src/nav/nav_category.rs b/thaw/src/nav/nav_category.rs new file mode 100644 index 0000000..bb9c61c --- /dev/null +++ b/thaw/src/nav/nav_category.rs @@ -0,0 +1,99 @@ +use super::NavDrawerInjection; +use crate::Icon; +use leptos::{either::Either, html, prelude::*}; +use thaw_components::CSSTransition; +use thaw_utils::{class_list, StoredMaybeSignal}; + +#[component] +pub fn NavCategory( + #[prop(into)] value: MaybeSignal, + children: Children, + nav_category_item: NavCategoryItem, +) -> impl IntoView { + let nav_drawer = NavDrawerInjection::expect_context(); + let value: StoredMaybeSignal<_> = value.into(); + let group_ref = NodeRef::::new(); + let on_click = move |_| { + let value = value.get_untracked(); + if nav_drawer + .selected_category_value + .with_untracked(|selected_category_value| selected_category_value != Some(&value)) + { + nav_drawer.selected_category_value.set(Some(value)); + } + }; + + let is_show_group = Memo::new(move |_| { + nav_drawer + .selected_category_value + .with_untracked(|selected_category_value| { + value.with_untracked(|value| selected_category_value == Some(value)) + }) + }); + + let NavCategoryItem { + class: item_class, + icon: item_icon, + children: item_children, + } = nav_category_item; + + view! { + + +
+ {children()} +
+
+ } +} + +#[slot] +pub struct NavCategoryItem { + #[prop(optional, into)] + class: MaybeProp, + #[prop(optional, into)] + icon: MaybeProp, + children: Children, +} diff --git a/thaw/src/nav/nav_drawer.rs b/thaw/src/nav/nav_drawer.rs index a40d5f7..f612931 100644 --- a/thaw/src/nav/nav_drawer.rs +++ b/thaw/src/nav/nav_drawer.rs @@ -1,12 +1,13 @@ use crate::Scrollbar; use leptos::{context::Provider, prelude::*}; use thaw_components::OptionComp; -use thaw_utils::{class_list, mount_style, Model}; +use thaw_utils::{class_list, mount_style, OptionModel}; #[component] pub fn NavDrawer( #[prop(optional, into)] class: MaybeProp, - #[prop(optional, into)] selected_value: Model, + #[prop(optional, into)] selected_value: OptionModel, + #[prop(optional, into)] selected_category_value: OptionModel, children: Children, #[prop(optional)] nav_drawer_header: Option, #[prop(optional)] nav_drawer_footer: Option, @@ -14,7 +15,7 @@ pub fn NavDrawer( mount_style("nav-drawer", include_str!("./nav-drawer.css")); view! { - +
{(header.children)()}
@@ -43,8 +44,13 @@ pub struct NavDrawerFooter { } #[derive(Clone)] -pub(crate) struct NavDrawerInjection(pub Model); - -pub(crate) fn use_nav_drawer() -> NavDrawerInjection { - expect_context() +pub(crate) struct NavDrawerInjection { + pub selected_value: OptionModel, + pub selected_category_value: OptionModel, +} + +impl NavDrawerInjection { + pub fn expect_context() -> Self { + expect_context() + } } diff --git a/thaw/src/nav/nav_item.rs b/thaw/src/nav/nav_item.rs index 9319afc..f6de0da 100644 --- a/thaw/src/nav/nav_item.rs +++ b/thaw/src/nav/nav_item.rs @@ -1,4 +1,5 @@ -use crate::{use_nav_drawer, Icon}; +use super::NavDrawerInjection; +use crate::Icon; use leptos::{either::Either, prelude::*}; use thaw_utils::{class_list, StoredMaybeSignal}; @@ -10,12 +11,15 @@ pub fn NavItem( #[prop(optional, into)] href: Option>, children: Children, ) -> impl IntoView { - let nav_drawer = use_nav_drawer(); + let nav_drawer = NavDrawerInjection::expect_context(); let value: StoredMaybeSignal<_> = value.into(); let on_click = move |_| { - let value = value.get(); - if nav_drawer.0.with(|key| key != &value) { - nav_drawer.0.set(value); + let value = value.get_untracked(); + if nav_drawer + .selected_value + .with_untracked(|selected_value| selected_value != Some(&value)) + { + nav_drawer.selected_value.set(Some(value)); } }; @@ -36,10 +40,16 @@ pub fn NavItem( } }; + let selected = Memo::new(move |_| { + nav_drawer.selected_value.with_untracked(|selected_value| { + value.with_untracked(|value| selected_value == Some(value)) + }) + }); + if let Some(href) = href { Either::Left(view! { @@ -49,7 +59,7 @@ pub fn NavItem( } else { Either::Right(view! {