(button: HTMLButtonElement, value: string)
| 686 | } |
| 687 | |
| 688 | async function copyValue(button: HTMLButtonElement, value: string) { |
| 689 | const originalLabel = |
| 690 | button.dataset.copyLabel ?? |
| 691 | button.getAttribute("aria-label") ?? |
| 692 | button.title ?? |
| 693 | "Copy"; |
| 694 | button.dataset.copyLabel = originalLabel; |
| 695 | |
| 696 | const copyIcon = button.querySelector<HTMLElement>(".copy-icon"); |
| 697 | const checkIcon = button.querySelector<HTMLElement>(".check-icon"); |
| 698 | const copied = await writeClipboard(value); |
| 699 | const selected = copied ? false : selectCopySource(button); |
| 700 | |
| 701 | window.clearTimeout(copyTimers.get(button)); |
| 702 | button.classList.toggle("copied", copied); |
| 703 | button.classList.toggle("selected", selected); |
| 704 | button.classList.toggle("copy-failed", !copied && !selected); |
| 705 | |
| 706 | const feedback = copied ? "Copied" : selected ? "Selected" : "Copy failed"; |
| 707 | button.setAttribute("aria-label", feedback); |
| 708 | button.title = feedback; |
| 709 | |
| 710 | if (copyIcon && checkIcon) { |
| 711 | copyIcon.style.display = copied ? "none" : "block"; |
| 712 | checkIcon.style.display = copied ? "block" : "none"; |
| 713 | } |
| 714 | |
| 715 | copyTimers.set( |
| 716 | button, |
| 717 | setTimeout(() => { |
| 718 | button.classList.remove("copied", "selected", "copy-failed"); |
| 719 | button.setAttribute("aria-label", originalLabel); |
| 720 | button.title = originalLabel; |
| 721 | if (copyIcon && checkIcon) { |
| 722 | copyIcon.style.display = "block"; |
| 723 | checkIcon.style.display = "none"; |
| 724 | } |
| 725 | }, 1200), |
| 726 | ); |
| 727 | } |
| 728 | |
| 729 | function copyFromEventTarget(target: EventTarget | null) { |
| 730 | if (!(target instanceof Element)) return undefined; |
no test coverage detected