Vulcan/packages/nova-lib/lib/components.js
2017-01-19 11:19:36 +09:00

112 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
export const Components = {}; // will be populated on startup (see nova:routing)
export const ComponentsTable = {} // storage for infos about components
/**
* 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),
* }
*
*/
export const registerComponent = (name, rawComponent, ...hocs) => {
// 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,
call: () => compose(...hocs)(rawComponent)
};
return compose(...hocs)(rawComponent);
};
/**
* Get a component registered with registerComponent(name, component, ...hocs).
*
* @param {String} name The name of the component to get.
* @returns {Function|React Component} A (wrapped) React component
*/
export const getComponent = (name) => {
return ComponentsTable[name].call();
};
/**
* 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);
});
}
/**
* Get the **raw** (original) component registered with registerComponent
* 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;
};
/**
* 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]
*
* 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];
// 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);
}