const smRadio = document.createElement('template') smRadio.innerHTML = `
` window.customElements.define('sm-radio', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }).append(smRadio.content.cloneNode(true)) this.radio = this.shadowRoot.querySelector('.radio'); this.reset = this.reset.bind(this) this.dispatchChangeEvent = this.dispatchChangeEvent.bind(this) this.dispatchGroupEvent = this.dispatchGroupEvent.bind(this) this.handleKeyup = this.handleKeyup.bind(this) this.handleClick = this.handleClick.bind(this) this.handleRadioGroup = this.handleRadioGroup.bind(this) this.options = { bubbles: true, composed: true, detail: { value: this.value, } } } static get observedAttributes() { return ['value', 'disabled', 'checked'] } get disabled() { return this.hasAttribute('disabled') } set disabled(val) { if (val) { this.setAttribute('disabled', '') } else { this.removeAttribute('disabled') } } get checked() { return this.hasAttribute('checked') } set checked(value) { if (value) { this.setAttribute('checked', '') } else { this.removeAttribute('checked') } } set value(val) { this.setAttribute('value', val) } get value() { return this.getAttribute('value') } reset() { this.removeAttribute('checked') } dispatchChangeEvent() { this.dispatchEvent(new CustomEvent('change', this.options)) } dispatchGroupEvent() { if (this.hasAttribute('name') && this.getAttribute('name').trim() !== '') { this.dispatchEvent(new CustomEvent(`changed${this.getAttribute('name')}`, this.options)) } } handleKeyup(e){ if (e.code === "Space") { this.handleClick() } } handleClick() { if (!this.hasAttribute('checked')) { this.setAttribute('checked', '') this.dispatchGroupEvent() } } handleRadioGroup(e) { if (e.detail.value !== this.getAttribute('value')) { this.reset() } } connectedCallback() { if (!this.hasAttribute('disabled')) { this.setAttribute('tabindex', '0') } this.setAttribute('role', 'radio') if (!this.hasAttribute('checked')) { this.setAttribute('aria-checked', 'false') } this.addEventListener('keyup', this.handleKeyup) this.addEventListener('click', this.handleClick) if (this.hasAttribute('name') && this.getAttribute('name').trim() !== '') { document.addEventListener(`changed${this.getAttribute('name')}`, this.handleRadioGroup) } } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { if (name === 'checked') { this.dispatchChangeEvent() } else if (name === 'disabled') { if (this.hasAttribute('disabled')) { this.removeAttribute('tabindex') } else { this.setAttribute('tabindex', '0') } } } } disconnectedCallback() { this.removeEventListener('keyup', this.handleKeyup) this.removeEventListener('change', this.handleClick) } });