class CustomProgressBar extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({mode: 'open'}); shadowRoot.innerHTML = `
0%
`; this._progressElement = shadowRoot.querySelector('.progress'); this._label = shadowRoot.querySelector('.label'); this._bar = shadowRoot.querySelector('.bar'); } static get observedAttributes() { return ['value']; } attributeChangedCallback(name, oldValue, newValue, namespaceURI) { if (name === 'value') { const newPercentage = newValue === null ? 0 : parseInt(newValue); this._progressElement.setAttribute('aria-valuenow', newPercentage); this._label.textContent = newPercentage + '%'; this._bar.style.width = newPercentage + '%'; } } get progress() { return this.getAttribute('value'); } set progress(newValue) { this.setAttribute('value', newValue); } }; customElements.define('custom-progress-bar', CustomProgressBar);