use crate::icon::{Icon, IconKind};
use crate::util::sleep_ms;
use dioxus::prelude::*;
#[component]
pub fn CopyButton(
value: String,
#[props(default = 2000)]
timeout_ms: u32,
#[props(default)]
label: Option<String>,
#[props(default = "Copiato!".to_string())]
copied_label: String,
#[props(default = false)]
icon_only: bool,
#[props(default = "Copia negli appunti".to_string())]
aria_label: String,
#[props(default)]
class: String,
) -> Element {
let mut is_copied = use_signal(|| false);
let val_to_copy = value.clone();
let handle_copy = move |e: MouseEvent| {
e.stop_propagation();
let text = val_to_copy.clone();
spawn(async move {
let eval = document::eval(
r#"
const text = await dioxus.recv();
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(text);
} else {
const el = document.createElement("textarea");
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand("copy");
document.body.removeChild(el);
}
"#,
);
let _ = eval.send(text);
let _ = eval.await;
is_copied.set(true);
sleep_ms(timeout_ms as u64).await;
is_copied.set(false);
});
};
let copied = *is_copied.read();
let copied_class = if copied { "sd-copy-btn--copied" } else { "" };
let icon_only_class = if icon_only { "sd-copy-btn--icon-only" } else { "" };
rsx! {
button {
r#type: "button",
class: "sd-copy-btn {copied_class} {icon_only_class} {class}",
title: if copied { &copied_label } else { &aria_label },
"aria-label": if copied { &copied_label } else { &aria_label },
onclick: handle_copy,
if copied {
Icon { kind: IconKind::Check, size: 15 }
if !icon_only {
span { class: "sd-copy-btn-label", "{copied_label}" }
}
} else {
Icon { kind: IconKind::Copy, size: 15 }
if let Some(lbl) = label {
if !icon_only {
span { class: "sd-copy-btn-label", "{lbl}" }
}
}
}
}
}
}