use leptos::prelude::*; use tailwind_fuse::tw_merge; use crate::components::ui::button::{Button, ButtonVariant}; #[component] pub fn ButtonAction( children: Children, #[prop(into)] on_action: Callback<()>, #[prop(optional, into)] class: String, #[prop(default = 1000)] hold_duration: u64, #[prop(default = ButtonVariant::Default)] variant: ButtonVariant, ) -> impl IntoView { let is_holding = RwSignal::new(false); let generation = StoredValue::new(0u64); let on_down = move |_| { generation.update_value(|g| *g += 1); is_holding.set(true); }; let on_up = move |_| is_holding.set(false); Effect::new(move |_| { if is_holding.get() { let current_gen = generation.get_value(); leptos::task::spawn_local(async move { gloo_timers::future::TimeoutFuture::new(hold_duration as u32).await; // Double validation: Is user still holding AND is it the SAME hold attempt? if is_holding.get_untracked() && generation.get_value() == current_gen { on_action.run(()); is_holding.set(false); } }); } }); let merged_class = move || tw_merge!( "relative overflow-hidden transition-all active:scale-[0.98]", class.clone() ); view! { } }