UNPKG

@travlrcom/uikit

Version:

TRAVLR UiKit

299 lines (253 loc) 8.29 kB
/** **************************************************** *** ******* ****** **** *** ****** ****** ***** *********** ************** ****** ****** *********** ************* ****** ******* *********** ************ ****** ******** *********** *********** ****** ********* *********** ********** ****** ********** *********** ********* ****** *********** *********** ******** ****** ************ *********** ******* ****** ************* *********** ****** ****** ************** **************************************************** * -------------------------------------------------- * Travlr UiKit: modal.js * By Travlr Team * -------------------------------------------------- */ import AttributeHandler from './utils/attributeHandler' import BooleanParse from './utils/booleanParse' import EventHandler from './utils/eventHandler' import CallbackHandler from './utils/callbackHandler' import ErrorMessageHandler from './utils/errorMessageHandler' // const const NAME = 'modal' const DATA_KEY = `trv.${NAME}` const EVENT_KEY = `.${DATA_KEY}` const Selector = { TRV_TOGGLE: `[trv-toggle="${NAME}"]`, TRV_DISMISS: `[trv-dismiss="${NAME}"]`, TRV_OVERLAY: `[trv-overlay="${NAME}"]` } const ClassName = { ACTIVE: 'active' } const EventName = { ACTIVE: `active${EVENT_KEY}`, INACTIVE: `inactive${EVENT_KEY}` } const ErrorMessages = [ { ERROR_ID: 0, ERROR_MESSAGE: 'Config must be an object' } ] const ConfigErrorMessage = { errorId: 0, errorMessages: ErrorMessages } class Modal { constructor (config = {}) { if (typeof config !== 'object') { const ConfigError = Object.assign({}, ConfigErrorMessage, { errorId: 0 }) new ErrorMessageHandler(ConfigError) } this._config = config this._element = typeof config.element === 'undefined' ? '' : config.element this._elementModalButton = window.$TravlrSelector(Selector.TRV_TOGGLE) this._modalButtonContext = null this._elementModalButtonDismiss = window.$TravlrSelector(Selector.TRV_DISMISS) this._modalButtonDismissContext = null this._elementModalOverlay = window.$TravlrSelector(Selector.TRV_OVERLAY) this._modalOverlayContext = null this._elementModalTarget = null this._modalTargetName = null this._modalTargetContext = null this._isShown = false this._beforeAction = config.beforeAction this._afterAction = config.afterAction this.init() } init () { if (this._element !== '') { this._elementModalButton = window.$TravlrSelector(`${Selector.TRV_TOGGLE}[trv-modal-target="${this._element}"]`) this._elementModalButtonDismiss = window.$TravlrSelector(`${Selector.TRV_DISMISS}[trv-modal-target="${this._element}"]`) this._elementModalOverlay = window.$TravlrSelector(`${Selector.TRV_OVERLAY}[trv-modal-target="${this._element}"]`) } if (this._elementModalButton.length > 0) { this._elementModalButton.forEach(element => { this._modalButtonContext = element const parent = this // trigger when click element.onclick = function (event) { parent._modalButtonContext = this parent.prepareModal(event.target, parent._config.status) parent.toggle() } }) } else { this.prepareModal(this._element, this._config.status) this.toggle() } } prepareModal (elementTarget, status) { if (elementTarget instanceof Element || elementTarget instanceof HTMLDocument && status) { const elAttributeStatus = new AttributeHandler({ element: elementTarget, attributeName: 'trv-status' }).getAttribute() const elAttributeModalTarget = new AttributeHandler({ element: elementTarget, attributeName: 'trv-modal-target' }).getAttribute() this._isShown = BooleanParse(elAttributeStatus) || false this._modalTargetName = elAttributeModalTarget } else { this._isShown = status === 'open' ? true : typeof status === 'undefined' || status === '' ? null : false this._modalTargetName = elementTarget ? elementTarget : '' } this._elementModalTarget = window.$TravlrSelector(`[trv-modal-name=${this._modalTargetName}]`) this.eventListener() } eventListener () { this._elementModalTarget.forEach(elementModal => { // add event listener for active button new EventHandler({ type: 'add', element: elementModal, eventName: EventName.ACTIVE, action: (event) => { this._elementContext = event.target // before action if (typeof this._beforeAction === 'function') { new CallbackHandler({ callback: this._beforeAction, params: this }) } this.show() // after action if (typeof this._afterAction === 'function') { new CallbackHandler({ callback: this._afterAction, params: this }) } } }) // add event listener for inactive button new EventHandler({ type: 'add', element: elementModal, eventName: EventName.INACTIVE, action: (event) => { this._elementContext = event.target // before action if (typeof this._beforeAction === 'function') { new CallbackHandler({ callback: this._beforeAction, params: this }) } this.hide() // after action if (typeof this._afterAction === 'function') { new CallbackHandler({ callback: this._afterAction, params: this }) } } }) }) } toggle () { this._isShown = !this._isShown if (this._isShown !== null) { // before action if (typeof this._beforeAction === 'function') { new CallbackHandler({ callback: this._beforeAction, params: this }) } if (!this._isShown) { this.hide() } else { this.show() } // after action if (typeof this._afterAction === 'function') { new CallbackHandler({ callback: this._afterAction, params: this }) } } } dismiss (elementTarget) { elementTarget.onclick = () => { this.hide() } } show () { this._isShown = true this._elementModalButton.forEach(element => { new AttributeHandler({ element: element, attributeName: 'trv-status', attributeValue: this._isShown }).setAttribute() }) this._elementModalButtonDismiss.forEach(elementDismiss => { new AttributeHandler({ element: elementDismiss, attributeName: 'trv-status', attributeValue: this._isShown }).setAttribute() }) this.modalToggle() // dismiss button this._elementModalButtonDismiss.forEach(elementDismiss => { this._modalButtonDismissContext = elementDismiss this.dismiss(elementDismiss) }) // dismiss overlay this._elementModalOverlay.forEach(elementOverlay => { this._modalOverlayContext = elementOverlay this.dismiss(elementOverlay) }) } hide () { this._isShown = false this._elementModalButton.forEach(element => { new AttributeHandler({ element: element, attributeName: 'trv-status', attributeValue: this._isShown }).setAttribute() }) this._elementModalButtonDismiss.forEach(elementDismiss => { new AttributeHandler({ element: elementDismiss, attributeName: 'trv-status', attributeValue: this._isShown }).setAttribute() }) this.modalToggle() } modalToggle () { this._elementModalTarget.forEach(element => { this._modalTargetContext = element this._isShown ? element.classList.add(ClassName.ACTIVE) : element.classList.remove(ClassName.ACTIVE) }) } } const ModalInit = (config) => { return new Modal(config) } export default ModalInit