@samitouri / QOS-React-2 / commits / d50148591b
Fork 0

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;