UNPKG

@borngroup/born-modal

Version:

BORN Module to handle Modals. Provides callbacks and static methods to open, update, and close the modals

1 lines 13.1 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=void 0;var _bornUtilities=require("@borngroup/born-utilities");var _bodyScrollLock=require("body-scroll-lock");function _typeof(obj){"@babel/helpers - typeof";if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function _typeof(obj){return typeof obj}}else{_typeof=function _typeof(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj}}return _typeof(obj)}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}var Modal=function(){function Modal(options){_classCallCheck(this,Modal);this.options=options||{};this.options.modalID=this.options.modalID||"auto-"+Math.floor((new Date).getTime()*Math.random()).toString();this.options.modalClass="window-modal "+(this.options.modalClass||"");this.options.openImmediately=this.options.hasOwnProperty("openImmediately")?this.options.openImmediately:true;this.options.allowEscClose=this.options.hasOwnProperty("allowEscClose")?this.options.allowEscClose:true;this.options.allowClickOutClose=this.options.hasOwnProperty("allowClickOutClose")?this.options.allowClickOutClose:true;this.options.allowCrossClose=this.options.hasOwnProperty("allowCrossClose")?this.options.allowCrossClose:true;this.options.resetScrollPositionOnClose=this.options.hasOwnProperty("resetScrollPositionOnClose")?this.options.resetScrollPositionOnClose:true;this._modalContentClass="window-modal__content";if(typeof this.options.container==="string"){this.options.container=document.querySelector(this.options.container)}else if(this.options.container instanceof HTMLElement){this.options.container=this.options.container}else{this.options.container=document.querySelector("body")}if(!Modal.getModal(this.options.modalID)){this._renderModal()}else{Modal.openModal(this.options.modalID)}}_createClass(Modal,[{key:"_renderModal",value:function _renderModal(){var _this=this;this.modalEl=(0,_bornUtilities.createElWithAttrs)(false,{id:"modal-"+this.options.modalID,class:this.options.modalClass,"data-modal":true});this.modalEl.modal={};this.modalEl.modal.content=(0,_bornUtilities.createElWithAttrs)(this.modalEl,{class:this._modalContentClass,tabindex:"-1"});this.modalEl.modal.options=this.options;this.modalEl.modal.container=this.options.container;this.modalEl.modal.keepAlive=this.options.hasOwnProperty("keepAlive")?this.options.keepAlive:true;this.modalEl.modal.beforeOpenCallback=this.options.beforeOpenCallback||function(){return true};this.modalEl.modal.afterOpenCallback=this.options.afterOpenCallback||function(){};this.modalEl.modal.beforeCloseCallback=this.options.beforeCloseCallback||function(){return true};this.modalEl.modal.afterCloseCallback=this.options.afterCloseCallback||function(){};this.modalEl.modal.afterCreateCallback=this.options.afterCreateCallback||function(){};this.modalEl.modal.afterScrollLockCallback=this.options.afterScrollLockCallback||function(){};this.open=this.modalEl.modal.open=Modal.openModal.bind(Modal,this.modalEl);this.close=this.modalEl.modal.close=Modal.closeModal;this.update=this.modalEl.modal.update=Modal.updateModal.bind(Modal,this.modalEl);if(this.options.content){Modal.insertContent(this.modalEl,this.options.content)}this.options.container.appendChild(this.modalEl);var checkReadyTries=0,checkReady=setInterval(function(){checkReadyTries++;if(Modal.getModal(_this.options.modalID)){clearInterval(checkReady);if(_this.options.allowCrossClose){Modal.insertCloseBtn(_this.modalEl)}if(_this.options.openImmediately){Modal.openModal(_this.modalEl)}_this.modalEl.modal.options.customAttributes=(0,_bornUtilities.objectAssign)(_this.getCustomAttributes(_this.modalEl),_this.modalEl.modal.options.customAttributes);Modal.updateAttributes(_this.modalEl);_this.modalEl.modal.afterCreateCallback(_this.modalEl)}else if(checkReadyTries>=25){clearInterval(checkReady)}},10)}},{key:"getCustomAttributes",value:function getCustomAttributes(targetModal){var labelledByEl=targetModal.querySelector('[data-modal-component="labelledby"]'),describedByEl=targetModal.querySelector('[data-modal-component="describedby"]');if(labelledByEl&&!labelledByEl.id){labelledByEl.id="ID_"+Math.floor((new Date).getTime()*Math.random()).toString()}if(describedByEl&&!describedByEl.id){describedByEl.id="ID_"+Math.floor((new Date).getTime()*Math.random()).toString()}return{role:{value:"dialog",target:true},"aria-labelledby":labelledByEl?{value:labelledByEl.id,target:true}:false,"aria-describedby":describedByEl?{value:describedByEl.id,target:true}:false,"aria-modal":{value:"true",target:true}}}}],[{key:"setModalPosition",value:function setModalPosition(){Modal.positionTop=Math.abs(document.body.getBoundingClientRect().top)}},{key:"toggleModalScroll",value:function toggleModalScroll(targetModal,disable){var scrollableEls=targetModal.querySelectorAll("[data-modal-scrollable]"),toggleBodyScroll=disable?_bodyScrollLock.disableBodyScroll:_bodyScrollLock.enableBodyScroll,scrollOptions=disable?{allowTouchMove:function allowTouchMove(el){while(el&&el!==document.body){if(el.hasAttribute("data-modal-scrollable")){return true}el=el.parentNode}}}:{};toggleBodyScroll(targetModal,scrollOptions);targetModal.scrollHeight;targetModal.modal.afterScrollLockCallback(targetModal)}},{key:"setModalShown",value:function setModalShown(){(0,_bodyScrollLock.clearAllBodyScrollLocks)();if(this.hasAttribute("data-modal-active")){if(!this.modal.options.allowScrolling){if(this.modal.options.lockViewport){document.documentElement.classList.add("cancel-scroll")}else{Modal.toggleModalScroll(this,true)}}this.modal.container.classList.add("modal-shown")}Modal.focusModal(this);this.removeEventListener((0,_bornUtilities.whichTransition)(),Modal.setModalShown)}},{key:"openModal",value:function openModal(targetModal){var activeModal=Modal.getActiveModal();targetModal=Modal.getModal(targetModal);if(targetModal===activeModal){return false}else if(targetModal.modal.beforeOpenCallback(targetModal)){var targetModalIndex=activeModal?parseInt(activeModal.getAttribute("data-modal-index"))+1:0;targetModal.setAttribute("data-modal-index",targetModalIndex);Modal.setModalPosition();if(!targetModal.modal.options.overlayOthers){Modal.closeAllModals()}else if(activeModal){targetModal.modal.modalInBackground=activeModal;activeModal.classList.add("modal-in-background")}targetModal.classList.add("modal-active");targetModal.setAttribute("data-modal-active",true);Modal.setupEventListeners(targetModal);if(targetModal.modal.options.timeOut){window.setTimeout(Modal.closeModal,targetModal.modal.options.timeOut)}targetModal.modal.afterOpenCallback(targetModal)}}},{key:"setupEventListeners",value:function setupEventListeners(targetModal){targetModal.addEventListener("mousedown",Modal.storeLastEvent);targetModal.addEventListener("click",Modal.closeModal);targetModal.addEventListener("mouseup",Modal.closeModal);if(targetModal.modal.options.allowEscClose){document.body.addEventListener("keydown",Modal.closeModal)}targetModal.addEventListener((0,_bornUtilities.whichTransition)(),Modal.setModalShown)}},{key:"storeLastEvent",value:function storeLastEvent(evt){this.modal.lastEvent=evt}},{key:"updateAttributes",value:function updateAttributes(targetModal,isActive){var customAttributes=targetModal.modal.options.customAttributes;for(var attrKey in customAttributes){if(customAttributes[attrKey]){if(customAttributes[attrKey].trigger){}else if(customAttributes[attrKey].target){Modal.setAttributeValue(targetModal.modal.content,attrKey,customAttributes[attrKey],isActive)}else{Modal.setAttributeValue(targetModal.modal.content,attrKey,customAttributes[attrKey],isActive)}}}}},{key:"setAttributeValue",value:function setAttributeValue(el,attrName,attrObject,isActive){var value=typeof attrObject.value==="string"?attrObject.value:isActive?attrObject.value[1]:attrObject.value[0];el.setAttribute(attrName,value)}},{key:"focusModal",value:function focusModal(targetModal){targetModal.modal.content.focus();targetModal.modal.content.style.outline="none";(0,_bornUtilities.focusTrap)(targetModal)}},{key:"updateModal",value:function updateModal(targetModal,content,newID){targetModal=Modal.getModal(targetModal);if(targetModal.modal.beforeOpenCallback(targetModal)){if(newID){targetModal.id="modal-"+newID}if(content){var targetModalContent=targetModal.querySelector(".window-modal__content");targetModalContent.innerHTML="";Modal.insertContent(targetModal,content);if(targetModal.modal.options.allowCrossClose){Modal.insertCloseBtn(targetModal)}}targetModal.modal.afterCreateCallback(targetModal);targetModal.modal.afterOpenCallback(targetModal)}}},{key:"closeAllModals",value:function closeAllModals(){var activeModals=Modal.getActiveModals();[].forEach.call(activeModals,function(currentModal){Modal.closeModal(false,true)})}},{key:"closeModal",value:function closeModal(evt,ignoreBeforeCallback){var targetModal=Modal.getActiveModal(),canClose=true,isCloseAllTarget,isCloseTarget;if(!targetModal){return}if(_typeof(evt)==="object"){var isOverlayTarget=targetModal.modal.options.allowClickOutClose&&evt.type==="mouseup"&&evt.target===targetModal&&targetModal.modal.lastEvent.target===targetModal&&evt.button===0,evtIsClick=evt.type==="click",evtIsEscKey=document.activeElement.tagName!=="INPUT"&&evt.keyCode===27&&targetModal.modal.options.allowEscClose,_isCloseTarget=evtIsClick&&evt.target.closest("[data-modal-close]");isCloseAllTarget=evtIsClick&&evt.target.closest("[data-modal-close-all]");canClose=isOverlayTarget||_isCloseTarget||isCloseAllTarget||evtIsEscKey}if(canClose&&(ignoreBeforeCallback||targetModal.modal.beforeCloseCallback(targetModal))){var activeModals=Modal.getActiveModals();if(activeModals.length<=1){document.body.removeEventListener("keydown",Modal.closeModal);document.documentElement.classList.remove("cancel-scroll");if(targetModal.modal.options.resetScrollPositionOnClose){window.scrollTo(0,Modal.positionTop||0)}}else if(targetModal.modal.options.closeAll||isCloseAllTarget){Modal.closeAllModals()}targetModal.classList.remove("modal-active");targetModal.removeAttribute("data-modal-active");if(!targetModal.modal.options.lockViewport){Modal.toggleModalScroll(targetModal)}if(targetModal.modal.options.afterCloseFocusEl&&targetModal.contains(document.activeElement)){targetModal.modal.options.afterCloseFocusEl.focus()}if(!targetModal.modal.modalInBackground||targetModal.modal.modalInBackground.modal.container!==targetModal.modal.container){targetModal.modal.container.classList.remove("modal-shown")}if(targetModal.modal.modalInBackground){if(!targetModal.modal.modalInBackground.modal.options.lockViewport&&!targetModal.modal.modalInBackground.modal.options.allowScrolling){Modal.toggleModalScroll(targetModal.modal.modalInBackground,true)}targetModal.modal.modalInBackground.classList.remove("modal-in-background")}if(!targetModal.modal.keepAlive){targetModal.addEventListener((0,_bornUtilities.whichTransition)(),Modal.destroyModal)}targetModal.modal.afterCloseCallback(targetModal)}}},{key:"destroyModal",value:function destroyModal(){var targetModal=this||Modal.getActiveModal();targetModal.removeEventListener((0,_bornUtilities.whichTransition)(),Modal.destroyModal);targetModal.parentNode.removeChild(targetModal)}},{key:"insertCloseBtn",value:function insertCloseBtn(targetModal){var closeBtnContainer=targetModal.modal.options.crossCloseContainer==="modal"?targetModal:targetModal.modal.content;return(0,_bornUtilities.createElWithAttrs)(closeBtnContainer,{class:"window-modal__close","data-modal-close":true,title:"Close modal","aria-label":"Close modal",type:"button"},"button")}},{key:"insertContent",value:function insertContent(targetModal,content){if(typeof content==="string"){targetModal.modal.content.insertAdjacentHTML("afterbegin",content)}else if(content instanceof HTMLElement){targetModal.modal.content.appendChild(content)}(0,_bornUtilities.parseScripts)(targetModal)}},{key:"getActiveModals",value:function getActiveModals(){return document.querySelectorAll(".window-modal[data-modal-active]")}},{key:"getActiveModal",value:function getActiveModal(){var activeModals=Modal.getActiveModals();return activeModals[activeModals.length-1]}},{key:"getModal",value:function getModal(targetModal){var matchedModal=typeof targetModal==="string"?document.querySelector("#modal-"+targetModal)||document.querySelector(targetModal):false;if(matchedModal){return matchedModal}else if(targetModal instanceof HTMLElement){return targetModal}else{return false}}}]);return Modal}();exports["default"]=Modal;