/* eslint-disable max-classes-per-file */
import { LionField } from '@lion/form-core';
class LionFieldWithSelect extends LionField {
/**
* @returns {HTMLSelectElement}
*/
get _inputNode() {
return /** @type {HTMLSelectElement} */ (Array.from(this.children).find(
el => el.slot === 'input',
));
}
}
/**
* LionSelectNative: wraps the native HTML element select
*
*
*
*
*
*
* You can preselect an option by setting the property modelValue.
* Example:
*
*
* It extends LionField so it inherits required and disabled.
*
* The option element needs to be a direct child of the select element.
*
* You cannot use interactive elements inside the options. Avoid very long names to
* facilitate the understandability and perceivability for screen reader users. Sets of options
* where each option name starts with the same word or phrase can also significantly degrade
* usability for keyboard and screen reader users.
*
* @customElement lion-select
*/
export class LionSelect extends LionFieldWithSelect {
connectedCallback() {
super.connectedCallback();
this._inputNode.addEventListener('change', this._proxyChangeEvent);
}
// FIXME: For some reason we have to override this FormatMixin getter/setter pair for the tests to pass
get value() {
return (this._inputNode && this._inputNode.value) || this.__value || '';
}
// We don't delegate, because we want to preserve caret position via _setValueAndPreserveCaret
/** @type {string} */
set value(value) {
// if not yet connected to dom can't change the value
if (this._inputNode) {
this._inputNode.value = value;
/** @type {string | undefined} */
this.__value = undefined;
} else {
this.__value = value;
}
}
/** @param {import('lit-element').PropertyValues } changedProperties */
updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('disabled')) {
this._inputNode.disabled = this.disabled;
this.validate();
}
if (changedProperties.has('name')) {
this._inputNode.name = this.name;
}
if (changedProperties.has('autocomplete')) {
this._inputNode.autocomplete = /** @type {string} */ (this.autocomplete);
}
}
disconnectedCallback() {
super.disconnectedCallback();
this._inputNode.removeEventListener('change', this._proxyChangeEvent);
}
_proxyChangeEvent() {
this.dispatchEvent(
new CustomEvent('user-input-changed', {
bubbles: true,
composed: true,
}),
);
}
}