Skip to content

Commit

Permalink
Implement getSeparatedStyles to reduce creation of unnecessary static…
Browse files Browse the repository at this point in the history
… rules classes/rules
  • Loading branch information
lttb committed May 26, 2017
1 parent f08e3ab commit c223c46
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 40 deletions.
9 changes: 5 additions & 4 deletions src/styled.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
import filterProps from './utils/filterProps'
import composeClasses from './utils/composeClasses'
import generateTagName from './utils/generateTagName'
import getSeparatedStyles from './utils/getSeparatedStyles'

import type {
JssSheet,
Expand All @@ -21,8 +22,8 @@ type StyledArgs = {
}

const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
const dynamicStyle = getDynamicStyles(elementStyle)
const staticTagName = generateTagName(tagName)
const {dynamicStyle, staticStyle} = getSeparatedStyles(elementStyle)
const staticTagName = staticStyle && generateTagName(tagName)

const availableDynamicTagNames = []
const classMap = {}
Expand Down Expand Up @@ -51,8 +52,8 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {

const rulesTotal = this.rulesIndex.length

if (!this.sheet.getRule(staticTagName)) {
this.sheet.addRule(staticTagName, elementStyle)
if (staticStyle && !this.sheet.getRule(staticTagName)) {
this.sheet.addRule(staticTagName, staticStyle)
}

if (!dynamicStyle) return
Expand Down
36 changes: 18 additions & 18 deletions src/tests/__snapshots__/index.spec.jsx.snap
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
exports[`base rendering tests renders correctly App with default Styled 1`] = `
<div
className="div-9-0-9">
className="div-8-0-8">
<header
className="header-10-0-10">
className="header-9-0-9">
<h1
className="h1-13-0-11">
className="h1-12-0-10">
Title
</h1>
</header>
<section
className="section-11-0-12"
className="section-10-0-11"
data-name="content">
<button
className="button-14-0-13 button-15-0-14">
className="button-13-0-12">
primitive test
</button>
<button
className="button-14-0-13 button-16-0-15">
className="button-14-0-13">
dynamic primitive test
</button>
</section>
<section
className="section-12-0-16">
className="section-11-0-14">
Another section
</section>
</div>
Expand All @@ -41,47 +41,47 @@ exports[`base rendering tests renders correctly App with default styled 1`] = `
className="section-3-0-3"
data-name="content">
<button
className="button-6-0-4 button-7-0-5">
className="button-6-0-4">
primitive test
</button>
<button
className="button-6-0-4 button-8-0-6">
className="button-7-0-5">
dynamic primitive test
</button>
</section>
<section
className="section-4-0-7">
className="section-4-0-6">
Another section
</section>
</div>
`;

exports[`base rendering tests renders correctly App with injectStyled 1`] = `
<div
className="root-0-17">
className="root-0-15">
<div
className="div-17-0-19">
className="div-15-0-17">
<header
className="header-18-0-20">
className="header-16-0-18">
<h1
className="h1-21-0-21">
className="h1-19-0-19">
Title
</h1>
</header>
<section
className="section-19-0-22"
className="section-17-0-20"
data-name="content">
<button
className="button-22-0-23 button-23-0-24">
className="button-20-0-21">
primitive test
</button>
<button
className="button-22-0-23 button-24-0-25">
className="button-21-0-22">
dynamic primitive test
</button>
</section>
<section
className="section-20-0-26">
className="section-18-0-23">
Another section
</section>
</div>
Expand Down
24 changes: 6 additions & 18 deletions src/tests/functional.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,9 @@ describe('functional tests', () => {
margin: 0;
}
.button-7-6 {
margin: 0;
}
.button-8-7 {
margin: 10px;
}
.section-4-8 {
.section-4-7 {
color: yellow;
}
`)
Expand All @@ -91,12 +88,9 @@ describe('functional tests', () => {
margin: 0;
}
.button-7-6 {
margin: 0;
}
.button-8-7 {
margin: 20px;
}
.section-4-8 {
.section-4-7 {
color: yellow;
}
`)
Expand Down Expand Up @@ -145,13 +139,10 @@ describe('functional tests', () => {
.div-1-2 {
padding: 15px;
}
.div-1-2:hover .button-1 {
.div-3-3:hover .button-1 {
color: green;
}
.div-3-5:hover .button-1 {
color: green;
}
.div-4-9:hover .button-1 {
.div-4-7:hover .button-1 {
color: red;
}
`)
Expand All @@ -167,13 +158,10 @@ describe('functional tests', () => {
.div-1-2 {
padding: 15px;
}
.div-1-2:hover .button-1 {
color: red;
}
.div-3-5:hover .button-1 {
.div-3-3:hover .button-1 {
color: red;
}
.div-4-9:hover .button-1 {
.div-4-7:hover .button-1 {
color: green;
}
`)
Expand Down
84 changes: 84 additions & 0 deletions src/tests/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import getSeparatedStyles from '../utils/getSeparatedStyles'

describe('unit tests for utils', () => {
it('should extract separated styles', () => {
const color = data => data.color
const styles = {
button: {
float: 'left',
margin: [5, 10],
color,
'@media screen': {
width: null,
},
'@media print': {
width: undefined,
color
},
'& a': {
color: 'red',
'& b': {
color
}
},
},
'@media': {
button: {
width: 2,
color
}
},
nested: {
'& a': {
color: 'red'
}
}
}

expect(getSeparatedStyles(styles)).toEqual({
dynamicStyle: {
button: {
color,
'@media print': {
color
},
'& a': {
'& b': {
color
}
}
},
'@media': {
button: {
color
}
}
},
staticStyle: {
button: {
float: 'left',
margin: [5, 10],
'@media screen': {
width: null,
},
'@media print': {
width: undefined,
},
'& a': {
color: 'red',
}
},
'@media': {
button: {
width: 2,
}
},
nested: {
'& a': {
color: 'red'
}
}
}
})
})
})
File renamed without changes.
27 changes: 27 additions & 0 deletions src/utils/getSeparatedStyles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const isObject = value =>
typeof value === 'object' && value !== null && !Array.isArray(value)

/**
* Extracts static and dynamic styles objects separately
*/
const getSeparatedStyles = (styles: Object) => {
const result = {}

for (const key in styles) {
const value = styles[key]
const itemStyles = {}

if (typeof value === 'function') itemStyles.dynamicStyle = value
else if (isObject(value)) Object.assign(itemStyles, getSeparatedStyles(value))
else itemStyles.staticStyle = value

for (const styleType in itemStyles) {
result[styleType] = result[styleType] || {}
result[styleType][key] = itemStyles[styleType]
}
}

return result
}

export default getSeparatedStyles

0 comments on commit c223c46

Please sign in to comment.