Skip to content

Commit ff2bc9a

Browse files
committed
Add support for iterable children.
React 0.13 added support for iterable children, making it possible to use Immutable.js for supplying your react chidlren to a container. This code commit supports that change.
1 parent d15d37d commit ff2bc9a

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

src/isIterable.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { isObject } from 'lodash';
2+
3+
const ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
4+
const OLD_ITERATOR_SYMBOL = '@@iterator';
5+
6+
export default function isIterable(obj) {
7+
return isObject(obj) &&
8+
typeof ((ITERATOR_SYMBOL && obj[ITERATOR_SYMBOL])
9+
|| obj[OLD_ITERATOR_SYMBOL]) === 'function';
10+
}

src/linkClass.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import makeConfiguration from './makeConfiguration';
3+
import isIterable from './isIterable';
34
import _ from 'lodash';
45

56
let linkClass;
@@ -12,6 +13,7 @@ let linkClass;
1213
*/
1314
linkClass = (element, styles = {}, userConfiguration) => {
1415
let appendClassName,
16+
children,
1517
clonedElement,
1618
configuration,
1719
newChildren,
@@ -62,10 +64,12 @@ linkClass = (element, styles = {}, userConfiguration) => {
6264

6365
// console.log(`element.props.children`, element.props.children, `React.Children.count(element.props.children)`, React.Children.count(element.props.children));
6466

65-
if (React.isValidElement(element.props.children)) {
66-
newChildren = linkClass(React.Children.only(element.props.children), styles, configuration);
67-
} else if (_.isArray(element.props.children)) {
68-
newChildren = React.Children.map(element.props.children, (node) => {
67+
children = element.props.children;
68+
69+
if (React.isValidElement(children)) {
70+
newChildren = linkClass(React.Children.only(children), styles, configuration);
71+
} else if (_.isArray(children) || isIterable(children)) {
72+
newChildren = React.Children.map(children, (node) => {
6973
if (React.isValidElement(node)) {
7074
return linkClass(node, styles, configuration);
7175
} else {

tests/linkClass.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,28 @@ describe('linkClass', () => {
108108
expect(subject.props.children[1].props.className).to.equal('bar-1');
109109
});
110110
});
111+
context('when multiple descendants have styleName and are iterable', () => {
112+
it('assigns a generated className', () => {
113+
let subject, iterable;
114+
115+
iterable = {
116+
0: <p key="1" styleName='foo'></p>,
117+
1: <p key="2" styleName='bar'></p>,
118+
length: 2,
119+
[Symbol.iterator]: Array.prototype[Symbol.iterator]
120+
};
121+
122+
subject = <div>{iterable}</div>;
123+
124+
subject = linkClass(subject, {
125+
foo: 'foo-1',
126+
bar: 'bar-1'
127+
});
128+
129+
expect(subject.props.children[0].props.className).to.equal('foo-1');
130+
expect(subject.props.children[1].props.className).to.equal('bar-1');
131+
});
132+
});
111133
context('when ReactElement does not have an existing className', () => {
112134
it('uses the generated class name to set the className property', () => {
113135
let subject;

0 commit comments

Comments
 (0)