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(): string[] { 163 return ['checked', 'value', 'disabled']; 164 } 165 166 get disabled(): boolean { 167 return this.getAttribute('disabled') !== null; 168 } 169 170 get checked(): boolean { 171 return this.getAttribute('checked') !== null; 172 } 173 174 get name(): string | null { 175 return this.getAttribute('name'); 176 } 177 178 set checked(radioValue: boolean) { 179 if (radioValue === null || !radioValue) { 180 this.removeAttribute('checked'); 181 } else { 182 this.setAttribute('checked', ''); 183 } 184 } 185 186 get value(): string { 187 let slot = this.shadowRoot?.getElementById('slot'); 188 return slot!.textContent || this.textContent || ''; 189 } 190 191 set disabled(value: boolean) { 192 if (value === null || value === false) { 193 this.removeAttribute('disabled'); 194 } else { 195 this.setAttribute('disabled', ''); 196 } 197 } 198 199 set dis(dis: string) { 200 this.setAttribute('dis', dis); 201 } 202 203 set value(value: string) { 204 this.setAttribute('value', value); 205 } 206 207 initHtml(): string { 208 return ` 209 ${initHtmlStyle} 210 <input type="checkbox" id="radio" > 211 <label id="label" for="radio"> 212 <span class="selected"> 213 <lit-icon name="checkmark" class="icon" size="8"> 214 </lit-icon> 215 </span> 216 <slot id='slot'></slot> 217 </label> 218 `; 219 } 220 221 initElements(): void { 222 this.radio = this.shadowRoot?.getElementById('radio') as HTMLInputElement; 223 } 224 225 connectedCallback(): void { 226 this.group = this.closest('lit-radio-group') as LitRadioGroup; 227 this.parent = this.group || this.getRootNode(); 228 this.radio = this.shadowRoot?.getElementById('radio') as HTMLInputElement; 229 this.checked = this.checked; 230 this.radio.addEventListener('change', () => { 231 const selector = this.group ? 'lit-radio[checked]' : 'lit-radio[name="${this.name}"][checked]'; 232 const siblingNode = this.parent?.querySelector(selector) as LitRadioBox; 233 if (siblingNode) { 234 siblingNode.checked = false; 235 } 236 this.checked = true; 237 }); 238 } 239 240 attributeChangedCallback(name: string, oldValue: string, newValue: string): void { 241 if (name === 'checked' && this.radio) { 242 this.radio.checked = newValue !== null; 243 } 244 if (name === 'value') { 245 let slot = this.shadowRoot?.getElementById('slot'); 246 slot!.textContent = newValue; 247 } 248 } 249} 250