const smCopy = document.createElement('template') smCopy.innerHTML = `

`; customElements.define('sm-copy', class extends HTMLElement { constructor() { super() this.attachShadow({ mode: 'open' }).append(smCopy.content.cloneNode(true)) this.copyContent = this.shadowRoot.querySelector('.copy-content') this.copyButton = this.shadowRoot.querySelector('.copy-button') this.copy = this.copy.bind(this) } static get observedAttributes() { return ['value'] } set value(val) { this.setAttribute('value', val) } get value() { return this.getAttribute('value') } fireEvent() { this.dispatchEvent( new CustomEvent('copy', { composed: true, bubbles: true, cancelable: true, }) ) } copy() { navigator.clipboard.writeText(this.copyContent.textContent) .then(res => this.fireEvent()) .catch(err => console.error(err)) } connectedCallback() { this.copyButton.addEventListener('click', this.copy) } attributeChangedCallback(name, oldValue, newValue) { if (name === 'value') { this.copyContent.textContent = newValue } } disconnectedCallback() { this.copyButton.removeEventListener('click', this.copy) } })