11import { Component , createElement } from 'react'
22import { getDynamicStyles } from 'jss'
3+ import type {
4+ Rule ,
5+ } from 'jss/lib/types'
36
47import filterProps from './utils/filterProps'
58import composeClasses from './utils/composeClasses'
69import generateTagName from './utils/generateTagName'
710
811import type {
9- JssStaticSheet ,
10- JssDynamicSheet ,
12+ JssSheet ,
1113 ComponentStyleType ,
1214 StyledElementPropsType
1315} from './types'
1416
1517type StyledArgs = {
1618 tagName : string ,
1719 elementStyle : ComponentStyleType ,
18- mountSheets : Function
20+ mountSheet : Function
1921}
2022
21- const styled = ( { tagName, elementStyle, mountSheets } : StyledArgs ) => {
23+ const styled = ( { tagName, elementStyle, mountSheet } : StyledArgs ) => {
2224 const dynamicStyle = getDynamicStyles ( elementStyle )
2325 const staticTagName = generateTagName ( tagName )
2426
2527 const availableDynamicTagNames = [ ]
28+ const classMap = { }
2629
2730 return class StyledElement extends Component {
2831 static tagName : string = tagName
@@ -31,8 +34,10 @@ const styled = ({tagName, elementStyle, mountSheets}: StyledArgs) => {
3134 props : StyledElementPropsType
3235
3336 dynamicTagName = ''
34- staticSheet : JssStaticSheet
35- dynamicSheet : JssDynamicSheet
37+
38+ sheet : JssSheet
39+ cssRules : CSSStyleRule [ ]
40+ rulesIndex : Rule [ ]
3641
3742 constructor ( props : StyledElementPropsType ) {
3843 super ( props )
@@ -42,24 +47,53 @@ const styled = ({tagName, elementStyle, mountSheets}: StyledArgs) => {
4247 }
4348
4449 componentWillMount ( ) {
45- Object . assign ( this , mountSheets ( ) )
50+ this . sheet = this . sheet || mountSheet ( )
51+ this . rulesIndex = this . sheet . rules . index
52+ this . cssRules = this . cssRules || this . sheet . renderer . getRules ( ) || [ ]
53+
54+ const rulesTotal = this . rulesIndex . length
55+ const cssRulesTotal = this . cssRules . length
4656
47- if ( ! this . staticSheet . getRule ( staticTagName ) ) {
48- this . staticSheet . addRule ( staticTagName , elementStyle )
57+ if ( ! this . sheet . getRule ( staticTagName ) ) {
58+ this . sheet . addRule ( staticTagName , elementStyle )
4959 }
5060
5161 if ( ! dynamicStyle ) return
5262
53- if ( ! this . dynamicSheet . getRule ( this . dynamicTagName ) ) {
54- this . dynamicSheet . addRule ( this . dynamicTagName , dynamicStyle )
63+ if ( ! this . sheet . getRule ( this . dynamicTagName ) ) {
64+ this . sheet . addRule ( this . dynamicTagName , dynamicStyle )
5565 }
5666
57- this . dynamicSheet . update ( this . dynamicTagName , this . props )
67+ classMap [ this . dynamicTagName ] = this . rulesIndex . slice ( rulesTotal )
68+
69+ let cssRule
70+ let rule
71+ let cssRuleIndex = 0
72+ let ruleIndex = 0
73+ for ( ruleIndex ; ruleIndex < classMap [ this . dynamicTagName ] . length ; ruleIndex ++ ) {
74+ rule = classMap [ this . dynamicTagName ] [ ruleIndex ]
75+ cssRule = this . cssRules [ cssRulesTotal + cssRuleIndex ]
76+ if ( cssRule && cssRule . selectorText === rule . selectorText ) {
77+ /**
78+ * we need to set cssRule in renderable
79+ * @see {@link https://github.com/cssinjs/jss/issues/500 }
80+ * and we don't want to use link(), because there is no need to iterate over all rules
81+ */
82+ rule . renderable = cssRule
83+ cssRuleIndex ++
84+ }
85+ this . sheet . update ( rule . name , this . props )
86+ }
5887 }
5988
60- componentWillReceiveProps ( nextProps : StyledElementPropsType ) {
89+ componentWillReceiveProps ( ) {
6190 if ( dynamicStyle ) {
62- this . dynamicSheet . update ( this . dynamicTagName , nextProps )
91+ let rule
92+ let ruleIndex = 0
93+ for ( ruleIndex ; ruleIndex < classMap [ this . dynamicTagName ] . length ; ruleIndex ++ ) {
94+ rule = classMap [ this . dynamicTagName ] [ ruleIndex ]
95+ this . sheet . update ( rule . name , this . props )
96+ }
6397 }
6498 }
6599
@@ -68,14 +102,12 @@ const styled = ({tagName, elementStyle, mountSheets}: StyledArgs) => {
68102 }
69103
70104 render ( ) {
71- if ( ! this . staticSheet ) return null
72-
73105 const { children, className, ...attrs } = this . props
74106
75107 const props = filterProps ( attrs )
76108 const tagClass = composeClasses ( [
77- this . staticSheet . classes [ staticTagName ] ,
78- this . dynamicSheet . classes [ this . dynamicTagName ] ,
109+ this . sheet . classes [ staticTagName ] ,
110+ this . sheet . classes [ this . dynamicTagName ] ,
79111 className
80112 ] )
81113
0 commit comments