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