1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { BaseElement, element } from '../BaseElement';
17fb726d48Sopenharmony_ci
18fb726d48Sopenharmony_ciconst initHtmlStyle: string = `
19fb726d48Sopenharmony_ci    <style>
20fb726d48Sopenharmony_ci        :host{ 
21fb726d48Sopenharmony_ci            display:inline-block; 
22fb726d48Sopenharmony_ci            -webkit-tap-highlight-color: transparent;
23fb726d48Sopenharmony_ci        }
24fb726d48Sopenharmony_ci        #name{
25fb726d48Sopenharmony_ci            transition:0.31s width,0.31s height,0.31s background-color;
26fb726d48Sopenharmony_ci            width:2.41em;
27fb726d48Sopenharmony_ci            height:1.21em;
28fb726d48Sopenharmony_ci            background: #3391FF;
29fb726d48Sopenharmony_ci            display:flex;
30fb726d48Sopenharmony_ci            padding:0.124em;
31fb726d48Sopenharmony_ci            border-radius:1.21em;
32fb726d48Sopenharmony_ci            cursor:pointer;
33fb726d48Sopenharmony_ci        }
34fb726d48Sopenharmony_ci        
35fb726d48Sopenharmony_ci        :host(:not([checked])) #name {
36fb726d48Sopenharmony_ci           background: #999999;
37fb726d48Sopenharmony_ci        }
38fb726d48Sopenharmony_ci       
39fb726d48Sopenharmony_ci        #name::before{
40fb726d48Sopenharmony_ci            content:'';
41fb726d48Sopenharmony_ci            flex:0;
42fb726d48Sopenharmony_ci            transition:.2s cubic-bezier(.12, .4, .29, 1.46) flex;
43fb726d48Sopenharmony_ci        }
44fb726d48Sopenharmony_ci        #name::after{
45fb726d48Sopenharmony_ci            content:'';
46fb726d48Sopenharmony_ci            width:.4em;
47fb726d48Sopenharmony_ci            height:.4em;
48fb726d48Sopenharmony_ci            border-radius:1.2em;
49fb726d48Sopenharmony_ci            border:.4em solid #fff;
50fb726d48Sopenharmony_ci            background-color:#ffffff;
51fb726d48Sopenharmony_ci            transition:.3s background,.3s padding,.3s width,.3s height,.3s border-radius,.3s border;
52fb726d48Sopenharmony_ci            box-shadow: 0 2px 4px 0 rgba(0,35,11,0.2);
53fb726d48Sopenharmony_ci        }
54fb726d48Sopenharmony_ci        #name:active::after{
55fb726d48Sopenharmony_ci            padding:0 .3em;
56fb726d48Sopenharmony_ci        }
57fb726d48Sopenharmony_ci        #switch:checked+#name{
58fb726d48Sopenharmony_ci            background:#42b983);
59fb726d48Sopenharmony_ci        }
60fb726d48Sopenharmony_ci        #switch:checked+#name::before{
61fb726d48Sopenharmony_ci            flex:1;
62fb726d48Sopenharmony_ci        }
63fb726d48Sopenharmony_ci        #switch{
64fb726d48Sopenharmony_ci            position:absolute;
65fb726d48Sopenharmony_ci            clip:rect(0,0px,0px,0);
66fb726d48Sopenharmony_ci        }
67fb726d48Sopenharmony_ci        :host(:focus-within) #name::after,:host(:active) ::after{ 
68fb726d48Sopenharmony_ci            background:#42b983;
69fb726d48Sopenharmony_ci        }
70fb726d48Sopenharmony_ci        :host(:focus-within) #name{ 
71fb726d48Sopenharmony_ci            box-shadow: 0 0 10px rgba(0,0,0,0.1); 
72fb726d48Sopenharmony_ci        }
73fb726d48Sopenharmony_ci        :host(:focus-within) #switch,:host(:active) #switch{
74fb726d48Sopenharmony_ci            z-index:2
75fb726d48Sopenharmony_ci        }
76fb726d48Sopenharmony_ci        :host([disabled]){ 
77fb726d48Sopenharmony_ci            pointer-events: none; 
78fb726d48Sopenharmony_ci            opacity:.5; 
79fb726d48Sopenharmony_ci        }
80fb726d48Sopenharmony_ci        :host([disabled]) #name{ 
81fb726d48Sopenharmony_ci            pointer-events: all;  
82fb726d48Sopenharmony_ci            cursor: not-allowed; 
83fb726d48Sopenharmony_ci        }
84fb726d48Sopenharmony_ci        </style>
85fb726d48Sopenharmony_ci    `;
86fb726d48Sopenharmony_ci
87fb726d48Sopenharmony_ci@element('lit-switch')
88fb726d48Sopenharmony_ciexport default class LitSwitch extends BaseElement {
89fb726d48Sopenharmony_ci  private switch: HTMLInputElement | null | undefined;
90fb726d48Sopenharmony_ci  private isfocus: boolean | undefined;
91fb726d48Sopenharmony_ci
92fb726d48Sopenharmony_ci  static get observedAttributes(): string[] {
93fb726d48Sopenharmony_ci    return ['disabled', 'checked'];
94fb726d48Sopenharmony_ci  }
95fb726d48Sopenharmony_ci
96fb726d48Sopenharmony_ci  get disabled(): boolean {
97fb726d48Sopenharmony_ci    return this.getAttribute('disabled') !== null;
98fb726d48Sopenharmony_ci  }
99fb726d48Sopenharmony_ci
100fb726d48Sopenharmony_ci  get checked(): boolean {
101fb726d48Sopenharmony_ci    return this.getAttribute('checked') !== null;
102fb726d48Sopenharmony_ci  }
103fb726d48Sopenharmony_ci
104fb726d48Sopenharmony_ci  set checked(value) {
105fb726d48Sopenharmony_ci    if (value === null || value === false) {
106fb726d48Sopenharmony_ci      this.removeAttribute('checked');
107fb726d48Sopenharmony_ci    } else {
108fb726d48Sopenharmony_ci      this.setAttribute('checked', '');
109fb726d48Sopenharmony_ci    }
110fb726d48Sopenharmony_ci  }
111fb726d48Sopenharmony_ci
112fb726d48Sopenharmony_ci  set disabled(value: boolean) {
113fb726d48Sopenharmony_ci    if (value === null || value === false) {
114fb726d48Sopenharmony_ci      this.removeAttribute('disabled');
115fb726d48Sopenharmony_ci    } else {
116fb726d48Sopenharmony_ci      this.setAttribute('disabled', '');
117fb726d48Sopenharmony_ci    }
118fb726d48Sopenharmony_ci  }
119fb726d48Sopenharmony_ci
120fb726d48Sopenharmony_ci  get name(): string | null {
121fb726d48Sopenharmony_ci    return this.getAttribute('name');
122fb726d48Sopenharmony_ci  }
123fb726d48Sopenharmony_ci
124fb726d48Sopenharmony_ci  initElements(): void {}
125fb726d48Sopenharmony_ci
126fb726d48Sopenharmony_ci  initHtml(): string {
127fb726d48Sopenharmony_ci    return `
128fb726d48Sopenharmony_ci        ${initHtmlStyle}
129fb726d48Sopenharmony_ci        <input type="checkbox" id="switch"><label id="name" for="switch"></label>
130fb726d48Sopenharmony_ci        `;
131fb726d48Sopenharmony_ci  }
132fb726d48Sopenharmony_ci
133fb726d48Sopenharmony_ci  connectedCallback(): void {
134fb726d48Sopenharmony_ci    this.switch = this.shadowRoot?.getElementById('switch') as HTMLInputElement;
135fb726d48Sopenharmony_ci    this.disabled = this.disabled;
136fb726d48Sopenharmony_ci    this.checked = this.checked;
137fb726d48Sopenharmony_ci    this.switch!.onchange = (ev): void => {
138fb726d48Sopenharmony_ci      this.checked = this.switch!.checked;
139fb726d48Sopenharmony_ci      let changeEvent: CustomEventInit<LitSwitchChangeEvent> = {
140fb726d48Sopenharmony_ci        detail: {
141fb726d48Sopenharmony_ci          checked: this.checked,
142fb726d48Sopenharmony_ci        },
143fb726d48Sopenharmony_ci      };
144fb726d48Sopenharmony_ci      this.dispatchEvent(new CustomEvent('change', changeEvent));
145fb726d48Sopenharmony_ci    };
146fb726d48Sopenharmony_ci    this.switch.onkeydown = (ev): void => {
147fb726d48Sopenharmony_ci      switch (ev.keyCode) {
148fb726d48Sopenharmony_ci        case 13: //enter
149fb726d48Sopenharmony_ci          this.checked = !this.checked;
150fb726d48Sopenharmony_ci          let changeEvent: CustomEventInit<LitSwitchChangeEvent> = {
151fb726d48Sopenharmony_ci            detail: {
152fb726d48Sopenharmony_ci              checked: this.checked,
153fb726d48Sopenharmony_ci            },
154fb726d48Sopenharmony_ci          };
155fb726d48Sopenharmony_ci          this.dispatchEvent(new CustomEvent('change', changeEvent));
156fb726d48Sopenharmony_ci          break;
157fb726d48Sopenharmony_ci        default:
158fb726d48Sopenharmony_ci          break;
159fb726d48Sopenharmony_ci      }
160fb726d48Sopenharmony_ci    };
161fb726d48Sopenharmony_ci    this.setEvent();
162fb726d48Sopenharmony_ci  }
163fb726d48Sopenharmony_ci
164fb726d48Sopenharmony_ci  setEvent(): void {
165fb726d48Sopenharmony_ci    this.switch!.onfocus = (ev): void => {
166fb726d48Sopenharmony_ci      ev.stopPropagation();
167fb726d48Sopenharmony_ci      if (!this.isfocus) {
168fb726d48Sopenharmony_ci        this.dispatchEvent(
169fb726d48Sopenharmony_ci          new CustomEvent('focus', {
170fb726d48Sopenharmony_ci            detail: { value: this.switch!.value },
171fb726d48Sopenharmony_ci          })
172fb726d48Sopenharmony_ci        );
173fb726d48Sopenharmony_ci      }
174fb726d48Sopenharmony_ci    };
175fb726d48Sopenharmony_ci    this.switch!.onblur = (ev): void => {
176fb726d48Sopenharmony_ci      ev.stopPropagation();
177fb726d48Sopenharmony_ci      if (getComputedStyle(this.switch!).zIndex === '2') {
178fb726d48Sopenharmony_ci        this.isfocus = true;
179fb726d48Sopenharmony_ci      } else {
180fb726d48Sopenharmony_ci        this.isfocus = false;
181fb726d48Sopenharmony_ci        this.dispatchEvent(
182fb726d48Sopenharmony_ci          new CustomEvent('blur', {
183fb726d48Sopenharmony_ci            detail: { value: this.switch!.value },
184fb726d48Sopenharmony_ci          })
185fb726d48Sopenharmony_ci        );
186fb726d48Sopenharmony_ci      }
187fb726d48Sopenharmony_ci    };
188fb726d48Sopenharmony_ci  }
189fb726d48Sopenharmony_ci
190fb726d48Sopenharmony_ci  attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
191fb726d48Sopenharmony_ci    if (name === 'disabled' && this.switch) {
192fb726d48Sopenharmony_ci      if (newValue !== null) {
193fb726d48Sopenharmony_ci        this.switch.setAttribute('disabled', '');
194fb726d48Sopenharmony_ci      } else {
195fb726d48Sopenharmony_ci        this.switch.removeAttribute('disabled');
196fb726d48Sopenharmony_ci      }
197fb726d48Sopenharmony_ci    }
198fb726d48Sopenharmony_ci    if (name === 'checked' && this.switch) {
199fb726d48Sopenharmony_ci      if (newValue !== null) {
200fb726d48Sopenharmony_ci        this.switch.checked = true;
201fb726d48Sopenharmony_ci      } else {
202fb726d48Sopenharmony_ci        this.switch.checked = false;
203fb726d48Sopenharmony_ci      }
204fb726d48Sopenharmony_ci    }
205fb726d48Sopenharmony_ci  }
206fb726d48Sopenharmony_ci}
207fb726d48Sopenharmony_ci
208fb726d48Sopenharmony_ciexport interface LitSwitchChangeEvent {
209fb726d48Sopenharmony_ci  checked: boolean;
210fb726d48Sopenharmony_ci}
211