mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34: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 tabs::*;
|
||||
pub use theme::Theme;
|
||||
pub use utils::mount_style::mount_style;
|
||||
pub use utils::{mount_style::mount_style, signal::SignalWatch};
|
||||
pub use wave::*;
|
||||
|
|
|
@ -2,13 +2,17 @@ mod menu_group;
|
|||
mod menu_item;
|
||||
mod theme;
|
||||
|
||||
use crate::utils::maybe_rw_signal::MaybeRwSignal;
|
||||
use leptos::*;
|
||||
pub use menu_group::MenuGroup;
|
||||
pub use menu_item::*;
|
||||
pub use theme::MenuTheme;
|
||||
|
||||
#[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()));
|
||||
create_effect(move |_| {
|
||||
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 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