- Tab 1
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
-
- Tab 2
+
+ Numquam libero id corporis odit animi voluptat, Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quia tempore eligendi tempora repellat officia rerum laudantium, veritatis officiis asperiores ipsum nam, distinctio, dolor provident culpa voluptatibus esse deserunt animi?
-
- Tab 3
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
- `;
-
- const tabsGroupWithAnchorCode = `
-
-
-
- Tab 1
-
-
-
-
- Tab 2
-
-
-
-
- Tab 2
-
+
+ Please review your shopping chart.
`;
- const tabsGroupWithLinkCode = `
-
-
-
-
- Tab 1
-
-
-
-
- Tab 2
-
-
-
-
- Tab 2
-
-
-
- `;
-
return (
@@ -98,115 +29,36 @@ export const TabsComponent = () => {
metaphor and is used to separate content into different sections.
They should be ordered to create a visual hierarchy based on priority.
-
+
+
-
+
+
-
Tab Group with URL
+
Tab Group
-
-
- Tab 1
-
-
- Tab 2
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
-
- Tab 3
-
-
-
-
{tabGroupCode}
-
-
-
-
Tab Group with Anchor
-
-
-
-
-
- Tab 1
-
+
+ Numquam libero id corporis odit animi voluptat, Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quia tempore eligendi tempora repellat officia rerum laudantium, veritatis officiis asperiores ipsum nam, distinctio, dolor provident culpa voluptatibus esse deserunt animi?
-
-
- Tab 2
-
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
-
-
- Tab 2
-
+
+ Please review your shopping chart.
-
{tabsGroupWithAnchorCode}
-
-
-
-
Tab Group with Link
-
-
-
-
-
-
- Tab 1
-
-
-
-
- Tab 2
-
-
-
-
- Tab 2
-
-
-
-
-
-
{tabsGroupWithLinkCode}
+
{tabGroupCode}
);
};
diff --git a/src/Tabs/Tabs.js b/src/Tabs/Tabs.js
deleted file mode 100644
index 382fd3a72..000000000
--- a/src/Tabs/Tabs.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import classnames from 'classnames';
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-
-export const Tab = props => {
- const { children, className, content, disabled, id, onClick, selected, tabContentProps, tabLinkProps, url, ...rest } = props;
-
- const linkClasses = classnames(
- className,
- 'fd-tabs__link',
- {
- 'is-selected': selected
- }
- );
-
- const renderLink = () => {
- if (url) {
- return (
- {
- if (!disabled) {
- onClick(e);
- }
- }}>
- {children}
-
- );
- } else if (children && React.isValidElement(children)) {
- return React.cloneElement(children, {
- ...tabLinkProps,
- 'aria-disabled': disabled,
- className: linkClasses,
- disabled: disabled,
- onClick: (e) => {
- if (!disabled) {
- onClick(e);
- }
- }
- });
- } else if (children) {
- return children;
- }
- };
-
- const tabClasses = classnames('fd-tabs__item', className);
-
- return (
-
- {renderLink()}
- {selected ? (
- {content}
- ) : null}
-
- );
-};
-Tab.displayName = 'Tab';
-
-Tab.propTypes = {
- children: PropTypes.node,
- className: PropTypes.string,
- content: PropTypes.node,
- disabled: PropTypes.bool,
- id: PropTypes.string,
- selected: PropTypes.bool,
- tabContentProps: PropTypes.object,
- tabLinkProps: PropTypes.object,
- url: PropTypes.string,
- onClick: PropTypes.func
-};
-
-Tab.defaultProps = {
- onClick: () => { }
-};
-
-Tab.propDescriptions = {
- children: 'Can be link text, an achor tag, or a react component like React Routers\'s `Link`.',
- content: 'Content to render when tab is selected.',
- selected: 'Set to **true** to mark tab as selected.',
- url: 'Creates an internal anchor when a child anchor is not provided.',
- tabContentProps: 'Additional props to be spread to the tab content\'s ` element.',
- tabLinkProps: 'Additional props to be spread to the tab\'s link element.'
-};
-
-export class TabGroup extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- selectedId: this.props.selectedId
- };
- }
-
- handleTabSelection = (e, id) => {
- this.setState({ selectedId: id });
- };
-
- renderTabs = (children) => {
- return React.Children.map(children, (child) => {
-
- return React.cloneElement(child, {
- selected: this.state.selectedId === child.props.id,
- onClick: (e) => {
- child.props.onClick && child.props.onClick(e);
- this.handleTabSelection(e, child.props.id);
- }
- });
- });
- }
-
- render() {
- const { children, className, selectedId, ...rest } = this.props;
-
- const tabClasses = classnames(
- 'fd-tabs',
- className
- );
-
- return (
-
- {this.renderTabs(children)}
-
- );
- }
-}
-TabGroup.displayName = 'TabGroup';
-
-TabGroup.propTypes = {
- children: PropTypes.node,
- className: PropTypes.string,
- selectedId: PropTypes.string
-};
-
-TabGroup.propDescriptions = {
- children: 'One or more `Tab` components to render within the component.',
- selectedId: 'The `id` of the selected `Tab`.'
-};
diff --git a/src/Tabs/Tabs.test.js b/src/Tabs/Tabs.test.js
deleted file mode 100644
index ddb0d808a..000000000
--- a/src/Tabs/Tabs.test.js
+++ /dev/null
@@ -1,177 +0,0 @@
-import { mount } from 'enzyme';
-import React from 'react';
-import renderer from 'react-test-renderer';
-import { Link, MemoryRouter } from 'react-router-dom';
-import { Tab, TabGroup } from './Tabs';
-
-
-describe(' ', () => {
- const tabsExample = (
- [
-
- Tab 1
- ,
-
- Tab 2
- ,
-
-
- Tab 3
-
-
- ]
- );
-
- const tabsExampleWithLink = (
- [
-
-
- Tab 1
-
- ,
-
-
- Tab 2
-
- ,
-
-
- Tab 3
-
-
- ]
- );
-
- const defaultTabs = (
-
- {tabsExample}
-
- );
- const defaultTabsWithClass = (
-
- {tabsExample}
-
- );
-
- const routerTabs = (
-
-
- {tabsExampleWithLink}
-
-
- );
- const routerTabsWithClass = (
-
-
- {tabsExampleWithLink}
-
-
- );
-
- test('create tabs component', () => {
- let component = renderer.create(defaultTabs);
- let tree = component.toJSON();
- expect(tree).toMatchSnapshot();
-
- component = renderer.create(defaultTabsWithClass);
- tree = component.toJSON();
- expect(tree).toMatchSnapshot();
-
- component = renderer.create(routerTabs);
- tree = component.toJSON();
- expect(tree).toMatchSnapshot();
-
- component = renderer.create(routerTabsWithClass);
- tree = component.toJSON();
- expect(tree).toMatchSnapshot();
- });
-
- test('tab selection', () => {
- const wrapper = mount(defaultTabsWithClass);
-
- // check selected tab
- expect(wrapper.state(['selectedId'])).toEqual('1');
-
- wrapper
- .find('ul.fd-tabs li.fd-tabs__item a.fd-tabs__link')
- .at(1)
- .simulate('click');
-
- // check selected tab changed
- expect(wrapper.state(['selectedId'])).toEqual('2');
- });
-
- describe('Prop spreading', () => {
- test('should allow props to be spread to the Tabs component', () => {
- const element = mount( );
-
- expect(
- element.getDOMNode().attributes['data-sample'].value
- ).toBe('Sample');
- });
-
- test('should allow props to be spread to the TabGroup component', () => {
- const element = mount( );
-
- expect(
- element.getDOMNode().attributes['data-sample'].value
- ).toBe('Sample');
- });
-
- test('should allow props to be spread to the Tab component\'s li elements', () => {
- const element = mount( );
-
- expect(
- element.find('li').at(0).getDOMNode().attributes['data-sample'].value
- ).toBe('Sample');
- });
-
- test('should allow props to be spread to the Tab component\'s content component', () => {
- const element = mount(
-
-
- );
-
- expect(
- element.find('li p').at(0).getDOMNode().attributes['data-sample'].value
- ).toBe('Sample');
- });
-
- test('should allow props to be spread to the TabGroup component\'s Link component', () => {
- const element = mount( );
-
- expect(
- element.find('li a').at(0).getDOMNode().attributes['data-sample'].value
- ).toBe('Sample');
- });
- });
-});
diff --git a/src/Tabs/_TabContent.js b/src/Tabs/_TabContent.js
new file mode 100644
index 000000000..946976139
--- /dev/null
+++ b/src/Tabs/_TabContent.js
@@ -0,0 +1,34 @@
+import classnames from 'classnames';
+import PropTypes from 'prop-types';
+import React from 'react';
+
+export const TabContent = (props) => {
+ const { children, selected, className, ...rest } = props;
+
+ // css classes for tab panels
+ const tabPanelClasses = classnames(
+ 'fd-tabs__panel',
+ className
+ );
+
+ return (
+
+ {children}
+
+ );
+};
+TabContent.displayName = 'TabContent';
+
+TabContent.propTypes = {
+ children: PropTypes.node,
+ className: PropTypes.string,
+ selected: PropTypes.bool
+};
+
+TabContent.propDescriptions = {
+ children: 'Content to render when tab is selected.'
+};
diff --git a/src/Tabs/_TabContent.test.js b/src/Tabs/_TabContent.test.js
new file mode 100644
index 000000000..761d73200
--- /dev/null
+++ b/src/Tabs/_TabContent.test.js
@@ -0,0 +1,57 @@
+import { mount } from 'enzyme';
+import React from 'react';
+import renderer from 'react-test-renderer';
+import { Tab } from './Tab';
+import { TabContent } from './_TabContent';
+import { TabGroup } from './TabGroup';
+
+describe(' ', () => {
+ const shownTabContent = (
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolore et ducimus veritatis officiis amet ? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat ? Debitis, delectus sequi ?
+ );
+
+ const hiddenTabContent = (
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolore et ducimus veritatis officiis amet ? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat ? Debitis, delectus sequi ?
+ );
+
+ test('create TabContent component', () => {
+ let component = renderer.create(shownTabContent);
+ let tree = component.toJSON();
+ expect(tree).toMatchSnapshot();
+
+ component = renderer.create(hiddenTabContent);
+ tree = component.toJSON();
+ expect(tree).toMatchSnapshot();
+ });
+
+ test('check if tab content is shown', () => {
+ const wrapper = mount(shownTabContent);
+ wrapper.setProps({ 'selected': true });
+
+ const isExpanded = wrapper.getDOMNode().getAttribute('aria-expanded');
+ expect(isExpanded).toEqual('true');
+ });
+
+ test('check if tab content is hidden', () => {
+ const wrapper = mount(hiddenTabContent);
+ wrapper.setProps({ 'selected': false });
+
+ const isExpanded = wrapper.getDOMNode().getAttribute('aria-expanded');
+ expect(isExpanded).toEqual('false');
+ });
+
+ describe('Prop spreading', () => {
+ test('should allow props to be spread to the Tab component\'s content component', () => {
+ const element = mount(
+
+
+ );
+
+ expect(
+ element.find('div.fd-tabs__panel').at(0).getDOMNode().attributes['data-sample'].value
+ ).toBe('Sample');
+ });
+ });
+});
diff --git a/src/Tabs/__snapshots__/Tab.test.js.snap b/src/Tabs/__snapshots__/Tab.test.js.snap
new file mode 100644
index 000000000..830425054
--- /dev/null
+++ b/src/Tabs/__snapshots__/Tab.test.js.snap
@@ -0,0 +1,48 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` create tabs component 1`] = `
+
+
+ Tab 1
+
+
+`;
+
+exports[` create tabs component 2`] = `
+
+
+ Tab 3
+
+
+`;
+
+exports[` create tabs component 3`] = `
+
+
+
+`;
diff --git a/src/Tabs/__snapshots__/TabGroup.test.js.snap b/src/Tabs/__snapshots__/TabGroup.test.js.snap
new file mode 100644
index 000000000..cb0f9a2d5
--- /dev/null
+++ b/src/Tabs/__snapshots__/TabGroup.test.js.snap
@@ -0,0 +1,187 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` create tabs component 1`] = `
+Array [
+ ,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore et ducimus veritatis officiis amet? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat? Debitis, delectus sequi?
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam libero id corporis odit animi voluptat, Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quia tempore eligendi tempora repellat officia rerum laudantium, veritatis officiis asperiores ipsum nam, distinctio, dolor provident culpa voluptatibus esse deserunt animi?
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. A quibusdam ipsa cumque soluta debitis accusantium iste alias quas vel perferendis voluptatibus quod asperiores praesentium quaerat, iusto repellendus nulla, maiores eius.
+
,
+]
+`;
+
+exports[` create tabs component 2`] = `
+Array [
+ ,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolore et ducimus veritatis officiis amet? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat? Debitis, delectus sequi?
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Numquam libero id corporis odit animi voluptat, Lorem ipsum dolor sit amet consectetur adipisicing elit. Possimus quia tempore eligendi tempora repellat officia rerum laudantium, veritatis officiis asperiores ipsum nam, distinctio, dolor provident culpa voluptatibus esse deserunt animi?
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+
,
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. A quibusdam ipsa cumque soluta debitis accusantium iste alias quas vel perferendis voluptatibus quod asperiores praesentium quaerat, iusto repellendus nulla, maiores eius.
+
,
+]
+`;
diff --git a/src/Tabs/__snapshots__/Tabs.test.js.snap b/src/Tabs/__snapshots__/Tabs.test.js.snap
deleted file mode 100644
index 0cc71a6f1..000000000
--- a/src/Tabs/__snapshots__/Tabs.test.js.snap
+++ /dev/null
@@ -1,189 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[` create tabs component 1`] = `
-
-`;
-
-exports[` create tabs component 2`] = `
-
-`;
-
-exports[` create tabs component 3`] = `
-
-`;
-
-exports[` create tabs component 4`] = `
-
-`;
diff --git a/src/Tabs/__snapshots__/_TabContent.test.js.snap b/src/Tabs/__snapshots__/_TabContent.test.js.snap
new file mode 100644
index 000000000..160191239
--- /dev/null
+++ b/src/Tabs/__snapshots__/_TabContent.test.js.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[` create TabContent component 1`] = `
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolore et ducimus veritatis officiis amet ? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat ? Debitis, delectus sequi ?
+
+`;
+
+exports[` create TabContent component 2`] = `
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolore et ducimus veritatis officiis amet ? Vitae officia optio dolor exercitationem incidunt magnam non, suscipit, illo quisquam numquam fugiat ? Debitis, delectus sequi ?
+
+`;
diff --git a/src/index.js b/src/index.js
index 9b48f3150..4ae933fa7 100644
--- a/src/index.js
+++ b/src/index.js
@@ -52,8 +52,9 @@ export { ProductTileContent } from './Tile/Tile';
export { ProductTileMedia } from './Tile/Tile';
export { SearchInput } from './SearchInput/SearchInput';
export { SideNav, SideNavList, SideNavListItem } from './SideNavigation/SideNavigation';
+export { Tab } from './Tabs/Tab';
+export { TabGroup } from './Tabs/TabGroup';
export { Table } from './Table/Table';
-export { Tab, TabGroup } from './Tabs/Tabs';
export { Token } from './Token/Token';
export { Tile } from './Tile/Tile';
export { TileContent } from './Tile/Tile';