modals-engine
v1.0.2
Published
small abstract framework agnostic library for modals management
Readme
abstract modals engine v1.0.2
This is framework agnostic modals engine. It works on vanilla js without any dependencies.
With this lib you can:
- show multiple modals
- destroy modals by pressing esc (optional)
- destroy modals by clicking outside the modal (optional and actualy you are the person who decided is there was clicked outside dom node or not)
install
npm install modals-engineuse
import modals from 'modals-engine';
const modalPromise = modals.show(options); // will show your modal
The modals.show(options) method always return a promise with additional properties:
destroy: function, will destroy and remove modal.
ready: promise, will settle when modal became fully initialized.
modal: object, modal itself.
returned promise always resolves into object: { ok: bool, value: any }:
example:
const result = await modals.show(confirmModal);
if (result.ok) {
// confirmed
} else {
// canceled
}tip: there is a special option for you to control returned result: see wrapPromiseResult
options
destroyOnEsc: Boolean, optional, default: true.
if true modal will be destroyed if it is the last, ready and Esc keyy presses. by default will resolve with destroy reason:
const res = await modals.show(options);
console.log(res); // { ok:false, value: 'destroy' }see getRejectValue option for details about how to change this.
isExternalElement: Function, optional, default: undefined, must return boolean.
const isTrue = isExternalElement(domElementClicked)If provided determines should modal be destroyed if there was a click on external dom element.
attach: Function, required.
modals-engine does not know what framework do you use, so you have to provide your method which will attach your modal html to the dom. Its all up to you.
destroy: Function, required. same as attach. Provide a function which will effectively destroy your modal component and remove it from the dom.
promise: Promise, required. Provide a modal's lifecicle promise. It should be resolved or rejected when the modal should be destroyed. (f.e. reject on close button click or resolve on confirm button click);
wrapPromiseResult: boolean, default: true.
If True will wrap promise value with result object {ok: true, value: resolvedPromiseValue } and will always in resolved state. otherwise will return clean promise resolved or rejected value and should be catched for reject case.
// by default wrapPromiseResult is true and nodals.show will always resolve;
const options = {
...,
promise: new Promise((ok, notOk) => {
$modal.find('button.close').one('click', () => notOk('skiped'));
$modal.find('button.confirm').one('click', () => ok('confirmed'));
})
}
let modalPromise = modals.show(options);
$modal.find('button.close').click();
const result = await modalPromise; // will be resolved
console.log(result); // { ok: false, value: 'skiped' }
modalPromise = modals.show(options);
$modal.find('button.confirm').click();
const result = await modalPromise; // will be resolved
console.log(result); // { ok: true, value: 'confirmed' }
// and there is clean promise values example
const options = {
...,
wrapPromiseResult: false,
promise: new Promise((ok, notOk) => {
$modal.find('button.close').one('click', () => notOk('skiped'));
$modal.find('button.confirm').one('click', () => ok('confirmed'));
})
}
modalPromise = modals.show(options);
$modal.find('button.confirm').click();
const result = await modalPromise; // will be resolved
console.log(result); // 'confirmed'
let modalPromise = modals.show(options);
$modal.find('button.close').click();
try {
await modalPromise; // will be rejected
} catch (exception) {
console.log(exception); // 'skiped'
}
getRejectValue: Function, optional.
There are three cases when modal will be rejected with some reason:
- escape press (if not forbidden in options)
- external element clicked (if isExternalElement option provided)
- modal destroy happens by some internal reason. (f.e. modals.destroyAll() called)
All three cases will reject modal with apropriate reason by default:
REJECT_REASONS = {
DESTROY: 'destroy',
ESC_PRESSED: 'esc-press',
EXTERNAL_CLICK: 'external-click',
}If you need to change this behavior you can provide own getRejectValue(reason) { } in options.
const options = {
...
getRejectValue: reason => {
switch(reason) {
case 'destroy': return 'my destroy'
default: return 'i dont care'
}
},
}
const promise = modals.show(options);
modals.destroyAll();
console.log(await promise); // { ok: false, value: 'my destroy' }
simple jquery example
import modals from 'modals-engine';
import $ from 'jquery';
const $modal = $(`
<div class="modal">
<header>
<button class="close">close</button>
</header>
<article>
<p>Confirm</p>
<button class="confirm">confirm</button>
<button class="cancel">cancel</button>
</article>
</div>
`);
const options = {
destroyOnEsc: true,
isExternalElement: el => !$modal.get(0).contains(el),
attach: () => $modal.appendTo(document.body),
destroy: () => $modal.remove(),
promise: new Promise((ok, notOk) => {
$modal.find('button.close').one('click', () => notOk('skiped'));
$modal.find('button.cancel').one('click', () => notOk('canceled'));
$modal.find('button.confirm').one('click', () => ok('confirmed'));
})
}
modals.show(options);
