fix(ui): trigger FilterTabs indicator animation on click

This commit is contained in:
xfy 2026-06-29 13:24:52 +08:00
parent 3daa09efc2
commit c69a632e75

View File

@ -207,41 +207,43 @@ pub fn FilterTabs(
let mut indicator_style = use_signal(|| "left: 0px; width: 0px; opacity: 0;".to_string()); let mut indicator_style = use_signal(|| "left: 0px; width: 0px; opacity: 0;".to_string());
let id_prefix = use_hook(|| TAB_GROUP_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst)); let id_prefix = use_hook(|| TAB_GROUP_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst));
use_effect({ let update_indicator = move |active: String| {
let active_value = active_value.clone(); spawn(async move {
move || { #[cfg(target_arch = "wasm32")]
#[allow(unused_variables)] {
let active = active_value.clone(); use wasm_bindgen::JsCast;
spawn(async move {
#[cfg(target_arch = "wasm32")]
{
use wasm_bindgen::JsCast;
// 等待 DOM 节点更新
let promise = js_sys::Promise::new(&mut |resolve, _| {
if let Some(window) = web_sys::window() {
let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 50);
}
});
let _ = wasm_bindgen_futures::JsFuture::from(promise).await;
// 等待 DOM 节点更新
let promise = js_sys::Promise::new(&mut |resolve, _| {
if let Some(window) = web_sys::window() { if let Some(window) = web_sys::window() {
if let Some(doc) = window.document() { let _ = window.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 50);
let element_id = format!("tab-{}-{}", id_prefix, active); }
if let Some(el) = doc.get_element_by_id(&element_id) { });
if let Ok(html_el) = el.dyn_into::<web_sys::HtmlElement>() { let _ = wasm_bindgen_futures::JsFuture::from(promise).await;
let left = html_el.offset_left();
let width = html_el.offset_width(); if let Some(window) = web_sys::window() {
indicator_style.set(format!( if let Some(doc) = window.document() {
"left: {}px; width: {}px; opacity: 1;", let element_id = format!("tab-{}-{}", id_prefix, active);
left, width if let Some(el) = doc.get_element_by_id(&element_id) {
)); if let Ok(html_el) = el.dyn_into::<web_sys::HtmlElement>() {
} let left = html_el.offset_left();
let width = html_el.offset_width();
indicator_style.set(format!(
"left: {}px; width: {}px; opacity: 1;",
left, width
));
} }
} }
} }
} }
}); }
});
};
use_effect({
let active_value = active_value.clone();
move || {
update_indicator(active_value.clone());
} }
}); });
@ -258,7 +260,10 @@ pub fn FilterTabs(
}, },
onclick: { onclick: {
let v = value.to_string(); let v = value.to_string();
move |_| on_change.call(v.clone()) move |_| {
on_change.call(v.clone());
update_indicator(v.clone());
}
}, },
"{label}" "{label}"
} }