UNPKG

@3mo/select-field

Version:

A select field web component

77 lines (76 loc) 2.96 kB
export class FieldSelectValueController { get menuValue() { return this._menuValue; } set menuValue(value) { this.preventSync = true; this._menuValue = value; this.select.index = this.index; this.select.value = this.value; this.select.data = this.data; this.select.requestValueUpdate(); this.select.updateComplete.then(() => setTimeout(() => this.preventSync = false, 5)); } constructor(select) { this.select = select; this.preventSync = false; this._menuValue = new Array(); } get selectedOptions() { return this.select.options.filter(o => o.index !== undefined && this.menuValue.includes(o.index)); } get multiple() { return this.select.multiple; } get index() { return this.getSelectValue(this.menuValue); } set index(value) { this._index = value; if (this.preventSync === false) { this.selectionOrigin = 'index'; this.setSelectValue(value, (o, indices) => o.index !== undefined && indices.includes(o.index)); } } get value() { return this.getSelectValue(this.selectedOptions.map(o => o.normalizedValue)); } set value(value) { this._value = value; if (this.preventSync === false) { this.selectionOrigin = 'value'; this.setSelectValue(value, (o, values) => values.some(v => o.valueMatches(v))); } } get data() { return this.getSelectValue(this.selectedOptions.map(o => o.data)); } set data(value) { this._data = value; if (this.preventSync === false) { this.selectionOrigin = 'data'; this.setSelectValue(value, (o, data) => o.data !== undefined && data.some(d => o.dataMatches(d))); } } requestSync() { this.select[FieldSelectValueController.requestSyncKey]++; } sync() { switch (this.selectionOrigin) { case 'index': this.index = this._index; break; case 'data': this.data = this._data; break; case 'value': this.value = this._value; break; } } getSelectValue(value) { const v = value instanceof Array ? value : [value]; return this.multiple ? v : v[0]; } async setSelectValue(value, predicate) { await new Promise(r => setTimeout(r, 0)); const array = value instanceof Array ? value : [value]; const newIndices = this.select.options .filter(o => array.some(() => predicate(o, array))) .map(o => o.index) .filter(i => i !== undefined); const equals = newIndices.length === this.menuValue.length && newIndices.every(i => this.menuValue.includes(i)); if (equals === false) { this.menuValue = newIndices; } } } FieldSelectValueController.requestSyncKey = 'requestSync';