feat: add MaybeRwSignal and watch

This commit is contained in:
luoxiao 2023-10-06 16:53:57 +08:00
parent 967d09deaa
commit ecffde423f
5 changed files with 86 additions and 2 deletions

View file

@ -38,5 +38,5 @@ pub use space::*;
pub use table::*; pub use table::*;
pub use tabs::*; pub use tabs::*;
pub use theme::Theme; pub use theme::Theme;
pub use utils::mount_style::mount_style; pub use utils::{mount_style::mount_style, signal::SignalWatch};
pub use wave::*; pub use wave::*;

View file

@ -2,13 +2,17 @@ mod menu_group;
mod menu_item; mod menu_item;
mod theme; mod theme;
use crate::utils::maybe_rw_signal::MaybeRwSignal;
use leptos::*; use leptos::*;
pub use menu_group::MenuGroup; pub use menu_group::MenuGroup;
pub use menu_item::*; pub use menu_item::*;
pub use theme::MenuTheme; pub use theme::MenuTheme;
#[component] #[component]
pub fn Menu(#[prop(into)] selected: RwSignal<String>, children: Children) -> impl IntoView { pub fn Menu(
#[prop(optional, into)] selected: MaybeRwSignal<String>,
children: Children,
) -> impl IntoView {
let menu_injection_key = create_rw_signal(MenuInjectionKey::new(selected.get_untracked())); let menu_injection_key = create_rw_signal(MenuInjectionKey::new(selected.get_untracked()));
create_effect(move |_| { create_effect(move |_| {
let selected_key = selected.get(); let selected_key = selected.get();

View file

@ -0,0 +1,32 @@
use leptos::RwSignal;
use std::ops::Deref;
pub struct MaybeRwSignal<T: Default + 'static>(RwSignal<T>);
impl<T: Default> Default for MaybeRwSignal<T> {
fn default() -> Self {
Self(RwSignal::new(Default::default()))
}
}
impl<T: Default> Clone for MaybeRwSignal<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T: Default> Copy for MaybeRwSignal<T> {}
impl<T: Default> Deref for MaybeRwSignal<T> {
type Target = RwSignal<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: Default> From<RwSignal<T>> for MaybeRwSignal<T> {
fn from(value: RwSignal<T>) -> Self {
Self(value)
}
}

View file

@ -1 +1,3 @@
pub mod maybe_rw_signal;
pub mod mount_style; pub mod mount_style;
pub mod signal;

46
src/utils/signal.rs Normal file
View file

@ -0,0 +1,46 @@
use leptos::{create_effect, untrack, RwSignal, SignalDispose, SignalWith};
pub trait SignalWatch {
type Value;
fn watch(&self, f: impl Fn(&Self::Value) + 'static) -> Box<dyn FnOnce()>;
}
impl<T> SignalWatch for RwSignal<T> {
type Value = T;
/// Listens for RwSignal changes and is not executed immediately
///
/// ## Usage
///
/// ```rust
/// use leptos::*;
/// use melt_ui::*;
///
/// let count = create_rw_signal(0);
/// let stop = count.watch(|count| {
/// assert_eq!(count, &1);
/// });
///
/// count.set(1); // assert_eq!(count, &1);
///
/// stop(); // stop watching
///
/// count.set(2); // nothing happens
/// ```
fn watch(&self, f: impl Fn(&Self::Value) + 'static) -> Box<dyn FnOnce()> {
let signal = self.clone();
let effect = create_effect(move |prev| {
signal.with(|value| {
if prev.is_some() {
untrack(|| f(value));
}
});
});
Box::new(move || {
effect.dispose();
})
}
}