The library for web and native user interfaces.
Introduce a supported way to slice children
Introduces a counterpart to mapChildren. It excludes empty children just as mapChildren for compatibility. With might introduce something like sliceChildrenIncludingEmptyValues at some point.
Sebastian Markbage committed
Jul 2, 2013 at 18:26 UTC
d50148591b9a8bf7a49f873e1eaf5f8af364cb70
2 files changed
+178
src/utils/__tests__/sliceChildren-test.js
new
+119
@@ -0,0 +1,119 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @emails react-core
17
+ * @jsx React.DOM
18
+ */
19
+
20
+"use strict";
21
+
22
+describe('sliceChildren', function() {
23
+
24
+ var React;
25
+ var ReactTestUtils;
26
+
27
+ var sliceChildren;
28
+ var reactComponentExpect;
29
+
30
+ var Partial;
31
+
32
+ beforeEach(function() {
33
+ React = require('React');
34
+ ReactTestUtils = require('ReactTestUtils');
35
+
36
+ sliceChildren = require('sliceChildren');
37
+ reactComponentExpect = require('reactComponentExpect');
38
+
39
+ Partial = React.createClass({
40
+ render: function() {
41
+ return (
42
+ <div>
43
+ {sliceChildren(
44
+ this.props.children,
45
+ this.props.start,
46
+ this.props.end
47
+ )}
48
+ </div>
49
+ );
50
+ }
51
+ });
52
+ });
53
+
54
+ function renderAndSlice(set, start, end) {
55
+ var instance = <Partial start={start} end={end}>{set}</Partial>;
56
+ ReactTestUtils.renderIntoDocument(instance);
57
+ var rendered = reactComponentExpect(instance)
58
+ .expectRenderedChild()
59
+ .instance();
60
+ return rendered.props.children;
61
+ }
62
+
63
+ it('should render the whole set if start zero is supplied', function() {
64
+ var fullSet = [
65
+ <div key="A" />,
66
+ <div key="B" />,
67
+ <div key="C" />
68
+ ];
69
+ var children = renderAndSlice(fullSet, 0);
70
+ expect(children).toEqual({
71
+ '[A]': fullSet[0],
72
+ '[B]': fullSet[1],
73
+ '[C]': fullSet[2]
74
+ });
75
+ });
76
+
77
+ it('should render the remaining set if no end index is supplied', function() {
78
+ var fullSet = [
79
+ <div key="A" />,
80
+ <div key="B" />,
81
+ <div key="C" />
82
+ ];
83
+ var children = renderAndSlice(fullSet, 1);
84
+ expect(children).toEqual({
85
+ '[B]': fullSet[1],
86
+ '[C]': fullSet[2]
87
+ });
88
+ });
89
+
90
+ it('should exclude everything at or after the end index', function() {
91
+ var fullSet = [
92
+ <div key="A" />,
93
+ <div key="B" />,
94
+ <div key="C" />,
95
+ <div key="D" />
96
+ ];
97
+ var children = renderAndSlice(fullSet, 1, 2);
98
+ expect(children).toEqual({
99
+ '[B]': fullSet[1]
100
+ });
101
+ });
102
+
103
+ it('should allow static children to be sliced', function() {
104
+ var a = <div />;
105
+ var b = <div />;
106
+ var c = <div />;
107
+
108
+ var instance = <Partial start={1} end={2}>{a}{b}{c}</Partial>;
109
+ ReactTestUtils.renderIntoDocument(instance);
110
+ var rendered = reactComponentExpect(instance)
111
+ .expectRenderedChild()
112
+ .instance();
113
+
114
+ expect(rendered.props.children).toEqual({
115
+ '[1]': b
116
+ });
117
+ });
118
+
119
+});
src/utils/sliceChildren.js
new
+59
@@ -0,0 +1,59 @@
1
+/**
2
+ * Copyright 2013 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule sliceChildren
17
+ */
18
+
19
+"use strict";
20
+
21
+var flattenChildren = require('flattenChildren');
22
+
23
+/**
24
+ * Slice children that are typically specified as `props.children`. This version
25
+ * of slice children ignores empty child components.
26
+ *
27
+ * @param {*} children The children set to filter.
28
+ * @param {number} start The first zero-based index to include in the subset.
29
+ * @param {?number} end The non-inclusive last index of the subset.
30
+ * @return {object} mirrored array with mapped children
31
+ */
32
+function sliceChildren(children, start, end) {
33
+ if (children == null) {
34
+ return children;
35
+ }
36
+
37
+ var slicedChildren = {};
38
+ var flattenedMap = flattenChildren(children);
39
+ var ii = 0;
40
+ for (var key in flattenedMap) {
41
+ if (!flattenedMap.hasOwnProperty(key)) {
42
+ continue;
43
+ }
44
+ var child = flattenedMap[key];
45
+ // In this version of slice children we ignore empty children.
46
+ if (child !== null) {
47
+ if (ii >= start) {
48
+ slicedChildren[key] = child;
49
+ }
50
+ ii++;
51
+ if (end != null && ii >= end) {
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ return slicedChildren;
57
+}
58
+
59
+module.exports = sliceChildren;