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