customElements.define('share-me', class extends HTMLElement { /** * The class constructor object */ constructor () { // Gives element access to the parent class properties super(); // Get the button this.btn = this.querySelector('button'); if (!this.btn) return; // If API not supported, hide and bail if (!navigator.share) { this.setAttribute('hidden'); return; } // Share settings this.title = this.getAttribute('title'); this.url = this.getAttribute('url'); this.text = this.getAttribute('text'); // Success settings this.originalBtn = this.btn.innerHTML; this.successBtn = this.getAttribute('on-success-btn') ?? 'Shared!'; this.successSR = this.getAttribute('on-success-sr') ?? this.successBtn; // Duration time settings let durationTime = parseFloat(this.getAttribute('success-duration')); this.duration = Number.isNaN(durationTime) ? 5000 : durationTime; // Add an ARIA live region this.notify = document.createElement('div'); this.notify.setAttribute('role', 'status'); this.append(this.notify); // Listen for events this.btn.addEventListener('click', this); } /** * Handle events on the Web Component */ handleEvent () { this.triggerShare(); } /** * Trigger the share card */ async triggerShare () { let { title, url, text } = this; try { // Open the share card await navigator.share({ title, url, text }); // Show success message this.btn.innerHTML = this.successBtn; this.notify.textContent = this.successSR; // Revert to original setTimeout(() => { this.btn.innerHTML = this.originalBtn; this.notify.textContent = ''; }, this.duration); } catch (error) { console.warn('Unable to share.', error); } } });