• 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
244
245        :host([direction="leftbottom"]) ::slotted(lit-pop-content){
246            right:100%;
247            top:0;
248            transform:translate(-10px) scale(0);
249        }
250        :host([direction="leftbottom"]) ::slotted(lit-pop-content[open]),
251        :host([direction="leftbottom"][trigger="hover"]:hover) ::slotted(lit-pop-content),
252        :host([direction="leftbottom"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
253            transform:translate(-10px) scale(1);
254        }
255
256        :host([direction="leftbottom"]) ::slotted(lit-pop-content)::after{
257            content: '';
258            position: absolute;
259            top: 10%;
260            left: 100%;
261            border-left: 10px solid #FFF;
262            border-bottom: 10px solid transparent;
263        }
264
265        :host([direction="lefttop"]) ::slotted(lit-pop-content){
266            right:100%;
267            bottom:0;
268            transform:translate(-10px) scale(0);
269            transform-origin: right bottom;
270        }
271        :host([direction="lefttop"]) ::slotted(lit-pop-content)::after{
272            content: '';
273            position: absolute;
274            bottom: 10%;
275            left: 100%;
276            border-left: 10px solid #FFF;
277            border-top: 10px solid transparent;
278        }
279        :host([direction="lefttop"]) ::slotted(lit-pop-content[open]),
280        :host([direction="lefttop"][trigger="hover"]:hover) ::slotted(lit-pop-content),
281        :host([direction="lefttop"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
282            transform:translate(-10px) scale(1);
283        }
284        :host([direction="topright"]) ::slotted(lit-pop-content){
285            bottom:100%;
286            left:50%;
287            transform:translate(0,-10px) scale(0);
288            transform-origin: left bottom;
289        }
290        :host([direction="topright"]) ::slotted(lit-pop-content)::after{
291            content: '';
292            position: absolute;
293            top: 100%;
294            left: 0%;
295            border-top: 10px solid #FFF;
296            border-right: 10px solid transparent;
297        }
298        :host([direction="topright"]) ::slotted(lit-pop-content[open]),
299        :host([direction="topright"][trigger="hover"]:hover) ::slotted(lit-pop-content),
300        :host([direction="topright"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
301            transform:translate(0,-10px) scale(1);
302        }
303
304
305        :host([direction="topleft"]) ::slotted(lit-pop-content){
306            bottom:100%;
307            right:50%;
308            transform:translate(0,-10px) scale(0);
309            transform-origin: right bottom;
310        }
311        :host([direction="topleft"]) ::slotted(lit-pop-content)::after{
312            content: '';
313            position: absolute;
314            top: 100%;
315            right: 0%;
316            border-top: 10px solid #FFF;
317            border-left: 10px solid transparent;
318        }
319        :host([direction="topleft"]) ::slotted(lit-pop-content[open]),
320        :host([direction="topleft"][trigger="hover"]:hover) ::slotted(lit-pop-content),
321        :host([direction="topleft"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
322            transform:translate(0,-10px) scale(1);
323        }
324
325
326        :host([direction="rightbottom"]) ::slotted(lit-pop-content){
327            left:100%;
328            top:0;
329            transform:translate(10px) scale(0);
330            transform-origin: left top;
331        }
332        :host([direction="rightbottom"]) ::slotted(lit-pop-content)::after{
333            content: '';
334            position: absolute;
335            top: 10%;
336            right: 100%;
337            border-top: 10px solid #FFF;
338            border-left: 10px solid transparent;
339        }
340        :host([direction="rightbottom"]) ::slotted(lit-pop-content[open]),
341        :host([direction="rightbottom"][trigger="hover"]:hover) ::slotted(lit-pop-content),
342        :host([direction="rightbottom"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
343            transform:translate(10px) scale(1);
344        }
345        :host([direction="righttop"]) ::slotted(lit-pop-content){
346            left:100%;
347            bottom:0;
348            transform:translate(10px) scale(0);
349            transform-origin: left bottom;
350        }
351        :host([direction="righttop"]) ::slotted(lit-pop-content[open]),
352        :host([direction="righttop"][trigger="hover"]:hover) ::slotted(lit-pop-content),
353        :host([direction="righttop"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
354            transform:translate(10px) scale(1);
355        }
356        :host([direction="righttop"]) ::slotted(lit-pop-content)::after{
357            content: '';
358            position: absolute;
359            bottom: 10%;
360            right: 100%;
361            border-bottom: 10px solid #FFF;
362            border-left: 10px solid transparent;
363        }
364
365        :host([direction="bottomright"]) ::slotted(lit-pop-content),
366        :host(:not([direction])) ::slotted(lit-pop-content){
367            left:0;
368            top:100%;
369            transform:translate(0,10px) scale(0);
370            transform-origin: left top;
371        }
372        :host([direction="bottomright"]) ::slotted(lit-pop-content)::after,
373        :host(:not([direction])) ::slotted(lit-pop-content)::after{
374            content: '';
375            position: absolute;
376            left: 10%;
377            bottom: 100%;
378            border-bottom: 10px solid #FFF;
379            border-right: 10px solid transparent;
380        }
381        :host(:not([direction])) ::slotted(lit-pop-content[open]),
382        :host(:not([direction])[trigger="hover"]:hover) ::slotted(lit-pop-content),
383        :host(:not([direction])[trigger="focus"]:focus-within) ::slotted(lit-pop-content),
384        :host([direction="bottomright"]) ::slotted(lit-pop-content[open]),
385        :host([direction="bottomright"][trigger="hover"]:hover) ::slotted(lit-pop-content),
386        :host([direction="bottomright"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
387            transform:translate(0,10px) scale(1);
388        }
389
390        :host([direction="bottomleft"]) ::slotted(lit-pop-content){
391            right:0;
392            top:100%;
393            transform:translate(0,10px) scale(0);
394            transform-origin: right top;
395        }
396        :host([direction="bottomleft"]) ::slotted(lit-pop-content)::after,
397        :host(:not([direction])) ::slotted(lit-pop-content)::after{
398            content: '';
399            position: absolute;
400            right: 10%;
401            bottom: 100%;
402            border-bottom: 10px solid #FFF;
403            border-left: 10px solid transparent;
404        }
405        :host([direction="bottomleft"]) ::slotted(lit-pop-content[open]),
406        :host([direction="bottomleft"][trigger="hover"]:hover) ::slotted(lit-pop-content),
407        :host([direction="bottomleft"][trigger="focus"]:focus-within) ::slotted(lit-pop-content){
408            transform:translate(0,10px) scale(1);
409        }
410
411        :host ::slotted(lit-pop-content[open]),
412        :host([trigger="hover"]:hover) ::slotted(lit-pop-content),
413        :host([trigger="focus"]:focus-within) ::slotted(lit-pop-content){
414            opacity:1;
415            visibility:visible;
416        }
417        slot{
418        }
419        </style>
420        <slot></slot>
421      `;
422    }
423
424    connectedCallback() {
425        if (!(this.trigger && this.trigger !== 'click')) {
426            this.addEventListener('click', () => {
427                this.popContent = this.querySelector<LitPopContent>('lit-pop-content');
428                if (!this.popContent) {
429                    this.popContent = new LitPopContent();
430                    this.appendChild(this.popContent);
431                }
432                this.popContent?.setAttribute("open", 'true')
433            });
434        }
435        document.addEventListener('mousedown', ev => {
436            const path = ev.composedPath && ev.composedPath();
437            if (this.popContent && !path.includes(this.popContent) && !path.includes(this.children[0]) && !path.includes(this.popContent)) {
438                this.popContent!.open = false;
439            }
440        });
441    }
442}
443
444export interface SelectBean {
445    text: string;
446    isSelected: boolean;
447    limitText?: LimitText;
448}
449
450export interface LimitText {
451    textUpperLimit: string;
452    textLowerLimit: string;
453}
454
455export interface Charge {
456    text: string;
457    isSelected: boolean;
458}
459