helpers/control-state.js

64 lines
1.8 KiB
JavaScript
Raw Normal View History

2022-03-11 23:42:26 +01:00
/**
@license
Copyright (c) 2022 trading_peter
This program is available under Apache License Version 2.0
*/
2023-07-27 16:40:07 +02:00
export const ControlState = function (superClass) {
2022-03-11 23:42:26 +01:00
return class extends superClass {
static get properties() {
return {
focused: { type: Boolean, reflect: true },
disabled: { type: Boolean, reflect: true },
};
}
constructor() {
super();
this._boundFocus = this._focusHandler.bind(this);
}
firstUpdated() {
super.firstUpdated();
2023-07-27 16:40:07 +02:00
if (!this.hasAttribute('tabindex')) {
this.setAttribute('tabindex', '0');
}
2022-03-11 23:42:26 +01:00
this.addEventListener('focus', this._boundFocus, true);
this.addEventListener('blur', this._boundFocus, true);
}
2023-07-27 16:40:07 +02:00
shouldUpdate(changes) {
if (changes.has('disabled')) {
this._disabledChanged(this.disabled);
}
return super.shouldUpdate(changes);
}
2022-03-11 23:42:26 +01:00
_focusHandler(e) {
this.focused = e.type === 'focus';
}
_disabledChanged(disabled) {
this.setAttribute('aria-disabled', disabled ? 'true' : 'false');
this.style.pointerEvents = disabled ? 'none' : '';
if (disabled) {
// Read the `tabindex` attribute instead of the `tabIndex` property.
// The property returns `-1` if there is no `tabindex` attribute.
// This distinction is important when restoring the value because
// leaving `-1` hides shadow root children from the tab order.
this._prevTabIndex = this.getAttribute('tabindex');
this.focused = false;
2023-07-27 16:40:07 +02:00
this.setAttribute('tabIndex', '-1');
2022-03-11 23:42:26 +01:00
this.blur();
} else if (this._prevTabIndex !== undefined) {
if (this._prevTabIndex === null) {
this.removeAttribute('tabindex');
} else {
this.setAttribute('tabindex', this._prevTabIndex);
}
}
}
};
2023-07-27 16:40:07 +02:00
}