@travlrcom/uikit
Version:
TRAVLR UiKit
299 lines (253 loc) • 8.29 kB
JavaScript
/**
****************************************************
*** ******* ****** ****
*** ****** ****** *****
*********** ************** ****** ******
*********** ************* ****** *******
*********** ************ ****** ********
*********** *********** ****** *********
*********** ********** ****** **********
*********** ********* ****** ***********
*********** ******** ****** ************
*********** ******* ****** *************
*********** ****** ****** **************
****************************************************
* --------------------------------------------------
* 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