From 7da18dc9e596c2467731f935f12986764894733d Mon Sep 17 00:00:00 2001 From: luoxiao Date: Tue, 23 Jul 2024 18:00:55 +0800 Subject: [PATCH] feat: adds ListboxInjection --- .../src/auto_complete/auto_complete_option.rs | 6 +- thaw/src/combobox/combobox_option.rs | 4 ++ thaw/src/combobox/listbox.rs | 63 ++++++++++++------- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/thaw/src/auto_complete/auto_complete_option.rs b/thaw/src/auto_complete/auto_complete_option.rs index 0d400a7..10bf4c3 100644 --- a/thaw/src/auto_complete/auto_complete_option.rs +++ b/thaw/src/auto_complete/auto_complete_option.rs @@ -1,19 +1,23 @@ use super::AutoCompleteInjection; +use crate::combobox::listbox::ListboxInjection; use leptos::prelude::*; #[component] pub fn AutoCompleteOption(value: String, children: Children) -> impl IntoView { let auto_complete = AutoCompleteInjection::expect_context(); + let listbox = ListboxInjection::expect_context(); let is_selected = Memo::new({ let value = value.clone(); move |_| auto_complete.is_selected(&value) }); let id = uuid::Uuid::new_v4().to_string(); - auto_complete.insert_option(id.clone(), value.clone()); { + auto_complete.insert_option(id.clone(), value.clone()); let id = id.clone(); + listbox.trigger(); on_cleanup(move || { auto_complete.remove_option(&id); + listbox.trigger(); }); } diff --git a/thaw/src/combobox/combobox_option.rs b/thaw/src/combobox/combobox_option.rs index 5b4a518..9c48905 100644 --- a/thaw/src/combobox/combobox_option.rs +++ b/thaw/src/combobox/combobox_option.rs @@ -1,3 +1,4 @@ +use super::listbox::ListboxInjection; use crate::ComboboxInjection; use leptos::prelude::*; use thaw_components::{Fallback, If, OptionComp, Then}; @@ -10,6 +11,7 @@ pub fn ComboboxOption( #[prop(optional)] children: Option, ) -> impl IntoView { let combobox = ComboboxInjection::expect_context(); + let listbox = ListboxInjection::expect_context(); let value = StoredValue::new(value.unwrap_or_else(|| text.clone())); let text = StoredValue::new(text); let is_selected = Memo::new(move |_| value.with_value(|value| combobox.is_selected(&value))); @@ -26,8 +28,10 @@ pub fn ComboboxOption( { combobox.insert_option(id.clone(), (value.get_value(), text.get_value())); let id = id.clone(); + listbox.trigger(); on_cleanup(move || { combobox.remove_option(&id); + listbox.trigger(); }); } diff --git a/thaw/src/combobox/listbox.rs b/thaw/src/combobox/listbox.rs index 6ad98f7..7efa96f 100644 --- a/thaw/src/combobox/listbox.rs +++ b/thaw/src/combobox/listbox.rs @@ -1,8 +1,7 @@ -use std::sync::Arc; - use super::utils::{get_dropdown_action_from_key, DropdownAction}; use crate::{ConfigInjection, _aria::ActiveDescendantController}; -use leptos::{ev, html, prelude::*}; +use leptos::{context::Provider, ev, html, prelude::*}; +use std::sync::Arc; use thaw_components::CSSTransition; use thaw_utils::mount_style; use web_sys::{HtmlElement, Node}; @@ -18,9 +17,14 @@ pub fn Listbox( mount_style("listbox", include_str!("./listbox.css")); let config_provider = ConfigInjection::expect_context(); - let effect = RenderEffect::new(move |_| { - if let Some(listbox_el) = listbox_ref.get() { - set_listbox(listbox_el.into()); + let trigger = ArcTrigger::new(); + let effect = RenderEffect::new({ + let trigger = trigger.clone(); + move |_| { + trigger.track(); + if let Some(listbox_el) = listbox_ref.get() { + set_listbox(listbox_el.into()); + } } }); on_cleanup(move || { @@ -28,23 +32,40 @@ pub fn Listbox( }); view! { - -
+ - {children()} -
-
+
+ {children()} +
+ + + } +} + +#[derive(Clone)] +pub(crate) struct ListboxInjection(ArcTrigger); + +impl ListboxInjection { + #[inline] + pub fn expect_context() -> Self { + expect_context() + } + + #[inline] + pub fn trigger(&self) { + self.0.trigger(); } }