• 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 {LitPopContent} from "./LitPopContent.js";
18import {LitPopoverTitle} from "./LitPopoverTitle.js";
19import {LitRadioGroup} from "../radiobox/LitRadioGroup.js";
20import {LitRadioBox} from "../radiobox/LitRadioBox.js";
21import {LitCheckBox} from "../checkbox/LitCheckBox.js";
22import {LitCheckGroup} from "../checkbox/LitCheckGroup.js";
23import {LitCheckBoxWithText} from "../checkbox/LitCheckBoxWithText.js";
24
25@element("lit-popover")
26export class LitPopover extends BaseElement {
27    private popContent: LitPopContent | null | undefined;
28    private litGroup: LitRadioGroup | LitCheckGroup | undefined
29    private _texBox: LitCheckBoxWithText | undefined
30
31    static get observedAttributes() {
32        return []
33    }
34
35    get type() {
36        return this.getAttribute("type") || ''
37    }
38
39    set type(type: string) {
40        this.setAttribute("type", type)
41    }
42
43    get title() {
44        return this.getAttribute("title") || ''
45    }
46
47    set title(title: string) {
48        this.setAttribute("title", title)
49    }
50
51    get limit(): LimitText {
52        if (this._texBox?.checked) {
53            return {textLowerLimit: this._texBox.lowerlimit, textUpperLimit: this._texBox.uplimit}
54        }
55        return {textLowerLimit: "", textUpperLimit: ""}
56    }
57
58    set dataSource(dataSource: Array<SelectBean>) {
59        this.popContent = this.querySelector<LitPopContent>('lit-pop-content');
60        if (!this.popContent) {
61            this.popContent = new LitPopContent();
62            this.appendChild(this.popContent);
63        }
64        switch (this.type) {
65            case "multiple":
66                this.litGroup = new LitCheckGroup();
67                this.litGroup.setAttribute("layout", "dispersion")
68                this.popContent!.appendChild(this.litGroup);
69                dataSource.forEach(data => {
70                    let litCheckBox = new LitCheckBox();
71                    this.litGroup?.appendChild(litCheckBox)
72                    if (data.isSelected) {
73                        litCheckBox.setAttribute('checked', "true")
74                    }
75                    litCheckBox.setAttribute("value", data.text)
76                })
77                break;
78            case "radio":
79                this.litGroup = new LitRadioGroup();
80                if (this.title !== '') {
81                    let title = new LitPopoverTitle();
82                    title.setAttribute('title', this.title || "");
83                    this.popContent!.appendChild(title);
84                    this.litGroup.setAttribute("layout", "compact")
85                } else {
86                    this.litGroup.setAttribute("layout", "dispersion")
87                }
88                this.popContent!.appendChild(this.litGroup);
89                dataSource.forEach(data => {
90                    let litRadioBox = new LitRadioBox();
91                    if (this.title == '') {
92                        litRadioBox.setAttribute('dis', 'round')
93                    } else {
94                        litRadioBox.setAttribute('dis', 'check')
95                    }
96                    if (data.isSelected) {
97                        litRadioBox.setAttribute('checked', "true")
98                    }
99                    this.litGroup?.appendChild(litRadioBox)
100                    litRadioBox.setAttribute("value", data.text)
101                })
102                break;
103            case "multiple-text":
104                dataSource.forEach(data => {
105                    this._texBox = new LitCheckBoxWithText();
106                    this._texBox.setAttribute("text", data.text)
107                    this._texBox.setAttribute("checked", "")
108                    this.popContent!.appendChild(this._texBox);
109                })
110                break;
111            case "data-ming":
112                break;
113        }
114    }
115
116    get select(): Array<string> | undefined {
117        if (this._texBox?.checked) {
118            return [this._texBox!.text]
119        }
120        return this.litGroup?.value;
121    }
122
123    get trigger() {
124        return this.getAttribute('trigger');
125    }
126
127    get direction() {
128        return this.getAttribute('direction') || 'topright'
129    }
130
131    set direction(value: string) {
132        this.setAttribute('direction', value);
133    }
134
135    get open() {
136        return this.getAttribute('open') !== null;
137    }
138
139    set open(value: boolean) {
140        if (value === null || value === false) {
141            this.removeAttribute('open');
142        } else {
143            this.setAttribute('open', '');
144        }
145    }
146
147    initElements(): void {
148    }
149
150    initHtml(): string {
151        return `
152        <style>
153        :host {
154            display:inline-block;
155            position:relative;
156            overflow:visible;
157        }
158        :host([direction="top"]) ::slotted(lit-pop-content){
159            bottom:100%;
160            left:50%;
161            transform:translate(-50%,-10px) scale(0);
162            transform-origin: center bottom;
163        }
164        :host([direction="top"]) ::slotted(lit-pop-content)::after{
165            content: '';
166            position: absolute;
167            top: 100%;
168            left: 50%;
169            border-top: 10px solid #FFF;
170            border-right: 10px solid transparent;
171            border-left: 10px solid transparent;
172
173        }
174        :host([direction="top"]) ::slotted(lit-pop-content[open]),
175        :host([direction="top"][trigger="hover"]:hover) ::slotted(lit-pop-content),
176        :host([direction="top"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
177            transform:translate(-50%,-10px) scale(1);
178        }
179
180        :host([direction="bottom"]) ::slotted(lit-pop-content){
181            top:100%;
182            left:50%;
183            transform:translate(-50%,10px) scale(0);
184            transform-origin: center top;
185        }
186        :host([direction="bottom"]) ::slotted(lit-pop-content)::after{
187            content: '';
188            position: absolute;
189            bottom: 100%;
190            left: 50%;
191            border-bottom: 10px solid #FFF;
192            border-right: 10px solid transparent;
193            border-left: 10px solid transparent;
194        }
195        :host([direction="bottom"]) ::slotted(lit-pop-content[open]),
196        :host([direction="bottom"][trigger="hover"]:hover) ::slotted(lit-pop-content),
197        :host([direction="bottom"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
198            transform:translate(-50%,10px) scale(1);
199        }
200
201
202        :host([direction="left"]) ::slotted(lit-pop-content){
203            right:100%;
204            top:50%;
205            transform:translate(-10px,-50%) scale(0);
206            transform-origin: right;
207        }
208        :host([direction="left"]) ::slotted(lit-pop-content)::after{
209            content: '';
210            position: absolute;
211            bottom: 40%;
212            left: 100%;
213            border-left: 10px solid #FFF;
214            border-bottom: 10px solid transparent;
215            border-top: 10px solid transparent;
216        }
217        :host([direction="left"]) ::slotted(lit-pop-content[open]),
218        :host([direction="left"][trigger="hover"]:hover) ::slotted(lit-pop-content),
219        :host([direction="left"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
220            transform:translate(-10px,-50%) scale(1);
221        }
222        :host([direction="right"]) ::slotted(lit-pop-content){
223            left:100%;
224            top:50%;
225            transform:translate(10px,-50%) scale(0);
226            transform-origin: left;
227        }
228        :host([direction="right"]) ::slotted(lit-pop-content)::after{
229            content: '';
230            position: absolute;
231            bottom: 40%;
232            right: 100%;
233            border-right: 10px solid #FFF;
234            border-bottom: 10px solid transparent;
235            border-top: 10px solid transparent;
236        }
237        :host([direction="right"]) ::slotted(lit-pop-content[open]),
238        :host([direction="right"][trigger="hover"]:hover) ::slotted(lit-pop-content),
239        :host([direction="right"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
240            transform:translate(10px,-50%) scale(1);
241        }
242
243        :host([direction="leftbottom"]) ::slotted(lit-pop-content){
244            right:100%;
245            top:0;
246            transform:translate(-10px) scale(0);
247        }
248        :host([direction="leftbottom"]) ::slotted(lit-pop-content[open]),
249        :host([direction="leftbottom"][trigger="hover"]:hover) ::slotted(lit-pop-content),
250        :host([direction="leftbottom"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
251            transform:translate(-10px) scale(1);
252        }
253
254        :host([direction="leftbottom"]) ::slotted(lit-pop-content)::after{
255            content: '';
256            position: absolute;
257            top: 10%;
258            left: 100%;
259            border-left: 10px solid #FFF;
260            border-bottom: 10px solid transparent;
261        }
262
263        :host([direction="lefttop"]) ::slotted(lit-pop-content){
264            right:100%;
265            bottom:0;
266            transform:translate(-10px) scale(0);
267            transform-origin: right bottom;
268        }
269        :host([direction="lefttop"]) ::slotted(lit-pop-content)::after{
270            content: '';
271            position: absolute;
272            bottom: 10%;
273            left: 100%;
274            border-left: 10px solid #FFF;
275            border-top: 10px solid transparent;
276        }
277        :host([direction="lefttop"]) ::slotted(lit-pop-content[open]),
278        :host([direction="lefttop"][trigger="hover"]:hover) ::slotted(lit-pop-content),
279        :host([direction="lefttop"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
280            transform:translate(-10px) scale(1);
281        }
282        :host([direction="topright"]) ::slotted(lit-pop-content){
283            bottom:100%;
284            left:50%;
285            transform:translate(0,-10px) scale(0);
286            transform-origin: left bottom;
287        }
288        :host([direction="topright"]) ::slotted(lit-pop-content)::after{
289            content: '';
290            position: absolute;
291            top: 100%;
292            left: 0%;
293            border-top: 10px solid #FFF;
294            border-right: 10px solid transparent;
295        }
296        :host([direction="topright"]) ::slotted(lit-pop-content[open]),
297        :host([direction="topright"][trigger="hover"]:hover) ::slotted(lit-pop-content),
298        :host([direction="topright"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
299            transform:translate(0,-10px) scale(1);
300        }
301
302
303        :host([direction="topleft"]) ::slotted(lit-pop-content){
304            bottom:100%;
305            right:50%;
306            transform:translate(0,-10px) scale(0);
307            transform-origin: right bottom;
308        }
309        :host([direction="topleft"]) ::slotted(lit-pop-content)::after{
310            content: '';
311            position: absolute;
312            top: 100%;
313            right: 0%;
314            border-top: 10px solid #FFF;
315            border-left: 10px solid transparent;
316        }
317        :host([direction="topleft"]) ::slotted(lit-pop-content[open]),
318        :host([direction="topleft"][trigger="hover"]:hover) ::slotted(lit-pop-content),
319        :host([direction="topleft"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
320            transform:translate(0,-10px) scale(1);
321        }
322
323
324        :host([direction="rightbottom"]) ::slotted(lit-pop-content){
325            left:100%;
326            top:0;
327            transform:translate(10px) scale(0);
328            transform-origin: left top;
329        }
330        :host([direction="rightbottom"]) ::slotted(lit-pop-content)::after{
331            content: '';
332            position: absolute;
333            top: 10%;
334            right: 100%;
335            border-top: 10px solid #FFF;
336            border-left: 10px solid transparent;
337        }
338        :host([direction="rightbottom"]) ::slotted(lit-pop-content[open]),
339        :host([direction="rightbottom"][trigger="hover"]:hover) ::slotted(lit-pop-content),
340        :host([direction="rightbottom"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
341            transform:translate(10px) scale(1);
342        }
343        :host([direction="righttop"]) ::slotted(lit-pop-content){
344            left:100%;
345            bottom:0;
346            transform:translate(10px) scale(0);
347            transform-origin: left bottom;
348        }
349        :host([direction="righttop"]) ::slotted(lit-pop-content[open]),
350        :host([direction="righttop"][trigger="hover"]:hover) ::slotted(lit-pop-content),
351        :host([direction="righttop"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
352            transform:translate(10px) scale(1);
353        }
354        :host([direction="righttop"]) ::slotted(lit-pop-content)::after{
355            content: '';
356            position: absolute;
357            bottom: 10%;
358            right: 100%;
359            border-bottom: 10px solid #FFF;
360            border-left: 10px solid transparent;
361        }
362
363        :host([direction="bottomright"]) ::slotted(lit-pop-content),
364        :host(:not([direction])) ::slotted(lit-pop-content){
365            left:0;
366            top:100%;
367            transform:translate(0,10px) scale(0);
368            transform-origin: left top;
369        }
370        :host([direction="bottomright"]) ::slotted(lit-pop-content)::after,
371        :host(:not([direction])) ::slotted(lit-pop-content)::after{
372            content: '';
373            position: absolute;
374            left: 10%;
375            bottom: 100%;
376            border-bottom: 10px solid #FFF;
377            border-right: 10px solid transparent;
378        }
379        :host(:not([direction])) ::slotted(lit-pop-content[open]),
380        :host(:not([direction])[trigger="hover"]:hover) ::slotted(lit-pop-content),
381        :host(:not([direction])[trigger="focus"]:focus-within) ::slotted(lit-pop-content),
382        :host([direction="bottomright"]) ::slotted(lit-pop-content[open]),
383        :host([direction="bottomright"][trigger="hover"]:hover) ::slotted(lit-pop-content),
384        :host([direction="bottomright"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
385            transform:translate(0,10px) scale(1);
386        }
387
388        :host([direction="bottomleft"]) ::slotted(lit-pop-content){
389            right:0;
390            top:100%;
391            transform:translate(0,10px) scale(0);
392            transform-origin: right top;
393        }
394        :host([direction="bottomleft"]) ::slotted(lit-pop-content)::after,
395        :host(:not([direction])) ::slotted(lit-pop-content)::after{
396            content: '';
397            position: absolute;
398            right: 10%;
399            bottom: 100%;
400            border-bottom: 10px solid #FFF;
401            border-left: 10px solid transparent;
402        }
403        :host([direction="bottomleft"]) ::slotted(lit-pop-content[open]),
404        :host([direction="bottomleft"][trigger="hover"]:hover) ::slotted(lit-pop-content),
405        :host([direction="bottomleft"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
406            transform:translate(0,10px) scale(1);
407        }
408
409        :host ::slotted(lit-pop-content[open]),
410        :host([trigger="hover"]:hover) ::slotted(lit-pop-content),
411        :host([trigger="focus"]:focus-within) ::slotted(lit-pop-content){
412            opacity:1;
413            visibility:visible;
414        }
415        slot{
416        }
417        </style>
418        <slot></slot>
419      `;
420    }
421
422    connectedCallback() {
423        if (!(this.trigger && this.trigger !== 'click')) {
424            this.addEventListener('click', () => {
425                this.popContent = this.querySelector<LitPopContent>('lit-pop-content');
426                if (!this.popContent) {
427                    this.popContent = new LitPopContent();
428                    this.appendChild(this.popContent);
429                }
430                this.popContent?.setAttribute("open", 'true')
431            });
432        }
433        document.addEventListener('mousedown', ev => {
434            const path = ev.composedPath && ev.composedPath();
435            if (this.popContent && !path.includes(this.popContent) && !path.includes(this.children[0]) && !path.includes(this.popContent)) {
436                this.popContent!.open = false;
437            }
438        });
439    }
440}
441
442export interface SelectBean {
443    text: string;
444    isSelected: boolean;
445    limitText?: LimitText;
446}
447
448export interface LimitText {
449    textUpperLimit: string;
450    textLowerLimit: string;
451}
452
453export interface Charge {
454    text: string;
455    isSelected: boolean;
456}
457