/* @flow */ import * as React from 'react'; import deepmerge from 'deepmerge'; import hoistNonReactStatics from 'hoist-non-react-statics'; import type { ThemeProviderType } from './createThemeProvider'; import type { $DeepShape } from './types'; export type WithThemeType = >( Comp: C ) => C & React.ComponentType< $Diff, { theme: T }> & { theme?: $DeepShape } >; const createWithTheme = >( ThemeProvider: ThemeProviderType, ThemeContext: React.Context ) => function withTheme(Comp: *, overrides?: $DeepShape) { class ThemedComponent extends React.Component<*> { _previous: ?{ a: T, b: ?S, c: ?S, result: T }; _merge = (a: T, b: ?S, c: ?S) => { const previous = this._previous; if ( previous && previous.a === a && previous.b === b && previous.c === c ) { return previous.result; } let result = a && b && a !== b ? deepmerge(a, b) : a || b; result = c && result !== c ? deepmerge(result, c) : result; this._previous = { a, b, c, result }; return result; }; render() { const { _reactThemeProviderForwardedRef, ...rest } = this.props; return ( {theme => ( )} ); } } const ResultComponent = React.forwardRef((props, ref) => ( )); ResultComponent.displayName = `withTheme(${Comp.displayName || Comp.name})`; hoistNonReactStatics(ResultComponent, Comp); return (ResultComponent: any); }; export default createWithTheme;