Copy to Clipboard
A component that allows users to copy text to the clipboard.
<!-- Copy to Clipboard -->
<!-- An Alpine.js and Tailwind CSS component by https://pinemix.com -->
<div
x-data="{
// Options
feedbackDuration: 1200,
// Helpers
copiedStates: {},
// Copy text to clipboard
async copyToClipboard(text, id) {
try {
await navigator.clipboard.writeText(text);
this.copiedStates[id] = true;
setTimeout(() => {
this.copiedStates[id] = false;
}, this.feedbackDuration);
} catch (err) {
console.error('Failed to copy:', err);
}
},
// Check if copied
isCopied(id) {
return this.copiedStates[id] || false;
}
}"
>
<!-- Placeholder -->
<div class="mx-auto flex max-w-xl flex-col gap-10">
<!-- Example 1: Buttons -->
<div class="flex flex-col gap-3">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Buttons
</h3>
<div class="flex items-center gap-3">
<button
x-on:click="copyToClipboard('Icon button clicked!', 'example1-icon-btn')"
type="button"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white p-2 text-sm leading-5 font-semibold text-zinc-800 hover:border-zinc-300 hover:text-zinc-900 hover:shadow-xs focus:ring-3 focus:ring-zinc-300/25 active:border-zinc-200 active:shadow-none dark:border-zinc-700 dark:bg-transparent dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:text-zinc-200 dark:focus:ring-zinc-600/40 dark:active:border-zinc-700"
>
<span class="relative inline-block size-5">
<svg
x-cloak
x-show="isCopied('example1-icon-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-200"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-200"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-check absolute inset-0 inline-block size-5 text-green-600 dark:text-green-400"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
<svg
x-cloak
x-show="!isCopied('example1-icon-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-0"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-0"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-clipboard-document-list absolute inset-0 inline-block size-5"
>
<path
fill-rule="evenodd"
d="M15.988 3.012A2.25 2.25 0 0 1 18 5.25v6.5A2.25 2.25 0 0 1 15.75 14H13.5V7A2.5 2.5 0 0 0 11 4.5H8.128a2.252 2.252 0 0 1 1.884-1.488A2.25 2.25 0 0 1 12.25 1h1.5a2.25 2.25 0 0 1 2.238 2.012ZM11.5 3.25a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v.25h-3v-.25Z"
clip-rule="evenodd"
/>
<path
fill-rule="evenodd"
d="M2 7a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm2 3.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm0 3.5a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
clip-rule="evenodd"
/>
</svg>
</span>
<span class="sr-only">Copy</span>
</button>
<button
x-on:click="copyToClipboard('Hello, World!', 'example1-simple-btn')"
type="button"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-zinc-800 bg-zinc-800 px-3 py-2 text-sm leading-5 font-medium text-white hover:border-zinc-900 hover:bg-zinc-900 hover:text-white focus:ring-2 focus:ring-zinc-500/50 focus:outline-hidden active:border-zinc-700 active:bg-zinc-700 dark:border-zinc-700/50 dark:bg-zinc-700/50 dark:ring-zinc-700/50 dark:hover:border-zinc-700 dark:hover:bg-zinc-700/75 dark:active:border-zinc-700/50 dark:active:bg-zinc-700/50"
>
<span class="relative inline-block size-5">
<svg
x-cloak
x-show="isCopied('example1-simple-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-200"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-200"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-check absolute inset-0 inline-block size-5 text-green-400"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
<svg
x-cloak
x-show="!isCopied('example1-simple-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-0"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-0"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-clipboard-document-list absolute inset-0 inline-block size-5"
>
<path
fill-rule="evenodd"
d="M15.988 3.012A2.25 2.25 0 0 1 18 5.25v6.5A2.25 2.25 0 0 1 15.75 14H13.5V7A2.5 2.5 0 0 0 11 4.5H8.128a2.252 2.252 0 0 1 1.884-1.488A2.25 2.25 0 0 1 12.25 1h1.5a2.25 2.25 0 0 1 2.238 2.012ZM11.5 3.25a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v.25h-3v-.25Z"
clip-rule="evenodd"
/>
<path
fill-rule="evenodd"
d="M2 7a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm2 3.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm0 3.5a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
clip-rule="evenodd"
/>
</svg>
</span>
<span
x-text="isCopied('example1-simple-btn') ? 'Copied!' : 'Copy Content'"
></span>
</button>
</div>
</div>
<!-- END Example 1: Simple Button -->
<!-- Example 2: Code Block -->
<div class="flex flex-col gap-3">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
Code Block
</h3>
<div
class="relative rounded-lg border border-zinc-200/75 bg-zinc-50 dark:border-zinc-700/75 dark:bg-zinc-800/75"
>
<div class="flex items-center justify-between">
<code class="grow p-4 text-sm text-zinc-700 dark:text-zinc-300">
npm install alpinejs
</code>
<button
x-on:click="copyToClipboard('npm install alpinejs', 'example2-code-btn')"
type="button"
class="mx-2 flex flex-none items-center justify-center p-2 text-zinc-500 hover:text-zinc-700 active:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300 dark:active:text-zinc-400"
>
<span class="relative inline-block size-5">
<svg
x-cloak
x-show="isCopied('example2-code-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-200"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-200"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-check absolute inset-0 inline-block size-5 text-green-600 dark:text-green-400"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
<svg
x-cloak
x-show="!isCopied('example2-code-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-0"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-0"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-clipboard-document-list absolute inset-0 inline-block size-5"
>
<path
fill-rule="evenodd"
d="M15.988 3.012A2.25 2.25 0 0 1 18 5.25v6.5A2.25 2.25 0 0 1 15.75 14H13.5V7A2.5 2.5 0 0 0 11 4.5H8.128a2.252 2.252 0 0 1 1.884-1.488A2.25 2.25 0 0 1 12.25 1h1.5a2.25 2.25 0 0 1 2.238 2.012ZM11.5 3.25a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v.25h-3v-.25Z"
clip-rule="evenodd"
/>
<path
fill-rule="evenodd"
d="M2 7a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm2 3.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm0 3.5a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
clip-rule="evenodd"
/>
</svg>
</span>
<span class="sr-only">Copy code</span>
</button>
</div>
</div>
</div>
<!-- END Example 2: Code Block -->
<!-- Example 3: Input -->
<div class="flex flex-col gap-3">
<label
for="website-url"
class="text-sm font-semibold text-zinc-900 dark:text-zinc-100"
>
Website URL
</label>
<div class="relative">
<input
type="text"
id="website-url"
value="https://pinemix.com/"
class="w-full rounded-lg border border-zinc-200/75 bg-white px-4 py-2.5 pe-20 text-sm leading-5 text-zinc-900 placeholder-zinc-500 focus:border-zinc-500 focus:ring-2 focus:ring-zinc-500/50 focus:outline-hidden dark:border-zinc-700/75 dark:bg-transparent dark:text-zinc-100 dark:placeholder-zinc-400 dark:focus:border-zinc-500"
readonly
/>
<div
class="absolute inset-y-0 end-0 flex items-center justify-center px-2"
>
<button
x-on:click="copyToClipboard(document.getElementById('website-url').value, 'example3-input-btn')"
type="button"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white px-2 py-1 text-xs font-semibold text-zinc-800 hover:border-zinc-300 hover:text-zinc-900 hover:shadow-xs focus:ring-3 focus:ring-zinc-300/25 active:border-zinc-200 active:shadow-none dark:border-zinc-700 dark:bg-transparent dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:text-zinc-200 dark:focus:ring-zinc-600/40 dark:active:border-zinc-700"
>
<span
x-bind:class="isCopied('example3-input-btn') ? 'text-green-600 dark:text-green-400' : ''"
x-text="isCopied('example3-input-btn') ? 'Copied!' : 'Copy'"
></span>
</button>
</div>
</div>
</div>
<!-- END Example 3: Input -->
<!-- Example 4: API Key -->
<div class="flex flex-col gap-3">
<h3 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100">
API Key
</h3>
<div
class="flex items-center justify-between gap-4 rounded-lg border border-zinc-200/75 p-4 dark:border-zinc-700/75"
>
<div class="flex min-w-0 flex-1 items-center gap-3">
<div
class="flex size-10 flex-none items-center justify-center rounded-lg bg-zinc-100 text-zinc-600 dark:bg-zinc-800/75 dark:text-zinc-400"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-key inline-block size-5"
>
<path
fill-rule="evenodd"
d="M8 7a5 5 0 1 1 3.61 4.804l-1.903 1.903A1 1 0 0 1 9 14H8v1a1 1 0 0 1-1 1H6v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-2a1 1 0 0 1 .293-.707L8.196 8.39A5.002 5.002 0 0 1 8 7Zm5-3a.75.75 0 0 0 0 1.5A1.5 1.5 0 0 1 14.5 7 .75.75 0 0 0 16 7a3 3 0 0 0-3-3Z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class="min-w-0 flex-1">
<div class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
API Key
</div>
<div
class="mt-0.5 truncate font-mono text-xs text-zinc-600 dark:text-zinc-400"
>
db_1234567890abcdefghijklmnopqrstuvwxyz
</div>
</div>
</div>
<button
x-on:click="copyToClipboard('db_1234567890abcdefghijklmnopqrstuvwxyz', 'example4-api-key-btn')"
type="button"
class="inline-flex items-center justify-center gap-2 rounded-lg border border-zinc-200 bg-white p-2 text-sm leading-5 font-semibold text-zinc-800 hover:border-zinc-300 hover:text-zinc-900 hover:shadow-xs focus:ring-3 focus:ring-zinc-300/25 active:border-zinc-200 active:shadow-none dark:border-zinc-700 dark:bg-transparent dark:text-zinc-300 dark:hover:border-zinc-600 dark:hover:text-zinc-200 dark:focus:ring-zinc-600/40 dark:active:border-zinc-700"
>
<span class="relative inline-block size-5">
<svg
x-cloak
x-show="isCopied('example4-api-key-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-200"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-200"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-check absolute inset-0 inline-block size-5 text-green-600 dark:text-green-400"
>
<path
fill-rule="evenodd"
d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z"
clip-rule="evenodd"
/>
</svg>
<svg
x-cloak
x-show="!isCopied('example4-api-key-btn')"
x-transition:enter="transition ease-out duration-150"
x-transition:enter-start="opacity-0 scale-0"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-0"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="hi-mini hi-clipboard-document-list inline-block size-5"
>
<path
fill-rule="evenodd"
d="M15.988 3.012A2.25 2.25 0 0 1 18 5.25v6.5A2.25 2.25 0 0 1 15.75 14H13.5V7A2.5 2.5 0 0 0 11 4.5H8.128a2.252 2.252 0 0 1 1.884-1.488A2.25 2.25 0 0 1 12.25 1h1.5a2.25 2.25 0 0 1 2.238 2.012ZM11.5 3.25a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v.25h-3v-.25Z"
clip-rule="evenodd"
/>
<path
fill-rule="evenodd"
d="M2 7a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7Zm2 3.25a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Zm0 3.5a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z"
clip-rule="evenodd"
/>
</svg>
</span>
<span class="sr-only">Copy API Key</span>
</button>
</div>
</div>
<!-- END Example 4: API Key -->
</div>
<!-- END Placeholder -->
</div>
<!-- END Copy to Clipboard -->
Props
The available data properties for this component.
| Property | Default | Description |
|---|---|---|
| feedbackDuration | 1200 | Sets the feedback duration in milliseconds |
Designed with
Tailkit
Featuring 2,000+ Tailwind CSS code snippets for HTML, React, Vue.js and Alpine.js projects
Unlock 15+ free templates
Join our pixelcave newsletter to get them now & we'll also keep you updated about any new Pinemix components!