-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.js
More file actions
109 lines (90 loc) · 2.58 KB
/
index.js
File metadata and controls
109 lines (90 loc) · 2.58 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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
const { keys, assign } = Object
const isPlainObject = require('is-plain-object')
const is = require('typeof-is')
const defaultPassThrough = [
'id',
'className',
'events',
'attributes',
'style',
'hooks',
'data'
]
module.exports = HyperFela
function HyperFela ({ h, renderRule }) {
assign(createStyledElement, {
createStyledElement,
connectStyles
})
return createStyledElement
function createStyledElement (type, rule, options) {
if (!isType(type)) {
options = rule
rule = type
type = 'div'
}
options = defined(options, {})
const {
passThrough: ctorPassThrough = []
} = options
if (is.object(rule)) {
const style = rule
rule = () => style
}
return StyledElement
function StyledElement (properties, children) {
if (!isPlainObject(properties)) {
children = properties
properties = {}
}
const {
passThrough: instPassThrough = []
} = properties
const passThrough = [
...defaultPassThrough,
...ctorPassThrough,
...instPassThrough
]
const elementProperties = passThrough
.reduce((sofar, key) => {
const value = properties[key]
if (!is.undefined(value)) sofar[key] = properties[key]
return sofar
}, {})
const tagName = defined(properties.is, type)
const element = is.string(tagName)
? h(tagName, elementProperties, children)
: type(elementProperties, children)
const className = renderRule(rule, properties)
// TODO should we handle if el is a string?
// we could use createTextNode
if (className) {
const classNames = className.split(' ')
classNames.forEach(c => element.classList.add(c))
}
return element
}
}
function connectStyles (mapStylesToProps, Element) {
return function StyledElement (properties, children) {
var styles = mapStylesToProps(properties)(renderRule)
keys(styles).forEach(key => {
if (is.function(styles[key])) {
// if style is rule, render rule with element properties
styles[key] = renderRule(styles[key], properties)
} else if (is.object(styles[key])) {
// if style is object, render rule to return object
styles[key] = renderRule(() => styles[key])
}
})
properties = assign({}, properties, { styles })
return Element(properties, children)
}
}
}
function isType (value) {
return is.string(value) || is.function(value)
}
function defined (a, b) {
return (!is.undefined(a)) ? a : b
}