File size: 2,309 Bytes
6426ece |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<script lang="ts">
import type { SvelteComponent } from 'svelte';
import { onDestroy } from 'svelte';
import IconCopy from '../Icons/IconCopy.svelte';
import { tooltip } from '../utils/tooltip';
export const hydrate = true;
export let classNames = '';
export let label = '';
export let noIcon = false;
export let icon: typeof SvelteComponent | undefined = undefined;
export let style: 'blank' | 'button' | 'button-clear' | 'text' = 'text';
export let title = '';
export let value: string;
export let successType: 'tooltip' | 'text' = 'tooltip';
export let successText: string = 'Copied';
let isSuccess = false;
let timeout: any;
onDestroy(() => {
if (timeout) {
clearTimeout(timeout);
}
});
function handleClick() {
copyToClipboard(value);
isSuccess = true;
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
isSuccess = false;
}, 1000);
}
function copyToClipboard(value: string): void {
const textArea = document.createElement('textarea');
document.body.appendChild(textArea);
textArea.value = value;
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
}
</script>
{#key isSuccess}
<button
class="border-gray-500 {classNames}
{style !== 'blank' ? 'inline-flex cursor-pointer items-center text-sm focus:outline-hidden' : ''}
{['button', 'button-clear'].includes(style) ? 'bg-white dark:bg-gray-900' : ''}
{style === 'text' ? 'mx-0.5' : ''}
{style === 'button' ? 'btn' : ''}
{style === 'button-clear' ? 'rounded-md border p-1 shadow-xs' : ''}
{!isSuccess && ['button-clear', 'text'].includes(style) ? 'text-gray-600' : ''}
{isSuccess && style !== 'blank' ? 'text-green-500' : ''}
"
on:click|preventDefault|stopPropagation={handleClick}
title={title || label || 'Copy to clipboard'}
type="button"
use:tooltip={{
content: successText,
disabled: successType !== 'tooltip' || !isSuccess,
showOn: 'always',
opts: { placement: 'bottom' }
}}
>
{#if !noIcon}
<svelte:component this={icon ?? IconCopy} />
{/if}
{#if label}
{#if isSuccess && successType === 'text'}
<span class="ml-1.5">{successText}</span>
{:else}
<span class="ml-1.5 {style === 'text' ? 'underline' : ''}">
{label}
</span>
{/if}
{/if}
</button>
{/key}
|