# Copy button

Copy button is a neobrutalist React component from Cruise UI. Copies a value (account number, code, key) and shows "Copied" or a toast; if the browser blocks it, it shows the text to copy by hand.

Install (with the @cruiseui registry in components.json, see Installation):

```bash
npx shadcn@latest add @cruiseui/cruise-copy-button
```

Import: `import { CruiseCopyButton, cruiseCopyText } from "@/components/cruise/copy-button";`

## When to use

Account numbers, referral codes, API keys, snippets.

## When not to

Copying long documents (offer a download instead).

## Example (React)

```tsx
"use client";

import { CruiseCopyButton } from "@/components/cruise/copy-button";

export default function CopyButtonExample() {
  return (
    <div className="flex flex-col gap-4">
      <p className="flex flex-wrap items-center gap-3">
        <span className="font-(family-name:--font-mono) text-h3">0123456789</span>
        <CruiseCopyButton value="0123456789" label="Copy account number" iconOnly />
      </p>
      <CruiseCopyButton value="OYA-2026-AB12" label="Copy referral code" />
    </div>
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<button type="button" class="brutal btn btn-secondary" data-copy="0123456789" aria-label="Copy account number">Copy</button>
<span class="visually-hidden" aria-live="polite"></span>
<script>
document.querySelectorAll('[data-copy]').forEach((button) => button.addEventListener('click', async () => {
  const live = button.nextElementSibling;
  try { await navigator.clipboard.writeText(button.dataset.copy); live.textContent = 'Copied'; }
  catch { live.textContent = "Copying didn't work."; }
}));
</script>
```

## Props: CruiseCopyButton

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `string` | — | The text to copy. |
| `label?` | `string` | `"Copy"` | Button text, or its accessible name when iconOnly (e.g. "Copy account number"). |
| `copiedLabel?` | `string` | `"Copied"` | — |
| `iconOnly?` | `boolean` | `false` | A 44px square icon button. |
| `toast?` | `string \| boolean` | `false` | Also show a toast (needs a <CruiseToaster /> mounted). |
| `variant?` | `CruiseButtonVariant` | `"secondary"` | — |
| `onCopied?` | `(() => void)` | — | — |
| `className?` | `string` | — | — |

## Accessibility

- Icon-only buttons have an aria-label, e.g. "Copy account number".
- "Copied" (or the failure) is announced in an aria-live region.
- Failure is explained in words, with the value shown to select by hand.
