Copy button
FreeCopies a value and confirms what was copied, with a fallback when the clipboard is blocked.
pnpm dlx shadcn@latest add https://caliperui.site/r/copy-button.jsonWhen to use #
Use it for
- API keys, invite links, IDs and install commands people paste elsewhere.
- You want proof of what landed on the clipboard, not just a tick.
Skip it when
- The value is long prose; let people select it.
- Copying is the main action of the page; use a labelled primary button.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/copy-button.json
Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above. It is built from CopyButton and shortenValue.
import { Copy } from "lucide-react" import { CopyButton } from "@/components/ui/copy-button" export function CopyKey() { return ( <div className="grid w-full max-w-md grid-cols-[minmax(0,1fr)] gap-1.5 pt-10"> <span className="text-[13px] font-medium">Live secret key</span> <div className="flex items-center gap-3 rounded-[12px] bg-sunken py-2 pl-4 pr-2 shadow-sunken"> <span className="min-w-0 flex-1 truncate font-mono text-[13px]">rv_live_8Kq2mZt7XcP1vW9yL3nB4f2a</span> <CopyButton value="rv_live_8Kq2mZt7XcP1vW9yL3nB4f2a" label="Copy live secret key" /> </div> <span className="text-xs text-muted-foreground">Treat it like a password. It can read and write billing data.</span> </div> ); }
API reference #
CopyButton
component
shortenValue
component
No props of its own; it accepts the native props of its root element.
Accessibility #
It is built on native elements and keeps aria-live, aria-hidden and aria-label in step with state. Changes that matter are announced through a live region.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.