leptos_use/use_debounce_fn.rs
1pub use crate::utils::DebounceOptions;
2use crate::utils::{create_filter_wrapper, create_filter_wrapper_with_arg, debounce_filter};
3use leptos::prelude::Signal;
4use std::sync::{Arc, Mutex};
5
6/// Debounce execution of a function.
7///
8/// > Debounce is an overloaded waiter: If you keep asking him your requests will be ignored until you stop and give him some time to think about your latest inquiry.
9///
10/// ## Demo
11///
12/// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_debounce_fn)
13///
14/// ## Usage
15///
16/// ```
17/// # use leptos::prelude::*;
18/// # use leptos::ev::resize;
19/// # use leptos_use::use_debounce_fn;
20/// #
21/// # #[component]
22/// # fn Demo() -> impl IntoView {
23/// let mut debounced_fn = use_debounce_fn(
24/// || {
25/// // do something
26/// },
27/// 1000.0,
28/// );
29///
30/// window_event_listener(resize, move |_| { debounced_fn(); });
31/// # view! { }
32/// # }
33/// ```
34///
35/// Please note that if the current component is cleaned up before the throttled callback is called, the throttled callback will not be called.
36///
37/// You can also pass options to [`use_debounce_fn_with_options`] with a maximum wait time, similar to
38/// [lodash debounce](https://lodash.com/docs/#debounce).
39///
40/// ```
41/// # use leptos::prelude::*;
42/// # use leptos::ev::resize;
43/// # use leptos_use::use_debounce_fn_with_options;
44/// # use leptos_use::utils::DebounceOptions;
45/// #
46/// # #[component]
47/// # fn Demo() -> impl IntoView {
48/// let mut debounced_fn = use_debounce_fn_with_options(
49/// || {
50/// // do something
51/// },
52/// 1000.0,
53/// DebounceOptions::default()
54/// .max_wait(Some(5000.0)),
55/// );
56///
57/// window_event_listener(resize, move |_| { debounced_fn(); });
58/// # view! { }
59/// # }
60/// ```
61///
62/// Currently there is no way to use a function with a return value. Please open an issue if you need this.
63///
64/// If you want to throttle a function that takes an argument there are also the versions
65/// [`use_debounce_fn_with_arg`] and [`use_debounce_fn_with_arg_and_options`].
66///
67/// ## SendWrapped Return
68///
69/// The returned closure is a sendwrapped function. It can
70/// only be called from the same thread that called `use_debounce_...`.
71///
72/// ## Recommended Reading
73///
74/// - [**Debounce vs Throttle**: Definitive Visual Guide](https://redd.one/blog/debounce-vs-throttle)
75/// - [Debouncing and Throttling Explained Through Examples](https://css-tricks.com/debouncing-throttling-explained-examples/)
76///
77/// ## Server-Side Rendering
78///
79/// Internally this uses `setTimeout` which is not supported on the server. So usually calling
80/// a debounced function on the server will simply be ignored.
81pub fn use_debounce_fn<F, R>(
82 func: F,
83 ms: impl Into<Signal<f64>> + 'static,
84) -> impl Fn() -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
85where
86 F: Fn() -> R + Clone + 'static,
87 R: 'static,
88{
89 use_debounce_fn_with_options(func, ms, DebounceOptions::default())
90}
91
92/// Version of [`use_debounce_fn`] with debounce options. See the docs for [`use_debounce_fn`] for how to use.
93pub fn use_debounce_fn_with_options<F, R>(
94 func: F,
95 ms: impl Into<Signal<f64>> + 'static,
96 options: DebounceOptions,
97) -> impl Fn() -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
98where
99 F: Fn() -> R + Clone + 'static,
100 R: 'static,
101{
102 create_filter_wrapper(Arc::new(debounce_filter(ms, options)), func)
103}
104
105/// Version of [`use_debounce_fn`] with an argument for the debounced function. See the docs for [`use_debounce_fn`] for how to use.
106pub fn use_debounce_fn_with_arg<F, Arg, R>(
107 func: F,
108 ms: impl Into<Signal<f64>> + 'static,
109) -> impl Fn(Arg) -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
110where
111 F: Fn(Arg) -> R + Clone + 'static,
112 Arg: Clone + 'static,
113 R: 'static,
114{
115 use_debounce_fn_with_arg_and_options(func, ms, DebounceOptions::default())
116}
117
118/// Version of [`use_debounce_fn_with_arg`] with debounce options.
119pub fn use_debounce_fn_with_arg_and_options<F, Arg, R>(
120 func: F,
121 ms: impl Into<Signal<f64>> + 'static,
122 options: DebounceOptions,
123) -> impl Fn(Arg) -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
124where
125 F: Fn(Arg) -> R + Clone + 'static,
126 Arg: Clone + 'static,
127 R: 'static,
128{
129 create_filter_wrapper_with_arg(Arc::new(debounce_filter(ms, options)), func)
130}