UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

68 lines (51 loc) 1.8 kB
/* @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<T> = <P, C: React.ComponentType<P>>( Comp: C ) => C & React.ComponentType< $Diff<React.ElementConfig<C>, { theme: T }> & { theme?: $DeepShape<T> } >; const createWithTheme = <T: Object, S: $DeepShape<T>>( ThemeProvider: ThemeProviderType<T>, ThemeContext: React.Context<T> ) => 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 ( <ThemeContext.Consumer> {theme => ( <Comp {...rest} theme={this._merge(theme, rest.theme)} ref={_reactThemeProviderForwardedRef} /> )} </ThemeContext.Consumer> ); } } const ResultComponent = React.forwardRef((props, ref) => ( <ThemedComponent {...props} _reactThemeProviderForwardedRef={ref} /> )); ResultComponent.displayName = `withTheme(${Comp.displayName || Comp.name})`; hoistNonReactStatics(ResultComponent, Comp); return (ResultComponent: any); }; export default createWithTheme;