import React from 'react'; import Tab from './Tab'; import TabContent from './TabContent'; import style from './style'; class Tabs extends React.Component { static propTypes = { children: React.PropTypes.node, className: React.PropTypes.string, disableAnimatedBottomBorder: React.PropTypes.bool, index: React.PropTypes.number, onChange: React.PropTypes.func }; static defaultProps = { index: 0 }; state = { pointer: {} }; componentDidMount () { !this.props.disableAnimatedBottomBorder && this.updatePointer(this.props.index); } componentWillReceiveProps (nextProps) { !this.props.disableAnimatedBottomBorder && this.updatePointer(nextProps.index); } componentWillUnmount () { clearTimeout(this.pointerTimeout); } handleHeaderClick = (idx) => { if (this.props.onChange) this.props.onChange(idx); }; parseChildren () { const headers = []; const contents = []; React.Children.forEach(this.props.children, (item) => { if (item.type === Tab) { headers.push(item); if (item.props.children) { contents.push(); } } else if (item.type === TabContent) { contents.push(item); } }); return {headers, contents}; } updatePointer (idx) { clearTimeout(this.pointerTimeout); this.pointerTimeout = setTimeout(() => { const startPoint = this.refs.tabs.getBoundingClientRect().left; const label = this.refs.navigation.children[idx].getBoundingClientRect(); this.setState({ pointer: { top: `${this.refs.navigation.getBoundingClientRect().height}px`, left: `${label.left - startPoint}px`, width: `${label.width}px` } }); }, 20); } renderHeaders (headers) { return headers.map((item, idx) => { return React.cloneElement(item, { key: idx, active: this.props.index === idx, onClick: this.handleHeaderClick.bind(this, idx, item) }); }); } renderContents (contents) { return contents.map((item, idx) => { return React.cloneElement(item, { key: idx, active: this.props.index === idx, tabIndex: idx }); }); } render () { let className = style.root; const { headers, contents } = this.parseChildren(); if (this.props.className) className += ` ${this.props.className}`; return (
{this.renderContents(contents)}
); } } export default Tabs;