11import { Component , createElement } from 'react'
2+ import PropTypes from 'prop-types'
3+ import { themeListener , channel } from 'theming'
24
35import filterProps from './utils/filterProps'
46import composeClasses from './utils/composeClasses'
@@ -27,18 +29,25 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
2729 return class StyledElement extends Component {
2830 static tagName : string = tagName
2931 static style : ComponentStyleType = elementStyle
32+ static contextTypes = {
33+ [ channel ] : PropTypes . object
34+ }
3035
3136 props : StyledElementPropsType
37+ sheet : JssSheet
38+ state : { theme ?: Object }
39+ unsubscribe: Function
3240
3341 dynamicTagName = ''
42+ setTheme = ( theme : Object ) => this . setState ( { theme} )
3443
35- sheet : JssSheet
36-
37- constructor ( props : StyledElementPropsType ) {
38- super ( props )
44+ constructor ( props : StyledElementPropsType , context : * ) {
45+ super ( props , context )
3946 if ( ! this . dynamicTagName && dynamicStyle ) {
4047 this . dynamicTagName = availableDynamicTagNames . pop ( ) || generateTagName ( tagName )
4148 }
49+
50+ this . state = context [ channel ] ? { theme : themeListener . initial ( context ) } : { }
4251 }
4352
4453 componentWillMount ( ) {
@@ -57,27 +66,37 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
5766 }
5867
5968 classMap [ this . dynamicTagName ] = classMap [ this . dynamicTagName ] || rulesIndex . slice ( rulesTotal )
60- this . updateSheet ( this . props )
69+ this . updateSheet ( this . props , this . state )
6170 }
6271
63- componentWillReceiveProps ( nextProps : StyledElementPropsType ) {
64- if ( dynamicStyle ) this . updateSheet ( nextProps )
72+ componentWillUpdate ( nextProps : StyledElementPropsType , nextState : * ) {
73+ if ( dynamicStyle ) this . updateSheet ( nextProps , nextState )
74+ }
75+
76+ componentDidMount ( ) {
77+ if ( this . state . theme ) {
78+ this . unsubscribe = themeListener . subscribe ( this . context , this . setTheme )
79+ }
6580 }
6681
6782 componentWillUnmount ( ) {
6883 availableDynamicTagNames . push ( this . dynamicTagName )
84+
85+ if ( typeof this . unsubscribe === 'function' ) this . unsubscribe ( )
6986 }
7087
71- updateSheet ( props : StyledElementPropsType ) {
88+ updateSheet ( props : StyledElementPropsType , state : * ) {
7289 let rule
7390 let ruleIndex = 0
7491
92+ const styles = Object . assign ( { } , props , state )
93+
7594 // nested styles become to flatten rules, so we need to update each nested rule
7695 for ( ruleIndex ; ruleIndex < classMap [ this . dynamicTagName ] . length ; ruleIndex ++ ) {
7796 rule = classMap [ this . dynamicTagName ] [ ruleIndex ]
7897
79- if ( rule . name ) this . sheet . update ( rule . name , props )
80- if ( rule . rules ) rule . rules . update ( props )
98+ if ( rule . name ) this . sheet . update ( rule . name , styles )
99+ if ( rule . rules ) rule . rules . update ( styles )
81100 }
82101 }
83102
0 commit comments