• 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";
17
18@element('lit-allocation-select')
19export class LitAllocationSelect extends BaseElement {
20    private inputElement: HTMLInputElement | null | undefined;
21    private inputContent: HTMLDivElement | undefined;
22    private options: any;
23
24    static get observedAttributes() {
25        return [
26            'value','disabled','placeholder'
27        ];
28    }
29
30    get defaultPlaceholder() {
31        return this.getAttribute('placeholder') || '';
32    }
33
34    get placeholder() {
35        return this.getAttribute('placeholder') || this.defaultPlaceholder;
36    }
37
38    set placeholder(value) {
39        this.setAttribute('placeholder', value);
40    }
41
42    get value() {
43        return this.getAttribute('value') || "";
44    }
45
46    set value(value: string) {
47        this.setAttribute('value', value);
48    }
49
50    set processData(value: Array<string>) {
51        this.options.innerHTML = '';
52        value.forEach(
53            item => {
54                let option = document.createElement("div");
55                option.className = 'option';
56                option.innerHTML = item;
57                option.style.padding = '8px 10px';
58                this.options.appendChild(option);
59                this.inputElement?.focus();
60            }
61        )
62    }
63
64    get placement(): string {
65        return this.getAttribute("placement") || "";
66    }
67
68    set placement(placement: string) {
69        if (placement) {
70            this.setAttribute("placement", placement);
71        } else {
72            this.removeAttribute("placement");
73        }
74    }
75
76    get listHeight() {
77        return this.getAttribute('list-height') || '256px';
78    }
79
80    set listHeight(value) {
81        this.setAttribute('list-height', value);
82    }
83
84    initElements(): void {
85        this.inputContent = this.shadowRoot!.querySelector('.multipleSelect') as HTMLDivElement;
86        this.addEventListener('click', () => {
87            if (this.options.style.visibility == 'visible') {
88                this.options.style.visibility = 'hidden';
89                this.options.style.opacity = '0';
90            } else {
91                this.options.style.visibility = 'visible';
92                this.options.style.opacity = '1';
93            }
94            this.inputContent!.dispatchEvent(new CustomEvent('inputClick', {}));
95        })
96        this.addEventListener('focusout', (e) => {
97            setTimeout(()=>{
98                this.options.style.visibility = 'hidden';
99                this.options.style.opacity = '0';
100            }, 200)
101            })
102        this.initData();
103    }
104
105    initHtml() {
106        return `
107        <style>
108        :host{
109            display: inline-flex;
110            position: relative;
111            overflow: visible;
112            cursor: pointer;
113            border-radius: 16px;
114            outline: none;
115            -webkit-user-select:none ;
116            -moz-user-select:none;
117            user-select:none;
118            width: 75%;
119        }
120        :host(:not([border])),
121        :host([border='true']){
122            border: 1px solid var(--bark-prompt,#dcdcdc);
123        }
124        input{
125            border: 0;
126            outline: none;
127            background-color: transparent;
128            cursor: pointer;
129            -webkit-user-select:none ;
130            -moz-user-select:none;
131            user-select:none;
132            display: inline-flex;
133            color: var(--dark-color2,rgba(0,0,0,0.9));
134            z-index: 8999;
135            width:100%;
136        }
137        .multipleSelect{
138            position: relative;
139            padding: 3px 6px;
140            display: flex;
141            align-items: center;
142            justify-content: space-between;
143            transition: all .3s;
144            outline: none;
145            font-size: 1rem;
146            z-index: 2999;
147            -webkit-user-select:none ;
148            -moz-user-select:none;
149            user-select:none;
150            width: 100%;
151        }
152         .body{
153            max-height: ${this.listHeight};
154            position: absolute;
155            bottom: 100%;
156            z-index: 99;
157            padding-top: 5px;
158            margin-top: 2px;
159            background-color: var(--dark-background4,#fff);
160            width: 100%;
161            transition: all 0.2s;
162            visibility: hidden;
163
164            opacity: 0;
165            transform-origin: bottom center;
166            display: block;
167            flex-direction: column;
168            box-shadow: 0 5px 15px 0px #00000033;
169            border-radius: 2px;
170            overflow: auto;
171        }
172          .body-bottom{
173            bottom: auto;
174            top: 100%;
175            transform-origin: top center;
176        }
177        :host([placement="bottom"]) .body{
178            bottom:unset;
179            top: 100%;
180            transition: none;
181            transform: none;
182        }
183
184        :host([disabled]) {
185           pointer-events: none;
186           background-color: var(--dark-background1,#f5f5f5);
187            cursor: not-allowed;
188        }
189
190        .multipleRoot input::-webkit-input-placeholder {
191                color: var(--dark-color,#aab2bd);
192        }
193        </style>
194        <div class="multipleSelect" tabindex="0">
195            <div class="multipleRoot" id="select" style="width:100%">
196            <input id="input" placeholder="${this.placeholder}"/>
197        </div>
198            <lit-icon class="icon" name='down' color="#c3c3c3"></lit-icon>
199        </div>
200        <div class="body body-bottom">
201            <slot></slot>
202            <slot name="footer"></slot>
203        </div>
204        `
205    }
206
207    connectedCallback() {
208    }
209
210    initData() {
211        this.inputElement = this.shadowRoot!.querySelector('input');
212        this.options = this.shadowRoot!.querySelector('.body') as HTMLDivElement;
213        this.inputElement?.addEventListener('keyup', () => {
214            let filter = [...this.shadowRoot!.querySelectorAll<HTMLDivElement>('.option')].filter((a: HTMLDivElement) => {
215                if (a.textContent!.indexOf(this.inputElement!.value) <= -1) {
216                    a.style.display = "none";
217                } else {
218                    a.style.display = "block";
219                }
220            });
221            this.value = this.inputElement!.value
222            this.inputContent!.dispatchEvent(new CustomEvent('valuable', {}));
223        })
224        this.shadowRoot?.querySelectorAll('.option').forEach(a => {
225            a.addEventListener('click', (e) => {
226                a.dispatchEvent(new CustomEvent('onSelected', {
227                    detail: {
228                        selected: true,
229                        text: a.textContent
230                    }
231                }))
232            })
233            a.addEventListener('onSelected', (e: any) => {
234                this.inputElement!.value = e.detail.text;
235                this.value = e.detail.text;
236                this.inputContent!.dispatchEvent(new CustomEvent('valuable', {}));
237            })
238        })
239    }
240
241}
242