Introduction
This component consists in a dialog box/popup window that is displayed on top of the current page.
Let's start by creating the structure of our web component. Create a file windowLab.js:
class modalLab extends HTMLElement {
//Here will be all the functionality.
}
window.customElements.define('modal-lab', modalLab);
Step 2: Add the observed attributes
class modalLab extends HTMLElement {
//Step 1
static get observedAttributes() {
return ['max-width','width','animate'];
}
}
window.customElements.define('modal-lab', modalLab);
In this case we create three attributes:
- max-width: The max width that the element can be.
- width: Preferably set for a mobile view. By default 95%.
- animate: Set if the modal is animated.
Step 7: Add a function connectedCallback
It fires when the component is created
class modalLab extends HTMLElement {
//Step 1
//Step 2
//Step 3
//Step 4
//Step 5
//Step 6
connectedCallback () {
//Here will be the functionality.
}
}
window.customElements.define('modal-lab', modalLab);
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 modalLab extends HTMLElement {
//Step 1
//Step 2
//Step 3
//Step 4
//Step 5
//Step 6
connectedCallback () {
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
.modal {
display: block;
position: fixed;
z-index: 3000;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
font-family: Verdana,sans-serif;
font-size: 15px;
line-height: 1.5;
}
.modal-content {
background-color: #fefefe;
margin: auto;
width: 95%;
max-width:768px;
}
#mydivheader {
padding: 10px;
z-index: 10;
background-color: #2196F3;
color: #fff;
}
#container{
padding: 20px;
}
.btn, .button {
border: none;
display: inline-block;
padding: 8px 16px;
vertical-align: middle;
overflow: hidden;
text-decoration: none;
color: inherit;
background-color: inherit;
text-align: center;
cursor: pointer;
white-space: nowrap;
}
.btn, .button {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.display-topright {
position: relative;
right: -9px;
top: -33px;
float: right;
}
@media (max-width:768px){
.modal{
padding-top:50px;
}
}
.animate-top{
position:relative;
animation:animatetop 0.4s;
}
@keyframes animatetop{
from{top:-300px;opacity:0}
to{top:0;opacity:1}
}
</style>
<div id="myModal" class="modal">
<div class="modal-content">
<div id="mydivheader">
<slot name="title">
<div>Default title</div>
</slot>
<span id='closeBtn' class="button display-topright" style='color:white;font-size:18px;top: -32px;float:right;padding: 7px 16px;'>×</span>
</div>
<div id="container" style='background-color:white;'>
<slot name='body'>
<div></div>
</slot>
</div>
</div>
</div>`;
if(this.maxWidth){
shadowRoot.querySelector('.modal-content').style.maxWidth = this.getAttribute('max-width');
}
if(this.width){
shadowRoot.querySelector('.modal-content').style.width = this.getAttribute('width');
}
if(this.animate){
shadowRoot.querySelector('.modal-content').classList.add("animate-top");
}
shadowRoot.querySelector('#closeBtn').addEventListener('click', e => {
this.style.display = 'none';
});
}
}
window.customElements.define('modal-lab', modalLab);
Check a working demo for this code: