minsky-kit
Version:
Kit of components for MINSKY web agency
140 lines (113 loc) • 3.99 kB
JavaScript
// imports
import EventDispatcher from '../managers/EventDispatcher';
import DomStateManager from '../managers/DomStateManager';
import PluginManager from '../managers/PluginManager';
import { strToDom } from '../utils/dom';
import { strToCssClass, strToReadyClass } from '../utils/css';
// private static properties
const plugins = new PluginManager();
// class definition
export default class Component extends EventDispatcher {
// public static props
// constructor
constructor (args, objectName = 'Component') {
// call super constructor
super(args, objectName);
this._hadObjectName = false;
// keep el accessible
this.$el = args.$el || args.el;
this._states = null;
if (args.states) this.states.add(args.states);
// set ready
this.ready = args.autoReady !== false;
}
// methods
initialize (args = {}) {
// init super method
super.initialize(args);
}
refresh () {
this.log('empty refresh');
}
destroy () {
// destroy
if (this._states) this._states.destroy();
// remove ready class
this.ready = false;
// clean up (use setters depending on their utility)
this._states = null;
this.$el = null;
// call super method
super.destroy();
}
// getters & setters
get $el () { return this._$el; }
set $el (value) {
if (this._$el !== value) {
// generate css class
const cssClass = strToCssClass(this.objectName);
// remove set classes before change
if (this._$el) {
if (!this._hadObjectName) this._$el.classList.remove(cssClass);
this._$el.classList.remove(strToReadyClass(this.objectName));
this._$el.classList.remove(strToCssClass('has-js'));
}
// change el
const old = this._$el;
this._$el = strToDom(value);
if (this._states) this.states.el = this._$el;
if (this._$el) {
// add object name class to element if not already present
this._hadObjectName = this._$el.classList.contains(cssClass);
if (!this._hadObjectName) this._$el.classList.add(cssClass);
this._$el.classList.add(strToCssClass('has-js'));
}
// dispatch state change
this.dispatch('elementChange', {
old,
new: value,
});
}
}
get ready () { return this._ready; }
set ready (value) {
if (this._ready !== value) {
// do some class management
if (this._$el) {
if (value) {
this._$el.classList.add(strToReadyClass(this.objectName));
}
else {
this._$el.classList.remove(strToReadyClass(this.objectName));
}
}
// keep flag
this._ready = value;
// dispatch state change
this.dispatch('readyStateChange', { ready: value });
}
}
get states () {
// automatically provide new domstate manager instance when it isn't present yet
// avoids useless creation of the instance when components without states are constructed
if (!this._states) {
this._states = new DomStateManager({
el: this._$el,
});
}
return this._states;
}
// static methods
get plugins () { return plugins; }
// deprecated getters & setters
get el () {
this.log('warn', 'The el property is deprecated. Use $el instead.');
this.deprecationMentioned = true;
return this._$el;
}
set el (value) {
this.log('warn', 'The el property is deprecated. Use $el instead.');
this.deprecationMentioned = true;
this._$el = value;
}
}