Copy button

Copy a value with immediate confirmation.

pnpm dlx shadcn@latest add @uiarc/copy-button
Live · keyboard ready
  • Next to API keys, install commands, links, or code snippets.
  • Icon-only copy controls in dense rows, with an accessible label.
  • Any copy action that should confirm Copied or Could not copy in place.
  • Use split-button when copying has alternatives, such as Copy link and Copy as Markdown.
  • Use code-block for full code samples, which include their own copy control.

Installation

Add Copy button with the shadcn CLI, or copy the source by hand.

pnpm dlx shadcn@latest add @uiarc/copy-button

Adds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:

example.tsx
import { CopyButton } from "@/registry/components/copy-button/copy-button"; export function ApiKeyRow({ apiKey }: { apiKey: string }) {  return (    <div className="row">      <code>{apiKey}</code>      <CopyButton value={apiKey} label="Copy key" iconOnly />    </div>  );}

CopyButton

Copies a string to the clipboard and morphs its icon and label to Copied or Failed.

PropTypeDefaultDescription
valueRequiredstring–The text to copy.
labelstring"Copy"Idle label and accessible name.
iconOnlybooleanfalseHides the text and shows only the icon.
variant"outline" | "plain""outline"Bordered or borderless.
disabledboolean–Disables the button.
onCopied() => void–Called after a successful copy.
classNamestring–Extra class on the button.
EnterorSpace
Copies the value.
  • Native button named by label, including when iconOnly.
  • A polite role="status" region announces "<label>: Copied" or "<label>: Could not copy".
  • The label cell reserves the widest of its three states, so the layout never shifts.
  • Icons trade places through a blur on a slow, nearly critically damped spring, and the check draws its stroke in.
  • Only the changed letters of the label move; the same motion plays in reverse on reset.
  • Reduced motion swaps icon and text with an instant fade and skips the stroke draw.
  • The label reserves the width of its widest state, so the button never shifts its neighbours when it changes.
  • It sizes to max-content with max-width 100%, so it stays compact in narrow rows.
  • Only changed letters animate; the icon swap and stroke draw are a single short spring per copy.
  • Clipboard access is async and needs a secure context; failures show the Failed state rather than throwing.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use next to any copyable value: API keys, install commands, links, code. For a copy action that also has alternatives use split-button.
  • Named export only; there is no default export.
  • Clipboard state and reset timing come from lib/use-copy-feedback, so copy that file along with the component.

The full library index for assistants is at /llms.txt.