diff --git a/examples/basic/app.js b/examples/basic/app.js index b781df5c33..5dc41dd89a 100644 --- a/examples/basic/app.js +++ b/examples/basic/app.js @@ -83,6 +83,30 @@ const App = React.createClass({

Source: Wikipedia

+ + + + Tabs: + Tab A + Tab B + (separator) + Tab C + End of tabs + + + +

This is Tab A

+

You can put arbitrary elements inside {''}.

+
+ +

This is Tab B

+

Navigating through the tabs with the keyboard will skip these arbitrary elements.

+
+ +

This is Tab C

+

Just mind that the output might be invalid HTML ({'

'} inside a {'
    '} for instance).

    + +
); }, diff --git a/src/components/Tabs.js b/src/components/Tabs.js index a230f35db3..3f28f23891 100644 --- a/src/components/Tabs.js +++ b/src/components/Tabs.js @@ -142,9 +142,12 @@ module.exports = React.createClass({ }, getTabsCount() { - return this.props.children && this.props.children[0] ? - React.Children.count(this.props.children[0].props.children) : - 0; + if (this.props.children && this.props.children[0]) { + const tabs = this.props.children[0].props.children.filter(x => x.type === Tab); + return React.Children.count(tabs); + } + + return 0; }, getPanelsCount() { @@ -202,6 +205,12 @@ module.exports = React.createClass({ return null; } + // Exit early if this is not a tab. That way we can have arbitrary + // elements anywhere inside + if (tab.type !== Tab) { + return tab; + } + const ref = `tabs-${index}`; const id = tabIds[index]; const panelId = panelIds[index]; @@ -210,17 +219,13 @@ module.exports = React.createClass({ index++; - if (tab.type === Tab) { - return cloneElement(tab, { - ref, - id, - panelId, - selected, - focus, - }); - } - - return tab; + return cloneElement(tab, { + ref, + id, + panelId, + selected, + focus, + }); }), }); @@ -282,7 +287,7 @@ module.exports = React.createClass({ return; } - const index = [].slice.call(node.parentNode.children).indexOf(node); + const index = [].slice.call(node.parentNode.children).filter(isTabNode).indexOf(node); this.setSelected(index); return; } diff --git a/src/components/__tests__/Tabs-test.js b/src/components/__tests__/Tabs-test.js index 7094504d78..20ad66eccc 100644 --- a/src/components/__tests__/Tabs-test.js +++ b/src/components/__tests__/Tabs-test.js @@ -190,22 +190,30 @@ describe('react-tabs', () => { it('should not clone non tabs element', () => { class Demo extends React.Component { render() { - const plus =
+
; + const arbitrary1 =
One
; + const arbitrary2 = Two; + const arbitrary3 = Three; return ( + {arbitrary1} Foo - {plus} + {arbitrary2} + Bar + {arbitrary3} Hello Baz + Hello Faz ); } } const wrapper = mount(); - expect(wrapper.ref('yolo').text()).toBe('+'); + expect(wrapper.ref('arbitrary1').text()).toBe('One'); + expect(wrapper.ref('arbitrary2').text()).toBe('Two'); + expect(wrapper.ref('arbitrary3').text()).toBe('Three'); }); }); diff --git a/src/helpers/childrenPropType.js b/src/helpers/childrenPropType.js index f13e8a0282..007178aa91 100644 --- a/src/helpers/childrenPropType.js +++ b/src/helpers/childrenPropType.js @@ -1,6 +1,7 @@ import React from 'react'; import Tab from '../components/Tab'; import TabList from '../components/TabList'; +import TabPanel from '../components/TabPanel'; module.exports = function childrenPropTypes(props, propName) { let error; @@ -27,7 +28,7 @@ module.exports = function childrenPropTypes(props, propName) { tabsCount++; } }); - } else if (child.type.displayName === 'TabPanel') { + } else if (child.type === TabPanel) { panelsCount++; } else { error = new Error(