Copy Button <mv-copy-button>

Bouton de copie avec retour façon compteur kilométrique : l’icône et le libellé défilent vers le haut jusqu’à une coche (ou vers le bas jusqu’à une alerte en cas d’échec) dans des fenêtres fixes, pendant qu’un voile teinté remplit le bouton puis se vide pendant le délai, comme un compte à rebours ; les boutons à icône reçoivent une étiquette d’état.

CatégorieMicro-interactions
TypeWeb Component (<mv-copy-button>)
Statutstable
Keywordscopy, clipboard, roll, odometer, success, feedback, code

When to use

  • A code block, API key or share link needs a copy button with clear success or failure feedback
  • An icon-only copy control in a toolbar or command bar should show a status tag and a timed reset
  • A copied state should visibly count down before the button returns to idle

Avoid when

  • The button toggles an on/off state rather than performing a one-shot copy → use Toggle instead

Installation

node scripts/add.mjs copy-button --out ./src/marvelous

Agent IA avec le serveur MCP de Marvelous UI : install_components({ slugs: ["copy-button"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Fichiers copiés (dépendances comprises) : tokens/tokens.css, core/base.css, core/element.js, core/motion.js, components/copy-button/copy-button.js, components/copy-button/copy-button.css.

Utilisation

Balisage de référence : partez de celui-ci et personnalisez-le avec les attributs, data-* et les variables CSS :

<div style="display:grid;gap:1rem;width:100%;max-width:520px">
  <div style="display:flex;align-items:center;gap:.5rem;padding:.4rem .4rem .4rem .9rem;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-bg-subtle);font:500 .85rem/1 var(--mv-font-mono)">
    <span style="color:var(--mv-fg-subtle)">$</span>
    <code style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">node scripts/add.mjs confetti</code>
    <mv-copy-button value="node scripts/add.mjs confetti" data-variant="ghost" label="Copy command"></mv-copy-button>
  </div>

  <div style="position:relative;border:1px solid var(--mv-border);border-radius:var(--mv-radius-lg);background:var(--mv-surface);overflow:hidden">
    <div style="display:flex;justify-content:space-between;align-items:center;padding:.4rem .5rem .4rem .9rem;border-bottom:1px solid var(--mv-border);font-size:.75rem;color:var(--mv-fg-muted)">
      <span>index.html</span>
      <mv-copy-button target="#mv-copy-demo-code">Copy code</mv-copy-button>
    </div>
    <pre style="margin:0;padding:.85rem 1rem;font:.8rem/1.6 var(--mv-font-mono);overflow:auto"><code id="mv-copy-demo-code">&lt;mv-like count="128"&gt;&lt;/mv-like&gt;
&lt;script type="module" src="like-button.js"&gt;&lt;/script&gt;</code></pre>
  </div>

  <div style="display:flex;flex-wrap:wrap;gap:.6rem;align-items:center">
    <input class="mv-input" id="mv-copy-demo-link" value="https://lumen.studio/invite/7QX2" readonly style="flex:1;min-width:200px">
    <mv-copy-button target="#mv-copy-demo-link" success-label="Link copied">
      <button class="mv-button" data-variant="outline">Copy link</button>
    </mv-copy-button>
    <mv-copy-button target="#mv-copy-demo-introuvable" label="Copy (missing target: error state)"></mv-copy-button>
  </div>
</div>

API

Attributes

NameTypeDefaultDescription
valuestringText to copy.
targetCSS selectorOtherwise: copies the value (field) or the text of the targeted element.
labelstringCopyAccessible name of the icon button.
success-labelstringCopied!Label / bubble / announcement on success.
error-labelstringCopy failedSame, on failure.
timeoutnumber2000Duration of the copied / error state (ms).
disabledbooleanDisables the button.
data-variantghostNo border or background (command bars, code blocks).
data-bubblebottomBubble below the button instead of above.
data-stateidle | copied | errorSet by the component (for styling).

Properties

NameTypeDescription
textstringText that will be copied (read-only).

Methods

NameDescription
copy()Copies and plays the feedback; Promise<boolean>.

Events

NameDescription
mv-copySuccess; detail = { text }.
mv-copy-errorFailure; detail = { error }.

Content structure

NameDescription
(text)Visible label; without text, an icon button with a bubble.
buttonOr your own child <button> (e.g. .mv-button): the icon and cross-fade are injected into it.

CSS classes

NameDescription
mv-copy-button-trigger / -icons / -reel / -slot / -label / -text / -wash / -bubbleGenerated parts (the wash and reel are aria-hidden).

CSS variables

NameDefaultDescription
--mv-copy-button-successvar(--mv-success)Check color.
--mv-copy-button-errorvar(--mv-danger)Error color.
--mv-copy-button-icon-size1.2emIcon size.

Accessibility

A real <button>; the icon button gets an aria-label (“Copy”). The result is announced by a polite role=status region (“Copied!” / “Copy failed”); alternate labels, icons, wash and tag are aria-hidden to avoid duplicates. Clipboard API with an execCommand fallback (insecure contexts); repeated copies restart the timer. Reduced motion: no roll or drain, the state swaps instantly and the tint stays static until reset.

Cette page a été traduite par IA. Signaler un problème de traduction