1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | import React from 'react';
|
7 | import hoistNonReactStatics from 'hoist-non-react-statics';
|
8 | import deepmerge from 'deepmerge';
|
9 | import getComponentName from 'airbnb-prop-types/build/helpers/getComponentName';
|
10 | import { CHANNEL, DIRECTIONS } from './constants';
|
11 | import brcastShape from './proptypes/brcast';
|
12 | import directionPropType from './proptypes/direction';
|
13 |
|
14 | const contextTypes = {
|
15 | [CHANNEL]: brcastShape,
|
16 | };
|
17 |
|
18 | export { DIRECTIONS };
|
19 |
|
20 |
|
21 |
|
22 | const defaultDirection = DIRECTIONS.LTR;
|
23 |
|
24 |
|
25 | export const withDirectionPropTypes = {
|
26 | direction: directionPropType.isRequired,
|
27 | };
|
28 |
|
29 | export default function withDirection(WrappedComponent) {
|
30 | class WithDirection extends React.Component {
|
31 | constructor(props, context) {
|
32 | super(props, context);
|
33 | this.state = {
|
34 | direction: context[CHANNEL] ? context[CHANNEL].getState() : defaultDirection,
|
35 | };
|
36 | }
|
37 |
|
38 | componentDidMount() {
|
39 | if (this.context[CHANNEL]) {
|
40 |
|
41 | this.channelUnsubscribe = this.context[CHANNEL].subscribe((direction) => {
|
42 | this.setState({ direction });
|
43 | });
|
44 | }
|
45 | }
|
46 |
|
47 | componentWillUnmount() {
|
48 | if (this.channelUnsubscribe) {
|
49 | this.channelUnsubscribe();
|
50 | }
|
51 | }
|
52 |
|
53 | render() {
|
54 | const { direction } = this.state;
|
55 |
|
56 | return (
|
57 | <WrappedComponent
|
58 | {...this.props}
|
59 | direction={direction}
|
60 | />
|
61 | );
|
62 | }
|
63 | }
|
64 |
|
65 | const wrappedComponentName = getComponentName(WrappedComponent) || 'Component';
|
66 |
|
67 | WithDirection.WrappedComponent = WrappedComponent;
|
68 | WithDirection.contextTypes = contextTypes;
|
69 | WithDirection.displayName = `withDirection(${wrappedComponentName})`;
|
70 | if (WrappedComponent.propTypes) {
|
71 | WithDirection.propTypes = deepmerge({}, WrappedComponent.propTypes);
|
72 | delete WithDirection.propTypes.direction;
|
73 | }
|
74 | if (WrappedComponent.defaultProps) {
|
75 | WithDirection.defaultProps = deepmerge({}, WrappedComponent.defaultProps);
|
76 | }
|
77 |
|
78 | return hoistNonReactStatics(WithDirection, WrappedComponent);
|
79 | }
|