43 lines
1.1 KiB
Svelte
43 lines
1.1 KiB
Svelte
<script lang="ts">
|
|
import Button from './primitives/Button.svelte';
|
|
let { value, label = 'ID' }: { value: string; label?: string } = $props();
|
|
let copyStatus = $state('');
|
|
$effect(() => {
|
|
void value;
|
|
copyStatus = '';
|
|
});
|
|
async function copy() {
|
|
copyStatus = '';
|
|
try {
|
|
await navigator.clipboard.writeText(value);
|
|
copyStatus = `${label} copied.`;
|
|
} catch {
|
|
copyStatus = 'Copy unavailable. Select and copy the text directly.';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="copy">
|
|
<code>{value}</code><Button variant="ghost" size="sm" ariaLabel={`Copy ${label}`} onclick={copy}
|
|
>Copy</Button
|
|
>{#if copyStatus}<span class="copy-status" role="status">{copyStatus}</span>{/if}
|
|
</div>
|
|
|
|
<style>
|
|
.copy-status {
|
|
font-size: var(--text-xs);
|
|
}
|
|
.copy {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: var(--space-2);
|
|
color: var(--text-secondary);
|
|
}
|
|
code {
|
|
font: var(--text-xs) var(--font-mono);
|
|
user-select: all;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
</style>
|