Copy button
Copies a value.
Styles
ghostdefault
secondary
Show label
falsedefault
true
States
rest
hover
fetching
copied
failed
disabled
Usage
When to use it
Rules
6 rules
- Must
- Pass label naming what is copied: label="job ID" gives "Copy job ID". Because a column of bare "Copy" buttons gives a screen reader no way to tell which value each one takes.
- Must
- Pass a function for a secret read on demand; never fetch it on render to fill value. Because a key fetched up front sits in the page for anyone who opens the inspector, and the function pends only when pressed.
- Never
- Show a toast or swap the label to confirm a copy; the button confirms in place. Because the glyph cuts to a check and a status region announces it, so a toast says it twice and a swapped label makes the button jump.
- Never
- Make a copy button the slab by restyling it or wrapping it in a primary Button. Because copying never moves the task on, so it is never the group's one yellow action.
- Should
- Keep it ghost in a row or a code block; make it secondary only when copying is the region's own action. Because an edged button on every row turns a list into a wall of boxes.
- Should
- Set showLabel where the glyph alone could be missed, such as beside a command or in a panel head.
State order
7 states, highest first
- 1
- disabled
- 2
- fetching
- 3
- failed
- 4
- copied
- 5
- focus-visible
- 6
- hover
- 7
- rest
Accessibility
4 checks
- The button is named "Copy" plus label; the visible Copy and Copied words are aria-hidden so the name never changes.
- A status region announces "job ID copied" or how to copy by hand; a second copy clears it for a frame so it is heard again.
- Fetching sets aria-busy and keeps focus; a second press does nothing.
- Failed turns the glyph and word to the failure colour and the warning glyph, so it never rests on colour alone.
Keyboard
2 keys
- Enter
- Copies.
- Space
- Copies on release.
Edge cases
6 edge cases
- Clipboard refused
- The glyph turns to the warning and the region says to select and copy by hand.
- Slow fetch
- The pending mark steps in place of the glyph, and repeat presses are ignored.
- Pressed again while Copied
- Copies again and restarts the timer; the announcement repeats.
- A fetched value
- Writes a ClipboardItem in the same tick as the press, so the user activation holds across the fetch.
- Empty value
- Disable it; there is nothing to copy.
- Reduced motion
- The pending mark stands still; the glyph cuts as it always does.
API
8 props
valuestring | (() => string | Promise<string>)labelstringshowLabelbooleandefaultfalsevariant'ghost' | 'secondary'default'ghost'sizeButton sizedefault'icon-sm' or 'sm'timeoutnumberdefault1600onCopy(value: string) => voidforceState'fetching' | 'copied' | 'failed'
Tokens
11 tokens
--hover- rgb(22 21 18 / 0.04)
--pressed- rgb(22 21 18 / 0.08)
--text-1- #161512
--text-2- #55524a
--fail-text- #b3261e
--line- #e2dfd5
--control-sm- 26px
--icon- 16px
--type-label-sm- 400 12px/16px var(--font-mono)
--focus- #7a5d00
--dur-press- 80ms