Skip to content

Soracom

Design System
Home Design System Ux Patterns 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 

<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>
<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 

<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">
<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>

Multiple line 

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

Textarea 

<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>
<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 

<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
<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>

Pre with reveal toggle 

<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
<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>

Pre with reveal toggle, and QR code 

<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
<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>