minsky-kit
Version:
Kit of components for MINSKY web agency
159 lines (129 loc) • 5.25 kB
JavaScript
/*
Future logic
------------
- Hamburger manipulation like menuOverlay
- Add multiple triggers
- Changeout el at runtime to provide consistent support with Component.js
*/
// imports
import Slideout from 'slideout';
import Component from './Component';
// private statics
const CSSCLASSES = ['slideout-menu', 'slideout-menu-left', 'slideout-menu-right', 'slideout-panel', 'slideout-open'];
// class definition
export default class SlideOutNav extends Component {
// constructor
constructor (args = {}, objectName = 'SlideOutNav') {
args.debug = args.debug || false;
// super
super(args, objectName);
// set properties
this._$trigger = args.$trigger;
this._$parent = args.$parent;
this._$container = args.$container;
this._$originalParent = this.$el.parentNode;
// prepare dom for init
prepDom.call(this);
// init slideout
const options = args.options || {};
this._slideout = new Slideout({
panel: this._$container,
menu: this._$el,
padding: options.padding || 320,
tolerance: options.tolerance || 70,
duration: options.duration || 500,
easing: options.easing || 'ease',
side: options.side || 'left',
touch: options.touch || true,
});
// add listener to trigger
if (this._$trigger) this._$trigger.addEventListener('click', this.blm.add('onTriggerClick', onTriggerClick));
// add listeners to slideout
this._slideout.on('beforeclose', this.blm.add('onSlideoutBeforeClose', onSlideoutBeforeClose));
this._slideout.on('close', this.blm.add('onSlideoutClose', onSlideoutClose));
this._slideout.on('beforeopen', this.blm.add('onSlideoutBeforeOpen', onSlideoutBeforeOpen));
this._slideout.on('open', this.blm.add('onSlideoutOpen', onSlideoutOpen));
this._slideout.on('translatestart', this.blm.add('onSlideoutTranslateStart', onSlideoutTranslateStart));
this._slideout.on('translate', this.blm.add('onSlideoutTranslate', onSlideoutTranslate));
this._slideout.on('translateend', this.blm.add('onSlideoutTranslateEnd', onSlideoutTranslateEnd));
this.log('ready');
}
// methods
show () {
this.log('show');
this._slideout.open();
}
hide () {
this.log('hide');
this._slideout.close();
}
toggle () {
this.log('toggle');
this._slideout.toggle();
}
refresh () {
this.log('refresh');
}
destroy () {
// add listener to trigger
if (this._$trigger) this._$trigger.removeEventListener('click', this.blm.remove('onTriggerClick'));
// remove slideout listeners
this._slideout.off('beforeClose', this.blm.remove('onSlideoutBeforeClose'));
this._slideout.off('close', this.blm.remove('onSlideoutClose'));
this._slideout.off('beforeOpen', this.blm.remove('onSlideoutBeforeOpen'));
this._slideout.off('open', this.blm.remove('onSlideoutOpen'));
this._slideout.off('translateStart', this.blm.remove('onSlideoutTranslateStart'));
this._slideout.off('translate', this.blm.remove('onSlideoutTranslate'));
this._slideout.off('translateEnd', this.blm.remove('onSlideoutTranslateEnd'));
// destroy slideout
this._slideout.destroy();
// reset dom change
resetDom.call(this);
// remove all possible classes from elements
this.$el.classList.remove(...CSSCLASSES);
this._$parent.classList.remove(...CSSCLASSES);
this._$container.classList.remove(...CSSCLASSES);
this._$originalParent.classList.remove(...CSSCLASSES);
// super destroy
super.destroy();
}
// getters & setters
get visible () {
return this._slideout.isOpen();
}
set visible (value) {
this.log('Visibility set', value);
if (value !== this.visible) {
if (value) {
this.show();
}
else {
this.hide();
}
}
}
}
// Utils
function prepDom () {
this.log('prepare dom');
// put el in designated parent
this._$parent.prepend(this.$el);
}
function resetDom () {
this.log('reset dom');
// put el in original parent
this._$originalParent.prepend(this.$el);
}
// Event handlers
function onTriggerClick (e) {
this.log('trigger click');
e.preventDefault();
this.toggle();
}
function onSlideoutBeforeClose () { this.dispatch('beforeHide'); }
function onSlideoutClose () { this.dispatch('hide'); }
function onSlideoutBeforeOpen () { this.dispatch('beforeShow'); }
function onSlideoutOpen () { this.dispatch('show'); }
function onSlideoutTranslateStart () { this.dispatch('translateStart'); }
function onSlideoutTranslate (translated) { this.dispatch('translate', { distance: translated }); }
function onSlideoutTranslateEnd () { this.dispatch('translateEnd'); }