Copy a value to the clipboard — an icon button, or a read-only field for API keys, resource ids and webhook URLs.
usr_8Kd2mPqR7xpnpm dlx shadcn@latest add https://matos-ui.com/r/copy-button.jsonimport { CopyButton, CopyField } from '@/components/matos-ui/copy-button'<CopyButton value="usr_8Kd2mPqR7xW3nL5vT" aria-label="Copy user ID" /><CopyButton value={apiKey} label="Copy" /><CopyField value="https://api.example.com/v1/webhooks/9f3c2a" /><CopyField secret value={liveKey} revealChars={4} />The value is masked behind dots with a reveal toggle; the copy button always takes the whole value, revealed or not.
spring.playful — the one tier the system keeps for a small thing
that went right — and reverts on spring.fast after timeout (2s). Both
glyphs share one grid cell, so nothing reflows during the swap.navigator.clipboard.writeText can fail — an
insecure context, a denied permission — so the hook returns false and the
button stays in its resting state rather than flashing "Copied". A
visually-hidden aria-live region announces the real result.CopyField is flush. A 1px border-input and no fill — it mirrors the
input it looks like, so it sits on its substrate rather than floating.hover-lift carries the 1px float and its press-back for every button
here — the DESIGN §3.9 token, not a hand-rolled whileHover.prefers-reduced-motion collapses every swap to a plain opacity
crossfade; the check, the label and the reveal toggle still change, they just
don't scale.| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The string written to the clipboard. |
label | ReactNode | — | Text beside the icon; swaps to "Copied" when active. |
timeout | number | 2000 | How long the copied state shows, in ms. |
onCopy | (value: string) => void | — | Fires after a successful copy. |
size | "sm" | "md" | "lg" | "md" | Size preset. |
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | The full value — copied whole even while masked. |
secret | boolean | false | Mask the value and show a reveal toggle. |
revealChars | number | 4 | Trailing characters left visible while masked. |
timeout | number | 2000 | Copied-state duration, in ms. |
onCopy | (value: string) => void | — | Fires after a successful copy. |
size | "sm" | "md" | "md" | Size preset. |
Install Matos UI
Choose a package manager and copy one command for every component.