DEV Community

Cover image for Create a Simple 0-dependency Toast (part 2) - Class-based
tsanak
tsanak

Posted on

8 3

Create a Simple 0-dependency Toast (part 2) - Class-based

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:

  1. title: (string) What the toast will "say" [default: '']
  2. timer: (int) How long before the Toast auto expires in ms [default: 2000]
  3. alwaysOn: (boolean) Overrides the timer option and the Toast doesn't auto expire [default: false]
  4. 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 = "&#10006;";

            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
    });
});

Alt Text

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
    });
});

Alt Text

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
    });
});

Alt Text

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 πŸ—¨.

Sentry blog image

How to reduce TTFB

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

In this article, we’ll see how we can identify what makes our TTFB high so we can fix it.

Read more

Top comments (2)

Collapse
 
js2me profile image
Sergey S. Volkov β€’

Thanks, will add this to my site, but add a small integration with React :)

Collapse
 
tsanak profile image
tsanak β€’

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:

new Toast("βœ”οΈ This is a dismissable toast without timer! πŸ‘", {
    dismiss: true,
    alwaysOn: true
});

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 πŸ˜‚πŸ˜‚

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

πŸ‘‹ Kindness is contagious

Please leave a ❀️ or a friendly comment on this post if you found it helpful!

Okay