Skip to content

Instantly share code, notes, and snippets.

@panayotoff
Last active January 15, 2019 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save panayotoff/3bf68c6de450e4bc80f0c88dcabdbf3a to your computer and use it in GitHub Desktop.
Save panayotoff/3bf68c6de450e4bc80f0c88dcabdbf3a to your computer and use it in GitHub Desktop.
Gia.js-ish component registration
/**
* Single Component helper
*/
import $ from 'jquery';
import Emitter from './Events';
class Component {
constructor(element, options) {
this.element = element;
this.$el = $(element);
this.el = this.$el.get(0);
this.el['__component__'] = this;
this._options = { ...options, ...parseOptions(this.$el) };
this._emitter = new Emitter();
}
// Simple mixin
use(mixinFn) {
$.isFunction(mixinFn) && mixinFn(this);
}
// Element selector
$(el) {
return this.$el.find(el);
}
// Component events
get events() {
return this._emitter;
}
// Options
get options() {
return this._options;
}
set options(defaults) {
this._options = {
...this._options,
...defaults,
...parseOptions(this.$el)
};
return this._options;
}
/**
* This is here only to be rewritten
*/
mount() {
console.warn(`Component ${this._name} does not have "mount" method.`);
}
unmount() {}
}
/**
* Instance
*/
const createInstance = (element, component, componentName, options) => {
component.prototype._name = String(componentName);
return new component(element, options);
};
const destroyInstance = element => {
const instance = getComponentFromElement(element);
if (instance) {
instance.events.trigger('beforeDestroy');
instance.unmount();
instance.events.trigger('destroyed');
instance.events.destroy();
instance.element['__component__'] = null;
//console.log(`Destroyed component ${instance._name}`);
}
};
const getComponentFromElement = element => $(element).get(0)['__component__'];
/**
* Load / Remove components from context element
*/
const loadComponents = (components = {}, ctx = document.documentElement) => {
if (!components || !Object.keys(components).length) {
console.warn(`Empty components passed to ${ctx}`);
return false;
}
const $context = $(ctx);
const context = $context.get(0);
if (!$.isArray(context['__components__'])) {
context['__components__'] = [];
}
$context.find('[data-component]').each((index, element) => {
const instance = getComponentFromElement(element);
if (instance) {
console.log(`Instance of ${instance._name} aleady mounted!`);
}
const $element = $(element);
const componentName = $element.data('component');
const componentConstructor = components[componentName];
if ($.isFunction(componentConstructor)) {
const instance = createInstance($element, componentConstructor, componentName);
context['__components__'].push(instance);
instance.events.trigger('created');
instance.mount();
instance.events.trigger('mounted');
}
});
};
const removeComponents = (ctx = document.documentElement) => {
const $context = $(ctx);
const context = $context.get(0);
$context.find('[data-component]').each((index, element) => {
destroyInstance(element);
});
if ($.isArray(context['__components__'])) {
context['__components__'].length = 0;
}
};
/**
* Helpers
*/
const parseOptions = el => {
return $(el).data('options');
};
/**
* Exports
*/
export default Component;
export { createInstance, destroyInstance, getComponentFromElement, loadComponents, removeComponents, parseOptions };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment