Soracom

Design System
  1. Home
  2. Design system
  3. Ux patterns
  4. Copy

Copy

Implementing a 'Copy code' element

Overview

SDS only includes the styling - it is assumed the code for the copy process will be implemented within the project locally (example javascript below).

The copy code options currently work with textarea, input and pre elements

Options

On successful copy

When the content has been successfully copied to the clipboard, you can set a class of ds-button--success on the button. The button will turn green, and the icon will change to a tick.

Setting the attribute data-ds-texttip="Copied!" to the button will also show a texttip indicating copy was successful.

When leaving the button hover state (i.e. onmouseout), the class ds-button--success and the attribute data-ds-texttip must be removed.

Javascript

The following example code implements the copy to clipboard functionality and changes the state of the button to provide user feedback.

  // Copy field to clipboard
  let copyFieldToClipboard = document.querySelectorAll('[class*="--copy"]');

  for (let copyElement of copyFieldToClipboard) {
    // copyFieldToClipboard.forEach((copyElement) => {
    let copyElementSource = copyElement.querySelector("input,textarea,pre");
    let copyElementButton = copyElement.querySelector('[class*="ds-button"]');

    // Copy when clicked
    copyElementButton.addEventListener("click", function () {
      // Make sure there is an element to copy
      if (!copyElementSource) {
        console.log("No element to copy");
        return false;
      }

      // Get the value or text to copy
      let textToCopy =
        "value" in copyElementSource ? copyElementSource.value : copyElementSource.innerText;

      // Copy to the clipboard
      navigator.clipboard.writeText(textToCopy).then(
        function () {
          // Successful, show feedback to the user
          this.classList.add("--success");
          this.dataset.dsTexttip = "Copied!";
        }.bind(this),
        function () {
          // An error occurred
          console.log("An error occurred");
        }
      );
    });

    // Remove success state and notification tip when exiting the button
    copyElementButton.addEventListener("mouseout", function () {
      this.classList.remove("--success", "ds-button --success");
      delete this.dataset.dsTexttip;
    });
  }

Examples

Single line

The following structure is suitable for implementing an single line ‘Copy code’ control.

Input

html
Copy
<div class="ds-field">
  <div class="ds-input --copy">
    <input type="text" value=" curl ‒O http://soracom-files.s3.amazonaws.com/connect_air.sh" readonly="true">
    <button class="ds-button --plain --hide-label --icon-clipboard">
      <span>Copy code</span>
    </button>
  </div>
</div>

Pre

html
Copy
<div class="ds-field">
  <div class="ds-input --copy">
    <pre>curl ‒O http://soracom-files.s3.amazonaws.com/connect_air.sh"></pre>
    <button class="ds-button --plain --hide-label --icon-clipboard">
      <span>Copy code</span>
    </button>
  </div>
</div>
curl ‒O http://soracom-files.s3.amazonaws.com/connect_air.sh">

Multiple line

The following structure is suitable for implementing an multi line ‘Copy code’ control.

Textarea

html
Copy
<div class="ds-field">
  <div class="ds-input --copy">
    <textarea type="text" readonly="true" rows="16">[Dialer Defaults]
Modem = /dev/ttyUSB2
Baud = 460800
Init1 = AT+CFUN=1
Init2 = ATZ
Init3 = AT+CGDCONT=1,"IP","soracom.io"
Phone = *99***1#
Dial Command = ATD
Username = sora
Password = sora</textarea>
    <button class="ds-button --plain --hide-label --icon-clipboard">
      <span>Copy code</span>
    </button>
  </div>
</div>

Pre

html
Copy
<div class="ds-field">
  <div class="ds-input --copy">
    <pre>[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010</pre>
    <button class="ds-button --plain --hide-label --icon-clipboard">
      <span>Copy code</span>
    </button>
  </div>
</div>
[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010

Pre with reveal toggle

html
Copy
<div class="ds-field">
  <div class="ds-input --copy">
    <details class="ds-toggle">
      <summary>
        <span class="ds-tag">Show keys</span>
        <span class="ds-tag --end --bottom">Hide keys</span>
      </summary>
    </details>
    <pre>[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010</pre>
    <pre aria-hidden="true">[Interface]
PrivateKey = ****************
Address = 10.207.114.156/32

[Peer]
PublicKey = ****************
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010</pre>
    <button class="ds-button --plain --hide-label --icon-clipboard">
      <span>Copy code</span>
    </button>
  </div>
</div>
Show keys Hide keys
[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010

Pre with reveal toggle, and QR code

html
Copy
<div class="ds-cols">

  <div class="ds-span">
    <details class="ds-toggle">
      <summary>
        <span class="ds-tag">Show QR code</span>
        <span class="--cover"></span>
      </summary>
    </details>
	  <img width="158" src="https://assets.codepen.io/178836/qr.png" />
  </div>

  <div class="ds-span --expand">
    <div class="ds-field">
      <div class="ds-input --copy">
        <details class="ds-toggle">
          <summary>
            <span class="ds-tag">Show keys</span>
            <span class="ds-tag --end --bottom">Hide keys</span>
          </summary>
        </details>
        <pre>[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010</pre>
      <pre aria-hidden="true">[Interface]
PrivateKey = ****************
Address = 10.207.114.156/32

[Peer]
PublicKey = ****************
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010</pre>
        <button class="ds-button --plain --hide-label --icon-clipboard">
          <span>Copy code</span>
        </button>
      </div>
    </div>
  </div>
</div>
Show QR code
Show keys Hide keys
[Interface]
PrivateKey = r3A8zNOTknwwKjEORrZZ1iU99nVHJggdwTRGF5m+sJ8=
Address = 10.207.114.156/32

[Peer]
PublicKey = woha3spWgVr2luPW/8J0OLlP2Csh7r7qu9Umyh7x4Hg=
AllowedIPs = 100.127.0.0/16
Endpoint = beck.arc.soracom.io:11010