-
Notifications
You must be signed in to change notification settings - Fork 1
/
qui-switch.js
132 lines (120 loc) · 4.15 KB
/
qui-switch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { LitElement, html, css} from 'lit';
/**
* Switch UI Component
*/
export class QuiSwitch extends LitElement {
static styles = css`
:host {
--switch-width: 2.75rem; /* Default width */
--switch-height: 1.65rem; /* Default height */
--knob-size: calc(var(--switch-height) - 0.4rem);
}
input {
appearance: none;
position: relative;
display: inline-block;
background: var(--lumo-contrast-10pct, hsla(214, 57%, 24%, 0.1));
height: var(--switch-height);
width: var(--switch-width);
vertical-align: middle;
border-radius: 2rem;
box-shadow: 0px 1px 3px var(--lumo-contrast-20pct, hsla(214, 53%, 23%, 0.16)) inset;
transition: 0.25s linear background;
}
input::before {
content: "";
display: block;
width: var(--knob-size);
height: var(--knob-size);
background: var(--lumo-base-color, hsla(0, 100%, 100%, 1.0));
border-radius: 50%;
position: absolute;
top: 0.2rem;
left: 0.2rem;
box-shadow: 0px 1px 3px var(--lumo-contrast-20pct, hsla(214, 53%, 23%, 0.16));
transition: 0.25s linear transform;
}
input:focus {
outline: none;
}
input:checked {
background: var(--lumo-success-color, hsla(145, 72%, 30%, 1.0));
}
input:checked::before {
transform: translateX(calc(var(--switch-width) - var(--knob-size) - 0.4rem));
}
.label {
color: var(--lumo-body-text-color, hsla(214, 40%, 16%, 0.94));
}
`;
static properties = {
label: {type: String},
checked: {type: Boolean, reflect: true},
size: {type: String}
};
constructor(){
super();
this.label = null;
this.checked = false; // Default unchecked
this.size = 'normal'; // Default size
}
connectedCallback() {
super.connectedCallback();
}
updated(changedProperties) {
if (changedProperties.has('size')) {
this.updateSize();
}
}
updateSize() {
switch (this.size) {
case 'tiny':
this.style.setProperty('--switch-width', '1.75rem');
this.style.setProperty('--switch-height', '1rem');
break;
case 'small':
this.style.setProperty('--switch-width', '2.25rem');
this.style.setProperty('--switch-height', '1.35rem');
break;
case 'normal':
this.style.setProperty('--switch-width', '2.75rem');
this.style.setProperty('--switch-height', '1.65rem');
break;
case 'large':
this.style.setProperty('--switch-width', '3.5rem');
this.style.setProperty('--switch-height', '2.1rem');
break;
default:
// Check if the value is a valid custom size in pixels
if (this.size.endsWith('px')) {
let sizeValues = this.size.split('x');
if (sizeValues.length === 2) {
this.style.setProperty('--switch-width', sizeValues[0]);
this.style.setProperty('--switch-height', sizeValues[1]);
}
}
break;
}
}
render() {
return html`<label>
<input type="checkbox" ?checked="${this.checked}" @click="${this._click}"/>
${this._renderLabel()}
</label>`;
}
_renderLabel() {
if (this.label) {
return html`<span class="label">${this.label}</span>`;
}
}
_click(e) {
this.checked = !this.checked;
// Dispatch the event with the new checked state
this.dispatchEvent(new CustomEvent('valueChanged', {
detail: { checked: this.checked },
bubbles: true,
composed: true
}));
}
}
customElements.define('qui-switch', QuiSwitch);