Skip to content

Instantly share code, notes, and snippets.

@NoamELB
Last active October 20, 2018 22:25
Show Gist options
  • Save NoamELB/8d61ef6ddbc15760c2cc1928dd20c7fb to your computer and use it in GitHub Desktop.
Save NoamELB/8d61ef6ddbc15760c2cc1928dd20c7fb to your computer and use it in GitHub Desktop.
tabs example
@import "../../../../SASS/lib/core";
@import "../../Cards/Card/mixins";
.tabs {
padding: 0;
border: $constants-border;
border-radius: 8px;
.tabs_header {
display: flex;
justify-content: space-between;
background-color: $palette-color-11;
border-radius: $card_border_radius $card_border_radius 0 0;
}
.tab_header_item {
flex: 1;
padding: 10px;
text-align: center;
cursor: pointer;
border-bottom: $constants-border;
&:first-child {
border-top-left-radius: $card_border_radius;
}
&:last-child {
border-top-right-radius: $card_border_radius;
}
&:not(:first-child) {
border-left: $constants-border;
}
&.active {
background-color: $palette-color-04;
border-bottom: none;
cursor: auto;
}
}
.tabs_content {
padding: 10px;
border-top: none;
border-radius: 0 0 $card_border_radius $card_border_radius;
}
}
/**
* @module Tabs
* @description Tab component
* @example
* <Tab value="banana" header="Banana header">
* Banana
* </Tab>
* @param {node} children
*/
export default function Tab ({children}) {
return (<div>{children}</div>);
}
import {Component, Children} from 'react';
import './index.scss';
/**
* @module Tabs
* @description Tabs component
*
* @example
* <Tabs value="banana" onChange="console.log">
* <Tab value="banana" header="Banana Header">Banana</Tab>
* <Tab value="apple" header="Apple Header">Apple</Tab>
* </Tabs>
*
* @param {string|number} value
* @param {function} onChange
* @param {node} children
*/
export default class Tabs extends Component {
constructor(props) {
super(props);
this.state = {};
this.isSelected = this.isSelected.bind(this);
this.selectTab = this.selectTab.bind(this);
}
componentWillReceiveProps(nextProps) {
const {value} = nextProps;
if (value !== this.props.value && value !== this.state.value) {
this.setState({value});
}
}
isSelected(tab) {
return tab.props.value === this.state.value;
}
selectTab(e, value) {
this.setState({value});
this.props.onChange && this.props.onChange(e, value);
}
getHeader(tabs) {
let className = 'tab_header_item';
return tabs.map(tab => (
<span
onClick={e => this.selectTab(e, tab.props.value)}
className={`${className}${this.isSelected(tab) ? ' active' : ''}`}>
{tab.props.header}
</span>
));
}
render() {
const {children} = this.props;
const tabs = Children.toArray(children);
const content = _.find(tabs, this.isSelected);
const header = this.getHeader(tabs);
return (
<div className="tabs">
<div className="tabs_header">
{header}
</div>
<div className="tabs_content">
{content}
</div>
</div>
);
}
}
@talyak
Copy link

talyak commented Aug 7, 2017

what about adding next button to the tabs component, how you will manage with it?

@NoamELB
Copy link
Author

NoamELB commented Sep 25, 2017

@talyak I would compose the Tabs component with the additional button as a built-in child. Since the component is controlled, it is very easy to create it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment