-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.jsx
87 lines (72 loc) · 2.09 KB
/
index.jsx
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 React from 'react';
const getDisplayName = (Comp) => {
if (!Comp) return 'UndefinedComp';
return Comp.displayName
|| Comp.name
|| 'Unknown'
};
const render = (node, position) => {
const { withProps, show } = node;
const props = typeof withProps === 'function' ?
withProps(position) : (withProps || {});
const Comp = show;
return <Comp {...props} />;
}
const evalNode = (node, position) => {
if (Array.isArray(node.show)) {
return reduce(node.show, position)
} else {
return render(node, position);
}
};
const isActive = (node, position) => {
const { when } = node;
const isFunc = typeof when === 'function';
return isFunc ? when(position) : when;
}
const firstActive = (tree, position) => {
for (const node of tree) {
if (isActive(node, position)) {
return node;
}
}
return undefined;
}
const allActive = (tree, position) => {
return tree.filter(p => isActive(p, position));
}
const reduce = (tree, position) => {
const reducer = process.env.NODE_ENV === 'production' ? reduceProd : reduceDev;
return reducer(tree, position);
}
const reduceProd = (tree, position) => {
const active = firstActive(tree, position);
return active ? evalNode(active, position) : null;
}
const reduceDev = (tree, position) => {
const all = allActive(tree, position)
if (all.length === 0) {
console.warn('Could not find node for position: ', position);
} else if (all.length > 1) {
console.group();
console.warn("More than one 'when' function returned true. Defaulting to the first.");
all.forEach((node, i) => {
const Comp = node.show;
console.log(`${i} ${getDisplayName(Comp)}`);
});
console.groupEnd();
}
const active = all[0];
return active ? evalNode(active, position) : null;
}
const stateful = (instance, tree) => {
return () => reduce(tree, { props: instance.props, state: instance.state, self: instance })
}
const sfc = (tree, name) => {
const PhotonicSFC = (props) => reduce(tree, { props });
if (name) {
PhotonicSFC.displayName = name;
}
return PhotonicSFC;
}
export { reduce, sfc, stateful };