CopyButton
Copies text to the clipboard and says whether it worked: the copy icon turns away, a check springs in and draws its own stroke (a cross draws and shakes), a tint blooms across the button, and after resetAfter it all settles back.
Icon-only by default; showLabel adds the text, which rolls up to the new word while the button eases to its width. The result is also announced through a polite live region, because an icon swap is silent. Uses the async Clipboard API, and falls back to execCommand('copy') where that is missing — a plain-http page on a LAN address is not a secure context, and there navigator.clipboard is undefined.
Actions · two-way: bind:status · keyboard contract
<script lang="ts">
import { CopyButton } from '@l4st/driftwood';
</script>
| Light | Dark |
|---|---|
![]() |
![]() |
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
value required |
string | (() => string | Promise<string>) |
— | The text to copy, or a function that returns it at click time. |
label |
string |
'Copy' |
Accessible name, and the visible text with showLabel. |
copiedLabel |
string |
'Copied' |
Shown and announced after a successful copy. |
failedLabel |
string |
'Copy failed' |
Shown and announced when the clipboard refused. |
showLabel |
boolean |
false |
Render the label next to the icon instead of an icon-only button. |
resetAfter |
number |
2000 |
Milliseconds before the icon returns to idle. |
variant |
'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' |
'ghost' |
Same variants as Button. |
size |
'default' | 'sm' | 'lg' | 'icon' |
— | Same sizes as Button. Defaults to icon, or sm with showLabel. |
status bind: |
CopyStatus |
'idle' |
The current state, readable with bind:status. |
onCopy |
(text: string) => void |
— | Fires with the copied text after a successful copy. |
onError |
(error: unknown) => void |
— | Fires when the copy failed (permission denied, no clipboard, a throwing value). |
class |
string |
— | Merged with the component's own classes, last — so yours win. |
Everything not listed above is spread onto the underlying element (HTMLButtonAttributes): aria-*, data-*, event handlers, and the rest of the native attributes.
Types
export type CopyStatus = 'idle' | 'copied' | 'failed';
Keyboard
| Key | Does |
|---|---|
| Enter / Space | copy |
Example
The markup behind the screenshot above, lifted from src/routes/shots/ — so it
compiles, and it is exactly what produced the image.
<CopyButton value="nas-01.local" label="Copy hostname" />
<CopyButton value="nas-01.local" label="Copy hostname" status="copied" />
<CopyButton value="nas-01.local" label="Copy hostname" status="failed" />
<CopyButton value="nas-01.local" variant="outline" showLabel />
<CopyButton value="nas-01.local" variant="outline" showLabel status="copied" />
Notes
- Insecure contexts.
navigator.clipboardonly exists on https and localhost. On a plain-http LAN address the button falls back todocument.execCommand('copy'), which still works from a click. - Async
value. A function returning a promise is awaited before the write. Safari ties clipboard access to the click, so a slow promise can be refused there and the button shows the failed state. Pass a string when you have one. - Name and status are separate. The accessible name stays
labelthe whole time; "Copied" / "Copy failed" go to a polite live region next to the button. Read the state withbind:statusordata-status. - It is
type="button", so it never submits the form it sits in.
Actions · Button · ButtonGroup · Toggle · Menu · ContextMenu
driftwood
Layout
Actions
Forms
- Field
- Input
- FileInput
- FileList
- Textarea
- CodeEditor
- Combobox
- RadioGroup
- NumberInput
- InlineEdit
- Label
- Select
- MultiSelect
- DatePicker
- TagsInput
- Checkbox
- Switch
- Slider
Feedback
Charts
Overlays
Navigation
Generated from the source by pnpm wiki · repository · v0.24.0

