@@ -10,7 +10,6 @@ import type {
1010 DefaultProps ,
1111 ForwardRefElement ,
1212 Frame ,
13- Visitor ,
1413 ComponentStatics
1514} from '../types'
1615
@@ -33,15 +32,25 @@ type Attr = void | AttrsFn | { [propName: string]: ?AttrsFn }
3332type StyledComponentStatics = {
3433 styledComponentId : string ,
3534 attrs : Attr | Attr [ ] ,
36- target : ComponentType < DefaultProps > & ComponentStatics
35+ target : ComponentType < DefaultProps > & ComponentStatics ,
36+ defaultProps ?: Object
37+ }
38+
39+ /** Determines a StyledComponent's theme taking defaults into account */
40+ const computeTheme = ( props : Object , defaultProps : Object ) : Object => {
41+ const defaultTheme = defaultProps ? defaultProps . theme : undefined
42+ const isDefaultTheme = defaultTheme ? props . theme === defaultTheme : false
43+
44+ if ( props . theme && ! isDefaultTheme ) {
45+ return props . theme
46+ } else {
47+ const contextTheme = readContextValue ( styledComponents . ThemeContext )
48+ return contextTheme || defaultTheme
49+ }
3750}
3851
3952/** Computes a StyledComponent's props with attributes */
40- const computeAttrsProps = (
41- input : Attr [ ] ,
42- props : DefaultProps ,
43- theme : mixed
44- ) : any => {
53+ const computeAttrsProps = ( input : Attr [ ] , props : any , theme : any ) : any => {
4554 const executionContext = { ...props , theme }
4655
4756 const attrs = input . reduce ( ( acc , attr ) => {
@@ -63,40 +72,37 @@ const computeAttrsProps = (
6372 return acc
6473 } , { } )
6574
66- return Object . assign ( attrs , props )
75+ const newProps = ( Object . assign ( attrs , props ) : any )
76+ newProps . className = props . className || ''
77+ newProps . style = props . style
78+ ? Object . assign ( { } , attrs . style , props . style )
79+ : attrs . style
80+ return newProps
6781}
6882
6983/** Checks whether a ForwardRefElement is a StyledComponent element */
7084export const isStyledElement = ( element : ForwardRefElement ) : boolean % checks =>
85+ styledComponents !== undefined &&
7186 typeof element . type . styledComponentId === 'string'
7287
7388/** This is an optimised faux mounting strategy for StyledComponents.
7489 It is only enabled when styled-components is installed and the component
7590 can safely be skipped */
76- export const mount = (
77- element : ForwardRefElement ,
78- queue : Frame [ ] ,
79- visitor : Visitor
80- ) : Node => {
81- if ( styledComponents === undefined ) {
82- // styled-components is not installed or incompatible, so the component will have to be
83- // mounted normally
84- const { render } = element . type
85- return mountFunctionComponent ( render , element . props , queue , visitor )
86- }
87-
91+ export const mount = ( element : ForwardRefElement ) : Node => {
8892 // Imitate styled-components' attrs props without computing styles
8993 const type = ( ( element . type : any ) : StyledComponentStatics )
90- const theme = readContextValue ( styledComponents . ThemeContext ) || { }
9194 const attrs : Attr [ ] = Array . isArray ( type . attrs ) ? type . attrs : [ type . attrs ]
92- const computedProps = computeProps ( element . props , ( type : any ) . defaultProps )
95+ const computedProps = computeProps ( element . props , type . defaultProps )
96+ const theme = computeTheme ( element . props , type )
9397 const props = computeAttrsProps ( attrs , computedProps , theme )
9498 const as = props . as || type . target
99+ const children = computedProps . children || null
95100
96- if ( typeof as !== 'function' ) {
97- // StyledComponents rendering DOM elements can safely be skipped like normal DOM elements
98- return element . props . children || null
101+ // StyledComponents rendering DOM elements can safely be skipped like normal DOM elements
102+ if ( typeof as === 'string' ) {
103+ return children
99104 } else {
100- return createElement ( ( as : any ) , props )
105+ delete props . as
106+ return createElement ( ( as : any ) , props , children )
101107 }
102108}
0 commit comments