leptos-use/src/use_interval.rs

130 lines
3 KiB
Rust
Raw Normal View History

2023-06-15 20:30:05 +01:00
use crate::utils::{CloneableFnWithArg, Pausable};
use crate::{use_interval_fn_with_options, UseIntervalFnOptions};
2023-06-15 18:02:13 +02:00
use default_struct_builder::DefaultBuilder;
2023-06-15 20:30:05 +01:00
2023-06-15 18:02:13 +02:00
use leptos::*;
/// Reactive counter increases on every interval.
///
/// ## Demo
///
/// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_interval)
///
/// ## Usage
///
/// ```
/// # use leptos::*;
/// # use leptos_use::{use_interval, UseIntervalReturn};
/// #
/// # #[component]
/// # fn Demo(cx: Scope) -> impl IntoView {
/// let UseIntervalReturn {
/// counter,
/// reset,
/// is_active,
/// pause,
/// resume
/// } = use_interval( cx, 200 );
/// # view! { cx, }
/// # }
/// ```
pub fn use_interval<N>(
cx: Scope,
interval: N,
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
2023-06-15 20:10:30 +01:00
where
N: Into<MaybeSignal<u64>>,
2023-06-15 18:02:13 +02:00
{
2023-06-15 20:10:30 +01:00
use_interval_with_options(cx, interval, UseIntervalOptions::default())
2023-06-15 18:02:13 +02:00
}
/// Version of [`use_interval`] that takes `UseIntervalOptions`. See [`use_interval`] for how to use.
2023-06-15 20:10:30 +01:00
pub fn use_interval_with_options<N>(
2023-06-15 18:02:13 +02:00
cx: Scope,
interval: N,
2023-06-15 20:10:30 +01:00
options: UseIntervalOptions,
2023-06-15 18:02:13 +02:00
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
2023-06-15 20:10:30 +01:00
where
N: Into<MaybeSignal<u64>>,
2023-06-15 18:02:13 +02:00
{
let UseIntervalOptions {
immediate,
callback,
} = options;
let (counter, set_counter) = create_signal(cx, 0u64);
let update = move || set_counter.update(|count| *count += 1);
let reset = move || set_counter.set(0);
2023-06-15 18:02:13 +02:00
2023-06-15 20:10:30 +01:00
let cb = move || {
update();
callback.clone()(counter.get());
2023-06-15 20:10:30 +01:00
};
2023-06-15 18:02:13 +02:00
2023-06-15 20:10:30 +01:00
let Pausable {
is_active,
pause,
resume,
} = use_interval_fn_with_options(
cx,
cb,
interval,
UseIntervalFnOptions {
immediate,
immediate_callback: false,
},
);
2023-06-15 18:02:13 +02:00
UseIntervalReturn {
counter: counter.into(),
reset,
is_active,
pause,
resume,
}
}
/// Options for [`use_interval_with_options`]
#[derive(DefaultBuilder)]
2023-06-15 20:10:30 +01:00
pub struct UseIntervalOptions {
2023-06-15 18:02:13 +02:00
/// Start the timer immediately. Defaults to `true`.
immediate: bool,
/// Callback on every interval.
2023-06-15 20:10:30 +01:00
callback: Box<dyn CloneableFnWithArg<u64>>,
2023-06-15 18:02:13 +02:00
}
2023-06-15 20:10:30 +01:00
impl Default for UseIntervalOptions {
fn default() -> Self {
Self {
2023-06-15 20:30:05 +01:00
immediate: true,
2023-06-15 20:10:30 +01:00
callback: Box::new(|_: u64| {}),
}
}
}
2023-06-15 18:02:13 +02:00
/// Return type of [`use_interval`].
#[derive(DefaultBuilder)]
pub struct UseIntervalReturn<PauseFn, ResumeFn, ResetFn>
2023-06-15 20:10:30 +01:00
where
PauseFn: Fn() + Clone,
ResumeFn: Fn() + Clone,
ResetFn: Fn() + Clone,
2023-06-15 18:02:13 +02:00
{
/// Counter signal that increases by one every interval.
pub counter: Signal<u64>,
/// Reset the counter to zero
pub reset: ResetFn,
/// A Signal that indicates whether the counter is active. `false` when paused.
pub is_active: Signal<bool>,
/// Temporarily pause the counter
pub pause: PauseFn,
/// Resume the counter
pub resume: ResumeFn,
2023-06-15 20:10:30 +01:00
}