{
  "$schema": "https://mian.ro/schema/v2/registry.json",
  "schemaVersion": "2.0.0",
  "generatedAt": "2026-10-02T13:14:06.957Z",
  "id": "copy-button",
  "name": "Copy button",
  "category": "Actions",
  "description": "Copies text to the clipboard and confirms it in place, visually and for screen readers.",
  "tags": [
    "copy",
    "clipboard",
    "copy to clipboard",
    "api key",
    "install command",
    "share link"
  ],
  "requiresJs": true,
  "license": "LicenseRef-MIAN-1.0",
  "composition": {
    "role": null,
    "intents": [
      "copy to clipboard",
      "copy code",
      "copy link",
      "share link"
    ],
    "prominence": null,
    "density": null,
    "worksAfter": [],
    "worksBefore": [],
    "alternatives": [],
    "avoid": null
  },
  "url": "https://mian.ro/components/copy-button",
  "markdownUrl": "https://mian.ro/ai/components/copy-button.md",
  "classes": [
    {
      "name": "mn-copy[data-mn-copy=\"text\"]",
      "description": "Copies the given text."
    },
    {
      "name": "data-mn-copy-target=\"#el\"",
      "description": "Copies an element’s value or text instead."
    },
    {
      "name": "mn-copy-idle · mn-copy-done",
      "description": "Content shown before and after copying."
    },
    {
      "name": "mn-copy-field",
      "description": "A read-only input joined to a copy button."
    }
  ],
  "accessibility": [
    "“Copied to clipboard” is announced in a polite live region (override with data-mn-copied).",
    "Keep a visible label or aria-label on icon-only copy buttons. Emits mn:copy with { text }."
  ],
  "examples": [
    {
      "title": "Copy buttons",
      "description": null,
      "html": "<button class=\"mn-btn mn-btn-outline mn-copy\" type=\"button\" data-mn-copy=\"&lt;link rel=&quot;stylesheet&quot; href=&quot;https://mian.ro/dist/mian.css&quot;&gt;\"><span class=\"mn-copy-idle\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2\"/><path d=\"M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1\"/></svg> Copy</span><span class=\"mn-copy-done\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\"/></svg> Copied</span></button>\n<button class=\"mn-btn mn-btn-ghost mn-btn-icon mn-copy\" type=\"button\" data-mn-copy=\"https://mian.ro\" aria-label=\"Copy link\"><span class=\"mn-copy-idle\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M10 14a4 4 0 0 0 5.7 0l3-3a4 4 0 0 0-5.7-5.7l-1 1\"/><path d=\"M14 10a4 4 0 0 0-5.7 0l-3 3a4 4 0 0 0 5.7 5.7l1-1\"/></svg></span><span class=\"mn-copy-done\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\"/></svg></span></button>"
    },
    {
      "title": "Copy field",
      "description": null,
      "html": "<div class=\"mn-field\" style=\"max-width:26rem\">\n  <label class=\"mn-label\" for=\"key-1\">API key</label>\n  <div class=\"mn-copy-field\">\n    <input class=\"mn-input\" id=\"key-1\" readonly value=\"mn_live_4f9c2b7e1d8a\">\n    <button class=\"mn-btn mn-btn-outline mn-copy\" type=\"button\" data-mn-copy-target=\"#key-1\" aria-label=\"Copy API key\"><span class=\"mn-copy-idle\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"12\" height=\"12\" rx=\"2\"/><path d=\"M5 15H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v1\"/></svg></span><span class=\"mn-copy-done\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M20 6 9 17l-5-5\"/></svg></span></button>\n  </div>\n</div>"
    }
  ],
  "css": ".mn-copy .mn-copy-done { display: none; }\n.mn-copy[data-copied] .mn-copy-idle { display: none; }\n.mn-copy[data-copied] .mn-copy-done { display: contents; }\n.mn-copy[data-copied] { color: var(--mn-success-text); }\n.mn-copy-field { display: flex; max-width: 100%; }\n.mn-copy-field > .mn-input { flex: 1; min-width: 0; font-family: var(--mn-font-mono); font-size: calc(var(--mn-text-sm) - 1px); border-start-end-radius: 0; border-end-end-radius: 0; }\n.mn-copy-field > .mn-btn { border-start-start-radius: 0; border-end-start-radius: 0; margin-inline-start: calc(var(--mn-border-w) * -1); }",
  "js": "/* <button class=\"mn-btn mn-copy\" data-mn-copy=\"text\"> or\n   data-mn-copy-target=\"#el\" (copies its value or text). Shows the\n   .mn-copy-done content for a moment, announces it, emits mn:copy. */\ndocument.addEventListener('click', async (e) => {\n  const b = e.target.closest('[data-mn-copy], [data-mn-copy-target]');\n  if (!b) return;\n  let text = b.getAttribute('data-mn-copy') || '';\n  if (!text && b.dataset.mnCopyTarget) { const t = document.querySelector(b.dataset.mnCopyTarget); text = t ? (t.value ?? t.textContent) : ''; }\n  try { await navigator.clipboard.writeText(text); }\n  catch (_) {\n    const ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;opacity:0';\n    document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch (__) {} ta.remove();\n  }\n  b.setAttribute('data-copied', '');\n  announce(b.dataset.mnCopied || 'Copied to clipboard');\n  emit(b, 'copy', { text });\n  clearTimeout(b._mnCopyTimer);\n  b._mnCopyTimer = setTimeout(() => b.removeAttribute('data-copied'), 1600);\n});",
  "install": {
    "css": "https://mian.ro/dist/mian.css",
    "js": "https://mian.ro/dist/mian.js",
    "registryItem": "https://mian.ro/r/copy-button.json"
  }
}
