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