/* @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: *) { class ThemedComponent extends React.Component<*> { _previous: ?{ a: T, b: ?S, result: T }; _merge = (a: T, b: ?S) => { const previous = this._previous; if (previous && previous.a === a && previous.b === b) { return previous.result; } const result = a && b && a !== b ? deepmerge(a, b) : a || b; this._previous = { a, b, 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;