melt_ui/utils/signal.rs
1use leptos::{create_effect, untrack, RwSignal, SignalDispose, SignalWith};
2
3pub trait SignalWatch {
4 type Value;
5
6 fn watch(&self, f: impl Fn(&Self::Value) + 'static) -> Box<dyn FnOnce()>;
7}
8
9impl<T> SignalWatch for RwSignal<T> {
10 type Value = T;
11
12 /// Listens for RwSignal changes and is not executed immediately
13 ///
14 /// ## Usage
15 ///
16 /// ```rust
17 /// use leptos::*;
18 /// use melt_ui::*;
19 ///
20 /// let count = create_rw_signal(0);
21 /// let stop = count.watch(|count| {
22 /// assert_eq!(count, &1);
23 /// });
24 ///
25 /// count.set(1); // assert_eq!(count, &1);
26 ///
27 /// stop(); // stop watching
28 ///
29 /// count.set(2); // nothing happens
30 /// ```
31 fn watch(&self, f: impl Fn(&Self::Value) + 'static) -> Box<dyn FnOnce()> {
32 let signal = *self;
33
34 let effect = create_effect(move |prev| {
35 signal.with(|value| {
36 if prev.is_some() {
37 untrack(|| f(value));
38 }
39 });
40 });
41
42 Box::new(move || {
43 effect.dispose();
44 })
45 }
46}