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.handleKeyDown = this.handleKeyDown.bind(this)
this.handleClick = this.handleClick.bind(this)
this.handleRadioGroup = this.handleRadioGroup.bind(this)
this.uniqueId
this.options
}
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))
}
}
handleKeyDown(e) {
if (e.code === "Space") {
e.preventDefault()
this.handleClick()
}
}
handleClick() {
if (!this.hasAttribute('checked')) {
this.setAttribute('checked', '')
this.dispatchGroupEvent()
}
}
handleRadioGroup(e) {
if (e.detail.uid !== this.uniqueId) {
this.reset()
}
}
randString(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++)
result += characters.charAt(Math.floor(Math.random() * characters.length));
return result;
}
connectedCallback() {
this.uniqueId = this.randString(8)
this.options = {
bubbles: true,
composed: true,
detail: {
uid: this.uniqueId,
value: this.value,
}
}
if (!this.hasAttribute('disabled')) {
this.setAttribute('tabindex', '0')
}
this.setAttribute('role', 'radio')
if (!this.hasAttribute('checked')) {
this.setAttribute('aria-checked', 'false')
}
this.addEventListener('keydown', this.handleKeyDown)
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('keydown', this.handleKeyDown)
this.removeEventListener('change', this.handleClick)
}
});