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}