-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathstyled.js
More file actions
87 lines (66 loc) · 2.25 KB
/
styled.js
File metadata and controls
87 lines (66 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import {Component, createElement} from 'react'
import {getDynamicStyles} from 'jss'
import filterProps from './utils/filterProps'
import composeClasses from './utils/composeClasses'
import generateTagName from './utils/generateTagName'
import type {
JssStaticSheet,
JssDynamicSheet,
ComponentStyleType,
StyledElementPropsType
} from './types'
type StyledArgs = {
tagName: string,
elementStyle: ComponentStyleType,
mountSheets: Function
}
const styled = ({tagName, elementStyle, mountSheets}: StyledArgs) => {
const dynamicStyle = getDynamicStyles(elementStyle)
const staticTagName = generateTagName(tagName)
const availableDynamicTagNames = []
return class StyledElement extends Component {
static tagName: string = tagName
static style: ComponentStyleType = elementStyle
props: StyledElementPropsType
dynamicTagName = ''
staticSheet: JssStaticSheet
dynamicSheet: JssDynamicSheet
constructor(props: StyledElementPropsType) {
super(props)
if (!this.dynamicTagName && dynamicStyle) {
this.dynamicTagName = availableDynamicTagNames.pop() || generateTagName(tagName)
}
}
componentWillMount() {
Object.assign(this, mountSheets())
if (!this.staticSheet.getRule(staticTagName)) {
this.staticSheet.addRule(staticTagName, elementStyle)
}
if (!dynamicStyle) return
if (!this.dynamicSheet.getRule(this.dynamicTagName)) {
this.dynamicSheet.addRule(this.dynamicTagName, dynamicStyle)
}
this.dynamicSheet.update(this.dynamicTagName, this.props)
}
componentWillReceiveProps(nextProps: StyledElementPropsType) {
if (dynamicStyle) {
this.dynamicSheet.update(this.dynamicTagName, nextProps)
}
}
componentWillUnmount() {
availableDynamicTagNames.push(this.dynamicTagName)
}
render() {
if (!this.staticSheet) return null
const {children, className, ...attrs} = this.props
const props = filterProps(attrs)
const tagClass = composeClasses([
this.staticSheet.classes[staticTagName],
this.dynamicSheet.classes[this.dynamicTagName],
className
])
return createElement(tagName, {...props, className: tagClass}, children)
}
}
}
export default styled