Yet Another Notification Library
Tags: ux, javascript, webdev, monster
Published: 2022-01-08 17:27:27

---
title: Yet Another Notification Library
published: true
description:  notify library to inform the user about events
tags: ux, javascript, webdev, monster
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9igg5iie6nkdwzc0ieit.png
---

## Motivation

We want to have something like this

![wonted](https://monsterjs.org/image/monster-control-notify.png)

There are a number of ready-made components out there, so what was our motivation for this control? 

As always, there are several reasons to develop your own components and not use existing ones. When you write code yourself, you not only have full control, but you also always learn something new. 

**The learning effect cannot be overemphasized.**

Here we would like to pass on a few learnings. 

Maybe it helps you!

## Technical conditions

But now let's get to our latest achievement, a notify control. 

The component itself is not rocket science. Showing and hiding is done via CSS properties `display` and the `setTimeout` functionality. Quite simple.

An exciting question when creating the component was the positioning. How can the messages be arranged? 

### Naive implementation

One possibility is absolute positioning. 

You simply define the top value for each message and thus have a first solution.

```html
<style>
.message {
  position: absolute;
  right: 20px;
}

:nth-child(0) {
 top: 0;
}
  
:nth-child(1) {
   top: calc(1 * 40px);
}

:nth-child(2) {
   top: calc(2 * 40px);
}
</style>

<div class="message">
  this is message 1
</div>

<div class="message">
  this is message 2
</div>

<div class="message">
  this is message 3
</div>
``` 

Looks quite nice already. Unfortunately, the solution has several problems. For example, what happens when the text of the notification is longer. Then the positions of the underlying are no longer correct.

{% codepen https://codepen.io/volker-schukai/pen/rNGZOKR %}

An improvement would be to calculate the height via Javascript

This is done by calculating the height and top of the messages and placing the next message below them accordingly.

```javascript
const element = document.querySelector('.message')
var domRect= element.getBoundingClientRect();

const margin = 20;
const nextPosition = domRect.bottom+margin;

console.log(nextPosition);
```

This can be cast into a nice function and used. This works quite well and is also done by some components in the wild.

### CSS should do the job

However, Javascript has the disadvantage that it is Javascript. Any calculation that has to run in Javascript is slower than native code.

**So what to do?**

The further consideration was, whether there is not a simpler system. Among other things, you can set up a `div` as a container and display the messages below each other.

This has the advantage, you don't need to calculate distances and you can adjust the positioning via `flex`.

```html
<style>
.container {
  position: absolute;
  top: 0;
  right: 0;
  display:flex;
  flex-direction: column;
}

.message {
  margin-top: 25px
}
</style>


<div class="container">

  <div class="message">
    this is message 1
  </div>

  <div class="message">
    this is message 2<br>
    second line
  </div>


  <div class="message">
    this is message 3
  </div>
    
</div>
``` 

However, a absolute positioned `div` has a disadvantage. The content behind it is not clickable or selectable.

This is where the CSS property `user-select` comes into play.

This allows a div to be expanded and pretend it's not there.

That's really all we need. 


## The final component

We have integrated all of this knowledge into a component.
You can examine the code in detail on our gitlab or in npm.

This is simply included via the tag `monster-notify`.

```html
<monster-notify id="notify"
                data-monster-options='{
        "orientation": "right top"
        }'>
</monster-notify>
``` 

{% codepen https://codepen.io/volker-schukai/pen/poWOWBw %}

The parameters, such as the positioning or the length of the overlay can be specified via a JSON `data-monster-options`.

New messages can be included via push method.

```javascript
import {Notify} from "@schukai/component-notify/notify.js"

// create new message
const message=document.createElement('monster-notify-message');

// simple HTML content
message.innerHTML='this is a message!';

// change standard timeout
message.setAttribute('data-monster-timeout', 1000)

// notify container
const notifyElement = document.getElementById('notify');

// show message
notifyElement.push(message);

```


The component itself has only one dependency to our own Monster library and uses only a few objects here.


_hope you enjoy it!_



## References


* [developer.mozilla.org/en-US/docs/Web/CSS/display](https://developer.mozilla.org/en-US/docs/Web/CSS/display)
* [https://developer.mozilla.org/en-US/docs/Web/API/setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout)
* [documentation](https://monsterjs.org/en/doc/components/notify/1.0.0/)
* [project home](https://monsterjs.org)
* [schukai GmbH](https://www.schukai.com)
* [form example](https://monsterjs.org/en/doc/1.29.1/tutorial-form-example.html)