1/* 2 * Copyright (C) 2022 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 */ 15 16import {BaseElement, element} from "../../../../base-ui/BaseElement.js"; 17 18@element("lit-search") 19export class LitSearch extends BaseElement { 20 valueChangeHandler: ((str: string) => void) | undefined | null; 21 private search: HTMLInputElement | undefined | null; 22 private _total: number = 0; 23 private _index: number = 0; 24 private _list: Array<any> = []; 25 private totalEL: HTMLSpanElement | null | undefined; 26 private indexEL: HTMLSpanElement | null | undefined; 27 28 get list(): Array<any> { 29 return this._list; 30 } 31 32 set list(value: Array<any>) { 33 this._list = value; 34 this.total = value.length; 35 } 36 37 get index(): number { 38 return this._index; 39 } 40 41 set index(value: number) { 42 this._index = value; 43 this.indexEL!.textContent = `${value + 1}`; 44 } 45 46 get searchValue(){ 47 return this.search?.value 48 } 49 50 get total(): number { 51 return this._total; 52 } 53 54 set total(value: number) { 55 value > 0 ? this.setAttribute("show-search-info", '') : this.removeAttribute("show-search-info"); 56 this._total = value; 57 this.indexEL!.textContent = '0'; 58 this.totalEL!.textContent = value.toString(); 59 } 60 61 get isLoading(): boolean{ 62 return this.hasAttribute('isLoading') 63 } 64 65 set isLoading(va){ 66 if (va) { 67 this.setAttribute('isLoading',''); 68 } else { 69 this.removeAttribute('isLoading') 70 } 71 } 72 73 setPercent(name: string = "", value: number) { 74 let searchHide = this.shadowRoot!.querySelector<HTMLElement>(".root") 75 let searchIcon = this.shadowRoot!.querySelector<HTMLElement>("#search-icon") 76 this.isLoading = false 77 if (value > 0 && value <= 100) { 78 searchHide!.style.display = "flex" 79 searchHide!.style.backgroundColor = "var(--dark-background5,#e3e3e3)" 80 searchIcon?.setAttribute('name', "cloud-sync"); 81 this.search!.setAttribute('placeholder', `${name}${value}%`); 82 this.search!.setAttribute('readonly', ""); 83 this.search!.className = "readonly" 84 this.isLoading = true 85 } else if (value > 100) { 86 searchHide!.style.display = "flex" 87 searchHide!.style.backgroundColor = "var(--dark-background5,#fff)" 88 searchIcon?.setAttribute('name', "search"); 89 this.search?.setAttribute('placeholder', `search`); 90 this.search?.removeAttribute('readonly'); 91 this.search!.className = "write" 92 } else if (value == -1) { 93 searchHide!.style.display = "flex" 94 searchHide!.style.backgroundColor = "var(--dark-background5,#e3e3e3)" 95 searchIcon?.setAttribute('name', "cloud-sync"); 96 this.search!.setAttribute('placeholder', `${name}`); 97 this.search!.setAttribute('readonly', ""); 98 this.search!.className = "readonly" 99 } else { 100 searchHide!.style.display = "none" 101 } 102 } 103 104 clear() { 105 this.search = this.shadowRoot!.querySelector<HTMLInputElement>("input"); 106 this.search!.value = ""; 107 this.list = []; 108 } 109 110 blur() { 111 this.search?.blur(); 112 } 113 114 initElements(): void { 115 this.search = this.shadowRoot!.querySelector<HTMLInputElement>("input"); 116 this.totalEL = this.shadowRoot!.querySelector<HTMLSpanElement>("#total"); 117 this.indexEL = this.shadowRoot!.querySelector<HTMLSpanElement>("#index"); 118 this.search!.addEventListener("focus", (e) => { 119 this.dispatchEvent(new CustomEvent("focus", { 120 detail: { 121 value: this.search!.value 122 } 123 })); 124 }); 125 this.search!.addEventListener("blur", (e) => { 126 this.dispatchEvent(new CustomEvent("blur", { 127 detail: { 128 value: this.search!.value 129 } 130 })); 131 }); 132 this.search!.addEventListener('change', (event) => { 133 this.index = -1; 134 }); 135 136 this.search!.addEventListener("keyup", (e: KeyboardEvent) => { 137 if (e.code == "Enter") { 138 if (e.shiftKey) { 139 this.dispatchEvent(new CustomEvent("previous-data", { 140 detail: { 141 value: this.search!.value 142 }, 143 composed:false 144 })); 145 } else { 146 this.dispatchEvent(new CustomEvent("next-data", { 147 detail: { 148 value: this.search!.value 149 }, 150 composed:false 151 })); 152 } 153 } else { 154 this.valueChangeHandler?.(this.search!.value); 155 } 156 e.stopPropagation(); 157 }); 158 this.shadowRoot?.querySelector("#arrow-left")?.addEventListener("click", (e) => { 159 this.dispatchEvent(new CustomEvent("previous-data", { 160 detail: { 161 value: this.search!.value 162 } 163 })); 164 }); 165 this.shadowRoot?.querySelector("#arrow-right")?.addEventListener("click", (e) => { 166 this.dispatchEvent(new CustomEvent("next-data", { 167 detail: { 168 value: this.search!.value 169 } 170 })); 171 }); 172 } 173 174 initHtml(): string { 175 return ` 176 <style> 177 :host{ 178 } 179 .root{ 180 background-color: var(--dark-background5,#fff); 181 border-radius: 40px; 182 padding: 3px 20px; 183 display: flex; 184 justify-content: center; 185 align-items: center; 186 border: 1px solid var(--dark-border,#c5c5c5); 187 width: 35vw; 188 } 189 .root input{ 190 outline: none; 191 border: 0px; 192 background-color: transparent; 193 font-size: inherit; 194 color: var(--dark-color,#666666); 195 flex: 1; 196 height: auto; 197 vertical-align:middle; 198 line-height:inherit; 199 height:inherit; 200 padding: 6px 6px 6px 6px}; 201 max-height: inherit; 202 box-sizing: border-box; 203 } 204 ::placeholder { 205 color: #b5b7ba; 206 font-size: 1em; 207 } 208 .write::placeholder { 209 color: #b5b7ba; 210 font-size: 1em; 211 } 212 .readonly::placeholder { 213 color: #4f7ab3; 214 font-size: 1em; 215 } 216 :host([show-search-info]) .search-info{ 217 display: inline-flex; 218 } 219 :host(:not([show-search-info])) .search-info{ 220 display: none; 221 } 222 .search-info span{ 223 color:#ABABAB; 224 } 225 .search-info lit-icon{ 226 font-weight: bold; 227 } 228 229 </style> 230 <div class="root" style="display: none"> 231 <lit-icon id="search-icon" name="search" size="20" color="#aaaaaa"> 232 </lit-icon> 233 <input class="readonly" placeholder="Search" readonly/> 234 <div class="search-info"> 235 <span id="index">0</span><span>/</span><span id="total">0</span> 236 <lit-icon class="icon" id="arrow-left" name="caret-left" color="#AAAAAA" size="22"> 237 </lit-icon> 238 <span>|</span> 239 <lit-icon class="icon" id="arrow-right" name="caret-right" color="#AAAAAA" size="22"> 240 </lit-icon> 241 </div> 242 </div> 243 `; 244 } 245} 246