Introduction
This component consists in a "toggle switch" (on/off button).
Let's start by creating the structure of our web component. Create a file switchLab.js:
class switchLab extends HTMLElement {
//Here will be all the functionality.
}
window.customElements.define('switch-lab', switchLab);
Step 1: Add a constructor and a getters.
class switchLab extends HTMLElement {
constructor () {
super();
}
get round() {
return this.hasAttribute('round');
}
get bgcolor() {
return this.hasAttribute('bgcolor');
}
get label() {
return this.hasAttribute('label');
}
get size() {
return this.hasAttribute('size');
}
get leftposition() {
return this.hasAttribute('leftposition');
}
get value() {
return this.hasAttribute('value');
}
get checked() {
return this.hasAttribute('checked');
}
}
window.customElements.define('switch-lab', switchLab);
In this case we create six attributes (not observables):
- round: If you want a rounded switch.
- bgcolor: Set a background color. By default #2196F3.
- label: Set the switch label.
- size: There are two available option: small and large. Without size will be a medium size component.
- value: Set the value to the component.
- checked: If you want that start checked.
Step 3: Add a function connectedCallback
It will be fired when the component is created
class switchLab extends HTMLElement {
//Step 1
//Step 2
connectedCallback () {
//Here will be the functionality.
}
}
window.customElements.define('switch-lab', switchLab);
Inside connectedCallback function we will create two things:
- shadowRoot: Is the shadowDOM of the component. It contains the styles of the component and its html definition.
- Conditions to apply certain functions to the component.
Filling the connectedCallback function:
class switchLab extends HTMLElement {
//Step 1
//Step 2
connectedCallback () {
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
.switch {
position: relative;
display: inline-block;
width: 55px;
height: 28px;
}
.switch_large {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch_small {
position: relative;
display: inline-block;
width: 41px;
height: 23px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider_large {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 22px;
width: 22px;
left: 4px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
.slider_large:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
.slider_small:before {
position: absolute;
content: "";
height: 17px;
width: 17px;
left: 3px;
bottom: 3px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider_small {
background-color: #2196F3;
}
input:focus + .slider_small {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
input:checked + .slider_small:before {
-webkit-transform: translateX(19px);
-ms-transform: translateX(19px);
transform: translateX(19px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
#label{
top: 3px;
position: relative;
left: 4px;
color: #5c5858;
}
.labelLarge{
top: 5px!important;
}
.labelSmall{
top: 0px!important;
}
</style>
<label id='switchCmp' class="switch">
<input type="checkbox">
<span id='switch' class="slider"></span>
</label>
<span id='label'></span>`;
if(this.round)
shadowRoot.querySelector('#switch').classList.add("round");
if(this.label)
shadowRoot.querySelector('#label').innerHTML = this.getAttribute('label');
if(this.leftposition)
shadowRoot.querySelector('#label').classList.add("leftPosition");
if(this.size){
if(this.getAttribute('size') == 'large'){
shadowRoot.querySelector('#switchCmp').classList.add("switch_large");
shadowRoot.querySelector('#switch').classList.add("slider_large");
if(this.leftposition)
shadowRoot.querySelector('#label').classList.add("leftPositionLarge");
else
shadowRoot.querySelector('#label').classList.add("labelLarge");
}
if(this.getAttribute('size') == 'small'){
shadowRoot.querySelector('#switchCmp').classList.add("switch_small");
shadowRoot.querySelector('#switch').classList.add("slider_small");
if(this.leftposition)
shadowRoot.querySelector('#label').classList.add("leftPositionSmall");
else
shadowRoot.querySelector('#label').classList.add("labelSmall");
}
}
if(this.value)
shadowRoot.querySelector('#switchCmp').children[0].value = this.getAttribute('value');
if(this.checked)
shadowRoot.querySelector('#switchCmp').children[0].checked = true;
if(this.bgcolor){
if(shadowRoot.querySelector('input:checked + .slider'))
shadowRoot.querySelector('input:checked + .slider').style.backgroundColor = this.getAttribute('bgcolor');
shadowRoot.querySelector('input').addEventListener('change', e => {
if(shadowRoot.querySelector('input:checked + .slider'))
shadowRoot.querySelector('input:checked + .slider').style.backgroundColor = this.getAttribute('bgcolor');
else
shadowRoot.querySelector('input + .slider').style.backgroundColor = '#ccc';
});
}
}
}
window.customElements.define('switch-lab', switchLab);
Check a working demo for this code: