• 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';
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