149 lines
4.2 KiB
JavaScript
149 lines
4.2 KiB
JavaScript
'use strict';
|
|
|
|
// Polyfills
|
|
import './polyfills/classList';
|
|
|
|
import {
|
|
append,
|
|
createElement,
|
|
createParagraph,
|
|
isString
|
|
} from './helpers';
|
|
|
|
(function Notifications(window) {
|
|
// Default notification options
|
|
const defaultOptions = {
|
|
closeOnClick: true,
|
|
displayCloseButton: false,
|
|
positionClass: 'nfc-top-right',
|
|
onclick: false,
|
|
showDuration: 3500,
|
|
theme: 'success'
|
|
};
|
|
|
|
function configureOptions(options) {
|
|
// Create a copy of options and merge with defaults
|
|
options = Object.assign({}, defaultOptions, options);
|
|
|
|
// Validate position class
|
|
function validatePositionClass(className) {
|
|
const validPositions = [
|
|
'nfc-top-left',
|
|
'nfc-top-right',
|
|
'nfc-bottom-left',
|
|
'nfc-bottom-right'
|
|
];
|
|
|
|
return validPositions.indexOf(className) > -1;
|
|
}
|
|
|
|
// Verify position, if invalid reset to default
|
|
if (!validatePositionClass(options.positionClass)) {
|
|
console.warn('An invalid notification position class has been specified.');
|
|
options.positionClass = defaultOptions.positionClass;
|
|
}
|
|
|
|
// Verify onClick is a function
|
|
if (options.onclick && typeof options.onclick !== 'function') {
|
|
console.warn('Notification on click must be a function.');
|
|
options.onclick = defaultOptions.onclick;
|
|
}
|
|
|
|
// Verify show duration
|
|
if(typeof options.showDuration !== 'number') {
|
|
options.showDuration = defaultOptions.showDuration;
|
|
}
|
|
|
|
// Verify theme
|
|
if(!isString(options.theme) || options.theme.length === 0) {
|
|
console.warn('Notification theme must be a string with length');
|
|
options.theme = defaultOptions.theme;
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
// Create a new notification instance
|
|
function createNotification(options) {
|
|
// Validate options and set defaults
|
|
options = configureOptions(options);
|
|
|
|
// Return a notification function
|
|
return function notification({ title, message } = {}) {
|
|
const container = createNotificationContainer(options.positionClass);
|
|
|
|
if(!title && !message) {
|
|
return console.warn('Notification must contain a title or a message!');
|
|
}
|
|
|
|
// Create the notification wrapper
|
|
const notificationEl = createElement('div', 'ncf', options.theme);
|
|
|
|
// Close on click
|
|
if(options.closeOnClick === true) {
|
|
notificationEl.addEventListener('click', () => container.removeChild(notificationEl));
|
|
}
|
|
|
|
// Custom click callback
|
|
if(options.onclick) {
|
|
notificationEl.addEventListener('click', (e) => options.onclick(e));
|
|
}
|
|
|
|
// Display close button
|
|
if(options.displayCloseButton) {
|
|
const closeButton = createElement('button');
|
|
closeButton.innerText = 'X';
|
|
|
|
// Use the wrappers close on click to avoid useless event listeners
|
|
if(options.closeOnClick === false){
|
|
closeButton.addEventListener('click', () =>container.removeChild(notificationEl));
|
|
}
|
|
|
|
append(notificationEl, closeButton);
|
|
}
|
|
|
|
// Append title and message
|
|
isString(title) && title.length && append(notificationEl, createParagraph('ncf-title')(title));
|
|
isString(message) && message.length && append(notificationEl, createParagraph('nfc-message')(message));
|
|
|
|
// Append to container
|
|
append(container, notificationEl);
|
|
|
|
// Remove element after duration
|
|
if(options.showDuration && options.showDuration > 0) {
|
|
const timeout = setTimeout(() => {
|
|
container.removeChild(notificationEl);
|
|
|
|
// Remove container if empty
|
|
if(container.querySelectorAll('.ncf').length === 0) {
|
|
document.body.removeChild(container);
|
|
}
|
|
}, options.showDuration);
|
|
|
|
// If close on click is enabled and the user clicks, cancel timeout
|
|
if(options.closeOnClick || options.displayCloseButton) {
|
|
notificationEl.addEventListener('click', () => clearTimeout(timeout));
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
function createNotificationContainer(position) {
|
|
let container = document.querySelector(`.${position}`);
|
|
|
|
if(!container) {
|
|
container = createElement('div', 'ncf-container', position);
|
|
append(document.body, container);
|
|
}
|
|
|
|
return container;
|
|
}
|
|
|
|
// Add Notifications to window to make globally accessible
|
|
if (window.createNotification) {
|
|
console.warn('Window already contains a create notification function. Have you included the script twice?');
|
|
} else {
|
|
window.createNotification = createNotification;
|
|
}
|
|
})(window);
|