diff options
Diffstat (limited to 'ui/app/components/tabs')
-rw-r--r-- | ui/app/components/tabs/index.js | 3 | ||||
-rw-r--r-- | ui/app/components/tabs/index.scss | 11 | ||||
-rw-r--r-- | ui/app/components/tabs/tab/index.js | 2 | ||||
-rw-r--r-- | ui/app/components/tabs/tab/index.scss | 15 | ||||
-rw-r--r-- | ui/app/components/tabs/tab/tab.component.js | 31 | ||||
-rw-r--r-- | ui/app/components/tabs/tabs.component.js | 62 |
6 files changed, 124 insertions, 0 deletions
diff --git a/ui/app/components/tabs/index.js b/ui/app/components/tabs/index.js new file mode 100644 index 000000000..3a8d18248 --- /dev/null +++ b/ui/app/components/tabs/index.js @@ -0,0 +1,3 @@ +import Tabs from './tabs.component' +import Tab from './tab' +export { Tabs, Tab } diff --git a/ui/app/components/tabs/index.scss b/ui/app/components/tabs/index.scss new file mode 100644 index 000000000..a3b42f8e3 --- /dev/null +++ b/ui/app/components/tabs/index.scss @@ -0,0 +1,11 @@ +@import './tab/index'; + +.tabs { + &__list { + display: flex; + justify-content: flex-start; + background-color: #f9fafa; + border-bottom: 1px solid $geyser; + padding: 0 16px; + } +} diff --git a/ui/app/components/tabs/tab/index.js b/ui/app/components/tabs/tab/index.js new file mode 100644 index 000000000..fbc309e8e --- /dev/null +++ b/ui/app/components/tabs/tab/index.js @@ -0,0 +1,2 @@ +import Tab from './tab.component' +module.exports = Tab diff --git a/ui/app/components/tabs/tab/index.scss b/ui/app/components/tabs/tab/index.scss new file mode 100644 index 000000000..1de6ffa0e --- /dev/null +++ b/ui/app/components/tabs/tab/index.scss @@ -0,0 +1,15 @@ +.tab { + color: #8C8E94; + font-size: .75rem; + text-transform: uppercase; + cursor: pointer; + padding: 8px 0; + margin: 0 8px; + min-width: 50px; + text-align: center; + + &--active { + color: $black; + border-bottom: 2px solid $curious-blue; + } +} diff --git a/ui/app/components/tabs/tab/tab.component.js b/ui/app/components/tabs/tab/tab.component.js new file mode 100644 index 000000000..a59da8904 --- /dev/null +++ b/ui/app/components/tabs/tab/tab.component.js @@ -0,0 +1,31 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' + +const Tab = props => { + const { name, onClick, isActive, tabIndex } = props + + return ( + <li + className={classnames( + 'tab', + isActive && 'tab--active', + )} + onClick={event => { + event.preventDefault() + onClick(tabIndex) + }} + > + { name } + </li> + ) +} + +Tab.propTypes = { + name: PropTypes.string.isRequired, + onClick: PropTypes.func, + isActive: PropTypes.bool, + tabIndex: PropTypes.number, +} + +export default Tab diff --git a/ui/app/components/tabs/tabs.component.js b/ui/app/components/tabs/tabs.component.js new file mode 100644 index 000000000..d26dcff2f --- /dev/null +++ b/ui/app/components/tabs/tabs.component.js @@ -0,0 +1,62 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +export default class Tabs extends Component { + static propTypes = { + defaultActiveTabIndex: PropTypes.number, + children: PropTypes.node, + } + + constructor (props) { + super(props) + + this.state = { + activeTabIndex: props.defaultActiveTabIndex || 0, + } + } + + handleTabClick (tabIndex) { + const { activeTabIndex } = this.state + + if (tabIndex !== activeTabIndex) { + this.setState({ + activeTabIndex: tabIndex, + }) + } + } + + renderTabs () { + const numberOfTabs = React.Children.count(this.props.children) + + return React.Children.map(this.props.children, (child, index) => { + return child && React.cloneElement(child, { + onClick: index => this.handleTabClick(index), + tabIndex: index, + isActive: numberOfTabs > 1 && index === this.state.activeTabIndex, + key: index, + }) + }) + } + + renderActiveTabContent () { + const { children } = this.props + const { activeTabIndex } = this.state + + return children[activeTabIndex] + ? children[activeTabIndex].props.children + : children.props.children + } + + render () { + return ( + <div className="tabs"> + <ul className="tabs__list"> + { this.renderTabs() } + </ul> + <div className="tabs__content"> + { this.renderActiveTabContent() } + </div> + </div> + ) + } +} |