← Overview

copyToClipboard

One press puts a string into the clipboard — and says so, to whoever cannot see the checkmark.

Five copy buttons, one component. What you see is this page's own CSS reacting to a single attribute — data-copy-state — and what you cannot see is the half that matters: a polite live region beside every button, saying in words what the checkmark says in green.

1 — A code snippet

data-copy-target names the <code> element. What lands in the clipboard is its text as it stands on screen — both lines, with the indentation of the second one — because the module reads textContent and not innerText, which would collapse exactly the whitespace a snippet is made of. Only the outer whitespace of the pretty-printed markup is trimmed away.

git clone --depth 1 \
  https://codeberg.org/webARTelier/werkbank.git

2 — A literal string

data-copy-text carries the value itself. This is where anything that is not visible text belongs — a share URL, an href, an order number the template knows. The value is short, so it goes into the announcement too: data-copy-copied-text="Coupon code {text} copied."

Your coupon code: SPRING-2026

3 — A field's value, and a state that stays

Pointed at an <input>, the module copies its value — so edit the field and press again, and what you get is what you typed. data-copy-duration="0" keeps the state until the next press instead of dropping it after two seconds: the checkmark stands, which is the right choice where the reader is meant to carry the value somewhere else and come back.

4 — When it cannot copy

This button points at #aBoxThatIsNotHere. A selector matching nothing yet is a warning and not a bail-out — the box may be filled later by something else, and the source is looked up again on every press. So the control is enhanced and it fails honestly: the state goes to error, the live region says the text can still be selected by hand, and the clipboard keeps whatever was in it. An empty source is never written, because writeText("") would take something away.

There is a second button in this markup that you cannot see, and never will — its target selector is not valid CSS. Read the source and the console.

5 — The message handed to toast

The module says the result; it draws nothing. For a visible message, toast is the component next door, and one listener joins them — copy:copied in, toast:show out. Neither module knows about the other. A toast is a live region of its own, though, so this button opts this module's announcement out with an empty data-copy-copied-text="": otherwise the reader is told twice.

sk_live_4f8b2c1e9d7a

The other way round needs no script at all: data-toast-trigger on the same button. It fires on the press, though, so it reports a copy before the write has settled — fine for a share link, wrong if the failure matters.