UNPKG

mainstay

Version:

The link between the client library and component

214 lines (160 loc) 6.15 kB
/** * This is the main file for componentInitializer */ import DataStoar from 'data-stoar'; const defaultOptions = { rootElementKey : 'hook', libraryComponents : [], renderKey : null, additionalProps : null } export class Mainstay { pageComponents = []; componentsToRender = []; renderComponents = []; javascriptComponents = []; instances = []; constructor( options ){ options = { ...defaultOptions, ...options } if( options.renderFunction ) { if( !options.renderKey ) throw "You need a 'renderKey' if you intend to use the render function"; if( !options.unmount ) throw "You need to define an 'unmount' function if intend to use the render function"; } this.options = options; this.getPageData = this.getPageData.bind( this ); this.getPageComponents = this.getPageComponents.bind( this ); this.filterComponents = this.filterComponents.bind( this ); this.render = this.render.bind( this ); this.renderFunction = this.renderFunction.bind(this); this.customRenderFunction = this.customRenderFunction.bind( this ); this.initializeJS = this.initializeJS.bind( this ); this.initializeAllJSComponents = this.initializeAllJSComponents.bind( this ); this.getPageComponents() } getPageComponents(){ this.pageComponents = null; let pageComponents = new DataStoar(); this.pageComponents = pageComponents.components; this.getPageData() } getPageData() { this.componentsToRender = this.pageComponents.map( ( pageComponent, index ) => { let libComponent = this.options.libraryComponents.find( ( libraryComponent ) => { if( libraryComponent.name === 'Connect' ){ return libraryComponent.WrappedComponent.name === pageComponent.name; } else { return libraryComponent.name === pageComponent.name; } } ) if( libComponent ){ return { instances : pageComponent.instances, jsClass : libComponent.component } } else { return { instances: [], jsClass: null } } } ) this.filterComponents(); } filterComponents() { this.componentsToRender.forEach( ( component ) => { component.instances.forEach( ( instance ) => { let type = null; if( instance.data[ this.options.renderKey ] ){ this.renderComponents.push( { data : instance.data, jsClass : component.jsClass } ) type = 'renderFunction' } else { this.javascriptComponents.push( { data : instance.data, jsClass : component.jsClass } ) type = 'js' } this.instances.push( { data : instance.data, jsClass : component.jsClass, type : type } ) } ) } ) } render(){ if( this.renderComponents.length > 0 ){ this.customRenderFunction() } if( this.javascriptComponents.length > 0 ){ this.initializeAllJSComponents() } } customRenderFunction(){ this.renderComponents.forEach( this.renderFunction ) } initializeAllJSComponents(){ this.javascriptComponents.forEach( this.initializeJS ) } renderFunction({ jsClass : Component, data } ) { let el = data.element ? data.element : document.querySelector( `[data-${this.options.rootElementKey}="${data[this.options.rootElementKey]}"]`); this.options.additionalProps ? this.options.renderFunction( {...this.options.additionalProps,...data}, el, Component ) : this.options.renderFunction( data, el, Component ); } initializeJS({ jsClass : Component, data } ) { let el = data.element ? data.element : document.querySelector( `[data-${this.options.rootElementKey}="${data[this.options.rootElementKey]}"]`); this.options.additionalProps ? new Component( {...this.options.additionalProps,...data}, el) : new Component( data, el ) } unmount(){ this.renderComponents.forEach( ({ jsClass : Component, data }) => { let el = data.element ? data.element : document.querySelector( `[data-${this.options.rootElementKey}="${data[this.options.rootElementKey]}"]`); this.options.unmount(el, data, Component); }) } reset(){ this.unmount(); this.componentsToRender = []; this.renderComponents = []; this.javascriptComponents = []; this.instances = []; } reRender(){ this.unmount(); this.componentsToRender = []; this.renderComponents = []; this.javascriptComponents = []; this.getPageComponents(); setTimeout( () => { this.render(); }, 100 ) } reRenderComponent( componentId ) { this.reset(); this.getPageComponents(); this.instances.forEach( ( component ) => { if( component.data[this.options.rootElementKey] === componentId ){ if( component.type === 'renderFunction' ) this.renderFunction( component ) if( component.type === 'js' ) this.initializeJS( component ) } } ) } } export default Mainstay