Copy Button
jarvis-ui/copy-buttonFreeComponent
A button that copies text to the clipboard with optional feedback.
Live preview
live · rendered by the registry
Rendered by jarvis-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.jarv.is/r/copy-button.jsonSource
1"use client";23import { IconCheck, IconCopy } from "@tabler/icons-react";4import * as React from "react";56import { Button } from "@/components/ui/button";7import { cn } from "@/lib/utils";89type CopyButtonClickEvent = Parameters<10 NonNullable<React.ComponentProps<typeof Button>["onClick"]>11>[0];1213type CopyButtonProps = Omit<React.ComponentProps<typeof Button>, "children" | "value"> & {14 value: string | (() => string);15 showLabel?: boolean;16 copyLabel?: string;17 copiedLabel?: string;18 resetDelay?: number;19 onCopied?: (value: string, event: CopyButtonClickEvent) => void;20 onCopyError?: (error: unknown, event: CopyButtonClickEvent) => void;21};2223function CopyButton({24 value,25 showLabel = false,26 copyLabel = "Copy to clipboard",27 copiedLabel = "Copied",28 resetDelay = 2000,29 variant = "ghost",30 size,31 className,32 disabled,33 onClick,34 onCopied,35 onCopyError,36 ...props37}: CopyButtonProps) {38 const resetTimeoutRef = React.useRef<number | undefined>(undefined);39 const [copied, setCopied] = React.useState(false);40 const buttonSize: React.ComponentProps<typeof Button>["size"] =41 size ?? (showLabel ? "sm" : "icon-sm");4243 React.useEffect(() => {44 return () => window.clearTimeout(resetTimeoutRef.current);45 }, []);4647 const handleClick = React.useCallback(48 async (event: CopyButtonClickEvent) => {49 onClick?.(event);5051 if (event.defaultPrevented || copied || disabled) {52 return;53 }5455 try {56 const textToCopy = typeof value === "function" ? value() : value;5758 await copyTextToClipboard(textToCopy);59 window.clearTimeout(resetTimeoutRef.current);60 setCopied(true);61 resetTimeoutRef.current = window.setTimeout(() => setCopied(false), resetDelay);62 onCopied?.(textToCopy, event);63 } catch (error) {64 setCopied(false);65 onCopyError?.(error, event);66 }67 },68 [copied, disabled, onClick, onCopied, onCopyError, resetDelay, value],69 );7071 return (72 <Button73 type="button"74 variant={variant}75 size={buttonSize}76 disabled={disabled}77 aria-label={copied ? copiedLabel : copyLabel}78 className={cn("shrink-0", copied && "cursor-default", className)}79 onClick={(event) => {80 void handleClick(event);81 }}82 {...props}83 >84 {copied ? (85 <IconCheck aria-hidden="true" data-icon={showLabel ? "inline-start" : undefined} />86 ) : (87// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from jarvis-ui
All 10 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Browser Windowbrowser-window | jarvis-ui | Components | Free | no deps | |
| Cookie Consentcookie-consent | jarvis-ui | Components | Free | no deps | |
| Copyable Fieldcopyable-field | jarvis-ui | Components | Free | no deps | |
| Parallax Cardparallax-card | jarvis-ui | Components | Free | 1 dep | |
| Scroll Areascroll-area | jarvis-ui | Components | Free | 1 dep | |
| Stepperstepper | jarvis-ui | Components | Free | 1 dep | |
| Tipovertipover | jarvis-ui | Components | Free | 1 dep · 2 files | |
| Toasttoast | jarvis-ui | Components | Free | 2 deps |
