Copy Button

A button that copies text to your clipboard when clicked. Shows a check mark after copying and comes in different sizes.

Utility function

Create a file lib/utils.ts and paste this code

import { ClassValue, clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); }

Install dependencies

npm i framer-motion

Copy Text Button

Create a file copy-text-button.tsx in your components folder and paste this code

'use client'; import React, { useState } from 'react'; import { Check, Copy } from 'lucide-react'; import { cn } from '@/lib/utils'; import { AnimatePresence, motion } from 'framer-motion'; const CopyTextButton = ({ label, icon = <Copy className="h-5 w-5" />, // * Icon to show on the button variant = 'default', className = '', onCopy, textToCopy // * Text you want to copy }: { label: string; icon?: React.ReactNode; variant?: 'default' | 'small'; className?: string; onCopy?: () => void; textToCopy?: string; }) => { const [copied, setCopied] = useState(false); const handleCopy = () => { if (onCopy) onCopy(); else navigator.clipboard.writeText(textToCopy || label); setCopied(true); setTimeout(() => setCopied(false), 1200); }; return ( <button className={cn( 'bg-zinc-800 w-min hover:bg-zinc-700 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition', variant === 'small' && 'text-xs', className )} onClick={handleCopy} > <AnimatePresence mode="popLayout"> {copied ? ( <motion.div key="copied" initial={{ opacity: 0, transform: 'blur(10px)' }} animate={{ opacity: 1, transform: 'blur(0px)' }} exit={{ opacity: 0, transform: 'blur(10px)' }} transition={{ duration: 0.1 }} > <Check className={cn(variant === 'small' ? 'w-4 h-4' : 'w-4 h-4', 'text-green-400')} /> </motion.div> ) : ( <motion.div key="icon" initial={{ opacity: 0, transform: 'blur(10px)' }} animate={{ opacity: 1, transform: 'blur(0px)' }} exit={{ opacity: 0, transform: 'blur(10px)' }} transition={{ duration: 0.1 }} > {icon} </motion.div> )} </AnimatePresence> <span className="whitespace-nowrap">{label}</span> </button> ); }; export default CopyTextButton;

Usage

<div className="flex flex-col gap-4 items-center justify-center"> <CopyTextButton label="Copy some text" textToCopy="pAsSwOrD" icon={<Copy className="w-4 h-4" />} /> <CopyTextButton label="Small Variant" textToCopy="pAsSwOrD" icon={<Copy className="w-4 h-4" />} variant="small" /> </div>