Avara UI

Copy Button

A button that puts text on the clipboard and says so — the icon pops from a clipboard to a check, the label rises from "Copy" to "Copied!", and both settle back after a moment.
It ships in three pieces: CopyButton for any surface (toolbars, code blocks, cards), CopyField for the classic read-only input with a copy button beside or inside it, and the useCopyToClipboard hook when you want the behaviour with your own markup. The write uses the async Clipboard API and falls back to a hidden textarea where that is unavailable, and a failed write shows a brief "Failed" state instead of lying about success.
Explore the different variations of the Copy Button — each example shows a live preview with the exact code to copy. Click a button to see it confirm.

Copy Button

Click it — the icon pops to a check and the label swaps to Copied! for two seconds.

value
is the text written to the clipboard.
label
is the resting text and copiedLabel the confirmation — Copy and Copied! by default.

Installation

New project? Follow the installation guide to set up Tailwind CSS, shadcn, the cn helper and lucide-react, register the @algorize-ui registry once, then copy your styles from the Themes page.

Install Copy Button

npx shadcn@latest add @algorize-ui/copy-button

components/custom/blocks/CopyButtonBlock.tsx is written into your project. Copy any snippet from a Usage tab above and it runs.

Install dependencies

Nothing beyond the shared setup — Copy Button needs only the cn helper and lucide-react, which the installation guide already put in place.

Examples

Variants

variant
is "solid" (default), "soft", "outline" or "ghost". Every variant flashes the theme colour on success so the confirmation reads even on a quiet button.

Sizes

size
is "sm", "md" (default) or "lg" — height, padding and icon scale together.

Icon only

SeticonOnly
for a square button with no label — for toolbars and table rows. It keeps an accessible name that flips to Copied after a successful write.

Copy field

The share-link pattern: a read-only input with the button beside it.

UseCopyField
to render the value in a read-only input with a CopyButton next to it. Clicking the input selects everything; buttonProps forwards labels, variant and timeout to the button.

Inset button

Setinset
on CopyField to tuck an icon-only ghost button inside the field's right edge; prefix adds an icon on the left.

In a code block

Combinevariant="ghost"
with a className to blend the button into any toolbar — here a terminal header that follows the light and dark theme.

Custom labels & timing

timeout
is how long the copied state lingers in milliseconds (default 2000). onCopy fires with the value and whether the write succeeded.

The hook on its own

useCopyToClipboard(timeout?), exported from copy-button-hooks.ts (installed beside the block), returns { copy, status, copied }. copy(text) resolves to a boolean, and status is "idle" | "copied" | "error", resetting itself after timeout ms — everything the button does, for your own markup.

Features

Discover the Copy Button's capabilities for confirming a clipboard write without a toast.

Inline confirmation

The feedback lives in the button itself — a popping check and a rising label — so nothing else on the page has to move.

Honest states

A blocked clipboard shows Failed rather than a false success, and onCopy tells you which it was.

Works everywhere

Uses the async Clipboard API and falls back to a hidden textarea on older browsers and non-secure origins.

Accessible

A polite live region announces the change; icon-only buttons carry a name that updates to Copied.

Best Practices & Guidelines

Say what was copied

Prefer specific labels — Copy Link, Code copied — over a bare Copy when more than one thing on the screen could be copied.

Don't close the surface on copy

Let the confirmation play before dismissing a dialog or popover — closing on click hides the only feedback the user gets.

Props Reference

<CopyButton> Props

PropTypeDefaultDescription
valuestringRequiredThe text written to the clipboard.
labelReactNode"Copy"Resting label.
copiedLabelReactNode"Copied!"Label shown after a successful write.
errorLabelReactNode"Failed"Label shown when the clipboard write is refused.
iconOnlybooleanfalseHide the label and render a square icon button with an accessible name.
timeoutnumber2000How long the copied / failed state lingers, in ms.
variant"solid" | "soft" | "outline" | "ghost""solid"Visual style.
size"sm" | "md" | "lg""md"Height, padding and icon size.
color"primary" | "indigo" | "rose" | "emerald" | "zinc" | string"primary"Theme colour for the solid / soft fills, the success flash and the focus ring. Accepts hex codes.
onCopy(value: string, ok: boolean) => void—Fires after the write with the value and whether it succeeded.
Every other <button> attribute (className, disabled, onClick…) is forwarded. Calling preventDefault() in your own onClick cancels the copy.

<CopyField> Props

PropTypeDefaultDescription
valuestringRequiredShown in the read-only input and copied by the button.
labelstring—Bold label above the field.
buttonPropsOmit<CopyButtonProps, "value">—Forwarded to the embedded button — labels, variant, timeout, onCopy…
insetbooleanfalseRender an icon-only ghost button inside the field's right edge instead of a full button beside it.
prefixReactNode—Icon or adornment on the field's left side.
selectOnClickbooleantrueSelect the whole value when the input is clicked.
size"sm" | "md" | "lg""md"Field and button height.
colorstring"primary"Theme colour shared by the button and the field's focus ring.