Skip to content

Commit d1c0d8e

Browse files
committed
Get rid from dynamicStyleSheet, fix nested dynamic rules
1 parent ac5cb91 commit d1c0d8e

5 files changed

Lines changed: 66 additions & 37 deletions

File tree

.flowconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,8 @@
55

66
<PROJECT_ROOT>/lib/
77

8+
[libs]
9+
node_modules/jss/flow-typed
10+
811
[options]
912
all=true

src/createStyled.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,17 @@ const getStyledArgs = (
2121
}
2222

2323
const createStyled = (jss: Function) => (baseStyles: BaseStylesType = {}): StyledType => {
24-
let staticSheet
25-
let dynamicSheet
24+
let sheet
2625

27-
const mountSheets = () => {
28-
if (!staticSheet) {
29-
staticSheet = jss.createStyleSheet(baseStyles, {
30-
meta: 'StaticBaseSheet',
31-
}).attach()
32-
33-
dynamicSheet = jss.createStyleSheet({}, {
26+
const mountSheet = () => {
27+
if (!sheet) {
28+
sheet = jss.createStyleSheet(baseStyles, {
3429
link: true,
35-
meta: 'DynamicComponentSheet',
30+
meta: 'sheet',
3631
}).attach()
3732
}
3833

39-
return {staticSheet, dynamicSheet}
34+
return sheet
4035
}
4136

4237
return Object.assign((
@@ -47,8 +42,8 @@ const createStyled = (jss: Function) => (baseStyles: BaseStylesType = {}): Style
4742
const {tagName, style} = getStyledArgs(tagNameOrStyledElement)
4843
const elementStyle = {...style, ...ownStyle}
4944

50-
return styled({tagName, baseStyles, elementStyle, mountSheets})
51-
}, {mountSheets, styles: baseStyles})
45+
return styled({tagName, baseStyles, elementStyle, mountSheet})
46+
}, {mountSheet, styles: baseStyles})
5247
}
5348

5449
export default createStyled

src/injectStyled.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import composeClasses from './utils/composeClasses'
44
import type {StyledType} from './types'
55

66
const injectStyled = (styled: StyledType) => (InnerComponent: ReactClass<any>) => {
7-
const {staticSheet, dynamicSheet} = styled.mountSheets()
7+
const sheet = styled.mountSheet()
88

9-
const classNames = Object.keys({...staticSheet.classes, ...dynamicSheet.classes})
9+
const classNames = Object.keys(sheet.classes)
1010

1111
const classes = [...classNames]
1212
.reduce((acc, name) => ({
1313
...acc,
14-
[name]: composeClasses([staticSheet.classes[name], dynamicSheet.classes[name]]),
14+
[name]: composeClasses([sheet.classes[name]]),
1515
}), {})
1616

1717
return (props: Object) => createElement(InnerComponent, {classes, ...props})

src/styled.js

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
import {Component, createElement} from 'react'
22
import {getDynamicStyles} from 'jss'
3+
import type {
4+
Rule,
5+
} from 'jss/lib/types'
36

47
import filterProps from './utils/filterProps'
58
import composeClasses from './utils/composeClasses'
69
import generateTagName from './utils/generateTagName'
710

811
import type {
9-
JssStaticSheet,
10-
JssDynamicSheet,
12+
JssSheet,
1113
ComponentStyleType,
1214
StyledElementPropsType
1315
} from './types'
1416

1517
type 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

src/types/index.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
export type JssStyles = Object
22
export type JssStyle = Object
3-
export type JssStaticSheet = Object
4-
export type JssDynamicSheet = JssStaticSheet
3+
export type JssSheet = Object
54

65
export type BaseStylesType = JssStyles
76
export type ComponentStyleType = JssStyle
87
export type StyledType = Function & {
9-
mountSheets: Function,
8+
mountSheet: Function,
109
styles: JssStyles
1110
}
1211
export type StyledElementAttrsType = {tagName: string, style: ComponentStyleType}

0 commit comments

Comments
 (0)