Components / Controls
CopyButton
An icon button that copies a value to the clipboard. It turns into a check for a moment and announces "Copied"; if the clipboard refuses, it shows an error instead and still never throws.
When to useLink to "When to use"
- Values people paste elsewhere: install commands, links, IDs, code blocks.
Use something else when: the copy is one step of a bigger action (copying while sharing a link), or the confirmation needs more than one word: call your own writer and show a Toast.
UsageLink to "Usage"
import { CopyButton } from "@arshad-shah/cynosure";
<CopyButton value="npm i @arshad-shah/cynosure" />
<CopyButton value={() => editor.getValue()} labels={{ copy: "Copy code" }} />In extensions and testsLink to "In extensions and tests"
The clipboard API is not available everywhere (an insecure page, some extension contexts). Pass copy to write another way, for example through an offscreen document:
<CopyButton value={url} copy={(text) => chrome.runtime.sendMessage({ type: "copy", text })} />Whatever copy does, a throw or a rejected promise shows the failed state.
PropsLink to "Props"
| Prop | What it does | Type | Default |
|---|---|---|---|
valueRequired | The text to copy (or a function that returns it when clicked). | string | (() => string) | |
labels | Replace the built-in English text: the button's name before copying, after a copy and after a failure. | Partial<CopyButtonLabels> | |
timeout | Milliseconds before the button goes back to its copy state (default 2000). | number | |
copy | Writes to the clipboard. Defaults to navigator.clipboard.writeText; pass your own for extensions (an offscreen document, chrome.runtime messaging) or tests. A rejection or throw shows the failed state. | ((text: string) => Promise<void> | void) | `navigator |
onCopy | Called after a successful copy, with the text that was copied. | ((text: string) => void) | |
onError | Called when copying fails, with the error. | ((error: unknown) => void) | |
size | Size of the button. Default "md". | Size | "md" |
variant | Fill style of the button. Default "ghost". | ButtonVariant | "ghost" |
tooltipPlacement | Where the label tooltip appears. Default "top". | Placement | "top" |
disabled | The button cannot be pressed. | boolean | |
className | Added to the root element, for layout. | string | |
style | Layout only. | CSSProperties |
Generated from the type definitions in @arshad-shah/cynosure 0.5.0.
Behaviour and accessibilityLink to "Behaviour and accessibility"
| Input | Result |
|---|---|
| Click, tap, Enter, Space | Copies |
- Name: the button is named by
labels.copy; after a copy its name and tooltip becomelabels.copied(orlabels.failed) untiltimeoutpasses. - Announcement: a visually hidden
role="status"exists from the start, and the result is written into it, so screen readers hear it once; copying again is announced again (a LiveRegion). - Colour: the icon takes the success or danger text colour while the result shows; the change is also in the icon shape and the words.
- Never throws: a missing clipboard, a refused permission and a throwing writer all end in the failed state, and
onErrorreceives the error.
TouchLink to "Touch"
The button keeps a 44px hit area on coarse pointers.
ThemingLink to "Theming"
It is an IconButton: restyle it through the Button tokens.
RelatedLink to "Related"
These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.