Skip to content

Instantly share code, notes, and snippets.

@joshbedo
Created March 6, 2015 15:21
Show Gist options
  • Save joshbedo/e737d0f93532ebf24744 to your computer and use it in GitHub Desktop.
Save joshbedo/e737d0f93532ebf24744 to your computer and use it in GitHub Desktop.
tabs
import React from 'react';
const D = React.DOM
var Tabs = React.createClass({
displayName: 'Tabs',
propTypes: {
tabActive: React.PropTypes.number,
onMount: React.PropTypes.func,
onBeforeChange: React.PropTypes.func,
onAfterChange: React.PropTypes.func,
// children: React.PropTypes.oneOfType([
// React.PropTypes.array,
// React.PropTypes.element
// ]).isRequired
},
getDefaultProps () {
return { tabActive: 1 }
},
getInitialState () {
return {
tabActive: this.props.tabActive
}
},
componentDidMount () {
var index = this.state.tabActive;
var $selectedPanel = this.refs['tab-panel'];
var $selectedMenu = this.refs[`tab-menu-${index}`];
if (this.props.onMount) {
this.props.onMount(index, $selectedPanel, $selectedMenu);
}
},
componentWillReceiveProps (newProps) {
if(newProps.tabActive) {
this.setState({ tabActive: newProps.tabActive });
}
},
render () {
return (
D.div({ className: 'tabs'}, [
this._getMenuItems(),
this._getSelectedPanel()
])
);
},
setActive (index, ev) {
var onAfterChange = this.props.onAfterChange;
var onBeforeChange = this.props.onBeforeChange;
var $selectedPanel = this.refs['tab-panel'];
var $selectedTabMenu = this.refs[`tab-menu-${index}`];
if (onBeforeChange) {
var cancel = onBeforeChange(index, $selectedPanel, $selectedTabMenu);
if (!cancel) return
}
this.setState({ tabActive: index }, () => {
if (onAfterChange) {
onAfterChange(index, $selectedPanel, $selectedTabMenu);
}
});
ev.preventDefault();
},
_getMenuItems () {
if (!this.props.children) {
throw new Error('Tabs must contain at least one Tab Panel');
}
if (!Array.isArray(this.props.children)) {
this.props.children = [this.props.children];
}
var $menuItems = this.props.children.map(($panel, index) => {
var ref = `tab-menu-${index + 1}`;
var title = $panel.props.title;
var classes = classSet({
'tabs-menu-item': true,
'is-active': this.state.tabActive === (index + 1)
});
return (
D.li({ ref: ref, key: index, className: classes }, [
D.a({ href: '#', onClick: this.setActive.bind(this, index + 1)}, title)
])
);
});
return (
D.nav({ className: 'tabs-navigation' }, [
D.ul({ className: 'tabs-menu' }, $menuItems)
])
);
},
_getSelectedPanel () {
var index = this.state.tabActive - 1;
var $panel = this.props.children[index];
return (
D.section({ ref: 'tab-panel', className: 'tab-panel' }, $panel)
)
}
});
Tabs.Panel = React.createClass({
displayName: 'Panel',
propTypes: {
title: React.PropTypes.string.isRequired,
// children: React.PropTypes.oneOfType([
// React.PropTypes.array,
// React.PropTypes.element
// ]).isRequired
},
render () {
return D.div({}, this.props.children)
}
});
export default Tabs;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment