Skip to content

ExpressiveCSS

Browse documentation

Copy to clipboard

Copy text or field values with accessible clipboard feedback.

View as Markdown

Copy text

Add data-copy to a named button. Clicking it copies the attribute's literal text and announces the result in a snackbar.

<button type="button" data-copy="Hello from ExpressiveCSS">Copy greeting</button>

The root bundle installs Copy.Init(). Buttons added later work through the same document listener. AutoInit() and per-element instances are unnecessary. Use HTTPS or localhost and a user click for clipboard access. A denied or unavailable Clipboard API shows the failure message; it does not copy the text.

Copy an element

Use data-copy-for="id" to name a source in the button's document or shadow root. Inputs, textareas and selects supply their current value. Other elements supply trimmed textContent, including text hidden by CSS.

<pre id="install-command">npm install @expressivecss/expressive</pre>
<button type="button" data-copy-for="install-command">Copy install command</button>

data-copy wins if both attributes are present, including an empty string. A missing source does nothing. Disabled buttons and controls with aria-disabled="true" do nothing. Give icon-only buttons an accessible name.

Feedback and translation

The defaults are Copied and Couldn't copy. Change Copy.i18n.copied and Copy.i18n.failed globally, or set data-copy-message and data-copy-error on one button.

<button type="button" data-copy="INV-42"
  data-copy-message="Invoice number copied"
  data-copy-error="Copy failed. Select the invoice number manually.">Copy invoice number</button>

Each attempt replaces the current snackbar so feedback appears at once. After the clipboard promise settles, expressive:copy bubbles from the button and crosses shadow roots. Its detail is { text, copied }. copied is false when clipboard access fails.

document.addEventListener('expressive:copy', (event) => {
  console.log(event.detail.copied, event.detail.text);
});

JavaScript API

import { Copy } from '@expressivecss/expressive/modular';

Copy.i18n.copied = 'Text copied';
Copy.i18n.failed = 'Clipboard unavailable';
Copy.Init();

const button = document.querySelector('[data-copy-for]');
const text = Copy.textFor(button); // string, or null if the source is missing

Copy.Init() installs the click listener. Repeated calls add no duplicate listener. Copy.textFor(button) resolves text without writing the clipboard, showing feedback or checking the button's disabled state. Copy has no init(element), getInstance() or destroy() method.

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow