• 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() {
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