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