Copy Button
spell-ui/copy-buttonFreeComponent
A copy-to-clipboard button with blur transition effect.
Live preview
live · rendered by the registry
Rendered by spell-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://spell.sh/r/copy-button.jsonSource
1"use client";23import * as React from "react";4import { CheckIcon, CopyIcon } from "lucide-react";5import { cn } from "@/lib/utils";67type SizeVariant = "sm" | "default" | "lg";89interface CopyButtonProps10 extends React.ButtonHTMLAttributes<HTMLButtonElement> {11 value?: string;12 size?: SizeVariant;13}1415const sizeMap: Record<SizeVariant, { button: string; icon: number }> = {16 sm: { button: "h-8 w-8", icon: 14 },17 default: { button: "h-9 w-9", icon: 16 },18 lg: { button: "h-12 w-12", icon: 20 },19};2021const CopyButton = React.forwardRef<HTMLButtonElement, CopyButtonProps>(22 (23 {24 value,25 size = "default",26 className,27 onClick,28 ...props29 },30 ref,31 ) => {32 const [copied, setCopied] = React.useState<boolean>(false);3334 const handleCopy = (event: React.MouseEvent<HTMLButtonElement>) => {35 if (value) {36 navigator.clipboard.writeText(value).catch(() => {});37 }38 setCopied(true);39 setTimeout(() => setCopied(false), 1500);40 onClick?.(event);41 };4243 const { button: buttonSize, icon: iconSize } = sizeMap[size];4445 return (46 <button47 ref={ref}48 type="button"49 onClick={handleCopy}50 aria-label={copied ? "Copied" : "Copy to clipboard"}51 disabled={copied}52 className={cn(53 "relative cursor-pointer active:scale-[0.97] transition-all ease-out duration-200 inline-flex items-center justify-center rounded-md text-neutral-900 disabled:pointer-events-none disabled:opacity-100 dark:text-neutral-50",54 buttonSize,55 className,56 )}57 {...props}58 >59 <div60 className={cn(61 "transition-all duration-200",62 copied63 ? "scale-100 opacity-100 blur-none"64 : "scale-70 opacity-0 blur-[2px]",65 )}66 >67 <CheckIcon68 size={iconSize}69 strokeWidth={2}70 aria-hidden="true"71 />72 </div>73 <div74 className={cn(75 "absolute transition-all duration-200",76 copied77 ? "scale-0 opacity-0 blur-[2px]"78 : "scale-100 opacity-100 blur-none",79 )}80 >81 <CopyIcon size={iconSize} strokeWidth={2} aria-hidden="true" />82 </div>83 </button>84 );85 },86);8788CopyButton.displayName = "CopyButton";8990export { CopyButton };91export type { CopyButtonProps };
What it pulls in
npm packages
Files it writes
More from spell-ui
All 33 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Checkboxanimated-checkbox | spell-ui | Components | Free | 1 dep | |
| Animated Gradientanimated-gradient | spell-ui | Components | Free | no deps | |
| Badgebadge | spell-ui | Components | Free | 2 deps | |
| Bars Spinnerbars-spinner | spell-ui | Components | Free | no deps | |
| Blur Revealblur-reveal | spell-ui | Components | Free | 1 dep | |
| Chartchart | spell-ui | Components | Free | no deps | |
| Color Selectorcolor-selector | spell-ui | Components | Free | no deps | |
| Exploding Inputexploding-input | spell-ui | Components | Free | no deps |
