-
Notifications
You must be signed in to change notification settings - Fork 100
/
compose.js
38 lines (30 loc) · 1.17 KB
/
compose.js
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
import * as React from 'react'
import renderProps from './renderProps'
const isElement = element => typeof element.type === 'function'
const compose = (...elements) => {
const reversedElements = elements.reverse()
return composedProps => {
// Stack children arguments recursively and pass
// it down until the last component that render children
// with these stacked arguments
function stackProps(i, elements, propsList = []) {
const element = elements[i]
const isTheLast = i === 0
// Check if is latest component.
// If is latest then render children,
// Otherwise continue stacking arguments
const renderFn = props =>
isTheLast
? renderProps(composedProps, ...propsList.concat(props))
: stackProps(i - 1, elements, propsList.concat(props))
// Clone a element if it's passed created as <Element initial={} />
// Or create it if passed as just Element
const elementFn = isElement(element)
? React.cloneElement
: React.createElement
return elementFn(element, {}, renderFn)
}
return stackProps(elements.length - 1, reversedElements)
}
}
export default compose