mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
fix: NavDrawer selected category value error (#252)
This commit is contained in:
parent
583b03100e
commit
f9d39f740c
5 changed files with 46 additions and 63 deletions
|
@ -53,7 +53,7 @@ view! {
|
|||
| --- | --- | --- | --- |
|
||||
| class | `MaybeProp<String>,` | `Default::default()` | |
|
||||
| selected_value | `OptionModel<String>` | `Default::default()` | The value of the currently selected navItem. |
|
||||
| selected_category_value | `VecModel<String>` | `vec![]` | Indicates a category that has a selected child Will show the category as selected if it is closed. |
|
||||
| selected_category_value | `OptionModel<String>` | `None` | Indicates a category that has a selected child Will show the category as selected if it is closed. |
|
||||
| nav_drawer_header | slot `Option<NavDrawerHeader>` | `None` | |
|
||||
| nav_drawer_footer | slot `Option<NavDrawerFooter>` | `None` | |
|
||||
| children | `Children` | | |
|
||||
|
|
|
@ -69,7 +69,8 @@
|
|||
background-color: var(--colorNeutralBackground4Pressed);
|
||||
}
|
||||
|
||||
.thaw-nav-item--selected::after {
|
||||
.thaw-nav-item--selected::after,
|
||||
.thaw-nav-category-item--selected[aria-expanded="false"]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use super::NavDrawerInjection;
|
||||
use crate::Icon;
|
||||
use leptos::{either::Either, html, prelude::*};
|
||||
use leptos::{context::Provider, either::Either, html, prelude::*};
|
||||
use thaw_components::CSSTransition;
|
||||
use thaw_utils::{class_list, StoredMaybeSignal, VecModelWithValue};
|
||||
use thaw_utils::{class_list, StoredMaybeSignal};
|
||||
|
||||
#[component]
|
||||
pub fn NavCategory(
|
||||
|
@ -13,56 +13,9 @@ pub fn NavCategory(
|
|||
let nav_drawer = NavDrawerInjection::expect_context();
|
||||
let value: StoredMaybeSignal<_> = value.into();
|
||||
let group_ref = NodeRef::<html::Div>::new();
|
||||
let is_show_group = Memo::new(move |_| {
|
||||
nav_drawer
|
||||
.selected_category_value
|
||||
.with(|selected_category_value| {
|
||||
value.with(|value| match selected_category_value {
|
||||
VecModelWithValue::T(v) => v == value,
|
||||
VecModelWithValue::Option(v) => v.as_ref() == Some(value),
|
||||
VecModelWithValue::Vec(v) => v.contains(value),
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
let on_click = move |_| {
|
||||
let value = value.get_untracked();
|
||||
let is_show_group = is_show_group.get_untracked();
|
||||
nav_drawer
|
||||
.selected_category_value
|
||||
.update(|selected_category_value| {
|
||||
match selected_category_value {
|
||||
(None, None, Some(v)) => {
|
||||
if is_show_group {
|
||||
if let Some(index) = v.iter().position(|item| item == &value) {
|
||||
v.remove(index);
|
||||
}
|
||||
} else {
|
||||
v.push(value);
|
||||
}
|
||||
}
|
||||
(None, Some(v), None) => {
|
||||
if is_show_group {
|
||||
*v = None;
|
||||
} else {
|
||||
*v = Some(value);
|
||||
}
|
||||
}
|
||||
(Some(v), None, None) => {
|
||||
if is_show_group {
|
||||
v.clear();
|
||||
} else {
|
||||
*v = value;
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
if is_show_group {
|
||||
} else {
|
||||
}
|
||||
});
|
||||
};
|
||||
let is_show_group = RwSignal::new(false);
|
||||
let is_selected_category =
|
||||
Memo::new(move |_| value.with(|value| nav_drawer.is_selected_category(value)));
|
||||
|
||||
let NavCategoryItem {
|
||||
class: item_class,
|
||||
|
@ -72,9 +25,13 @@ pub fn NavCategory(
|
|||
|
||||
view! {
|
||||
<button
|
||||
class=class_list!["thaw-nav-category-item", item_class]
|
||||
on:click=on_click
|
||||
aria-expanded=move || is_show_group.get()
|
||||
class=class_list![
|
||||
"thaw-nav-category-item",
|
||||
("thaw-nav-category-item--selected", move || is_selected_category.get()),
|
||||
item_class
|
||||
]
|
||||
on:click=move |_| { is_show_group.update(|show| *show = !*show); }
|
||||
aria-expanded=move || if is_show_group.get() { "true" } else { "false" }
|
||||
>
|
||||
{move || {
|
||||
if let Some(icon) = item_icon.get() {
|
||||
|
@ -117,7 +74,9 @@ pub fn NavCategory(
|
|||
node_ref=group_ref
|
||||
style=move || display.get().unwrap_or_default()
|
||||
>
|
||||
{children()}
|
||||
<Provider value=NavCategoryInjection { value }>
|
||||
{children()}
|
||||
</Provider>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
}
|
||||
|
@ -131,3 +90,14 @@ pub struct NavCategoryItem {
|
|||
icon: MaybeProp<icondata_core::Icon>,
|
||||
children: Children,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) struct NavCategoryInjection {
|
||||
pub value: StoredMaybeSignal<String>,
|
||||
}
|
||||
|
||||
impl NavCategoryInjection {
|
||||
pub fn use_context() -> Option<Self> {
|
||||
use_context()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::Scrollbar;
|
||||
use leptos::{context::Provider, prelude::*};
|
||||
use thaw_components::OptionComp;
|
||||
use thaw_utils::{class_list, mount_style, OptionModel, VecModel};
|
||||
use thaw_utils::{class_list, mount_style, OptionModel, OptionModelWithValue};
|
||||
|
||||
#[component]
|
||||
pub fn NavDrawer(
|
||||
|
@ -10,8 +10,8 @@ pub fn NavDrawer(
|
|||
#[prop(optional, into)]
|
||||
selected_value: OptionModel<String>,
|
||||
/// Indicates a category that has a selected child Will show the category as selected if it is closed.
|
||||
#[prop(default = vec![].into(), into)]
|
||||
selected_category_value: VecModel<String>,
|
||||
#[prop(optional, into)]
|
||||
selected_category_value: OptionModel<String>,
|
||||
children: Children,
|
||||
#[prop(optional)] nav_drawer_header: Option<NavDrawerHeader>,
|
||||
#[prop(optional)] nav_drawer_footer: Option<NavDrawerFooter>,
|
||||
|
@ -51,11 +51,19 @@ pub struct NavDrawerFooter {
|
|||
#[derive(Clone)]
|
||||
pub(crate) struct NavDrawerInjection {
|
||||
pub selected_value: OptionModel<String>,
|
||||
pub selected_category_value: VecModel<String>,
|
||||
pub selected_category_value: OptionModel<String>,
|
||||
}
|
||||
|
||||
impl NavDrawerInjection {
|
||||
pub fn expect_context() -> Self {
|
||||
expect_context()
|
||||
}
|
||||
|
||||
pub fn is_selected_category(&self, value: &String) -> bool {
|
||||
self.selected_category_value
|
||||
.with(|selected_category_value| match selected_category_value {
|
||||
OptionModelWithValue::T(v) => v == value,
|
||||
OptionModelWithValue::Option(v) => v.as_ref() == Some(value),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::NavDrawerInjection;
|
||||
use super::{NavCategoryInjection, NavDrawerInjection};
|
||||
use crate::Icon;
|
||||
use leptos::{either::Either, prelude::*};
|
||||
use thaw_utils::{class_list, OptionModelWithValue, StoredMaybeSignal};
|
||||
|
@ -12,6 +12,7 @@ pub fn NavItem(
|
|||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let nav_drawer = NavDrawerInjection::expect_context();
|
||||
let nav_category = NavCategoryInjection::use_context();
|
||||
let value: StoredMaybeSignal<_> = value.into();
|
||||
let on_click = move |_| {
|
||||
let value = value.get_untracked();
|
||||
|
@ -23,6 +24,9 @@ pub fn NavItem(
|
|||
})
|
||||
{
|
||||
nav_drawer.selected_value.set(Some(value));
|
||||
nav_drawer
|
||||
.selected_category_value
|
||||
.set(nav_category.map(|c| c.value.get_untracked()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue