/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import {BaseElement, element} from "../BaseElement.js"; @element('lit-select') export class LitSelect extends BaseElement { private focused: any; private inputElement: any; private clearElement: any; private iconElement: any; private searchElement: any; private multipleRootElement: any; static get observedAttributes() { return [ 'value', 'default-value', 'placeholder', 'disabled', 'loading', 'allow-clear', 'show-search', 'list-height', 'border', 'mode', ]; } get value() { return this.getAttribute('value') || this.defaultValue; } set value(value) { this.setAttribute('value', value); } get rounded() { return this.hasAttribute("rounded"); } set rounded(rounded: boolean) { if (rounded) { this.setAttribute("rounded", ''); } else { this.removeAttribute("rounded"); } } get placement(): string { return this.getAttribute("placement") || ""; } set placement(placement: string) { if (placement) { this.setAttribute("placement", placement); } else { this.removeAttribute("placement"); } } get border() { return this.getAttribute('border') || 'true'; } set border(value) { if (value) { this.setAttribute('border', 'true'); } else { this.setAttribute('border', 'false'); } } get listHeight() { return this.getAttribute('list-height') || '256px'; } set listHeight(value) { this.setAttribute('list-height', value); } get defaultPlaceholder() { return this.getAttribute('placeholder') || '请选择'; } set canInsert(can:boolean) { if (can) { this.setAttribute("canInsert",''); } else { this.removeAttribute("canInsert") } } get canInsert() { return this.hasAttribute("canInsert") } get showSearch() { return this.hasAttribute('show-search'); } get defaultValue() { return this.getAttribute('default-value') || ''; } set defaultValue(value) { this.setAttribute('default-value', value); } get placeholder() { return this.getAttribute('placeholder') || this.defaultPlaceholder; } set placeholder(value) { this.setAttribute('placeholder', value); } get loading() { return this.hasAttribute('loading'); } set loading(value) { if (value) { this.setAttribute('loading', ''); } else { this.removeAttribute('loading') } } set dataSource(value: any) { value.forEach((a: any) => { let option = document.createElement('lit-select-option'); option.setAttribute('value', a.key); option.textContent = a.val; this.append(option) }) this.initOptions(); } initElements(): void { } initHtml() { return `
` } isMultiple() { return this.hasAttribute('mode') && this.getAttribute('mode') === 'multiple' } newTag(value: any, text: any) { let tag: any = document.createElement('div'); let icon: any = document.createElement('lit-icon'); icon.classList.add('tag-close') icon.name = 'close' let span = document.createElement('span'); tag.classList.add('tag'); span.dataset['value'] = value; span.textContent = text; tag.append(span); tag.append(icon); icon.onclick = (ev: any) => { tag.parentElement.removeChild(tag); this.querySelector(`lit-select-option[value=${value}]`)!.removeAttribute('selected') if (this.shadowRoot!.querySelectorAll('.tag').length == 0) { this.inputElement.style.width = 'auto'; this.inputElement.placeholder = this.defaultPlaceholder; } ev.stopPropagation(); } tag.value = value; tag.dataset['value'] = value; tag.text = text; tag.dataset['text'] = text; return tag; } connectedCallback() { this.tabIndex = 0; this.focused = false; this.inputElement = this.shadowRoot!.querySelector('input'); this.clearElement = this.shadowRoot!.querySelector('.clear'); this.iconElement = this.shadowRoot!.querySelector('.icon'); this.searchElement = this.shadowRoot!.querySelector('.search'); this.multipleRootElement = this.shadowRoot!.querySelector('.multipleRoot'); this.clearElement.onclick = (ev: any) => { if (this.isMultiple()) { let delNodes: Array = [] this.multipleRootElement.childNodes.forEach((a: any) => { if (a.tagName === 'DIV') { delNodes.push(a); } }) for (let i = 0; i < delNodes.length; i++) { delNodes[i].remove(); } if (this.shadowRoot!.querySelectorAll('.tag').length == 0) { this.inputElement.style.width = 'auto'; this.inputElement.placeholder = this.defaultPlaceholder; } } this.querySelectorAll('lit-select-option').forEach(a => a.removeAttribute('selected')); this.inputElement.value = '' this.clearElement.style.display = 'none'; this.iconElement.style.display = 'flex'; this.blur(); ev.stopPropagation(); this.dispatchEvent(new CustomEvent('onClear', {detail: ev})) } this.initOptions(); this.onclick = (ev: any) => { if (ev.target.tagName === 'LIT-SELECT') { if (this.focused === false) { this.inputElement.focus(); this.focused = true; } else { this.blur(); this.focused = false; } } } this.onmouseover = this.onfocus = ev => { if (this.focused === false && this.hasAttribute("adaptive-expansion")) { let body = this.shadowRoot!.querySelector(".body"); if (this.parentElement!.offsetTop < body!.clientHeight) { body!.classList.add('body-bottom'); } else { body!.classList.remove('body-bottom'); } } if (this.hasAttribute('allow-clear')) { if (this.inputElement.value.length > 0 || this.inputElement.placeholder !== this.defaultPlaceholder) { this.clearElement.style.display = 'flex' this.iconElement.style.display = 'none'; } else { this.clearElement.style.display = 'none' this.iconElement.style.display = 'flex'; } } } this.onmouseout = this.onblur = ev => { if (this.hasAttribute('allow-clear')) { this.clearElement.style.display = 'none'; this.iconElement.style.display = 'flex'; } this.focused = false; } this.inputElement.onfocus = (ev: any) => { if (this.hasAttribute('disabled')) return; if (this.inputElement.value.length > 0) { this.inputElement.placeholder = this.inputElement.value; this.inputElement.value = '' } if (this.hasAttribute('show-search')) { this.searchElement.style.display = 'flex'; this.iconElement.style.display = 'none'; } this.querySelectorAll('lit-select-option').forEach(a => { // @ts-ignore a.style.display = 'flex'; }) } this.inputElement.onblur = (ev: any) => { if (this.hasAttribute('disabled')) return; if (this.isMultiple()) { if (this.hasAttribute('show-search')) { this.searchElement.style.display = 'none'; this.iconElement.style.display = 'flex'; } } else { if (this.inputElement.placeholder !== this.defaultPlaceholder) { this.inputElement.value = this.inputElement.placeholder; this.inputElement.placeholder = this.defaultPlaceholder; } if (this.hasAttribute('show-search')) { this.searchElement.style.display = 'none'; this.iconElement.style.display = 'flex'; } } } this.inputElement.oninput = (ev: any) => { let els = [...this.querySelectorAll('lit-select-option')]; if(this.hasAttribute("show-search")) { if (!ev.target.value) { els.forEach((a: any) => a.style.display = 'flex'); } else { els.forEach((a: any) => { let value = a.getAttribute('value'); if (value.toLowerCase().indexOf(ev.target.value.toLowerCase()) !== -1 || a.textContent.toLowerCase().indexOf(ev.target.value.toLowerCase()) !== -1) { a.style.display = 'flex'; } else { a.style.display = 'none'; } }) } } else { this.value = ev.target.value } } this.inputElement.onkeydown = (ev: any) => { if (ev.key === 'Backspace') { if (this.isMultiple()) { let tag = this.multipleRootElement.lastElementChild.previousElementSibling; if (tag) { this.querySelector(`lit-select-option[value=${tag.value}]`)?.removeAttribute('selected'); tag.remove() if (this.shadowRoot!.querySelectorAll('.tag').length == 0) { this.inputElement.style.width = 'auto'; this.inputElement.placeholder = this.defaultPlaceholder; } } } else { this.clear(); this.dispatchEvent(new CustomEvent('onClear', {detail: ev}))//向外派发清理事件 } } else if (ev.key === 'Enter') { if (!this.canInsert) { let filter = [...this.querySelectorAll('lit-select-option')].filter((a: any) => a.style.display !== 'none'); if (filter.length > 0) { this.inputElement.value = filter[0].textContent; this.inputElement.placeholder = filter[0].textContent; this.blur(); // @ts-ignore this.value = filter[0].getAttribute('value') this.dispatchEvent(new CustomEvent('change', { detail: { selected: true, value: filter[0].getAttribute('value'), text: filter[0].textContent } })); } } } } } initOptions() { this.querySelectorAll('lit-select-option').forEach(a => { if (this.isMultiple()) { a.setAttribute('check', ''); if (a.getAttribute('value') === this.defaultValue) { let tag = this.newTag(a.getAttribute('value'), a.textContent); this.multipleRootElement.insertBefore(tag, this.inputElement); this.inputElement.placeholder = ''; this.inputElement.value = ''; this.inputElement.style.width = '1px'; a.setAttribute('selected', ''); } } else { if (a.getAttribute('value') === this.defaultValue) { this.inputElement.value = a.textContent; a.setAttribute('selected', ''); } } a.addEventListener('mouseup',(e)=>{ e.stopPropagation() }); a.addEventListener('mousedown',(e)=>{ e.stopPropagation() }); a.addEventListener('onSelected', (e: any) => { if (this.isMultiple()) { if (a.hasAttribute('selected')) { let tag = this.shadowRoot!.querySelector(`div[data-value=${e.detail.value}]`) as HTMLElement; if (tag) { tag.parentElement!.removeChild(tag); } e.detail.selected = false; } else { let tag = this.newTag(e.detail.value, e.detail.text); this.multipleRootElement.insertBefore(tag, this.inputElement); this.inputElement.placeholder = ''; this.inputElement.value = ''; this.inputElement.style.width = '1px'; } if (this.shadowRoot!.querySelectorAll('.tag').length == 0) { this.inputElement.style.width = 'auto'; this.inputElement.placeholder = this.defaultPlaceholder; } this.inputElement.focus(); } else { [...this.querySelectorAll('lit-select-option')].forEach(a => a.removeAttribute('selected')) this.blur(); // @ts-ignore this.inputElement.value = e.detail.text; } if (a.hasAttribute('selected')) { a.removeAttribute('selected') } else { a.setAttribute('selected', '') } // @ts-ignore this.value = e.detail.value; this.dispatchEvent(new CustomEvent('change', {detail: e.detail}));//向外层派发change事件,返回当前选中项 }) }) } clear() { this.inputElement.value = ''; this.inputElement.placeholder = this.defaultPlaceholder; } reset() { this.querySelectorAll('lit-select-option').forEach(a => { [...this.querySelectorAll('lit-select-option')].forEach(a => a.removeAttribute('selected')) if (a.getAttribute('value') === this.defaultValue) { this.inputElement.value = a.textContent; a.setAttribute('selected', ''); } }) } disconnectedCallback() { } adoptedCallback() { } attributeChangedCallback(name: any, oldValue: any, newValue: any) { if (name === 'value' && this.inputElement) { if (newValue) { [...this.querySelectorAll('lit-select-option')].forEach(a => { if (a.getAttribute('value') === newValue) { a.setAttribute('selected', ''); this.inputElement.value = a.textContent; } else { a.removeAttribute('selected') } }) } else { this.clear(); } } } }