Actions

Copy button for clipboard actions

Copy button copies any string to the clipboard and transitions from an idle clipboard icon to a copied checkmark, then resets after a configurable timeout. It ships icon-only and labeled layouts, an optional animated icon swap, an onCopy callback, and the full Zentauri appearance and size system.

npm install @zentauri-ui/zentauri-components

Examples

Copy button copies any string to the clipboard and transitions through idle and copied states. Pair it with code blocks, tokens, share links, and CLI snippets.


Nothing copied yet.



Copy button variants examples

Use Show output / Show code on each row. Snippets start with a Variant line naming the axis and token.


Appearance: DEFAULT | Size: MD


Appearance: SECONDARY | Size: MD


Appearance: DESTRUCTIVE | Size: MD


Appearance: OUTLINE | Size: MD


Appearance: GHOST | Size: MD


Appearance: GLASS | Size: MD


Appearance: EMERALD | Size: MD


Appearance: INDIGO | Size: MD


Appearance: PURPLE | Size: MD


Appearance: PINK | Size: MD


Appearance: ROSE | Size: MD


Appearance: SKY | Size: MD


Appearance: TEAL | Size: MD


Appearance: YELLOW | Size: MD


Appearance: ORANGE | Size: MD


Appearance: GRAY | Size: MD


Appearance: AMBER | Size: MD


Appearance: VIOLET | Size: MD


Appearance: GRADIENT-BLUE | Size: MD


Appearance: GRADIENT-GREEN | Size: MD


Appearance: GRADIENT-RED | Size: MD


Appearance: GRADIENT-YELLOW | Size: MD


Appearance: GRADIENT-PURPLE | Size: MD


Appearance: GRADIENT-TEAL | Size: MD


Appearance: GRADIENT-INDIGO | Size: MD


Appearance: GRADIENT-PINK | Size: MD


Appearance: GRADIENT-ORANGE | Size: MD


Appearance: DEFAULT | Size: SM


Appearance: DEFAULT | Size: MD


Appearance: DEFAULT | Size: LG


Motion: ANIMATED ICON SWAP

CSS variable overrides

Copy button CSS variables

Override these copy-button variables on :root, a theme selector, or a component wrapper. Structural variables drive the radius, focus ring, and ring offset; each appearance sets background, foreground, border, shadow, and hover tokens.

207 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-copy-button-radius: 0.75rem;
  --zui-copy-button-ring-offset: #f8fafc;
  --zui-copy-button-focus-ring: #475569;
  --zui-copy-button-default-bg: #0f172a;
  --zui-copy-button-default-fg: #f8fafc;
  --zui-copy-button-default-shadow: 0 1px 2px #0f172a14;
  --zui-copy-button-default-bg-hover: #000000;
  --zui-copy-button-secondary-bg: #e2e8f0;
  --zui-copy-button-secondary-fg: #0f172a;
  --zui-copy-button-secondary-bg-hover: #cbd5e1;
  --zui-copy-button-destructive-bg: #f43f5e;
  --zui-copy-button-destructive-fg: #ffffff;
  --zui-copy-button-destructive-bg-hover: #f43f5e;
  --zui-copy-button-outline-border: #0000001a;
  --zui-copy-button-outline-bg: #0000000d;
  --zui-copy-button-outline-fg: #0f172a;
  --zui-copy-button-outline-bg-hover: #0000001a;
  --zui-copy-button-ghost-fg: #334155;
  --zui-copy-button-ghost-bg-hover: #0000000d;
  --zui-copy-button-glass-border: #00000026;
  --zui-copy-button-glass-bg: #0000001a;
  --zui-copy-button-glass-fg: #0f172a;
  --zui-copy-button-glass-bg-hover: #00000026;
  --zui-copy-button-emerald-bg: #10b981;
  --zui-copy-button-emerald-fg: #ffffff;
  --zui-copy-button-emerald-bg-hover: #10b981;
  --zui-copy-button-indigo-bg: #3730a3;
  --zui-copy-button-indigo-fg: #ffffff;
  --zui-copy-button-indigo-bg-hover: #3730a3;
  --zui-copy-button-purple-bg: #6b21a8;
  --zui-copy-button-purple-fg: #ffffff;
  --zui-copy-button-purple-bg-hover: #6b21a8;
  --zui-copy-button-pink-bg: #9d174d;
  --zui-copy-button-pink-fg: #ffffff;
  --zui-copy-button-pink-bg-hover: #9d174d;
  --zui-copy-button-rose-bg: #9f1239;
  --zui-copy-button-rose-fg: #ffffff;
  --zui-copy-button-rose-bg-hover: #9f1239;
  --zui-copy-button-sky-bg: #0ea5e9;
  --zui-copy-button-sky-fg: #ffffff;
  --zui-copy-button-sky-bg-hover: #0ea5e9;
  --zui-copy-button-teal-bg: #14b8a6;
  --zui-copy-button-teal-fg: #ffffff;
  --zui-copy-button-teal-bg-hover: #14b8a6;
  --zui-copy-button-yellow-bg: #eab308;
  --zui-copy-button-yellow-fg: #ffffff;
  --zui-copy-button-yellow-bg-hover: #eab308;
  --zui-copy-button-orange-bg: #f97316;
  --zui-copy-button-orange-fg: #ffffff;
  --zui-copy-button-orange-bg-hover: #f97316;
  --zui-copy-button-gray-bg: #6b7280;
  --zui-copy-button-gray-fg: #ffffff;
  --zui-copy-button-gray-bg-hover: #6b7280;
  --zui-copy-button-amber-bg: #f59e0b;
  --zui-copy-button-amber-fg: #ffffff;
  --zui-copy-button-amber-bg-hover: #f59e0b;
  --zui-copy-button-violet-bg: #5b21b6;
  --zui-copy-button-violet-fg: #ffffff;
  --zui-copy-button-violet-bg-hover: #5b21b6;
  --zui-copy-button-gradient-blue-from: #1e40af;
  --zui-copy-button-gradient-blue-to: #6b21a8;
  --zui-copy-button-gradient-blue-fg: #ffffff;
  --zui-copy-button-gradient-blue-from-hover: #1e40af;
  --zui-copy-button-gradient-blue-to-hover: #6b21a8;
  --zui-copy-button-gradient-green-from: #166534;
  --zui-copy-button-gradient-green-to: #3f6212;
  --zui-copy-button-gradient-green-fg: #ffffff;
  --zui-copy-button-gradient-green-from-hover: #166534;
  --zui-copy-button-gradient-green-to-hover: #3f6212;
  --zui-copy-button-gradient-red-from: #991b1b;
  --zui-copy-button-gradient-red-to: #9d174d;
  --zui-copy-button-gradient-red-fg: #ffffff;
  --zui-copy-button-gradient-red-from-hover: #991b1b;
  --zui-copy-button-gradient-red-to-hover: #9d174d;
  --zui-copy-button-gradient-yellow-from: #854d0e;
  --zui-copy-button-gradient-yellow-to: #9a3412;
  --zui-copy-button-gradient-yellow-fg: #ffffff;
  --zui-copy-button-gradient-yellow-from-hover: #854d0e;
  --zui-copy-button-gradient-yellow-to-hover: #9a3412;
  --zui-copy-button-gradient-purple-from: #6b21a8;
  --zui-copy-button-gradient-purple-to: #9d174d;
  --zui-copy-button-gradient-purple-fg: #ffffff;
  --zui-copy-button-gradient-purple-from-hover: #6b21a8;
  --zui-copy-button-gradient-purple-to-hover: #9d174d;
  --zui-copy-button-gradient-teal-from: #115e59;
  --zui-copy-button-gradient-teal-to: #155e75;
  --zui-copy-button-gradient-teal-fg: #ffffff;
  --zui-copy-button-gradient-teal-from-hover: #115e59;
  --zui-copy-button-gradient-teal-to-hover: #155e75;
  --zui-copy-button-gradient-indigo-from: #3730a3;
  --zui-copy-button-gradient-indigo-to: #6b21a8;
  --zui-copy-button-gradient-indigo-fg: #ffffff;
  --zui-copy-button-gradient-indigo-from-hover: #3730a3;
  --zui-copy-button-gradient-indigo-to-hover: #6b21a8;
  --zui-copy-button-gradient-pink-from: #9d174d;
  --zui-copy-button-gradient-pink-to: #9f1239;
  --zui-copy-button-gradient-pink-fg: #ffffff;
  --zui-copy-button-gradient-pink-from-hover: #9d174d;
  --zui-copy-button-gradient-pink-to-hover: #9f1239;
  --zui-copy-button-gradient-orange-from: #9a3412;
  --zui-copy-button-gradient-orange-to: #991b1b;
  --zui-copy-button-gradient-orange-fg: #ffffff;
  --zui-copy-button-gradient-orange-from-hover: #9a3412;
  --zui-copy-button-gradient-orange-to-hover: #991b1b;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-copy-button-ring-offset-dark: #020617;
  --zui-copy-button-focus-ring-dark: #cbd5e1;
  /* ...same variables with -dark at the end */
}

What it does

Copy button wraps the clipboard write in a single accessible control with built-in idle and copied states. It uses the library's useClipboard hook, so the copied flag is managed for you and resets on the timeout you choose.

The static entry swaps the icon instantly, while the animated entry transitions the clipboard and checkmark icons through a spring scale and rotation.

Composition and API

Import CopyButton from the copy-button entrypoint, or CopyButtonAnimated from copy-button/animated for the motion variant. Set value with the text to copy, and tune the control with timeout, iconOnly, label, copiedLabel, copyIcon, copiedIcon, onCopy, appearance, and size.

Common use cases

Reach for Copy button anywhere a user benefits from one-click copying: install commands and code samples in docs, API keys and tokens in dashboards, share links, invoice or order IDs in tables, and onboarding steps that surface copyable values.

Accessibility

The control renders a real button with an aria-label that reflects the current state, and a visually hidden live region announces the copied label to assistive technology. Provide your own aria-label when the surrounding context already names the value.

Next.js integration notes

Copy button is a client component because it reads navigator.clipboard in the browser. Render it inside client components or interactive islands; the clipboard write is a no-op during SSR and resolves only once the component is hydrated.

FAQ

How long does the copied state last?

It resets after the timeout prop in milliseconds (2000 by default). Pass timeout={0} to keep the copied state until the button is pressed again.

Can I show a text label instead of just an icon?

Yes. Pass iconOnly={false} to render the label and copiedLabel text next to the icon. The icon-only layout still exposes an accessible label.

How do I react to a successful copy?

Pass an onCopy callback. It receives the copied value after the clipboard write resolves, so you can toast, log analytics, or update local state.