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'; 17import { LitRadioGroup } from './LitRadioGroup'; 18 19const initHtmlStyle: string = ` 20 <style> 21 :host([dis=round]):host{ 22 font-family: Helvetica,serif; 23 font-size: 14px; 24 color: var(--dark-color1,#212121); 25 text-align: left; 26 line-height: 16px; 27 font-weight: 400; 28 } 29 :host([dis=round]) lit-icon{ 30 display: none; 31 } 32 :host([dis=round]) #radio{ 33 position:absolute; 34 clip:rect(0,0,0,0); 35 } 36 :host([dis=round]) :host(:focus-within) .selected label:hover .selected{ 37 z-index:1; 38 border-color:#a671ef; 39 } 40 :host([dis=round]) label{ 41 box-sizing:border-box; 42 cursor:pointer; 43 display:flex; 44 align-items:center; 45 } 46 :host([dis=round]) .selected{ 47 position:relative; 48 display: flex; 49 box-sizing: border-box; 50 width: 16px; 51 height: 16px; 52 border-radius:50%; 53 border: 2px solid var(--dark-color1,#4D4D4D); 54 margin-right:1em; 55 } 56 .selected{ 57 position:relative; 58 box-sizing: border-box; 59 margin-right:1em; 60 } 61 :host([dis=round]) .selected::before{ 62 content:''; 63 width:6px; 64 height:6px; 65 margin:auto; 66 border-radius:50%; 67 background:#a671ef; 68 transform: scale(0); 69 } 70 :host([dis=round]) .blue::before{ 71 background: #0a59f7; 72 } 73 :host([dis=round]) #radio:focus-visible+label .selected::after{ 74 transform:scale(2.5); 75 } 76 :host([dis=round]) #radio:checked+label .selected::before{ 77 transform: scale(1); 78 } 79 :host([dis=round]) #radio:checked+label .selected{ 80 border-color:#a671ef; 81 } 82 :host([dis=round]) #radio:checked+label .blue{ 83 border-color: #0a59f7; 84 } 85 :host([dis=check]):host{ 86 opacity: 0.9; 87 font-family: Helvetica,serif; 88 font-size: 14px; 89 text-align: left; 90 font-weight: 400; 91 } 92 :host([dis=round]) lit-icon{ 93 visibility: visible; 94 } 95 :host([dis=check]) #radio{ 96 position:absolute; 97 clip:rect(0,0,0,0); 98 } 99 :host([dis=check]) label{ 100 box-sizing:border-box; 101 cursor:pointer; 102 display:flex; 103 align-items:center; 104 } 105 :host([dis=check]) .selected{ 106 position:relative; 107 display:flex; 108 justify-content: center; 109 align-items: center; 110 margin-right:5px; 111 width: 16px; 112 height:16px; 113 } 114 :host([dis=check]) .selected::before{ 115 position:absolute; 116 content:''; 117 width:74%; 118 height:0.15em; 119 background:#fff; 120 transform:scale(0); 121 border-radius: 0.15em; 122 } 123 :host([dis=check]) .selected::after{ 124 content:''; 125 position:absolute; 126 width:100%; 127 height:100%; 128 border-radius:50%; 129 background:#1A83FF; 130 opacity:0.2; 131 transform:scale(0); 132 z-index:-1; 133 } 134 :host([dis=check]) #radio:checked:not(:indeterminate)+label .selected .icon{ 135 transform: scale(1.5); 136 } 137 :host([dis=check]) #radio:indeterminate+label .selected::before{ 138 transform:scale(1); 139 } 140 :host([dis=check]) .icon{ 141 width: 90%; 142 height: 55%; 143 margin-left: 5px; 144 transform: scale(0); 145 } 146 :host([checked][dis=check]) { 147 background-color: #1A83FF; 148 color:#ffffff 149 } 150 :host([disabled]){ 151 pointer-events: none; 152 } 153 </style> 154 `; 155 156@element('lit-radio') 157export class LitRadioBox extends BaseElement { 158 private group: LitRadioGroup | undefined | null; 159 private parent: LitRadioGroup | undefined | null; 160 private radio: HTMLInputElement | undefined | null; 161 162 static get observedAttributes() { 163 return ['checked', 'value', 'disabled']; 164 } 165 166 get disabled() { 167 return this.getAttribute('disabled') !== null; 168 } 169 170 171 get checked() { 172 return this.getAttribute('checked') !== null; 173 } 174 175 get name() { 176 return this.getAttribute('name'); 177 } 178 179 set checked(radioValue: boolean) { 180 if (radioValue === null || !radioValue) { 181 this.removeAttribute('checked'); 182 } else { 183 this.setAttribute('checked', ''); 184 } 185 } 186 187 get value() { 188 let slot = this.shadowRoot?.getElementById('slot'); 189 return slot!.textContent || this.textContent || ''; 190 } 191 192 set disabled(value: boolean) { 193 if (value === null || value === false) { 194 this.removeAttribute('disabled'); 195 } else { 196 this.setAttribute('disabled', ''); 197 } 198 } 199 200 set dis(dis: string) { 201 this.setAttribute('dis', dis); 202 } 203 204 set value(value: string) { 205 this.setAttribute('value', value); 206 } 207 208 initHtml(): string { 209 return ` 210 ${initHtmlStyle} 211 <input type="checkbox" id="radio" > 212 <label id="label" for="radio"> 213 <span class="selected"> 214 <lit-icon name="checkmark" class="icon" size="8"> 215 </lit-icon> 216 </span> 217 <slot id='slot'></slot> 218 </label> 219 `; 220 } 221 222 initElements(): void { 223 this.radio = this.shadowRoot?.getElementById('radio') as HTMLInputElement; 224 } 225 226 connectedCallback() { 227 this.group = this.closest('lit-radio-group') as LitRadioGroup; 228 this.parent = this.group || this.getRootNode(); 229 this.radio = this.shadowRoot?.getElementById('radio') as HTMLInputElement; 230 this.checked = this.checked; 231 this.radio.addEventListener('change', () => { 232 const selector = this.group ? `lit-radio[checked]` : `lit-radio[name="${this.name}"][checked]`; 233 const siblingNode = this.parent?.querySelector(selector) as LitRadioBox; 234 if (siblingNode) { 235 siblingNode.checked = false; 236 } 237 this.checked = true; 238 }); 239 } 240 241 attributeChangedCallback(name: string, oldValue: string, newValue: string) { 242 if (name == 'checked' && this.radio) { 243 this.radio.checked = newValue !== null; 244 } 245 if (name == 'value') { 246 let slot = this.shadowRoot?.getElementById('slot'); 247 slot!.textContent = newValue; 248 } 249 } 250} 251