{
    "id": "bhaskar/copy-value-button",
    "kind": "component",
    "title": "Copy Value Button",
    "summary": "Copies text to the clipboard and cross-fades the copy icon into a check with a Copied label, then resets.",
    "author": "Admin",
    "stars": 0,
    "url": "https://ownlyplans.com/bhaskar/copy-value-button/",
    "stack": [],
    "tools": [
        "claude-code",
        "cursor",
        "lovable"
    ],
    "difficulty": "beginner",
    "license": "mit",
    "version": "1.0",
    "overview": "Set the text in data-text. The two icons sit on top of each other and swap with a small scale, and the label change is announced to screen readers.",
    "steps": [],
    "files": [],
    "install": "",
    "how_to_use": "Use the component code (html, css, js, or react) directly, or run the install command.",
    "component": {
        "category": "Buttons",
        "html": "<button class=\"cv\" type=\"button\" data-text=\"pnpm add your-package\"><span class=\"cv__i\"><svg class=\"cv__copy\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\"/><path d=\"M5 15V6a2 2 0 0 1 2-2h9\"/></svg><svg class=\"cv__ok\" viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"m5 12 5 5 9-10\"/></svg></span><span class=\"cv__t\" aria-live=\"polite\">Copy</span></button>",
        "css": ".cv{display:inline-flex;align-items:center;gap:10px;padding:13px 20px;border:1px solid #e5e5e5;border-radius:12px;background:#fff;color:#262626;font:500 16px/1 system-ui,sans-serif;cursor:pointer;box-shadow:0 1px 2px rgba(0,0,0,.06),0 8px 18px rgba(0,0,0,.07);transition:transform .12s ease}\n.cv:active{transform:translateY(1px)}\n.cv:focus-visible{outline:2px solid #1659f5;outline-offset:3px}\n.cv__i{position:relative;width:18px;height:18px}\n.cv svg{position:absolute;inset:0;width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:opacity .22s ease,transform .3s cubic-bezier(.2,.8,.2,1)}\n.cv__ok{opacity:0;transform:scale(.4);stroke:#16a34a}\n.cv.is-done .cv__copy{opacity:0;transform:scale(.4)}\n.cv.is-done .cv__ok{opacity:1;transform:none}\n@media (prefers-reduced-motion:reduce){.cv,.cv svg{transition:none}}",
        "js": "const b=document.querySelector('.cv'),t=b.querySelector('.cv__t');let id;\nb.addEventListener('click',()=>{try{navigator.clipboard.writeText(b.dataset.text).catch(()=>{})}catch(e){}\nb.classList.add('is-done');t.textContent='Copied';clearTimeout(id);id=setTimeout(()=>{b.classList.remove('is-done');t.textContent='Copy'},1600);});",
        "react": "",
        "dependencies": [],
        "install": "",
        "licence_notice": ""
    }
}