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.
Every copy button on this page is hidden — and that
is the component working, not failing. This page is on
, which is not a
secure context, so navigator.clipboard does not
exist here and the module left all six controls with the
hidden attribute they were authored with. The snippets,
the field and the coupon code are all still readable and selectable,
which is the whole point. Open the page via
http://localhost or http://127.0.0.1 — or
over https — to try the buttons.
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.