avvo-styleguide
Version:
Avvo styleguide
106 lines (91 loc) • 2.5 kB
JavaScript
const NAME = 'off-canvas'
const CLASSES = {
active: 'in',
close: 'fa-times',
container: `${NAME}-container`,
exit: `${NAME}-exit`,
wrapper: `${NAME}-wrapper`,
}
const DATA = {
icon: 'fa',
target: 'target',
}
const EVENTS = {
click: 'click.ui.offcanvas',
hide: 'hide.ui.offcanvas',
show: 'show.ui.offcanvas',
}
const REGEX = {
ICON: /(fa-[a-zA-Z]+)/g,
}
/**
* Class that handles off-canvas elements
* @param {string} sel The selector matching elements to initialize
* @return {object} jQuery object representing the off-canvas elements
*/
const OffCanvas = function OffCanvas(sel) {
this.$element = $(sel)
this.$wrapper = this.$element.closest(`.${CLASSES.wrapper}`)
this.$container = this.$element.closest(`.${CLASSES.container}`)
this.$button = getTrigger(DATA.target, sel)
this.$button.data(DATA.icon, getIcon(this.$button))
this.$exit = $(`<a href="#" role="button" class="${CLASSES.exit}" />`)
this.$exit.appendTo(this.$wrapper)
bindEvents(this)
return this
}
/**
* Toggles off-canvas item's state between in and out
* @param {boolean} isOpen A flag indicating whether to activate
* @return {OffCanvas} The OffCanvas instance
*/
OffCanvas.prototype.toggle = function toggle(isOpen) {
const icon = this.$button.data(DATA.icon)
this.$container.toggleClass(CLASSES.active, isOpen)
this.$button.attr('aria-expanded', isOpen)
this.$button.find('.icon').toggleClass(icon, !isOpen)
.toggleClass(CLASSES.close, isOpen)
return this
}
/**
* Makes the off-canvas element visible
* @return {this}
*/
OffCanvas.prototype.show = function show() {
this.$element.trigger(EVENTS.show)
return this.toggle(true)
}
/**
* Hides the off-canvas element
* @return {this}
*/
OffCanvas.prototype.hide = function hide() {
this.$element.trigger(EVENTS.hide)
return this.toggle(false)
}
function bindEvents(obj) {
obj.$button.on(EVENTS.click, (e) => {
e.preventDefault()
if (obj.$container.hasClass(CLASSES.active)) {
obj.hide()
} else {
obj.show()
}
})
obj.$exit.on(EVENTS.click, (e) => {
e.preventDefault()
obj.hide()
})
}
function getIcon($el) {
const iconClass = $el.find('.icon').attr('class')
const match = REGEX.ICON.exec(iconClass)
if (match && match.length) {
return match[0]
}
return ''
}
function getTrigger(attr, value) {
return $(`[data-toggle=${NAME}][data-${attr}=${value}]`)
}
module.exports = OffCanvas