leptos_use/use_interval.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use crate::utils::Pausable;
use crate::{use_interval_fn_with_options, UseIntervalFnOptions};
use default_struct_builder::DefaultBuilder;
use std::rc::Rc;
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() -> impl IntoView {
/// let UseIntervalReturn {
/// counter,
/// reset,
/// is_active,
/// pause,
/// resume
/// } = use_interval( 200 );
/// # view! { }
/// # }
/// ```
///
/// ## Server-Side Rendering
///
/// On the server this function will simply be ignored.
pub fn use_interval<N>(
interval: N,
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
where
N: Into<MaybeSignal<u64>>,
{
use_interval_with_options(interval, UseIntervalOptions::default())
}
/// Version of [`use_interval`] that takes `UseIntervalOptions`. See [`use_interval`] for how to use.
pub fn use_interval_with_options<N>(
interval: N,
options: UseIntervalOptions,
) -> UseIntervalReturn<impl Fn() + Clone, impl Fn() + Clone, impl Fn() + Clone>
where
N: Into<MaybeSignal<u64>>,
{
let UseIntervalOptions {
immediate,
callback,
} = options;
let (counter, set_counter) = create_signal(0u64);
let update = move || set_counter.update(|count| *count += 1);
let reset = move || set_counter.set(0);
let cb = move || {
update();
callback(counter.get());
};
let Pausable {
is_active,
pause,
resume,
} = use_interval_fn_with_options(
cb,
interval,
UseIntervalFnOptions {
immediate,
immediate_callback: false,
},
);
UseIntervalReturn {
counter: counter.into(),
reset,
is_active,
pause,
resume,
}
}
/// Options for [`use_interval_with_options`]
#[derive(DefaultBuilder)]
pub struct UseIntervalOptions {
/// Start the timer immediately. Defaults to `true`.
immediate: bool,
/// Callback on every interval.
callback: Rc<dyn Fn(u64)>,
}
impl Default for UseIntervalOptions {
fn default() -> Self {
Self {
immediate: true,
callback: Rc::new(|_: u64| {}),
}
}
}
/// Return type of [`use_interval`].
#[derive(DefaultBuilder)]
pub struct UseIntervalReturn<PauseFn, ResumeFn, ResetFn>
where
PauseFn: Fn() + Clone,
ResumeFn: Fn() + Clone,
ResetFn: Fn() + Clone,
{
/// 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,
}