license import React from 'react' ; import hoistNonReactStatics from 'hoist-non-react-statics' ; import { ThemeStyleType } from '@eva-design/dss' ; import { StyleConsumerService } from './styleConsumer.service' ; import { Interaction , StyleType , } from './style.service' ; import { MappingContext } from '../mapping/mappingContext' ; import { ThemeContext } from '../theme/themeContext' ; import { ThemeType } from '../theme/theme.service' ; interface PrivateRefProps < T = React . ReactInstance > { forwardedRef ? : React . Ref < T > ; } export interface EvaProp { theme ? : ThemeType ; style ? : StyleType ; dispatch ? : ( interaction : Interaction [ ] ) => void ; } export interface StyledComponentProps { appearance ? : string ; eva ? : EvaProp ; } interface State { interaction : Interaction [ ] ; } type WrappedComponentProps = any ; type WrappedComponent = any ; type StyledComponent = any ; property property param name overview-example overview-example overview-example overview-example export const styled = ( name ) : StyledComponent => { return ( component ) : StyledComponent => { return styleInjector ( component , name ) ; } ; } ; const styleInjector = ( Component , name ) : StyledComponent => { if ( ! name ) { console . warn ( 'Components annotated with @styled function should also have its in mapping.json.' ) ; return null ; } class Wrapper extends React . PureComponent < PrivateRefProps , State > { public state : State = { interaction : [ ] , } ; private init : boolean = false ; private defaultProps : WrappedComponentProps ; private service : StyleConsumerService ; private onInit = ( style , theme ) : void => { this . service = new StyleConsumerService ( name , style ) ; this . defaultProps = this . service . createDefaultProps ( ) ; this . init = true ; } ; private onDispatch = ( interaction ) : void => { this . setState ( { interaction } ) ; } ; private withEvaProp = ( sourceProps , sourceStyle , theme ) : StyledComponentProps => { const props = { ... this . defaultProps , ... sourceProps } ; const style = this . service . createStyleProp ( props , sourceStyle , theme , this . state . interaction ) ; return { ... props , eva : { theme , style , dispatch : this . onDispatch , } , } ; } ; private renderWrappedElement = ( style , theme ) : React . ReactElement => { if ( ! this . init ) { this . onInit ( style , theme ) ; } const { forwardedRef , ... restProps } = this . props ; return ( < Component { ... this . withEvaProp ( restProps as any , style , theme ) } ref = { forwardedRef } / > ) ; } ; public render ( ) { return ( < MappingContext . Consumer > { ( style ) : React . ReactElement => ( < ThemeContext . Consumer > { ( theme ) : React . ReactElement => { return this . renderWrappedElement ( style , theme ) ; } } < /ThemeContext.Consumer>)}</MappingContext . Consumer > ) ; } } const WrappingElement = ( props , ref ) : React . ReactElement => { return ( < Wrapper { ... props } forwardedRef = { ref } / > ) ; } ; const ResultComponent = React . forwardRef < React . ReactInstance , PrivateRefProps > ( WrappingElement ) ; ResultComponent . displayName = Component . displayName || Component . name ; hoistNonReactStatics ( ResultComponent , Component ) ; return ResultComponent ; } ;