This repository has been archived by the owner on Sep 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy path02 - Layout Components.js
72 lines (66 loc) · 2.31 KB
/
02 - Layout Components.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
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
// Layout System Example Components
// The Vertical List can layout items in vertically based on their dynamic
// height. It also provides its own total height so that it can be used as
// an item within itself.
class VerticalList {
getChildContext() {
return {
layoutWidth: this.props.width || this.context.layoutWidth
};
}
// NEW FEATURE: Pre-render a subtree before continuing with the normal render.
preRender() {
// Children that needs to be prerendered. If some children needs to be
// prerendered, but not others (e.g. for flexbox layouts), then they're
// filtered, here and the rest is rendered inside render.
return this.props.children;
}
render() {
var children = this.prerendered;
var positionedChildren = [];
var y = 0;
for (var i = 0; i < children.length; i++) {
// This child is an opaque black box whose props cannot be inspected,
// nor cloned. It can only be rendered once. Rendering it twice results
// in a conflict, at least until we support painting the same stateful
// component in many different places (e.g. SVG's <use />)
var child = children[i];
positionedChildren.push(
<Positioner key={child.key} x={0} y={y}>{child}</Positioner>
);
// We can use it to inspect the child's reverse context though.
y += child.result.layoutHeight;
}
return <Fragment>{positionedChildren}</Fragment>;
}
// NEW FEATURE: When a component itself is is prerendered, it can bubble a
// result back up the tree.
getResult() {
// We already had this height calculated in render, but to allow for render
// to be deferred, and to preserve the standard render() API, we have to
// recalculate it here. This is helpful in the cases where a parent decides
// not to render this child. That way we can avoid calling render.
var totalHeight = 0;
var children = this.prerendered;
for (var i = 0; i < children.length; i++) {
totalHeight += children[i].result.layoutHeight;
}
return {
layoutHeight: totalHeight
};
}
}
class VerticalListItem {
render() {
return (
<Box width={this.context.layoutWidth} height={this.props.height}>
{this.props.children}
</Box>
);
}
getResult() {
return {
layoutHeight: this.props.height
};
}
}