diff --git a/.fleet/run.json b/.fleet/run.json new file mode 100644 index 0000000..c6a052e --- /dev/null +++ b/.fleet/run.json @@ -0,0 +1,10 @@ +{ + "configurations": [ + { + "type": "cargo", + "name": "Tests", + "cargoArgs": ["test", "--all-features"], + }, + + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9454d6e..3a3d0fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v0.2.2 + +### New Functions + +- `whenever` + ## 0.2.1 ### New Functions diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 9814fee..4eac86d 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -38,6 +38,7 @@ - [watch_debounced](watch/watch_debounced.md) - [watch_pausable](watch/watch_pausable.md) - [watch_throttled](watch/watch_throttled.md) +- [whenever](watch/whenever.md) # Utilities diff --git a/docs/book/src/watch/whenever.md b/docs/book/src/watch/whenever.md new file mode 100644 index 0000000..af39dd3 --- /dev/null +++ b/docs/book/src/watch/whenever.md @@ -0,0 +1,3 @@ +# whenever + + diff --git a/src/lib.rs b/src/lib.rs index ebfaa3d..519b83a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,6 +37,7 @@ mod watch; mod watch_debounced; mod watch_pausable; mod watch_throttled; +mod whenever; pub use use_breakpoints::*; pub use use_debounce_fn::*; @@ -55,3 +56,4 @@ pub use watch::*; pub use watch_debounced::*; pub use watch_pausable::*; pub use watch_throttled::*; +pub use whenever::*; diff --git a/src/watch.rs b/src/watch.rs index a16bc5e..75ae84f 100644 --- a/src/watch.rs +++ b/src/watch.rs @@ -196,6 +196,7 @@ pub struct WatchOptions { /// the first change is detected of any signal that is accessed in `deps`. immediate: bool, + /// Allows to debounce or throttle the callback filter: FilterOptions, } diff --git a/src/whenever.rs b/src/whenever.rs new file mode 100644 index 0000000..670d8a0 --- /dev/null +++ b/src/whenever.rs @@ -0,0 +1,116 @@ +use crate::{watch_with_options, WatchOptions}; +use leptos::*; + +/// Shorthand for watching a signal to be `true`. +/// +/// ## Usage +/// +/// ``` +/// # use leptos::*; +/// # use leptos_use::whenever; +/// # +/// # pub fn Demo(cx: Scope) -> impl IntoView { +/// let (is_ready, set_ready) = create_signal(cx, false); +/// +/// whenever(cx, is_ready, |v, _, _| log!("{}", v)); +/// # +/// # view! { cx, } +/// # } +/// ``` +/// +/// ### Callback Function +/// +/// Same as [`watch`], the callback will be called with `callback(input, prev_input, prev_return)`. +/// +/// ``` +/// # use leptos::*; +/// # use leptos_use::whenever; +/// # +/// # pub fn Demo(cx: Scope) -> impl IntoView { +/// # let (is_ready, set_ready) = create_signal(cx, false); +/// whenever(cx, is_ready, |value, prev_value, _| { +/// log!("before: {prev_value:?}; now: {value}"); +/// }); +/// # +/// # view! { cx, } +/// # } +/// ``` +/// +/// ### Computed +/// +/// Same as [`watch`], you can pass a getter function to calculate on each change. +/// +/// ``` +/// # use leptos::*; +/// # use leptos_use::whenever; +/// # +/// # pub fn Demo(cx: Scope) -> impl IntoView { +/// # let (counter, set_counter) = create_signal(cx, 0); +/// whenever( +/// cx, +/// move || counter() == 7, +/// |_, _, _| log!("counter is 7 now!"), +/// ); +/// # +/// # view! { cx, } +/// # } +/// ``` +/// +/// ### Options +/// +/// Options and defaults are same as [`watch_with_options`]. +/// +/// ``` +/// # use leptos::*; +/// # use leptos_use::{WatchOptions, whenever_with_options}; +/// # +/// # pub fn Demo(cx: Scope) -> impl IntoView { +/// # let (counter, set_counter) = create_signal(cx, 0); +/// whenever_with_options( +/// cx, +/// move || counter() == 7, +/// |_, _, _| log!("counter is 7 now!"), +/// WatchOptions::default().immediate(true), +/// ); +/// # +/// # view! { cx, } +/// # } +/// ``` +pub fn whenever(cx: Scope, source: DFn, callback: CFn) -> impl Fn() + Clone +where + DFn: Fn() -> bool + 'static, + CFn: Fn(bool, Option, Option) -> T + Clone + 'static, + T: Clone + 'static, +{ + whenever_with_options(cx, source, callback, WatchOptions::default()) +} + +/// Version of `whenever` that accepts `WatchOptions`. See [`whenever`] for how to use. +pub fn whenever_with_options( + cx: Scope, + source: DFn, + callback: CFn, + options: WatchOptions, +) -> impl Fn() + Clone +where + DFn: Fn() -> bool + 'static, + CFn: Fn(bool, Option, Option) -> T + Clone + 'static, + T: Clone + 'static, +{ + watch_with_options( + cx, + source, + move |value, prev_value, prev_return| { + if *value { + Some(callback( + *value, + prev_value.copied(), + prev_return.unwrap_or_default(), + )) + } else { + None + } + }, + options, + ) +}