Skip to content
NewService Map: 30 components for hosts, ports and routes
<UiCopyButton />ReactControlsFree

Copy button

Copy-to-clipboard button whose icon turns into a drawn check as the label rolls to "Copied"; it says so when the browser refuses.

View as Markdown
<UiCopyButton />

Playground

Change a prop and the component re-renders. Props marked remounts set an initial value, so the component starts over.

Loading <UiCopyButton />
Props
labellive
doneLabellive
React
<UiCopyButton
  text="npx shadcn@latest add @lumesec/ui-copy-button"
  label="Copy"
  doneLabel="Copied"
/>

Installation

pnpm dlx shadcn@latest add @lumesec/ui-copy-button
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/ui-copy-button.json

Usage

ui-copy-button-example.tsx
import { UiCopyButton } from "@/components/lumesec/ui-copy-button";

export function Example() {
  return <UiCopyButton text="npx shadcn@latest add @lumesec/ui-copy-button" />;
}

Behaviour

The clipboard icon spins away as a check draws itself in, the label rolls to “Copied”, and a small pop of pixels confirms it. If the browser refuses the copy, it says so instead.

API reference

Props

Also accepts every prop of <button> (React.ComponentProps<"button">), spread onto the root element.

textTypestringDefault""

Text written to the clipboard. Read on each click.

labelTypestringDefault"Copy"

Idle label.

doneLabelTypestringDefault"Copied"

Label shown for 1.8 s after a successful copy.

onCopyType(ok: boolean, text: string) => void

Called after each copy attempt; ok is false when the clipboard write was rejected.

Ref

ref points at the root HTMLButtonElement.

Keyboard

KeysAction
Space / EnterCopy.

Accessibility

  • A native <button>; its accessible name is the visible label.
  • The label is an aria-live="polite" region, so "Copied" or "Couldn’t copy" is announced.
  • The clipboard and check icons are aria-hidden.
  • Reduced motion: the label swaps without rolling and the check pop and pixel sparks are skipped; the icon cross-fade still runs.

Theming

Styled with Tailwind classes on your shadcn theme tokens, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --card, --muted, --border, --foreground, --lumesec-success, --destructive, --lumesec and --lumesec-glint.

Notes

  • Uses navigator.clipboard.writeText, which requires a secure context (HTTPS or localhost). On failure the label reads "Couldn’t copy", built in English.
  • The button carries data-state="done" or data-state="fail" for 1.8 s after a click, data-state="idle" otherwise.
  • The button keeps the width of its longest label, so it does not change size as the label rolls.
  • onCopy replaces the native clipboard copy event handler of the same name.

Was this page helpful?