Intro
Please read the first of this two part mini-series to get a better understanding of this post π.
A few minutes after I published the first post on how to create a simple Toast, I started thinking about ways to make it better and easier to use.
After some thinking, I decided that the best way to easily manage and create Toasts is through classes. So I created a class-based Toast, that accepts a few options to customize the functionality.
These options are the following:
- title: (string) What the toast will "say" [default: '']
- timer: (int) How long before the Toast auto expires in ms [default: 2000]
- alwaysOn: (boolean) Overrides the timer option and the Toast doesn't auto expire [default: false]
- dismiss: (boolean) Shows an 'x' icon, when user clicks the icon => the Toast closes [default: false]
How it works
First the styles are the following:
.toast {
position: fixed;
bottom: -100px;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 300px;
background-color: #213cfd;
background-image: linear-gradient(19deg, #213cfd 0%, #b421ff 100%);
color: #fff;
font-size: 16px;
padding: 10px;
-webkit-transition: bottom 350ms;
-moz-transition: bottom 350ms;
-o-transition: bottom 350ms;
-ms-transition: bottom 350ms;
transition: bottom 350ms;
}
.toast.active {
bottom: 20px;
}
.toast--dismiss {
border: 0;
outline: 0;
background: transparent;
color: #fff;
position: absolute;
top: 1px;
right: 1px;
font-size: 12px;
cursor: pointer;
}
You can customize the css to fit your needs: change the background color of the Toast, the position etc.
The javascript class:
class Toast {
constructor(title = '', {
timer = 2000,
alwaysOn = false,
dismiss = false
} = {}) {
this.autoTimer = null;
let self = this;
/* Close all previous Toasts */
document.querySelectorAll('.toast').forEach(el => {
el.classList.remove('active');
})
this.title = title;
/* Check if timer is valid integer */
let ms = parseInt(timer);
if(isNaN(ms) || ms < 1) {
ms = 2000;
}
this.toast_el = document.createElement('div');
this.toast_el.classList.add('toast');
this.toast_el.innerText = title;
if(dismiss) {
let toast_dismiss = document.createElement('button');
toast_dismiss.setAttribute('type', 'button');
toast_dismiss.classList.add('toast--dismiss');
toast_dismiss.innerHTML = "✖";
this.toast_el.appendChild(toast_dismiss);
toast_dismiss.addEventListener('click', () => {
/* Remove Toast when user click on 'x' button */
self.toast_el.classList.remove('active');
setTimeout(function() {
document.querySelector('body').removeChild(self.toast_el);
}, 100);
clearTimeout(self.autoTimer);
});
}
/* Append Toast element to body */
document.querySelector('body').appendChild(this.toast_el);
setTimeout(function() {
self.toast_el.classList.add('active');
}, 100);
if(!alwaysOn) {
/* Auto expire the Toast after the specified ms */
this.autoTimer = setTimeout(function() {
self.toast_el.classList.remove('active');
setTimeout(function() {
document.querySelector('body').removeChild(self.toast_el);
}, 100);
}, ms);
}
}
}
Examples
1. Classic Toast
document.querySelector('#btn-show-toast').addEventListener('click', (e) => {
let toast = new Toast("βοΈ This is a classic toast! π", {
timer: 2000
});
});
2. Dismissable Toast with timer
document.querySelector('#btn-show-toast--dismiss').addEventListener('click', (e) => {
let toast = new Toast("βοΈ This is a dismissable toast with auto expire! π", {
timer: 2000,
dismiss: true
});
});
3. Always-on, dismissable Toast
document.querySelector('#btn-show-toast--dismiss--no-timer').addEventListener('click', (e) => {
let toast = new Toast("βοΈ This is a dismissable toast without timer! π", {
dismiss: true,
alwaysOn: true
});
});
Demo with all the code
Outro
π Thank you for reading through all the post! π
If you have any questions or feedback, let me know in the comments π¨.
Top comments (2)
Thanks, will add this to my site, but add a small integration with React :)
Thank you for your comment!
I tried for like an hour to convert this to a React component, but the problem is that I don't know React π !
Then I tried to think at it from a Vue standpoint and I realized that while it is very feasible, it would take away the fun of just writing:
You can find the hackiest solution to use the Toast Class in React in the codepen below:
please don't judge me on that code ππ