From bbe145a42b874866b523ec2ee602a8a78eb2c50a Mon Sep 17 00:00:00 2001 From: Maccesch Date: Fri, 26 May 2023 19:27:42 +0100 Subject: [PATCH] added use_debounce_fn --- .idea/leptos-use.iml | 2 + CHANGELOG.md | 7 +- docs/book/src/SUMMARY.md | 2 + docs/book/src/changelog.md | 1 + docs/book/src/utilities/use_debounce_fn.md | 3 + examples/use_debounce_fn/Cargo.toml | 16 ++++ examples/use_debounce_fn/README.md | 16 ++++ examples/use_debounce_fn/Trunk.toml | 2 + examples/use_debounce_fn/index.html | 5 ++ examples/use_debounce_fn/rust-toolchain.toml | 2 + examples/use_debounce_fn/src/main.rs | 40 +++++++++ examples/use_throttle_fn/src/main.rs | 3 +- src/use_debounce_fn.rs | 88 +++++++++++++++++--- src/use_event_listener.rs | 61 +++++++------- src/use_throttle_fn.rs | 40 ++++----- src/utils/filters/debounce.rs | 26 ++++-- src/utils/filters/mod.rs | 27 +++--- src/utils/filters/throttle.rs | 2 +- 18 files changed, 256 insertions(+), 87 deletions(-) create mode 100644 docs/book/src/changelog.md create mode 100644 docs/book/src/utilities/use_debounce_fn.md create mode 100644 examples/use_debounce_fn/Cargo.toml create mode 100644 examples/use_debounce_fn/README.md create mode 100644 examples/use_debounce_fn/Trunk.toml create mode 100644 examples/use_debounce_fn/index.html create mode 100644 examples/use_debounce_fn/rust-toolchain.toml create mode 100644 examples/use_debounce_fn/src/main.rs diff --git a/.idea/leptos-use.iml b/.idea/leptos-use.iml index 201a77c..a753bb6 100644 --- a/.idea/leptos-use.iml +++ b/.idea/leptos-use.iml @@ -11,12 +11,14 @@ + + diff --git a/CHANGELOG.md b/CHANGELOG.md index 295292c..047d98b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,4 +2,9 @@ ## 0.1.3 -- Added `use_scroll`. \ No newline at end of file +#### New Functions +- `use_scroll` +- `use_debounce_fn` + +#### Other Changes +- Better and more beautiful demo integration into the guide. \ No newline at end of file diff --git a/docs/book/src/SUMMARY.md b/docs/book/src/SUMMARY.md index 6afe548..57c0c9b 100644 --- a/docs/book/src/SUMMARY.md +++ b/docs/book/src/SUMMARY.md @@ -1,6 +1,7 @@ # Summary [Introduction]() +[Changelog](changelog.md) # Getting Started @@ -13,4 +14,5 @@ # Utilities +- [use_debounce_fn](utilities/use_debounce_fn.md) - [use_throttle_fn](utilities/use_throttle_fn.md) \ No newline at end of file diff --git a/docs/book/src/changelog.md b/docs/book/src/changelog.md new file mode 100644 index 0000000..29f8b6a --- /dev/null +++ b/docs/book/src/changelog.md @@ -0,0 +1 @@ +{{#include ../../../CHANGELOG.md}} \ No newline at end of file diff --git a/docs/book/src/utilities/use_debounce_fn.md b/docs/book/src/utilities/use_debounce_fn.md new file mode 100644 index 0000000..bcd5ec8 --- /dev/null +++ b/docs/book/src/utilities/use_debounce_fn.md @@ -0,0 +1,3 @@ +# use_debounce_fn + + diff --git a/examples/use_debounce_fn/Cargo.toml b/examples/use_debounce_fn/Cargo.toml new file mode 100644 index 0000000..df49a7a --- /dev/null +++ b/examples/use_debounce_fn/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "use_debounce_fn" +version = "0.1.0" +edition = "2021" + +[dependencies] +leptos = "0.3" +console_error_panic_hook = "0.1" +console_log = "1" +log = "0.4" +leptos-use = { path = "../.." } +web-sys = "0.3" + +[dev-dependencies] +wasm-bindgen = "0.2" +wasm-bindgen-test = "0.3.0" diff --git a/examples/use_debounce_fn/README.md b/examples/use_debounce_fn/README.md new file mode 100644 index 0000000..6d5ce15 --- /dev/null +++ b/examples/use_debounce_fn/README.md @@ -0,0 +1,16 @@ +A simple example for `use_debounce_fn`. + +If you don't have it installed already, install [Trunk](https://trunkrs.dev/) +as well as the nightly toolchain for Rust and the wasm32-unknown-unknown target: + +```bash +cargo install trunk +rustup toolchain install nightly +rustup target add wasm32-unknown-unknown +``` + +To run the demo: + +```bash +trunk serve --open +``` diff --git a/examples/use_debounce_fn/Trunk.toml b/examples/use_debounce_fn/Trunk.toml new file mode 100644 index 0000000..f521021 --- /dev/null +++ b/examples/use_debounce_fn/Trunk.toml @@ -0,0 +1,2 @@ +[build] +public_url = "./demo/" \ No newline at end of file diff --git a/examples/use_debounce_fn/index.html b/examples/use_debounce_fn/index.html new file mode 100644 index 0000000..25f83eb --- /dev/null +++ b/examples/use_debounce_fn/index.html @@ -0,0 +1,5 @@ + + + + + diff --git a/examples/use_debounce_fn/rust-toolchain.toml b/examples/use_debounce_fn/rust-toolchain.toml new file mode 100644 index 0000000..271800c --- /dev/null +++ b/examples/use_debounce_fn/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" \ No newline at end of file diff --git a/examples/use_debounce_fn/src/main.rs b/examples/use_debounce_fn/src/main.rs new file mode 100644 index 0000000..6801092 --- /dev/null +++ b/examples/use_debounce_fn/src/main.rs @@ -0,0 +1,40 @@ +use leptos::*; +use leptos_use::use_debounce_fn_with_options; +use leptos_use::utils::{demo_or_body, DebounceOptions}; + +#[component] +fn Demo(cx: Scope) -> impl IntoView { + let (click_count, set_click_count) = create_signal(cx, 0); + let (debounced_count, set_debounced_count) = create_signal(cx, 0); + + let debounced_fn = use_debounce_fn_with_options( + move || set_debounced_count(debounced_count() + 1), + 1000.0, + DebounceOptions { + max_wait: Some(5000.0), + }, + ); + + view! { cx, + +
"Delay is set to 1000ms and max_wait is set to 5000ms for this demo."
+

"Button clicked: " { click_count }

+

"Event handler called: " { debounced_count }

+ } +} + +fn main() { + _ = console_log::init_with_level(log::Level::Debug); + console_error_panic_hook::set_once(); + + mount_to(demo_or_body(), |cx| { + view! { cx, } + }) +} diff --git a/examples/use_throttle_fn/src/main.rs b/examples/use_throttle_fn/src/main.rs index 6aeab76..1db6efc 100644 --- a/examples/use_throttle_fn/src/main.rs +++ b/examples/use_throttle_fn/src/main.rs @@ -7,8 +7,7 @@ fn Demo(cx: Scope) -> impl IntoView { let (click_count, set_click_count) = create_signal(cx, 0); let (throttled_count, set_throttled_count) = create_signal(cx, 0); - let mut throttled_fn = - use_throttle_fn(move || set_throttled_count(throttled_count() + 1), 1000.0); + let throttled_fn = use_throttle_fn(move || set_throttled_count(throttled_count() + 1), 1000.0); view! { cx, -/// } +/// # use leptos::*; +/// # use leptos_use::use_throttle_fn; +/// # +/// # #[component] +/// # fn Demo(cx: Scope) -> impl IntoView { +/// let mut throttled_fn = use_throttle_fn( +/// || { +/// // do something, it will be called at most 1 time per second +/// }, +/// 1000.0, +/// ); +/// view! { cx, +/// /// } +/// # } /// ``` /// /// You can provide options when you use [`use_throttle_fn_with_options`]. @@ -68,7 +68,7 @@ pub use crate::utils::ThrottleOptions; pub fn use_throttle_fn( func: F, ms: impl Into>, -) -> impl FnMut() -> Rc>> +) -> impl Fn() -> Rc>> where F: FnOnce() -> R + Clone + 'static, R: 'static, @@ -81,7 +81,7 @@ pub fn use_throttle_fn_with_options( func: F, ms: impl Into>, options: ThrottleOptions, -) -> impl FnMut() -> Rc>> +) -> impl Fn() -> Rc>> where F: FnOnce() -> R + Clone + 'static, R: 'static, @@ -93,7 +93,7 @@ where pub fn use_throttle_fn_with_arg( func: F, ms: impl Into>, -) -> impl FnMut(Arg) -> Rc>> +) -> impl Fn(Arg) -> Rc>> where F: FnOnce(Arg) -> R + Clone + 'static, Arg: Clone + 'static, @@ -107,7 +107,7 @@ pub fn use_throttle_fn_with_arg_and_options( func: F, ms: impl Into>, options: ThrottleOptions, -) -> impl FnMut(Arg) -> Rc>> +) -> impl Fn(Arg) -> Rc>> where F: FnOnce(Arg) -> R + Clone + 'static, Arg: Clone + 'static, diff --git a/src/utils/filters/debounce.rs b/src/utils/filters/debounce.rs index e25d4de..576ff32 100644 --- a/src/utils/filters/debounce.rs +++ b/src/utils/filters/debounce.rs @@ -5,17 +5,28 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; use std::time::Duration; -#[derive(Default)] -pub struct DebounceOptions { +pub struct DebounceOptions +where + W: Into>>, +{ /// The maximum time allowed to be delayed before it's invoked. /// In milliseconds. - max_wait: MaybeSignal>, + pub max_wait: W, } -pub fn debounce_filter( +impl Default for DebounceOptions> { + fn default() -> Self { + Self { max_wait: None } + } +} + +pub fn debounce_filter( ms: impl Into>, - options: DebounceOptions, -) -> impl FnMut(Box>) -> Rc>> { + options: DebounceOptions, +) -> impl Fn(Box>) -> Rc>> +where + W: Into>>, +{ let timer = Rc::new(Cell::new(None::)); let max_timer = Rc::new(Cell::new(None::)); @@ -27,10 +38,11 @@ pub fn debounce_filter( }; let ms = ms.into(); + let max_wait_signal = options.max_wait.into(); move |invoke: Box>| { let duration = ms.get_untracked(); - let max_duration = options.max_wait.get_untracked(); + let max_duration = max_wait_signal.get_untracked(); // TODO : return value like throttle_filter? diff --git a/src/utils/filters/mod.rs b/src/utils/filters/mod.rs index 03cfc03..c30b1d9 100644 --- a/src/utils/filters/mod.rs +++ b/src/utils/filters/mod.rs @@ -8,55 +8,52 @@ use crate::utils::CloneableFnWithReturn; use std::cell::RefCell; use std::rc::Rc; -pub fn create_filter_wrapper(mut filter: Filter, func: F) -> impl FnMut() +pub fn create_filter_wrapper(filter: Filter, func: F) -> impl Fn() where F: FnOnce() + Clone + 'static, - Filter: FnMut(Box>) -> Rc>>, + Filter: Fn(Box>) -> Rc>>, { move || { filter(Box::new(func.clone())); } } -pub fn create_filter_wrapper_with_arg( - mut filter: Filter, - func: F, -) -> impl FnMut(Arg) +pub fn create_filter_wrapper_with_arg(filter: Filter, func: F) -> impl Fn(Arg) where F: FnOnce(Arg) + Clone + 'static, Arg: Clone + 'static, - Filter: FnMut(Box>) -> Rc>>, + Filter: Fn(Box>) -> Rc>>, { move |arg: Arg| { - let mut func = func.clone(); + let func = func.clone(); filter(Box::new(move || func(arg))); } } pub fn create_filter_wrapper_with_return( - mut filter: Filter, + filter: Filter, func: F, -) -> impl FnMut() -> Rc>> +) -> impl Fn() -> Rc>> where F: FnOnce() -> R + Clone + 'static, R: 'static, - Filter: FnMut(Box>) -> Rc>>, + Filter: Fn(Box>) -> Rc>>, { move || filter(Box::new(func.clone())) } pub fn create_filter_wrapper_with_return_and_arg( - mut filter: Filter, + filter: Filter, func: F, -) -> impl FnMut(Arg) -> Rc>> +) -> impl Fn(Arg) -> Rc>> where F: FnOnce(Arg) -> R + Clone + 'static, R: 'static, Arg: Clone + 'static, - Filter: FnMut(Box>) -> Rc>>, + Filter: Fn(Box>) -> Rc>>, { move |arg: Arg| { - let mut func = func.clone(); + let func = func.clone(); filter(Box::new(move || func(arg))) } } diff --git a/src/utils/filters/throttle.rs b/src/utils/filters/throttle.rs index c011923..a03b8e5 100644 --- a/src/utils/filters/throttle.rs +++ b/src/utils/filters/throttle.rs @@ -25,7 +25,7 @@ impl Default for ThrottleOptions { pub fn throttle_filter( ms: impl Into>, options: ThrottleOptions, -) -> impl FnMut(Box>) -> Rc>> +) -> impl Fn(Box>) -> Rc>> where R: 'static, {