Skip to content

Instantly share code, notes, and snippets.

@Beaglefoot
Created October 12, 2019 08:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Beaglefoot/48ec1a2b3e3604d5394685f5dd008d4d to your computer and use it in GitHub Desktop.
Save Beaglefoot/48ec1a2b3e3604d5394685f5dd008d4d to your computer and use it in GitHub Desktop.
Simple Toast Notifications (with vanillaJS)
<div class="buttons">
<button class="button__success">Success</button>
<button class="button__info">Info</button>
<button class="button__warning">Warning</button>
<button class="button__error">Error</button>
</div>
const getTransitionDuration = element => {
const duration = getComputedStyle(element)['transitionDuration'];
return duration.includes('ms') ? parseFloat(duration) : parseFloat(duration) * 1000;
};
class ToastNotifications {
static hideDelay = 5000;
constructor() {
this.toastNode = document.createElement('div');
this.toastNode.classList.add('toast');
document.body.appendChild(this.toastNode);
}
scheduleHiding(messageNode) {
setTimeout(
() => this.hideMessageNode(messageNode),
ToastNotifications.hideDelay
);
}
getCrossIcon() {
const tmpContainer = document.createElement('div');
tmpContainer.innerHTML = '<svg class="toast__message-cross-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348.333 348.334" fill="currentColor"><path d="M336.559,68.611L231.016,174.165l105.543,105.549c15.699,15.705,15.699,41.145,0,56.85 c-7.844,7.844-18.128,11.769-28.407,11.769c-10.296,0-20.581-3.919-28.419-11.769L174.167,231.003L68.609,336.563 c-7.843,7.844-18.128,11.769-28.416,11.769c-10.285,0-20.563-3.919-28.413-11.769c-15.699-15.698-15.699-41.139,0-56.85 l105.54-105.549L11.774,68.611c-15.699-15.699-15.699-41.145,0-56.844c15.696-15.687,41.127-15.687,56.829,0l105.563,105.554 L279.721,11.767c15.705-15.687,41.139-15.687,56.832,0C352.258,27.466,352.258,52.912,336.559,68.611z"/></svg>';
return tmpContainer.firstChild;
}
getMessageNode({ title = '', text = '' } = {}) {
const messageNode = document.createElement('div');
const messageTitle = document.createElement('div');
const crossIcon = this.getCrossIcon();
crossIcon.addEventListener('click', () => this.hideMessageNode(messageNode));
messageTitle.classList.add('toast__message-title');
messageTitle.appendChild(document.createTextNode(title));
messageNode.classList.add('toast__message');
messageNode.appendChild(messageTitle);
messageNode.appendChild(document.createTextNode(text));
messageNode.appendChild(crossIcon);
return messageNode;
}
showMessageNode(messageNode) {
messageNode.classList.add('toast__message--hidden');
requestAnimationFrame(() => {
this.toastNode.appendChild(messageNode);
requestAnimationFrame(() => {
messageNode.classList.remove('toast__message--hidden');
});
});
this.scheduleHiding(messageNode);
}
hideMessageNode(messageNode) {
messageNode.classList.add('toast__message--hidden');
setTimeout(
() => {
if (this.toastNode.contains(messageNode)) {
this.toastNode.removeChild(messageNode);
}
},
getTransitionDuration(messageNode)
);
}
showSuccess({ title = '', text = '' } = {}) {
const messageNode = this.getMessageNode({ title, text });
messageNode.classList.add('toast__message--success');
this.showMessageNode(messageNode);
}
showInfo({ title = '', text = '' } = {}) {
const messageNode = this.getMessageNode({ title, text });
messageNode.classList.add('toast__message--info')
this.showMessageNode(messageNode);
}
showWarning({ title = '', text = '' } = {}) {
const messageNode = this.getMessageNode({ title, text });
messageNode.classList.add('toast__message--warning')
this.showMessageNode(messageNode);
}
showError({ title = '', text = '' } = {}) {
const messageNode = this.getMessageNode({ title, text });
messageNode.classList.add('toast__message--error')
this.showMessageNode(messageNode);
}
}
const toastNotifications = new ToastNotifications();
const [
successButton,
infoButton,
warningButton,
errorButton
] = document.querySelectorAll('button');
successButton.addEventListener('click', () => toastNotifications.showSuccess({
title: 'Success',
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
}));
infoButton.addEventListener('click', () => toastNotifications.showInfo({
title: 'Info',
text: 'Vitae congue mauris rhoncus aenean vel elit scelerisque mauris.'
}));
warningButton.addEventListener('click', () => toastNotifications.showWarning({
title: 'Warning',
text: 'Elementum nibh tellus molestie nunc.'
}));
errorButton.addEventListener('click', () => toastNotifications.showError({
title: 'Error',
text: 'Vivamus arcu felis bibendum ut tristique et egestas quis ipsum.'
}));
$success_color: #CDFFA7;
$info_color: #A7FFE4;
$warning_color: #FFFAA7;
$error_color: #FFA7A7;
html, body {
height: 100%;
margin: 0;
}
.toast {
position: fixed;
top: 0;
right: 0;
}
.toast__message {
position: relative;
width: 300px;
min-height: 50px;
border-radius: 5px;
border: 1px solid;
margin-top: 10px;
margin-right: 10px;
padding: 0.4em 0.5em;
font-size: 14px;
font-family: Roboto, Arial, sans-serif;
line-height: 1.25;
box-shadow: 1px 1px 4px gray;
transition: all 0.3s ease;
}
.toast__message-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 0.4em;
}
.toast__message-cross-icon {
position: absolute;
top: 0;
right: 0.5em;
width: 0.8em;
height: 0.8em;
padding-top: inherit;
transform: translateY(10%);
cursor: pointer;
}
.toast__message--hidden {
transform: translateX(50%);
opacity: 0;
}
.toast__message--success {
$color: $success_color;
$color_darken: darken($color, 50%);
background: $color;
border-color: darken($color, 50%);
color: darken($color, 70%);
.toast__message-cross-icon {
color: darken($color, 60%);
}
}
.toast__message--info {
$color: $info_color;
background: $color;
border-color: darken($color, 50%);
color: darken($color, 70%);
.toast__message-cross-icon {
color: darken($color, 60%);
}
}
.toast__message--warning {
$color: $warning_color;
background: $color;
border-color: darken($color, 50%);
color: darken($color, 70%);
.toast__message-cross-icon {
color: darken($color, 60%);
}
}
.toast__message--error {
$color: $error_color;
background: $color;
border-color: darken($color, 50%);
color: darken($color, 60%);
.toast__message-cross-icon {
color: darken($color, 50%);
}
}
.buttons {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
button {
font-size: 16px;
font-family: Roboto, Arial, sans-serif;
border-radius: 5px;
padding: 0.2em 0.6em;
color: #fff;
}
button:not(:last-of-type) {
margin-right: 0.4em;
}
.button__success {
$color: $success_color;
background: darken($color, 50%);
border-bottom-color: darken($color, 50%);
border-right-color: darken($color, 50%);
border-left-color: darken($color, 47%);
border-top-color: darken($color, 47%);
}
.button__info {
$color: $info_color;
background: darken($color, 50%);
border-bottom-color: darken($color, 50%);
border-right-color: darken($color, 50%);
border-left-color: darken($color, 47%);
border-top-color: darken($color, 47%);
}
.button__warning {
$color: $warning_color;
background: darken($color, 42%);
border-bottom-color: darken($color, 42%);
border-right-color: darken($color, 42%);
border-left-color: darken($color, 40%);
border-top-color: darken($color, 40%);
}
.button__error {
$color: $error_color;
background: darken($color, 46%);
border-bottom-color: darken($color, 46%);
border-right-color: darken($color, 46%);
border-left-color: darken($color, 44%);
border-top-color: darken($color, 44%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment