build69
build69  /  Components  /  Buttons & Actions  /  CopyButton

CopyButton

v1.0.7Updated 27 Aug 2026

Button that copies a value to the clipboard — a plain string or a sync/async producer resolved at click time. Writes via navigator.clipboard with a hidden-textarea/execCommand fallback, flips to a check icon for a config

Preview

Live · 12 stories
DefaultOpen ↗
Why this is recommendedcopyclipboardbuttonsnippet+3

The default, out-of-the-box CopyButton.

Recommended for+14
  • Copying invoice numbers, tax IDs, account numbers
  • Copy-link / share-URL actions (minted async)
  • Code or API-key snippets in settings pages
Tags+6
copyclipboardbuttonsnippetsharehookdefault
Features+4
  • String or async () => string value (resolved on click)
  • navigator.clipboard with textarea/execCommand fallback
  • Copied state with check icon, configurable timeout
  • Copy / Copied tooltip (hideable) + sr-only live region
  • Controlled or uncontrolled copied state
  • onCopied / onError / onCopiedChange callbacks
  • Full Button tone x emphasis x size inheritance
  • Headless useClipboard hook { copy, copied, error, reset }
  • Reduced-motion safe icon crossfade
Not recommended for−2
  • Generic actions without clipboard semantics (use Button)
  • Copying rich HTML content (plain text only)

Install

Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.

get_registry_item({ name: "CopyButton" })

Usage

import { CopyButton, useClipboard } from '@/components/actions/copy-button';

<CopyButton value="0105561234567" aria-label="Copy tax ID" />
<CopyButton value={async () => (await mintPayLink()).url} tone="primary" emphasis="soft">
  Copy payment link
</CopyButton>

Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.

Props

PropTypeRequired
value

Text to copy, or a sync/async producer of it

string | (() => string | Promise<string>)yes
timeout

How long the copied state persists in ms (default 2000)

number
copied

Controlled copied state

boolean
onCopiedChange

Mirrors internal copied-state changes

(copied: boolean) => void
onCopied

Called with the resolved text on success

(text: string) => void
onError

Called when resolving or writing fails

(error: Error) => void
copyLabel

Idle tooltip / accessible label (default "Copy")

ReactNode
copiedLabel

Copied tooltip / announced label (default "Copied")

ReactNode
showTooltip

Hide the tooltip; live region remains (default true)

boolean
tone

Semantic tone (default neutral)

'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info'
emphasis

Visual loudness (default ghost)

'solid' | 'soft' | 'outline' | 'ghost' | 'link'
size

Button size

'xs' | 'sm' | 'md' | 'lg'

Every tonal component shares the same tone × emphasis API, so the pair looks identical across Button, Badge, Alert and more.

Related