├── .gitignore ├── example ├── screenshot.gif ├── index.html ├── webpack.config.js └── index.js ├── src ├── index.js ├── __tests__ │ ├── __snapshots__ │ │ └── tab.spec.js.snap │ └── tab.spec.js ├── tab.js └── tabs.js ├── .babelrc ├── lib ├── index.js ├── __tests__ │ └── tab.spec.js ├── Tab.js └── Tabs.js ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .node-version 4 | -------------------------------------------------------------------------------- /example/screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-z/react-tab-view/HEAD/example/screenshot.gif -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Tabs from './Tabs' 2 | import Tab from './Tab' 3 | 4 | export { Tabs, Tab } 5 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env" 5 | ], 6 | "@babel/preset-react" 7 | ], 8 | "plugins": [ 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example 5 | 6 | 7 |
8 | 9 | 10 | -------------------------------------------------------------------------------- /src/__tests__/__snapshots__/tab.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Tab renders correctly and matches snapshot 1`] = ` 4 |
7 | 8 | Test tab content 9 | 10 |
11 | `; 12 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | Object.defineProperty(exports, "Tabs", { 7 | enumerable: true, 8 | get: function get() { 9 | return _Tabs.default; 10 | } 11 | }); 12 | Object.defineProperty(exports, "Tab", { 13 | enumerable: true, 14 | get: function get() { 15 | return _Tab.default; 16 | } 17 | }); 18 | 19 | var _Tabs = _interopRequireDefault(require("./Tabs")); 20 | 21 | var _Tab = _interopRequireDefault(require("./Tab")); 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -------------------------------------------------------------------------------- /example/webpack.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin') 2 | 3 | module.exports = { 4 | entry: ['./example/index.js'], 5 | devtool: 'inline-source-map', 6 | output: { filename: 'bundle.js', publicPath: '' }, 7 | module: { 8 | rules: [ 9 | { 10 | test: /\.js$/, 11 | use: [ { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/react'] } } ], 12 | exclude: /node_modules/, 13 | } 14 | ] 15 | }, 16 | plugins: [ 17 | new HtmlWebpackPlugin({ title: 'react infinite loader example', template: './example/index.html' }) 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /src/tab.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import styled from 'styled-components' 4 | 5 | /** 6 | * Tab module 7 | * A simple tab component. 8 | **/ 9 | class Tab extends Component { 10 | static get propTypes() { 11 | return { 12 | children: PropTypes.node.isRequired 13 | } 14 | } 15 | 16 | render() { 17 | return ( 18 | 19 | {this.props.children} 20 | 21 | ) 22 | } 23 | } 24 | 25 | export default Tab 26 | 27 | const TabWrapper = styled.div` 28 | background: rgb(250, 250, 250); 29 | margin: 1em auto; 30 | border: 1px solid #ddd; 31 | padding: 1em; 32 | 33 | .hidden { 34 | display: none; 35 | } 36 | ` 37 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import { Tabs, Tab } from '../lib/index' // 'react-tab-view' 2 | import ReactDOM from 'react-dom' 3 | import React, { Component } from 'react' 4 | 5 | class TestComponent extends Component { 6 | handleChange(e) { 7 | this.setState({ value: e }) 8 | console.log(e) 9 | } 10 | 11 | render() { 12 | const headers = ['Heading 1', 'Heading 2', 'Heading 3'] 13 | 14 | return ( 15 |
16 | 17 | 18 |
19 |

This is the first tab

20 |

with some content

21 |
22 |
23 |

and some more content

24 |
25 |
26 | 27 |

This is the second tab

28 |
29 | 30 |

This is the third tab

31 |
32 |
33 |
34 | ) 35 | } 36 | } 37 | 38 | ReactDOM.render(, document.getElementById('root')) 39 | -------------------------------------------------------------------------------- /src/__tests__/tab.spec.js: -------------------------------------------------------------------------------- 1 | /* setup enzyme */ 2 | import { configure } from 'enzyme' 3 | import Adapter from 'enzyme-adapter-react-16' 4 | configure({ adapter: new Adapter() }) 5 | 6 | /* setup jsdom */ 7 | var jsdom = require('jsdom') 8 | const { JSDOM } = jsdom 9 | const window = new JSDOM('').window 10 | global.window = window 11 | global.document = window.document 12 | 13 | import React from 'react' 14 | import renderer from 'react-test-renderer' 15 | import { shallow } from 'enzyme' 16 | import Tab from '../tab' 17 | 18 | test('Tab renders correctly and matches snapshot', () => { 19 | const component = renderer.create( 20 | Test tab content 21 | ) 22 | 23 | let tree = component.toJSON() 24 | expect(tree).toMatchSnapshot() 25 | }) 26 | 27 | test('YearMonthPicker renders the correct elements and props', () => { 28 | const wrapper = shallow( 29 | Test tab content 30 | ) 31 | 32 | expect(wrapper.find('span').length).toEqual(1) 33 | expect( 34 | wrapper 35 | .find('span') 36 | .text() 37 | ).toContain('Test tab content') 38 | 39 | // console.log(wrapper.debug()) 40 | }) 41 | -------------------------------------------------------------------------------- /lib/__tests__/tab.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var _enzyme = require("enzyme"); 4 | 5 | var _enzymeAdapterReact = _interopRequireDefault(require("enzyme-adapter-react-16")); 6 | 7 | var _react = _interopRequireDefault(require("react")); 8 | 9 | var _reactTestRenderer = _interopRequireDefault(require("react-test-renderer")); 10 | 11 | var _tab = _interopRequireDefault(require("../tab")); 12 | 13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 14 | 15 | /* setup enzyme */ 16 | (0, _enzyme.configure)({ 17 | adapter: new _enzymeAdapterReact.default() 18 | }); 19 | /* setup jsdom */ 20 | 21 | var jsdom = require('jsdom'); 22 | 23 | var JSDOM = jsdom.JSDOM; 24 | var window = new JSDOM('').window; 25 | global.window = window; 26 | global.document = window.document; 27 | test('Tab renders correctly and matches snapshot', function () { 28 | var component = _reactTestRenderer.default.create(_react.default.createElement(_tab.default, null, _react.default.createElement("span", null, "Test tab content"))); 29 | 30 | var tree = component.toJSON(); 31 | expect(tree).toMatchSnapshot(); 32 | }); 33 | test('YearMonthPicker renders the correct elements and props', function () { 34 | var wrapper = (0, _enzyme.shallow)(_react.default.createElement(_tab.default, null, _react.default.createElement("span", null, "Test tab content"))); 35 | expect(wrapper.find('span').length).toEqual(1); 36 | expect(wrapper.find('span').text()).toContain('Test tab content'); // console.log(wrapper.debug()) 37 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-tab-view", 3 | "version": "1.1.1", 4 | "description": "a simple tab component", 5 | "main": "lib/index.js", 6 | "author": "Steven Iseki ", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/StevenIseki/react-tab-view.git" 10 | }, 11 | "license": "MIT", 12 | "peerDependencies": { 13 | "react": "^16.0.0" 14 | }, 15 | "dependencies": { 16 | "prop-types": "^15.6.0", 17 | "styled-components": "^4.1.3" 18 | }, 19 | "devDependencies": { 20 | "@babel/cli": "^7.2.3", 21 | "@babel/core": "7.3.3", 22 | "@babel/preset-env": "7.3.1", 23 | "@babel/preset-react": "7.0.0", 24 | "babel-jest": "^24.7.1", 25 | "babel-loader": "8.0.5", 26 | "enzyme": "3.9.0", 27 | "enzyme-adapter-react-16": "^1.9.1", 28 | "html-webpack-plugin": "3.2.0", 29 | "jest": "^24.7.1", 30 | "jsdom": "13.2.0", 31 | "react": "^16.0.0", 32 | "react-dom": "^16.0.0", 33 | "webpack": "4.29.4", 34 | "webpack-cli": "3.2.3", 35 | "webpack-dev-server": "3.1.14" 36 | }, 37 | "scripts": { 38 | "build": "babel src --out-dir lib", 39 | "dev": "webpack-dev-server --mode=development --port 3000 --inline --hot --config example/webpack.config", 40 | "test": "jest" 41 | }, 42 | "keywords": [ 43 | "react", 44 | "react-component", 45 | "tabs", 46 | "tab view", 47 | "tab component", 48 | "react tab component", 49 | "react tabs", 50 | "react-tabs", 51 | "react tab", 52 | "tab", 53 | "tab control" 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-tab-view 2 | 3 | [![npm version](https://badge.fury.io/js/react-tab-view.svg)](https://badge.fury.io/js/react-tab-view) 4 | 5 | ![](https://raw.githubusercontent.com/StevenIseki/react-tab-view/master/example/screenshot.gif) 6 | 7 | react-tab-view is a simple tabs component using react.js. 8 | 9 | ## Install 10 | 11 | `yarn add react-tab-view` 12 | 13 | ## Usage 14 | 15 | ```jsx 16 | import { Tabs, Tab } from 'react-tab-view' 17 | import ReactDOM from 'react-dom' 18 | import React, { Component } from 'react' 19 | 20 | class TestComponent extends Component { 21 | handleChange(e) { 22 | this.setState({ value: e }) 23 | console.log(e) 24 | } 25 | 26 | render() { 27 | const headers = ['Heading 1', 'Heading 2', 'Heading 3'] 28 | 29 | return ( 30 |
31 | 32 | 33 |
34 |

This is the first tab

35 |

with some content

36 |
37 |
38 | 39 |

This is the second tab

40 |
41 | 42 |

This is the third tab

43 |
44 |
45 |
46 | ) 47 | } 48 | } 49 | 50 | ReactDOM.render(, document.getElementById('root')) 51 | 52 | ``` 53 | 54 | ## Styles 55 | Uses styled-components 💅 for the base styling. 56 | 57 | ## Development 58 | yarn 59 | yarn dev 60 | 61 | ## Test 62 | yarn test 63 | 64 | ## Build 65 | yarn 66 | yarn build 67 | 68 | ## Publish 69 | npm login 70 | npm version patch 71 | git add -A 72 | git push origin master 73 | npm publish 74 | 75 | ## License 76 | 77 | [MIT](http://isekivacenz.mit-license.org/) 78 | -------------------------------------------------------------------------------- /src/tabs.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import PropTypes from 'prop-types' 3 | import styled from 'styled-components' 4 | 5 | /** 6 | * Tabs module 7 | * A simple tab component. 8 | **/ 9 | class Tabs extends Component { 10 | static get propTypes() { 11 | return { 12 | onChangeTab: PropTypes.func, 13 | children: PropTypes.array.isRequired, 14 | headers: PropTypes.array.isRequired 15 | } 16 | } 17 | 18 | constructor(props) { 19 | super(props) 20 | this.changeTab = this.changeTab.bind(this) 21 | } 22 | 23 | componentDidMount() { 24 | // set 1st tab and tab header as active 25 | this.refs.tabs.children[0].className = 'react-tab' 26 | this.refs['list0'].className = 'selected' 27 | } 28 | 29 | changeTab(e) { 30 | if (this.props.onChangeTab !== undefined) { 31 | this.props.onChangeTab(e) 32 | } 33 | 34 | let id = e.target.getAttribute('data-tab-id') 35 | this.setActiveTab(id) 36 | 37 | let list = e.target.parentElement.parentElement.children 38 | this.setActiveTabHeader(list, id) 39 | } 40 | 41 | setActiveTab(id) { 42 | // hide all tab content 43 | let tabs = this.refs.tabs.children 44 | for (let i = 0; i < tabs.length; i++) { 45 | tabs[i].className = 'tab hidden' 46 | } 47 | // set selected tab content as visible 48 | tabs[id].className = 'tab' 49 | } 50 | 51 | setActiveTabHeader(list, id) { 52 | // set all headings as deselected 53 | for (let i = 0; i < list.length; i++) { 54 | list[i].className = '' 55 | } 56 | // set selected heading as selected 57 | list[id].className = 'selected' 58 | } 59 | 60 | render() { 61 | let headers = this.props.headers.map((h, i) => { 62 | return ( 63 |
  • 64 | 65 | {h} 66 | 67 |
  • 68 | ) 69 | }) 70 | 71 | return ( 72 | 73 |
    74 |
      {headers}
    75 |
    76 | 77 |
    78 | {this.props.children} 79 |
    80 |
    81 | ) 82 | } 83 | } 84 | 85 | export default Tabs 86 | 87 | const TabsWrapper = styled.div` 88 | border: 1px solid #ddd; 89 | border-radius: 2px; 90 | height: auto; 91 | margin: 0; 92 | padding: 10px; 93 | margin: 0 auto; 94 | display: block; 95 | 96 | .tab { 97 | margin: 0; 98 | padding: 10px; 99 | } 100 | .hidden { 101 | display: none; 102 | } 103 | content { 104 | width: 80%; 105 | } 106 | 107 | &:focus { 108 | outline: none; 109 | } 110 | 111 | ul { 112 | margin: 0; 113 | padding: 0; 114 | list-style-type: none; 115 | } 116 | 117 | ul li { 118 | display: inline; 119 | } 120 | 121 | a { 122 | text-decoration: none; 123 | padding: 0.5em; 124 | } 125 | 126 | .selected a { 127 | color: #b7b7b7 !important; 128 | } 129 | 130 | a:hover { 131 | color: #b7b7b7; 132 | } 133 | ` 134 | -------------------------------------------------------------------------------- /lib/Tab.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = _interopRequireWildcard(require("react")); 9 | 10 | var _propTypes = _interopRequireDefault(require("prop-types")); 11 | 12 | var _styledComponents = _interopRequireDefault(require("styled-components")); 13 | 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 15 | 16 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } 17 | 18 | function _templateObject() { 19 | var data = _taggedTemplateLiteral(["\n background: rgb(250, 250, 250);\n margin: 1em auto;\n border: 1px solid #ddd;\n padding: 1em;\n\n .hidden {\n display: none;\n }\n"]); 20 | 21 | _templateObject = function _templateObject() { 22 | return data; 23 | }; 24 | 25 | return data; 26 | } 27 | 28 | function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } 29 | 30 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 31 | 32 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 33 | 34 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 35 | 36 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 37 | 38 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 39 | 40 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 41 | 42 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 43 | 44 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 45 | 46 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 47 | 48 | /** 49 | * Tab module 50 | * A simple tab component. 51 | **/ 52 | var Tab = 53 | /*#__PURE__*/ 54 | function (_Component) { 55 | _inherits(Tab, _Component); 56 | 57 | function Tab() { 58 | _classCallCheck(this, Tab); 59 | 60 | return _possibleConstructorReturn(this, _getPrototypeOf(Tab).apply(this, arguments)); 61 | } 62 | 63 | _createClass(Tab, [{ 64 | key: "render", 65 | value: function render() { 66 | return _react.default.createElement(TabWrapper, { 67 | className: "hidden" 68 | }, this.props.children); 69 | } 70 | }], [{ 71 | key: "propTypes", 72 | get: function get() { 73 | return { 74 | children: _propTypes.default.node.isRequired 75 | }; 76 | } 77 | }]); 78 | 79 | return Tab; 80 | }(_react.Component); 81 | 82 | var _default = Tab; 83 | exports.default = _default; 84 | 85 | var TabWrapper = _styledComponents.default.div(_templateObject()); -------------------------------------------------------------------------------- /lib/Tabs.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.default = void 0; 7 | 8 | var _react = _interopRequireWildcard(require("react")); 9 | 10 | var _propTypes = _interopRequireDefault(require("prop-types")); 11 | 12 | var _styledComponents = _interopRequireDefault(require("styled-components")); 13 | 14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 15 | 16 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } } 17 | 18 | function _templateObject() { 19 | var data = _taggedTemplateLiteral(["\n border: 1px solid #ddd;\n border-radius: 2px;\n height: auto;\n margin: 0;\n padding: 10px;\n margin: 0 auto;\n display: block;\n\n .tab {\n margin: 0;\n padding: 10px;\n }\n .hidden {\n display: none;\n }\n content {\n width: 80%;\n }\n\n &:focus {\n outline: none;\n }\n\n ul {\n margin: 0;\n padding: 0;\n list-style-type: none;\n }\n\n ul li {\n display: inline;\n }\n\n a {\n text-decoration: none;\n padding: 0.5em;\n }\n\n .selected a {\n color: #b7b7b7 !important;\n }\n\n a:hover {\n color: #b7b7b7;\n }\n"]); 20 | 21 | _templateObject = function _templateObject() { 22 | return data; 23 | }; 24 | 25 | return data; 26 | } 27 | 28 | function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } 29 | 30 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 31 | 32 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 33 | 34 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } 35 | 36 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } 37 | 38 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 39 | 40 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 41 | 42 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 43 | 44 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } 45 | 46 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } 47 | 48 | /** 49 | * Tabs module 50 | * A simple tab component. 51 | **/ 52 | var Tabs = 53 | /*#__PURE__*/ 54 | function (_Component) { 55 | _inherits(Tabs, _Component); 56 | 57 | _createClass(Tabs, null, [{ 58 | key: "propTypes", 59 | get: function get() { 60 | return { 61 | onChangeTab: _propTypes.default.func, 62 | children: _propTypes.default.array.isRequired, 63 | headers: _propTypes.default.array.isRequired 64 | }; 65 | } 66 | }]); 67 | 68 | function Tabs(props) { 69 | var _this; 70 | 71 | _classCallCheck(this, Tabs); 72 | 73 | _this = _possibleConstructorReturn(this, _getPrototypeOf(Tabs).call(this, props)); 74 | _this.changeTab = _this.changeTab.bind(_assertThisInitialized(_this)); 75 | return _this; 76 | } 77 | 78 | _createClass(Tabs, [{ 79 | key: "componentDidMount", 80 | value: function componentDidMount() { 81 | // set 1st tab and tab header as active 82 | this.refs.tabs.children[0].className = 'react-tab'; 83 | this.refs['list0'].className = 'selected'; 84 | } 85 | }, { 86 | key: "changeTab", 87 | value: function changeTab(e) { 88 | if (this.props.onChangeTab !== undefined) { 89 | this.props.onChangeTab(e); 90 | } 91 | 92 | var id = e.target.getAttribute('data-tab-id'); 93 | this.setActiveTab(id); 94 | var list = e.target.parentElement.parentElement.children; 95 | this.setActiveTabHeader(list, id); 96 | } 97 | }, { 98 | key: "setActiveTab", 99 | value: function setActiveTab(id) { 100 | // hide all tab content 101 | var tabs = this.refs.tabs.children; 102 | 103 | for (var i = 0; i < tabs.length; i++) { 104 | tabs[i].className = 'tab hidden'; 105 | } // set selected tab content as visible 106 | 107 | 108 | tabs[id].className = 'tab'; 109 | } 110 | }, { 111 | key: "setActiveTabHeader", 112 | value: function setActiveTabHeader(list, id) { 113 | // set all headings as deselected 114 | for (var i = 0; i < list.length; i++) { 115 | list[i].className = ''; 116 | } // set selected heading as selected 117 | 118 | 119 | list[id].className = 'selected'; 120 | } 121 | }, { 122 | key: "render", 123 | value: function render() { 124 | var _this2 = this; 125 | 126 | var headers = this.props.headers.map(function (h, i) { 127 | return _react.default.createElement("li", { 128 | key: i, 129 | ref: 'list' + i 130 | }, _react.default.createElement("a", { 131 | "data-tab-id": i, 132 | onClick: _this2.changeTab 133 | }, h)); 134 | }); 135 | return _react.default.createElement(TabsWrapper, null, _react.default.createElement("div", null, _react.default.createElement("ul", null, headers)), _react.default.createElement("div", { 136 | className: "content", 137 | ref: "tabs" 138 | }, this.props.children)); 139 | } 140 | }]); 141 | 142 | return Tabs; 143 | }(_react.Component); 144 | 145 | var _default = Tabs; 146 | exports.default = _default; 147 | 148 | var TabsWrapper = _styledComponents.default.div(_templateObject()); --------------------------------------------------------------------------------