let tmpl = document.createElement('template');
tmpl.innerHTML = `
  <style>
    button {
      background: white;
      border: none;
      fill: black;
      border-radius: 50%;
      padding: 6px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      outline: none;
    }

    button svg {
      height: 14px;
      width: 14px;
    }
  </style>

  <button>
  <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="copy" class="svg-inline--fa fa-copy fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M320 448v40c0 13.255-10.745 24-24 24H24c-13.255 0-24-10.745-24-24V120c0-13.255 10.745-24 24-24h72v296c0 30.879 25.121 56 56 56h168zm0-344V0H152c-13.255 0-24 10.745-24 24v368c0 13.255 10.745 24 24 24h272c13.255 0 24-10.745 24-24V128H344c-13.2 0-24-10.8-24-24zm120.971-31.029L375.029 7.029A24 24 0 0 0 358.059 0H352v96h96v-6.059a24 24 0 0 0-7.029-16.97z"></path></svg>
  </button>
`;


class CopyButton extends HTMLElement {
  
  constructor() {
    super(); // always call super() first in the constructor.

    // Attach a shadow root to the element.
    let shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(tmpl.content.cloneNode(true));
    
    shadowRoot.querySelector('button').addEventListener('click', () => {
      
      if (this.codeurl) {
        this.getCode();
      }
    });
  }
  
  static get observedAttributes() {
    return ['codeurl'];
  }
  
  get codeurl() {
    return this.hasAttribute('codeurl');
  }

  set codeurl(val) {
    if (val) {
      this.setAttribute('codeurl', val);
    } else {
      this.removeAttribute('codeurl');
    }
  }
  
  async copyCode(data) {
    if (navigator.clipboard) {
        try {
          await navigator.clipboard.writeText(data);
        } catch (err) {
          console.error(err);
        }
      }
      else {
        const clipScript = document.createElement('script');
        clipScript.src = "https://unpkg.com/clipboard@2/dist/clipboard.min.js";
        this.shadowRoot.appendChild(clipScript);
        
        clipScript.addEventListener('load', () => {
          let realClip = new ClipboardJS(this.shadowRoot.querySelector('button'));

          realClip.on("success", e => {
            e.clearSelection();
          });

          realClip.on("error", e => {
            console.error("Trigger:", e.trigger);
          });
        })
        
      }
  }
  
  async getCode() {
    const codeURL = this.getAttribute('codeurl');
    
    if (codeURL) {
      const response = await fetch(codeURL);
      const data = await response.text();
      
      
      this.shadowRoot.querySelector('button').setAttribute('data-clipboard-text', data);
      
      setTimeout(() => {
        this.copyCode(data);
      }, 500)
      
    }
  }
}

window.customElements.define('copy-button', CopyButton);
@@ -383,16 +383,140 @@
 x;%0A    %7D
+%0A%0A    .copied %7B%0A      padding-left: 1em;%0A      padding-right: 1em;%0A      border-radius: 14px;%0A      font-weight: bold;%0A    %7D
 %0A  %3C/sty
@@ -531,16 +531,18 @@
 button%3E%0A
+  
   %3Csvg a
@@ -2951,24 +2951,170 @@
 yCode(data);
+%0A%0A        this.shadowRoot.querySelector('button').classList.add('copied');%0A        this.shadowRoot.querySelector('button').textContent = %22Copied!%22
 %0A      %7D, 50

improve copying UX