@flk/modal
Version:
Modal popup for Falak framework
131 lines (106 loc) • 3.82 kB
JavaScript
class Modal {
/**
* Constructor
* Put your required dependencies in the constructor parameters list
*/
constructor(animator) {
this.animator = animator;
this.availableThemes = [
'default',
'dark',
'dark-transparent',
];
this.defaultTheme = 'default';
this.hide = false;
if (typeof window.openedModals == 'undefined') {
window.openedModals = [];
}
document.documentElement.classList.add('noscroll');
}
/**
* {@inheritdoc}
*/
init() {
this.defaultConfig = Config.get('modal', {});
this.modalId = this.prop('id');
if (! this.modalId) {
this.modalId = Random.id();
}
this.modalSize = this.prop('size', this.config('size', 'medium'));
this.additionalClasses = this.prop('class', '');
this.esc = this.prop('esc', this.config('keyboard', true));
this.closeButton = this.prop('closeBtn', this.config('closeBtn', true));;
this.theme = this.prop('theme', this.config('theme', this.defaultTheme));
this.backdrop = this.prop('backdrop', this.config('backdrop', true));
this.modalHeader = this.prop('heading', this.prop('header'));
this.showUpAnimation = this.prop('animateShow', this.config('animation.show', 'fadeIn'));
this.hideAnimation = this.prop('animateHide', this.config('animation.hide', 'fadeOut'));
this.animationSpeed = this.prop('animateSpeed', this.config('animation.speed', 'normal'));
this.dismissible = this.prop('dismissible', this.config('animation.dismissible', true));
if (this.dismissible === false) {
this.closeButton = false;
this.backdrop = false;
this.esc = false;
}
if (!this.availableThemes.includes(this.theme)) {
throw new Error(`Unknown modal theme ${this.theme}, available themes: ${this.availableThemes.join(', ')}`);
}
window.openedModals.push(this.modalId);
}
/**
* Get config value
*/
config(key, $default = null) {
return Object.get(this.defaultConfig, key, $default);
}
/**
* Close the modal
*/
close() {
document.documentElement.classList.remove('noscroll');
this.animator.animate(this.modalContent, this.hideAnimation, 'normal');
this.hide = true;
setTimeout(() => {
this.hide = false;
window.openedModals = Array.remove(window.openedModals, this.modalId);
}, 300);
setTimeout(() => {
this.event('close')();
}, 300);
}
/**
* The component is ready to do any action after being rendered in dom
*/
ready() {
if (this.esc) {
this.closeByEscKey();
}
let readyEvent = this.event('open');
readyEvent();
}
/**
* Close by backdrop
*/
closeByBackdrop(backdropElement, event) {
if (!this.backdrop) return;
if (backdropElement !== event.target) return;
this.close();
}
/**
* Close using the Esc key
*/
closeByEscKey() {
document.addEventListener('keydown', e => {
if (e.which != 27) return true;
// only close the modal if it is the last opened modal
if (Array.end(window.openedModals) != this.modalId) return;
let modal = document.getElementById(this.modalId);
if (modal) {
this.close();
}
});
}
destroy() {
document.documentElement.classList.remove('noscroll');
}
}