| <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} | |