import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { themr } from 'react-css-themr';
import { TABS } from '../identifiers';
import InjectFontIcon from '../font_icon/FontIcon';
import isComponentOfType from '../utils/is-component-of-type';
import InjectTab from './Tab';
import InjectTabContent from './TabContent';
const factory = (Tab, TabContent, FontIcon) => {
const isTab = child => isComponentOfType(Tab, child);
const isTabContent = child => isComponentOfType(TabContent, child);
class Tabs extends Component {
static propTypes = {
children: PropTypes.node,
className: PropTypes.string,
disableAnimatedBottomBorder: PropTypes.bool,
fixed: PropTypes.bool,
hideMode: PropTypes.oneOf(['display', 'unmounted']),
index: PropTypes.number,
inverse: PropTypes.bool,
onChange: PropTypes.func,
theme: PropTypes.shape({
arrow: PropTypes.string,
arrowContainer: PropTypes.string,
disableAnimation: PropTypes.string,
fixed: PropTypes.string,
inverse: PropTypes.string,
navigation: PropTypes.string,
navigationContainer: PropTypes.string,
pointer: PropTypes.string,
tabs: PropTypes.string,
}),
};
static defaultProps = {
index: 0,
fixed: false,
inverse: false,
hideMode: 'unmounted',
};
state = {
pointer: {},
arrows: {},
};
componentDidMount() {
window.addEventListener('resize', this.handleResize);
this.handleResize();
}
componentDidUpdate(prevProps) {
const { index, children } = this.props;
const { index: prevIndex, children: prevChildren } = prevProps;
if (index !== prevIndex || children !== prevChildren) {
this.updatePointer(index);
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
clearTimeout(this.resizeTimeout);
if (this.updatePointerAnimationFrame) cancelAnimationFrame(this.updatePointerAnimationFrame);
}
handleHeaderClick = (idx) => {
if (this.props.onChange) {
this.props.onChange(idx);
}
};
handleResize = () => {
if (this.resizeTimeout) clearTimeout(this.resizeTimeout);
this.resizeTimeout = setTimeout(() => {
this.updatePointer(this.props.index);
this.updateArrows();
}, 100);
};
updatePointer = (idx) => {
if (this.navigationNode && this.navigationNode.children[idx]) {
this.updatePointerAnimationFrame = window.requestAnimationFrame(() => {
const nav = this.navigationNode.getBoundingClientRect();
const label = this.navigationNode.children[idx].getBoundingClientRect();
const scrollLeft = this.navigationNode.scrollLeft;
this.setState({
pointer: {
top: `${nav.height}px`,
left: `${(label.left + scrollLeft) - nav.left}px`,
width: `${label.width}px`,
},
});
});
}
}
updateArrows = () => {
const idx = this.navigationNode.children.length - 2;
if (idx >= 0) {
const scrollLeft = this.navigationNode.scrollLeft;
const nav = this.navigationNode.getBoundingClientRect();
const lastLabel = this.navigationNode.children[idx].getBoundingClientRect();
this.setState({
arrows: {
left: scrollLeft > 0,
right: nav.right < (lastLabel.right - 5),
},
});
}
}
scrollNavigation = (factor) => {
const oldScrollLeft = this.navigationNode.scrollLeft;
this.navigationNode.scrollLeft += factor * this.navigationNode.clientWidth;
if (this.navigationNode.scrollLeft !== oldScrollLeft) {
this.updateArrows();
}
}
scrollRight = () =>
this.scrollNavigation(-1);
scrollLeft = () =>
this.scrollNavigation(+1);
parseChildren() {
const headers = [];
const contents = [];
React.Children.forEach(this.props.children, (item) => {
if (isTab(item)) {
headers.push(item);
if (item.props.children) {
contents.push(