1/* 2 * Copyright (C) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import {SearchHtml} from './Search.html.js'; 16 17const LOCAL_STORAGE_SEARCH_KEY = 'search_key'; 18 19export class LitSearch extends HTMLElement { 20 21 22 constructor() { 23 super(); 24 this._index = 0; 25 this._list = []; 26 this._value = false; 27 this.historyMaxCount = 100; 28 this.searchList = []; 29 this.searchELList = []; 30 this.attachShadow({mode: 'open'}).innerHTML = this.initHtml(); 31 this.initElements(); 32 } 33 34 get list() { 35 return this._list; 36 } 37 38 set list(value) { 39 this._list = value; 40 } 41 42 get index() { 43 return this._index; 44 } 45 46 set index(value) { 47 this._index = value; 48 } 49 50 get searchValue() { 51 return this.search?.value ?? ''; 52 } 53 54 get isLoading() { 55 return this.hasAttribute('isLoading'); 56 } 57 58 set isLoading(va) { 59 if (va) { 60 this.setAttribute('isLoading', ''); 61 } else { 62 this.removeAttribute('isLoading'); 63 window.localStorage.setItem(LOCAL_STORAGE_SEARCH_KEY, ''); 64 } 65 } 66 67 set isClearValue(value) { 68 this._value = value; 69 } 70 71 get isClearValue() { 72 return this._value; 73 } 74 75 valueChangeHandler = () => { 76 }; 77 78 setPercent(name = '', value) { 79 let searchHide = this.shadowRoot.querySelector('.root'); 80 let searchIcon = this.shadowRoot.querySelector('#search-icon'); 81 if (this.hasAttribute('textRoll')) { 82 this.removeAttribute('textRoll'); 83 } 84 this.isLoading = false; 85 if (value > 0 && value <= 100) { 86 searchHide.style.display = 'flex'; 87 searchHide.style.backgroundColor = '#e3e3e3'; 88 searchIcon === null || searchIcon === void 0 ? void 0 : searchIcon.setAttribute('name', 'cloud-sync'); 89 this.search.setAttribute('placeholder', `${name}${value}%`); 90 this.search.setAttribute('readonly', ''); 91 this.search.className = 'readonly'; 92 this.isLoading = true; 93 } else if (value > 100) { 94 searchHide.style.display = 'flex'; 95 searchHide.style.backgroundColor = '#fff'; 96 searchIcon?.setAttribute('name', 'search'); 97 this.search?.setAttribute('placeholder', 'search'); 98 this.search?.removeAttribute('readonly'); 99 this.search.className = 'write'; 100 } else if (value === -1) { 101 searchHide.style.display = 'flex'; 102 searchHide.style.backgroundColor = '#e3e3e3'; 103 searchIcon === null || searchIcon === void 0 ? void 0 : searchIcon.setAttribute('name', 'cloud-sync'); 104 this.search.setAttribute('placeholder', `${name}`); 105 this.search.setAttribute('readonly', ''); 106 this.search.className = 'readonly'; 107 } else { 108 searchHide.style.display = 'none'; 109 } 110 } 111 112 clear() { 113 this.search = this.shadowRoot.querySelector('input'); 114 this.search.value = ''; 115 this.list = []; 116 } 117 118 blur() { 119 this.search?.blur(); 120 } 121 122 updateSearchList(searchStr) { 123 if (searchStr === null || searchStr.length === 0 || searchStr.trim().length === 0) { 124 return; 125 } 126 let searchInfo = this.searchList.find((searchInfo) => searchInfo.searchContent === searchStr); 127 if (searchInfo !== undefined) { 128 let index = this.searchList.indexOf(searchInfo); 129 this.searchList.splice(index, 1); 130 this.searchList.unshift({searchContent: searchStr, useCount: 1}); 131 } else { 132 this.searchList.unshift({searchContent: searchStr, useCount: 1}); 133 } 134 } 135 136 getSearchHistory() { 137 let searchString = window.localStorage.getItem(LOCAL_STORAGE_SEARCH_KEY); 138 if (searchString) { 139 let searHistory = JSON.parse(searchString); 140 if (Array.isArray(searHistory)) { 141 this.searchList = searHistory; 142 return searHistory; 143 } 144 } 145 return []; 146 } 147 148 searchFocusListener() { 149 } 150 151 searchBlurListener() { 152 this.dispatchEvent(new CustomEvent('blur', { 153 detail: { 154 value: this.search.value, 155 }, 156 })); 157 } 158 159 searchKeyupListener(e) { 160 if (e.code === 'Enter' || e.code === 'NumpadEnter') { 161 this.updateSearchList(this.search.value); 162 } else { 163 this.updateSearchHistoryList(this.search.value); 164 this.valueChangeHandler?.call(this, this.trimSideSpace(this.search.value)); 165 } 166 e.stopPropagation(); 167 } 168 169 trimSideSpace(str) { 170 return str.replace(/(^\s*)|(\s*$)/g, ''); 171 } 172 173 initElements() { 174 this.search = this.shadowRoot.querySelector('input'); 175 this.searchHistoryListEL = this.shadowRoot.querySelector('.search-history-list'); 176 this.retargetIndex = this.shadowRoot.querySelector('input[name="retarge_index"]'); 177 this.search.addEventListener('focus', () => { 178 }); 179 this.search.addEventListener('blur', () => { 180 this.searchBlurListener(); 181 }); 182 this.search.addEventListener('change', () => { 183 this.index = -1; 184 this.retargetIndex.value = ''; 185 }); 186 this.search.addEventListener('keyup', (e) => { 187 this.retargetIndex.value = ''; 188 this.index = -1; 189 this.searchKeyupListener(e); 190 }); 191 (this.shadowRoot?.querySelector('input[name="retarget_index"]'))?.addEventListener('keydown', (event) => { 192 if (event.key === 'Enter') { 193 event.stopPropagation(); 194 } 195 }); 196 } 197 198 initHtml() { 199 return SearchHtml; 200 } 201 202 hideSearchHistoryList() { 203 this.searchHistoryListEL.style.display = 'none'; 204 if (this.searchList.length > this.historyMaxCount) { 205 this.searchList = this.searchList.slice(0, this.historyMaxCount); 206 } 207 if (this.searchList.length === 0) { 208 return; 209 } 210 let historyStr = JSON.stringify(this.searchList); 211 window.localStorage.setItem(LOCAL_STORAGE_SEARCH_KEY, historyStr); 212 this.searchList = []; 213 this.searchELList = []; 214 } 215 216 updateSearchHistoryList(searchValue) { 217 const keyword = searchValue.toLowerCase(); 218 this.searchELList.forEach((item) => { 219 if (item.textContent.toLowerCase().includes(keyword)) { 220 item.style.display = 'block'; 221 } else { 222 item.style.display = 'none'; 223 } 224 }); 225 } 226} 227 228if (!customElements.get('lit-search')) { 229 customElements.define('lit-search', LitSearch); 230} 231