Add loading state to Button

- Add loading: bool prop to Button - Disable button when loading or
disabled - Show spinner and wrap content in a ui-button-content span
during loading - Add data-loading and aria-busy attributes for
accessibility - Prevent click handlers from firing while loading
This commit is contained in:
tommy
2025-11-05 18:40:40 +08:00
parent 09e96859d6
commit f551a41a5b

View File

@@ -65,6 +65,7 @@ pub fn Button(
#[props(default)] size: ButtonSize,
#[props(into, default)] class: Option<String>,
#[props(default)] disabled: bool,
#[props(default)] loading: bool,
#[props(default = "button".to_string())]
#[props(into)]
r#type: String,
@@ -78,20 +79,36 @@ pub fn Button(
}
let click_handler = on_click.clone();
let is_disabled = disabled || loading;
rsx! {
button {
class: classes,
disabled,
disabled: is_disabled,
r#type: r#type,
"data-variant": variant.as_str(),
"data-size": size.as_str(),
"data-loading": if loading { "true" } else { "false" },
"aria-busy": if loading { "true" } else { "false" },
onclick: move |event| {
if loading {
event.stop_propagation();
return;
}
if let Some(handler) = click_handler.clone() {
handler.call(event);
}
},
{children}
if loading {
span {
class: "ui-button-spinner",
"aria-hidden": "true",
}
}
span {
class: "ui-button-content",
{children}
}
}
}
}