Skip to the page
Tactile UI

Kit part · Buttons

Copy key

A key that copies a value and says so. Its lamp sits dark in the cap; when the text is on the clipboard the lamp lights, winks once, and the legend says Copied before it goes back to Copy. If the browser refuses the clipboard, the text is selected for the keyboard and the lamp lights amber.

Element
<button class="tui-key tui-copy-key" data-copy-value>
Needs
kit.css + kit.mjs
Rules
copy-key.rules.md · 5
Finishes
Aluminium · Graphite · Oak · Walnut · Porcelain · Black · Daylight · Night · Paper · Phosphor · E-paper · AMOLED
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts

Seats open in 11 days. Want one email that morning?

Variants

At rest
Copied · lamp lit, green
Refused · lamp amber, text selected
Small · --sm
git clone tactile
Beside its text
Disabled · nothing to copy

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

Aluminium

PartRestHoverPressingFocusCopiedSelected
Key

Graphite

PartRestHoverPressingFocusCopiedSelected
Key

API

NameKindValuesWhat it does
<button class="tui-key tui-copy-key">elementwith data-copy-value or data-copy-fromThe key. Empty, it is given its lamp and its legend by the script.
data-copy-valueattributethe text itselfThe value to copy.
data-copy-fromattributea selector, such as #cmdAn element that holds the value: an input or textarea by its value, anything else by its text. It is also what is selected if the clipboard refuses.
aria-labelattributeon the keySays what is copied: “Copy install command”. Start it with the visible word.
.tui-copy-key__legendclassinside the keyThe word on the key: Copy, then Copied or Selected for a moment.
.tui-copy-key__statusclassafter the keyA polite status line, added by the script, that says aloud what happened.
tui-copyeventdetail { ok, text }Bubbles from the key once the clipboard has answered; ok is false if the text was only selected.
copyFromKey(key)functiona keyDoes what a press does and resolves to whether the clipboard took the text.
copyKeyView(state, legend) · copyText(attrs, read)functionpureThe legend, lamp and spoken words for each stage; the text a key points at.

Markup

<!-- A value in the key -->
<button class="tui-key tui-copy-key" type="button" data-copy-value="npm install @northwind/cli" aria-label="Copy install command"></button>

<!-- Or the text of an element on the page, which is also what gets selected if the clipboard refuses -->
<code id="cmd">pnpm add @northwind/cli</code>
<button class="tui-key tui-copy-key" type="button" data-copy-from="#cmd" aria-label="Copy the command"></button>

<!-- Dressed by the script; this is what it leaves -->
<button class="tui-key tui-copy-key" type="button" data-copy-value="tok_8c1e" aria-label="Copy token">
  <span class="tui-lamp" aria-hidden="true"></span><span class="tui-copy-key__legend">Copy</span>
</button>
<span class="tui-copy-key__status" role="status"></span>
import { copyFromKey } from '/kit/kit.mjs';

document.addEventListener('tui-copy', (e) => {
  if (!e.detail.ok) hint('Press Ctrl+C or Cmd+C to take the selected text');
});

await copyFromKey(document.querySelector('#token-key'));   // true if the clipboard took it

Needs kit.css and kit.mjs. How to install the kit.

Accessibility

  • It is a native <button> named “Copy install command”, with the visible word first in the name so voice control can say it.
  • The result is said aloud by a polite status line: “Copied”, or “The clipboard said no. The text is selected; copy it with your keyboard.” The lamp and the legend say the same to the eye, so colour is never the only sign.
  • When the clipboard is refused the text is selected where it is, or set in a small labelled field beside the key, and the focus is on it, so the next keystroke can copy it.
  • The legend goes back after 1.6 seconds; the focus stays on the key throughout.
  • The wink is a 360ms change of the lamp, which reduced motion removes; the lamp stays lit for the whole confirmation. On a phone the cap is 44px tall.

How it’s built

It is the kit’s key with the kit’s lamp set in the cap, dark at rest. Nothing is drawn for the copied stage that the lamp does not already know how to draw: a lit lamp, green for done and amber for a question. One listener on the page answers every key that carries data-copy-value. It asks the clipboard first, then tries the old way from a hidden field, and only when both refuse does it select the text for the person to take. The key’s width is held between Copy and Copied so a toolbar does not shift.

Rules

copy-key.rules.mdIn the brain

Copy a command, a token or an address with one press, hear that it worked, and keep working when the clipboard says no.

5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

Key

Every button, and every link that acts like one: a cap on a skirt that drops below the plate when pressed.

Toggle key

One key that latches below the plate and stays there. It is the kit’s own key with one state to keep, down or up, so it is the way to say mute, pin, bold or armed without the weight of a switch. A lamp in the cap may light while it is down.

Input group

One recess that holds a field and everything that belongs to it. Words that are part of the value but are not typed, such as https:// or a currency, are printed on the floor of the well behind an engraved line; a glyph sits at the start; small keys sit at the end to clear the text, copy it, or show a password.

Preset saved.

Toast

A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.