added whenever

This commit is contained in:
Maccesch 2023-06-11 17:11:16 +01:00
parent c8003f7eb9
commit cea87c858e
7 changed files with 139 additions and 0 deletions

10
.fleet/run.json Normal file
View file

@ -0,0 +1,10 @@
{
"configurations": [
{
"type": "cargo",
"name": "Tests",
"cargoArgs": ["test", "--all-features"],
},
]
}

View file

@ -1,5 +1,11 @@
# Changelog
## v0.2.2
### New Functions
- `whenever`
## 0.2.1
### New Functions

View file

@ -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

View file

@ -0,0 +1,3 @@
# whenever
<!-- cmdrun python3 ../extract_doc_comment.py whenever -->

View file

@ -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::*;

View file

@ -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,
}

116
src/whenever.rs Normal file
View file

@ -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<T, DFn, CFn>(cx: Scope, source: DFn, callback: CFn) -> impl Fn() + Clone
where
DFn: Fn() -> bool + 'static,
CFn: Fn(bool, Option<bool>, Option<T>) -> 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<T, DFn, CFn>(
cx: Scope,
source: DFn,
callback: CFn,
options: WatchOptions,
) -> impl Fn() + Clone
where
DFn: Fn() -> bool + 'static,
CFn: Fn(bool, Option<bool>, Option<T>) -> 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,
)
}