• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "../BaseElement.js";
17import {LitSelectOption} from "./LitSelectOption.js";
18
19@element('lit-select-v')
20export class LitSelectV extends BaseElement {
21    showItems: Array<string> = [];
22    itemValue: Array<string> = [];
23    customItem: Array<string> = [];
24    private focused: any;
25    private inputElement: any;
26    private iconElement: any;
27    private options: HTMLDivElement | undefined;
28    private valueStr: string = '';
29
30    static get observedAttributes() {
31        return [
32            'value',
33            'default-value',
34            'placeholder',
35            'disabled',
36            'show-search',
37            'border',
38            'mode',
39        ];
40    }
41
42    get value() {
43        return this.inputElement!.value || this.defaultValue;
44    }
45
46    get rounded() {
47        return this.hasAttribute("rounded");
48    }
49
50    set rounded(rounded: boolean) {
51        if (rounded) {
52            this.setAttribute("rounded", '');
53        } else {
54            this.removeAttribute("rounded");
55        }
56    }
57
58    get placement(): string {
59        return this.getAttribute("placement") || "";
60    }
61
62    set placement(placement: string) {
63        if (placement) {
64            this.setAttribute("placement", placement);
65        } else {
66            this.removeAttribute("placement");
67        }
68    }
69
70    get border() {
71        return this.getAttribute('border') || 'true';
72    }
73
74    set border(value) {
75        if (value) {
76            this.setAttribute('border', 'true');
77        } else {
78            this.setAttribute('border', 'false');
79        }
80    }
81
82    get defaultPlaceholder() {
83        return this.getAttribute('placeholder') || '';
84    }
85
86    get defaultValue() {
87        return this.getAttribute('default-value') || '';
88    }
89
90    set defaultValue(value) {
91        this.setAttribute('default-value', value);
92    }
93
94    get placeholder() {
95        return this.getAttribute('placeholder') || this.defaultPlaceholder;
96    }
97
98    set placeholder(value) {
99        this.setAttribute('placeholder', value);
100    }
101
102    set all(isAll: boolean) {
103        if (isAll) {
104            this.setAttribute('is-all', '');
105        } else {
106            this.removeAttribute('is-all');
107        }
108    }
109
110    get all() {
111        return this.hasAttribute('is-all');
112    }
113
114    dataSource(value: Array<string>, valueStr: string) {
115        this.options!.innerHTML = '';
116        if (value.length > 0) {
117            this.options!.style.display = "block"
118            this.valueStr = valueStr;
119            this.itemValue = value;
120            if (valueStr != "") {
121                let option = document.createElement("lit-select-option");
122                if (this.all) {
123                    option.setAttribute("selected", "");
124                    this.showItems = value
125                }
126                option.setAttribute('value', valueStr);
127                option.textContent = valueStr;
128                this.options!.appendChild(option);
129                this.initDataItem(value);
130                this.initCustomOptions()
131            } else {
132                this.initDataItem(value);
133                this.initOptions()
134            }
135        } else {
136            this.options!.style.display = "none"
137        }
138        if (this.title == 'Event List') {
139            let inputElement = this.shadowRoot?.querySelector('input') as HTMLInputElement;
140            inputElement.readOnly = false
141        }
142    }
143
144    initDataItem(value: Array<string>) {
145        value.forEach(
146            item => {
147                let option = document.createElement("lit-select-option");
148                if (this.showItems.indexOf(item) > -1 || this.all) {
149                    option.setAttribute("selected", "")
150                }
151                option.setAttribute('value', item);
152                option.textContent = item;
153                this.options!.appendChild(option);
154            }
155        )
156    }
157
158    initElements(): void {
159        this.tabIndex = 0;
160        this.focused = false;
161        this.inputElement = this.shadowRoot!.querySelector('input') as HTMLInputElement;
162        this.options = this.shadowRoot!.querySelector('.body') as HTMLDivElement;
163        this.iconElement = this.shadowRoot!.querySelector('.icon');
164        this.onclick = (ev: any) => {
165            if (this.focused === false) {
166                this.focused = true;
167            } else {
168                this.focused = false;
169            }
170        }
171
172        this.onmouseout = this.onblur = ev => {
173            this.focused = false;
174        }
175        this.inputElement.onfocus = (ev: any) => {
176            if (this.hasAttribute('disabled')) return;
177        }
178        this.inputElement.onblur = (ev: any) => {
179            if (this.hasAttribute('disabled')) return;
180        }
181    }
182
183    initHtml() {
184        return `
185        <style>
186        :host{
187            display: inline-flex;
188            position: relative;
189            overflow: visible;
190            cursor: pointer;
191            border-radius: 2px;
192            outline: none;
193            -webkit-user-select:none ;
194            -moz-user-select:none;
195            user-select:none;
196        }
197        :host(:not([border])),
198        :host([border='true']){
199            border: 1px solid var(--bark-prompt,#dcdcdc);
200        }
201        input{
202            border: 0;
203            outline: none;
204            background-color: transparent;
205            cursor: pointer;
206            -webkit-user-select:none ;
207            -moz-user-select:none;
208            user-select:none;
209            display: inline-flex;
210            color: var(--dark-color2,rgba(0,0,0,0.9));
211        }
212        :host([highlight]) input {
213            color: rgba(255,255,255,0.9);
214        }
215        input{
216            width: 100%;
217        }
218        :host([mode])  input{
219            padding: 6px 0px;
220        }
221        :host([mode])  .root{
222            padding: 1px 8px;
223        }
224        .root{
225            position: relative;
226            padding: 3px 6px;
227            display: flex;
228            align-items: center;
229            justify-content: space-between;
230            border-radius: 2px;
231            outline: none;
232            font-size: 1rem;
233            z-index: 2;
234            -webkit-user-select:none ;
235            -moz-user-select:none;
236            user-select:none;
237            width: 100%;
238        }
239        .body{
240            max-height: 256px;
241            position: absolute;
242            bottom: 100%;
243            z-index: 99;
244            padding-top: 5px;
245            margin-top: 2px;
246            background-color: var(--dark-background4,#fff);
247            width: 100%;
248            transform: scaleY(.6);
249            visibility: hidden;
250            opacity: 0;
251            transform-origin: bottom center;
252            display: block;
253            flex-direction: column;
254            box-shadow: 0 5px 15px 0px #00000033;
255            border-radius: 2px;
256            overflow: auto;
257        }
258        .body-bottom{
259            bottom: auto;
260            top: 100%;
261            transform-origin: top center;
262        }
263        :host([placement="bottom"]) .body{
264            bottom:unset;
265            top: 100%;
266            transition: none;
267            transform: none;
268        }
269
270        :host([rounded]) .body {
271            border-radius: 16px;
272        }
273        :host([rounded]) .root {
274            border-radius: 16px;
275            height: 25px;
276        }
277        .icon{
278            pointer-events: none;
279        }
280        .noSelect{
281          -moz-user-select:none;
282          -ms-user-select:none;
283          user-select:none;
284          -khtml-user-select:none;
285          -webkit-touch-callout:none;
286          -webkit-user-select:none;
287        }
288
289        :host(:not([border]):not([disabled]):focus),
290        :host([border='true']:not([disabled]):focus),
291        :host(:not([border]):not([disabled]):hover),
292        :host([border='true']:not([disabled]):hover){
293            border:1px solid var(--bark-prompt,#ccc)
294        }
295        :host(:not([disabled]):focus) .body,
296        :host(:not([disabled]):focus-within) .body{
297            transform: scaleY(1);
298            opacity: 1;
299            z-index: 99;
300            visibility: visible;
301        }
302        :host(:not([disabled]):focus)  input{
303            color: var(--dark-color,#bebebe);
304        }
305        input::-webkit-input-placeholder {
306                color: var(--dark-color,#aab2bd);
307        }
308        :host(:not([border])[disabled]) *,
309        :host([border='true'][disabled]) *{
310            background-color: var(--dark-background1,#f5f5f5);
311            color: #b7b7b7;
312            cursor: not-allowed;
313        }
314        :host([border='false'][disabled]) *{
315            color: #b7b7b7;
316            cursor: not-allowed;
317        }
318        .loading{
319            display: none;
320        }
321        .icon{
322            display: flex;
323        }
324
325        </style>
326        <div class="root noSelect" tabindex="0" hidefocus="true">
327            <input placeholder="${this.placeholder}" tabindex="0" readonly="readonly">
328            <lit-icon class="icon" name='down' color="#c3c3c3"></lit-icon>
329        </div>
330        <div class="body">
331            <slot></slot>
332            <slot name="footer"></slot>
333        </div>
334        `
335    }
336
337    connectedCallback() {
338    }
339
340    initCustomOptions() {
341        let querySelector = this.shadowRoot?.querySelector(`lit-select-option[value="${this.valueStr}"]`) as LitSelectOption;
342        this.shadowRoot?.querySelectorAll('lit-select-option').forEach(a => {
343            a.setAttribute('check', '');
344            a.addEventListener('onSelected', (e: any) => {
345                if (a.hasAttribute("selected")) {
346                    let number = this.showItems.indexOf(a.textContent!);
347                    if (number > -1) {
348                        this.showItems!.splice(number, 1);
349                        this.inputElement!.value = this.showItems;
350                    }
351                    this.all = false
352                    querySelector.removeAttribute("selected");
353                    a.removeAttribute("selected");
354                    return;
355                } else {
356                    let index = this.itemValue.indexOf(a.textContent!);
357                    let value = this.showItems.indexOf(a.textContent!);
358                    if (index > -1 && value == -1) {
359                        this.showItems.push(a.textContent!);
360                        this.inputElement!.value = this.showItems;
361                    }
362                    if (this.showItems.length >= this.itemValue.length) {
363                        querySelector.setAttribute('selected', '')
364                        this.all = true;
365                    } else {
366                        querySelector.removeAttribute('selected')
367                        this.all = false;
368                    }
369                    a.setAttribute('selected', '')
370                }
371            })
372        })
373        this.selectAll(querySelector);
374    }
375
376
377    initOptions() {
378        this.options!.addEventListener('click', ev => {
379            let items = this.inputElement!.value.split(",");
380            this.customItem = []
381            items.forEach((item: string) => {
382                if (item.trim() != "") {
383                    let indexItem = this.itemValue.indexOf(item.trim());
384                    if (indexItem == -1) {
385                        this.customItem.push(item.trim())
386                    }
387                }
388            });
389            if (this.customItem.length > 0) {
390                this.inputElement.value = this.customItem.concat(this.showItems);
391            } else {
392                this.inputElement.value = this.showItems
393            }
394        })
395        this.shadowRoot?.querySelectorAll('lit-select-option').forEach(a => {
396            a.setAttribute('check', '');
397            a.addEventListener('onSelected', (e: any) => {
398                if (a.hasAttribute("selected")) {
399                    let number = this.showItems.indexOf(a.textContent!);
400                    if (number > -1) {
401                        this.showItems.splice(number, 1)
402                    }
403                    a.removeAttribute("selected");
404                    return;
405                } else {
406                    let index = this.itemValue.indexOf(a.textContent!);
407                    if (index > -1) {
408                        this.showItems.push(a.textContent!);
409                    }
410                    a.setAttribute('selected', '')
411                }
412            })
413        })
414    }
415
416    selectAll(querySelector: LitSelectOption) {
417        querySelector?.addEventListener("click", ev => {
418            if (querySelector.hasAttribute("selected")) {
419                this.shadowRoot?.querySelectorAll('lit-select-option').forEach(a => {
420                    a.setAttribute('selected', '');
421                    this.all = true
422                })
423                this.itemValue.forEach(i => {
424                    this.showItems.push(i)
425                })
426                this.inputElement.value = this.itemValue;
427            } else {
428                this.shadowRoot?.querySelectorAll('lit-select-option').forEach(i => {
429                    i.removeAttribute('selected');
430                    this.all = false
431                })
432                this.showItems = [];
433                this.inputElement.value = "";
434            }
435        })
436    }
437
438    attributeChangedCallback(name: any, oldValue: any, newValue: any) {
439    }
440
441}
442