diff --git a/examples/basic/app.js b/examples/basic/app.js index fe51d3e8da..b781df5c33 100644 --- a/examples/basic/app.js +++ b/examples/basic/app.js @@ -17,6 +17,8 @@ const App = React.createClass({ React Ember Angular + + + diff --git a/src/components/TabList.js b/src/components/TabList.js index f276ee3eb7..d0d8f43fd4 100644 --- a/src/components/TabList.js +++ b/src/components/TabList.js @@ -1,13 +1,23 @@ import React, { PropTypes } from 'react'; import cx from 'classnames'; +import Tab from './Tab'; function renderChildren(props) { - return React.Children.map(props.children, (child) => - React.cloneElement(child, { + return React.Children.map(props.children, (child) => { + // if child is not a tab we don't need to clone it + // since we don't need to add custom props + + if (child.type !== Tab) { + return child; + } + + const clonedProps = { activeTabClassName: props.activeTabClassName, disabledTabClassName: props.disabledTabClassName, - }) - ); + }; + + return React.cloneElement(child, clonedProps); + }); } module.exports = React.createClass({ diff --git a/src/components/Tabs.js b/src/components/Tabs.js index 7b3707aa0b..a230f35db3 100644 --- a/src/components/Tabs.js +++ b/src/components/Tabs.js @@ -4,6 +4,7 @@ import cx from 'classnames'; import jss from 'js-stylesheet'; import uuid from '../helpers/uuid'; import childrenPropType from '../helpers/childrenPropType'; +import Tab from './Tab'; // Determine if a node from event.target is a Tab element function isTabNode(node) { @@ -209,13 +210,17 @@ module.exports = React.createClass({ index++; - return cloneElement(tab, { - ref, - id, - panelId, - selected, - focus, - }); + if (tab.type === Tab) { + return cloneElement(tab, { + ref, + id, + panelId, + selected, + focus, + }); + } + + return tab; }), }); diff --git a/src/components/__tests__/Tabs-test.js b/src/components/__tests__/Tabs-test.js index 7fcb5724f5..7094504d78 100644 --- a/src/components/__tests__/Tabs-test.js +++ b/src/components/__tests__/Tabs-test.js @@ -1,3 +1,4 @@ +/* eslint-disable react/no-multi-comp */ /* global jest, describe, it, expect */ import React from 'react'; import { shallow, mount } from 'enzyme'; @@ -185,6 +186,27 @@ describe('react-tabs', () => { expect(wrapper.childAt(2).text()).toBe('Hello Bar'); expect(wrapper.childAt(3).text()).toBe('Hello Baz'); }); + + it('should not clone non tabs element', () => { + class Demo extends React.Component { + render() { + const plus =
+
; + + return ( + + Foo + {plus} + + + Hello Baz + ); + } + } + + const wrapper = mount(); + + expect(wrapper.ref('yolo').text()).toBe('+'); + }); }); describe('validation', () => { @@ -201,7 +223,25 @@ describe('react-tabs', () => { expect(result instanceof Error).toBe(true); }); - it('should result with a warning when wrong element is found', () => { + it(`should result with warning when tabs/panels are imbalanced and + it should ignore non tab children`, () => { + const wrapper = shallow( + + + Foo +
+
+
+ + Hello Foo + Hello Bar +
+ ); + + const result = Tabs.propTypes.children(wrapper.props(), 'children', 'Tabs'); + expect(result instanceof Error).toBe(true); + }); + + it('should not throw a warning when wrong element is found', () => { const wrapper = shallow( @@ -213,7 +253,7 @@ describe('react-tabs', () => { ); const result = Tabs.propTypes.children(wrapper.props(), 'children', 'Tabs'); - expect(result instanceof Error).toBe(true); + expect(result instanceof Error).toBe(false); }); it('should be okay with rendering without any children', () => { diff --git a/src/helpers/childrenPropType.js b/src/helpers/childrenPropType.js index 94be6e64fe..f13e8a0282 100644 --- a/src/helpers/childrenPropType.js +++ b/src/helpers/childrenPropType.js @@ -25,10 +25,6 @@ module.exports = function childrenPropTypes(props, propName) { if (c.type === Tab) { tabsCount++; - } else { - error = new Error( - `Expected 'Tab' but found '${c.type.displayName || c.type}'` - ); } }); } else if (child.type.displayName === 'TabPanel') {