Vulcan/packages/nova-lib/lib/modules/components.js

112 lines
4 KiB
JavaScript
Raw Normal View History

import { compose } from 'react-apollo'; // note: at the moment, compose@react-apollo === compose@redux ; see https://github.com/apollostack/react-apollo/blob/master/src/index.ts#L4-L7
2016-11-29 11:35:20 +09:00
export const Components = {}; // will be populated on startup (see nova:routing)
export const ComponentsTable = {} // storage for infos about components
2016-11-29 11:35:20 +09:00
/**
* Register a Telescope component with a name, a raw component than can be extended
* and one or more optional higher order components.
*
* @param {String} name The name of the component to register.
* @param {React Component} rawComponent Interchangeable/extendable component.
* @param {...Function} hocs The HOCs to compose with the raw component.
*
* Note: when a component is registered without higher order component, `hocs` will be
* an empty array, and it's ok!
* See https://github.com/reactjs/redux/blob/master/src/compose.js#L13-L15
*
* @returns Structure of a component in the list:
*
* ComponentsTable.Foo = {
* name: 'Foo',
* hocs: [fn1, fn2],
* rawComponent: React.Component,
* call: () => compose(...hocs)(rawComponent),
* }
*
2016-11-29 11:35:20 +09:00
*/
export const registerComponent = (name, rawComponent, ...hocs) => {
2016-11-29 11:35:20 +09:00
// console.log('// registering component');
// console.log(name);
// console.log('raw component', rawComponent);
// console.log('higher order components', hocs);
// store the component in the table
ComponentsTable[name] = {
name,
rawComponent,
hocs,
};
2016-11-29 11:35:20 +09:00
};
/**
2016-12-12 16:48:49 +09:00
* Get a component registered with registerComponent(name, component, ...hocs).
2016-11-29 11:35:20 +09:00
*
* @param {String} name The name of the component to get.
* @returns {Function|React Component} A (wrapped) React component
*/
export const getComponent = (name) => {
const component = ComponentsTable[name];
const hocs = component.hocs.map(hoc => Array.isArray(hoc) ? hoc[0](hoc[1]) : hoc);
return compose(...hocs)(component.rawComponent)
2016-11-29 11:35:20 +09:00
};
/**
* Populate the lookup table for components to be callable
* Called once on app startup
**/
export const populateComponentsApp = () => {
// loop over each component in the list
Object.keys(ComponentsTable).map(name => {
// populate an entry in the lookup table
Components[name] = getComponent(name);
// uncomment for debug
// console.log('init component:', name);
});
}
2016-11-29 11:35:20 +09:00
/**
2016-12-12 16:48:49 +09:00
* Get the **raw** (original) component registered with registerComponent
2016-11-29 11:35:20 +09:00
* without the possible HOCs wrapping it.
*
* @param {String} name The name of the component to get.
* @returns {Function|React Component} An interchangeable/extendable React component
*/
export const getRawComponent = (name) => {
return ComponentsTable[name].rawComponent;
2016-11-29 11:35:20 +09:00
};
/**
* Replace a Telescope component with the same name with a new component or
* an extension of the raw component and one or more optional higher order components.
* This function keeps track of the previous HOCs and wrap the new HOCs around previous ones
*
* @param {String} name The name of the component to register.
* @param {React Component} rawComponent Interchangeable/extendable component.
* @param {...Function} hocs The HOCs to compose with the raw component.
* @returns {Function|React Component} A component callable with Components[name]
2016-11-29 11:35:20 +09:00
*
* Note: when a component is registered without higher order component, `hocs` will be
* an empty array, and it's ok!
* See https://github.com/reactjs/redux/blob/master/src/compose.js#L13-L15
*/
export const replaceComponent = (name, newComponent, ...newHocs) => {
const previousComponent = ComponentsTable[name];
2016-11-29 11:35:20 +09:00
// xxx : throw an error if the previous component doesn't exist
// console.log('// replacing component');
// console.log(name);
// console.log(newComponent);
// console.log('new hocs', newHocs);
// console.log('previous hocs', previousComponent.hocs);
return registerComponent(name, newComponent, ...newHocs, ...previousComponent.hocs);
};
export const copyHoCs = (sourceComponent, targetComponent) => {
return compose(...sourceComponent.hocs)(targetComponent);
}