• 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-drawer')
19export class LitDrawer extends BaseElement {
20  static get observedAttributes() {
21    return ['title', 'visible', 'placement', 'mask', 'mask-closable', 'closeable', 'content-padding', 'content-width'];
22  }
23
24  initHtml(): string {
25    return `
26        <style>
27        :host{
28            display: flex;
29            position: absolute;
30            top: 0;
31            bottom: 0;
32            left: 0;
33            right: 0;
34            width: 100%;
35            height: 100%;
36            overflow: hidden;
37            z-index: 2001;
38            pointer-events: none;
39         }
40         :host([mask]) .bg{
41            position:absolute;
42            top: 0;
43            right: 0;
44            left: 0;
45            bottom: 0;
46            width: 100%;
47            height: 100%;
48            background-color: #00000055;
49         }
50         :host(:not([mask])) .bg{
51            display: none;
52         }
53
54
55         .title{
56            display: flex;
57            justify-content: space-between;
58            align-items: center;
59            padding: 12px 20px;
60            border-bottom: var(--dark-border1,#f0f0f0) 1px solid;
61            font-size: 18px;
62            font-weight: bold;
63            color: var(--dark-color1,#262626);
64         }
65         slot{
66            padding: ${this.contentPadding};
67            display: block;
68         }
69         :host([visible]) .bg{
70            transition: all .3s;
71            opacity: 1;
72            visibility: visible;
73         }
74         :host(:not([visible])) .bg{
75            transition: all .3s;
76            opacity: 0;
77            visibility: hidden;
78         }
79         /*
80            right(默认)
81         */
82         :host(:not([placement])) .drawer,
83         :host([placement='right']) .drawer{
84            width: ${this.contentWidth};
85            box-sizing: border-box;
86            position: absolute;
87            display: flex;
88            flex-direction: column;
89            right: 0px;
90            top: 0px;
91            bottom: 0px;
92            height: 100%;
93            overflow: auto;
94            background-color: var(--dark-background,#FFFFFF);
95            -webkit-transform: translateZ(0);
96            -moz-transform: translateZ(0);
97            -ms-transform: translateZ(0);
98            -o-transform: translateZ(0);
99            transform: translateZ(0);
100            transform: translateX(100%);
101            transition: transform .3s;
102         }
103         :host(:not([placement])[visible]) .drawer,
104         :host([placement='right'][visible]) .drawer{
105            transform: translateX(0%);
106            box-shadow: 0px 0 20px 0px #00000055;
107         }
108         :host(:not([visible]):not([placement])) .drawer,
109         :host(:not([visible])[placement='right']) .drawer{
110            transform: translateX(100%);
111         }
112         /*
113            左边
114         */
115         :host([placement='left']) .drawer{
116            width: ${this.contentWidth};
117            box-sizing: border-box;
118            position: absolute;
119            display: flex;
120            flex-direction: column;
121            left: 0px;
122            top: 0px;
123            bottom: 0px;
124            right: auto;
125            height: 100%;
126            background-color: var(--dark-background,#FFFFFF);
127            webkit-transform: translate3d(0,0,0);
128            -moz-transform: translate3d(0,0,0);
129            -ms-transform: translate3d(0,0,0);
130            -o-transform: translate3d(0,0,0);
131            transform: translate3d(0,0,0);
132            transform: translate(0%,0%);
133         }
134         :host([placement='left']) .drawer{
135            transition: transform .3s;
136         }
137         :host([placement='left'][visible]) .drawer{
138            box-shadow: 0px 0 60px 0px #00000055;
139            transform: translate(0%,0%);
140         }
141         :host(:not([visible])[placement='left']) .drawer{
142            transform: translate(-100%,0%);
143         }
144
145         /*
146            top
147         */
148         :host([placement='top']) .drawer{
149            box-sizing: border-box;
150            position: absolute;
151            display: flex;
152            flex-direction: column;
153            left: 0px;
154            top: 0px;
155            right: 0px;
156            width: 100%;
157            background-color: var(--dark-background,#FFFFFF);
158            webkit-transform: translate3d(0,0,0);
159            -moz-transform: translate3d(0,0,0);
160            -ms-transform: translate3d(0,0,0);
161            -o-transform: translate3d(0,0,0);
162            transform: translate3d(0,0,0);
163         }
164         :host([placement='top']) .drawer{
165            transform: translateY(-100%);
166            transition: transform .3s;
167         }
168         :host([placement='top'][visible]) .drawer{
169            box-shadow: 0px 0 60px 0px #00000055;
170            transform: translateY(0%);
171         }
172         :host(:not([visible])[placement='top']) .drawer{
173            transform: translateY(-100%);
174         }
175
176         /*
177            bottom
178         */
179         :host([placement='bottom']) .drawer{
180            box-sizing: border-box;
181            position: absolute;
182            display: flex;
183            flex-direction: column;
184            left: 0px;
185            bottom: 0px;
186            right: 0px;
187            top: auto;
188            width: 100%;
189            background-color: var(--dark-background,#FFFFFF);
190            webkit-transform: translate3d(0,0,0);
191            -moz-transform: translate3d(0,0,0);
192            -ms-transform: translate3d(0,0,0);
193            -o-transform: translate3d(0,0,0);
194            transform: translate3d(0,0,0);
195            transform: translate(0%,0%);
196            transition: transform .3s;
197         }
198         :host([placement='bottom'][visible]) .drawer{
199            box-shadow: 0px 0 60px 0px #00000055;
200            transform: translate(0%,0%);
201         }
202         :host(:not([visible])[placement='bottom']) .drawer{
203            transform: translate(0%,100%);
204         }
205
206         :host([closeable]) .close-icon{
207            display: flex;
208            color: #8c8c8c;
209            padding: 5px;
210         }
211         :host([closeable]) .close-icon:hover{
212            color: #414141;
213         }
214         :host(:not([closeable])) .close-icon{
215            display: none;
216         }
217        </style>
218        <div class="bg"></div>
219        <div class="drawer">
220            <div class="title">
221                <label id="drawer-tittle-text">${this.title}</label>
222                <lit-icon class="close-icon" name="close"></lit-icon>
223            </div>
224            <div style="overflow-x: hidden;overflow-y: auto">
225                <slot></slot>
226            </div>
227        </div>
228        `;
229  }
230  get contentWidth() {
231    return this.getAttribute('content-width') || '400px';
232  }
233  set contentWidth(value) {
234    this.shadowRoot!.querySelector<HTMLDivElement>('.drawer')!.style.width = value;
235    this.setAttribute('content-width', value);
236  }
237  get contentPadding() {
238    return this.getAttribute('content-padding') || '20px';
239  }
240  set contentPadding(value) {
241    this.shadowRoot!.querySelector('slot')!.style.padding = value;
242    this.setAttribute('content-padding', value);
243  }
244  get placement() {
245    return this.getAttribute('placement');
246  }
247  set placement(value: any) {
248    this.setAttribute('placement', value);
249  }
250  get title() {
251    return this.getAttribute('title') || '';
252  }
253  set title(value) {
254    this.shadowRoot!.querySelector('#drawer-tittle-text')!.textContent = value;
255    this.setAttribute('title', value);
256  }
257  get visible() {
258    return this.getAttribute('visible') !== null;
259  }
260  set visible(value: any) {
261    if (value) {
262      this.setAttribute('visible', value);
263    } else {
264      this.removeAttribute('visible');
265    }
266  }
267  get mask() {
268    return this.getAttribute('mask') !== null;
269  }
270  set mask(value) {
271    if (value) {
272      this.setAttribute('mask', '');
273    } else {
274      this.removeAttribute('mask');
275    }
276  }
277  get maskCloseable() {
278    return this.getAttribute('mask-closeable') !== null;
279  }
280  set maskCloseable(value) {
281    if (value) {
282      this.setAttribute('mask-closeable', '');
283    } else {
284      this.removeAttribute('mask-closeable');
285    }
286  }
287  get closeable() {
288    return this.getAttribute('closeable') !== null;
289  }
290
291  set closeable(value) {
292    if (value) {
293      this.setAttribute('closeable', '');
294    } else {
295      this.removeAttribute('closeable');
296    }
297  }
298
299  //当 custom element首次被插入文档DOM时,被调用。
300  initElements(): void {
301    let bg: HTMLDivElement | null = this.shadowRoot!.querySelector('.bg');
302    if (this.maskCloseable) {
303      bg!.onclick = (e: any) => {
304        e.stopPropagation();
305        this.visible = false;
306        this.dispatchEvent(new CustomEvent('onClose', e));
307      };
308    }
309    if (this.closeable) {
310      (this.shadowRoot!.querySelector('.close-icon') as any).onclick = (e: any) => {
311        this.visible = false;
312        this.dispatchEvent(new CustomEvent('onClose', e));
313      };
314    }
315  }
316  set onClose(fn: any) {
317    this.addEventListener('onClose', fn);
318  }
319  //当 custom element从文档DOM中删除时,被调用。
320  disconnectedCallback() {}
321
322  //当 custom element被移动到新的文档时,被调用。
323  adoptedCallback() {
324
325  }
326
327  //当 custom element增加、删除、修改自身属性时,被调用。
328  attributeChangedCallback(name: string, oldValue: string, newValue: string) {
329    if (this.mask) {
330      if (name === 'visible') {
331        if (newValue !== null) {
332          this.style.pointerEvents = 'all';
333        } else {
334          this.style.pointerEvents = 'none';
335        }
336      } else if (name === 'placement') {
337        if (newValue === 'bottom') {
338          let el = this.shadowRoot!.querySelector('.drawer');
339        }
340      }
341    }
342  }
343}
344
345if (!customElements.get('lit-drawer')) {
346  customElements.define('lit-drawer', LitDrawer);
347}
348