← Controllers

Sheet 26 Revision 1.7.1

clipboard

Copy text to clipboard with visual feedback.

Live Demo

npm install @11ty/eleventy

Usage

<button data-controller="clipboard"
        data-clipboard-text-value="Text to copy"
        data-action="click->clipboard#copy">
  <span data-clipboard-target="label">Copy</span>
</button>

Targets

Target Purpose
label Text that changes to show feedback

Values

Value Type Default Description
text String — Text to copy
successText String "Copied!" Success message
duration Number 2000 Feedback duration (ms)

Source

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["label"];
  static values = {
    text: String,
    successText: { type: String, default: "Copied!" },
    duration: { type: Number, default: 2000 },
  };

  async copy() {
    const text = this.textValue || this.element.textContent;

    try {
      await navigator.clipboard.writeText(text);
      this.showSuccess();
    } catch (err) {
      console.error("Failed to copy:", err);
    }
  }

  showSuccess() {
    if (this.hasLabelTarget) {
      const originalText = this.labelTarget.textContent;
      this.labelTarget.textContent = this.successTextValue;

      setTimeout(() => {
        this.labelTarget.textContent = originalText;
      }, this.durationValue);
    }
  }
}

Use with Code Blocks

<div class="code-block">
  <div class="code-block-header">
    <span>package.json</span>
    <button data-controller="clipboard"
            data-clipboard-text-value="npm install"
            data-action="click->clipboard#copy">
      <span data-clipboard-target="label">Copy</span>
    </button>
  </div>
  <pre><code>npm install</code></pre>
</div>