Repository URL to install this package:
|
Version:
1.3.3 ▾
|
/* utils */
import hoistNonReactStatic from 'hoist-non-react-statics'
import { toComponentName } from '@skava/identifier'
/**
* @description
* || Observable.Container
* @ connectToData(TargetViewComponent) // decorates component
* |> ViewInsideContainer // is react wrapper to let containers top into the view
* |> Observer(ViewInsideContainer) // makes it update for any observable property changes
* => TargetViewContainer.render // call original view component, with all our injections form container
* // ^ such as on props
* @example
* const state = observable({
* text: 'loading',
* list: [1, 2],
* })
* class Container {
* static connectToData(Target) {
* Target = observer(Target)
*
* class ViewInsideContainer extends Target {
* componentWillMount() {
* setTimeout(() => state.text = 'eh' && list.push(3), 1000)
* }
* render() {
* // or {text={state.text}, list={state.list}}
* // but this handles dereferencing problems
* return <Target {...state/>
* }
* }
* return observer(ViewInsideContainer)
* }
* }
* class Button extends React.Component {
* static types = { text: '' }
* componentDidUpdate = () => console.log(this.props.list)
* render = () => <button>{this.props.text}</button>
* }
*
*
* @example
*
* <Button />
*
* => <button>loading</button>
* -> console.log([1, 2, 3])
*
* // 1 second later
* => <button>eh</button>
* -> console.log([1, 2, 3])
*
* @alias decorateHigherOrderComponent
* @alias decorateComponentStaticProperties
*
* @param {ViewInsideContainer} ViewInsideContainer HigherOrder.ReactComponent
* @param {TargetViewComponent} TargetViewComponent ReactComponent.componentClass
* @param {ObservableContainer | *} [container=undefined] Container wrapping ReactComponent
*
* @inner side effect only - returns component ONLY for convenience :s
* @return {ViewInsideContainer}
*/
function decorateComponentStatics(
ViewInsideContainer,
TargetViewComponent,
container
) {
/**
* @tutorial https://reactjs.org/docs/higher-order-components.html#static-methods-must-be-copied-over
* @see https://github.com/mridgway/hoist-non-react-statics/blob/master/index.js
*
* @description basically copies all properties from 1 class to another
* (that aren't going to conflict with a wrapping React.Component)
*/
hoistNonReactStatic(ViewInsideContainer, TargetViewComponent)
/**
* @see https://reactjs.org/docs/react-component.html#displayname
* @description this is the name that is displayed in react devtools
* @type {String}
* @TODO add store name passed in here
*
* this will get the best name for this component
* 1. if it has static displayName, use that
* 2. if it's a class, get the constructor/class name
* 3. if it's a function, get the function name
* 4. if it has any name prop, use that
*/
ViewInsideContainer.displayName =
toComponentName(TargetViewComponent) +
'(' +
toComponentName(container) +
')'
/**
* @description reference to our container
* @type {ObservableContainer}
*/
ViewInsideContainer.container = container
/**
* @tutorial https://reactjs.org/docs/refs-and-the-dom.html
* @see https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e
* @spec https://www.ecma-international.org/ecma-262/8.0/index.html#sec-object.getownpropertynames
*
* @alias originalComponentReference
* @description gives us a static reference to the original component
* @type {ReactComponent}
*/
ViewInsideContainer.wrappedComponentRef = TargetViewComponent
/**
* @see https://github.com/mobxjs/mobx-react/blob/master/src/observer.js#L306
* @description now we lift the react-specific props
* @note injector does not want you to do this
*/
// ViewInsideContainer.contextTypes = TargetViewComponent.contextTypes
ViewInsideContainer.propTypes = TargetViewComponent.propTypes
ViewInsideContainer.defaultProps = TargetViewComponent.defaultProps
return ViewInsideContainer
}
export { decorateComponentStatics }
export default decorateComponentStatics