src/components/copy_button.rs
//! Copy-to-clipboard with feedback: the button says what it copies (the
//! accessible name carries it too) and confirms with a brief "copied".
use leptos::prelude::*;
use leptos::task::spawn_local;
use crate::webio;
#[component]
pub fn CopyButton(
#[prop(into)] label: String,
#[prop(into)] value: Signal<String>,
) -> impl IntoView {
let state: RwSignal<Option<Result<(), String>>> = RwSignal::new(None);
let aria = format!("Copy {label}");
let copy = move |_| {
let text = value.get_untracked();
spawn_local(async move {
let res = webio::copy_text(&text).await;
state.set(Some(res));
});
};
view! {
<button class="copy" aria-label=aria on:click=copy>
{move || match state.get() {
Some(Ok(())) => "copied ✓".to_string(),
Some(Err(_)) => "copy failed".to_string(),
None => format!("copy {label}"),
}}
</button>
}
}