mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-30 16:50:47 +08:00
47 lines
1003 B
Svelte
47 lines
1003 B
Svelte
<script lang="ts">
|
|
import { writeToClipboard } from "@app/lib/invoke";
|
|
|
|
import Icon from "@app/components/Icon.svelte";
|
|
|
|
interface Props {
|
|
// Produces the text lazily, so large content isn't built until clicked.
|
|
text: () => string;
|
|
title?: string;
|
|
}
|
|
|
|
const { text, title = "Copy" }: Props = $props();
|
|
|
|
let copied = $state(false);
|
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
|
|
async function copy() {
|
|
await writeToClipboard(text());
|
|
copied = true;
|
|
clearTimeout(timer);
|
|
timer = setTimeout(() => {
|
|
copied = false;
|
|
}, 1000);
|
|
}
|
|
|
|
$effect(() => () => clearTimeout(timer));
|
|
</script>
|
|
|
|
<style>
|
|
.copy {
|
|
background: none;
|
|
border: none;
|
|
padding: 0;
|
|
cursor: pointer;
|
|
color: var(--color-text-secondary);
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.copy:hover {
|
|
color: var(--color-text-primary);
|
|
}
|
|
</style>
|
|
|
|
<button class="copy" {title} onclick={copy}>
|
|
<Icon name={copied ? "checkmark" : "clipboard"} />
|
|
</button>
|