mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 16:44:15 -05:00
feat: add MaybeRwSignal and watch
This commit is contained in:
parent
967d09deaa
commit
ecffde423f
5 changed files with 86 additions and 2 deletions
|
@ -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::*;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
32
src/utils/maybe_rw_signal.rs
Normal file
32
src/utils/maybe_rw_signal.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
46
src/utils/signal.rs
Normal 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();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue