2019-11-11 12:28:13 +00:00
|
|
|
import React, { Component } from "react";
|
|
|
|
import PropTypes from "prop-types";
|
|
|
|
import styled from "styled-components";
|
2019-08-07 11:43:24 +00:00
|
|
|
import { Text } from "../text";
|
2019-11-12 06:52:27 +00:00
|
|
|
import Scrollbar from "../scrollbar";
|
2019-08-05 13:09:12 +00:00
|
|
|
|
2019-11-25 09:32:18 +00:00
|
|
|
const StyledScrollbar = styled(Scrollbar)`
|
|
|
|
width: 100% !important;
|
|
|
|
height: 50px !important;
|
2019-11-20 11:10:35 +00:00
|
|
|
`;
|
2019-11-25 09:32:18 +00:00
|
|
|
|
2019-08-05 13:09:12 +00:00
|
|
|
const NavItem = styled.div`
|
2019-08-06 09:04:01 +00:00
|
|
|
position: relative;
|
|
|
|
white-space: nowrap;
|
2019-11-11 12:28:13 +00:00
|
|
|
display: flex;
|
2019-08-06 09:04:01 +00:00
|
|
|
`;
|
|
|
|
|
2019-11-11 12:28:13 +00:00
|
|
|
const Label = styled.div`
|
2019-08-06 09:04:01 +00:00
|
|
|
height: 32px;
|
|
|
|
border-radius: 16px;
|
2019-11-12 06:52:27 +00:00
|
|
|
min-width: fit-content;
|
2019-11-11 12:28:13 +00:00
|
|
|
margin-right: 8px;
|
|
|
|
width: fit-content;
|
|
|
|
|
|
|
|
.title_style {
|
|
|
|
text-align: center;
|
|
|
|
margin: 7px 15px 7px 15px;
|
2019-11-12 06:52:27 +00:00
|
|
|
overflow: hidden;
|
2019-11-18 09:40:21 +00:00
|
|
|
|
|
|
|
-webkit-touch-callout: none;
|
|
|
|
-webkit-user-select: none;
|
|
|
|
-khtml-user-select: none;
|
|
|
|
-moz-user-select: none;
|
|
|
|
-ms-user-select: none;
|
|
|
|
user-select: none;
|
2019-11-11 12:28:13 +00:00
|
|
|
}
|
2019-08-05 13:09:12 +00:00
|
|
|
|
2019-11-11 12:28:13 +00:00
|
|
|
${props => (props.isDisabled ? `pointer-events: none;` : ``)}
|
2019-08-06 09:04:01 +00:00
|
|
|
|
2019-11-11 12:28:13 +00:00
|
|
|
${props =>
|
|
|
|
props.selected
|
|
|
|
? `cursor: default
|
|
|
|
background-color: #265A8F
|
|
|
|
.title_style {
|
|
|
|
color: #fff
|
|
|
|
}`
|
|
|
|
: `
|
2019-08-05 13:09:12 +00:00
|
|
|
&:hover{
|
|
|
|
cursor: pointer;
|
2019-08-05 16:05:03 +00:00
|
|
|
background-color: #F8F9F9;
|
2019-11-11 12:28:13 +00:00
|
|
|
}`}
|
2019-08-06 09:04:01 +00:00
|
|
|
|
2019-11-11 12:28:13 +00:00
|
|
|
${props =>
|
|
|
|
props.isDisabled && props.selected
|
2019-11-20 12:32:39 +00:00
|
|
|
? `background-color: #ECEEF1
|
|
|
|
.title_style {color: #D0D5DA}`
|
2019-11-11 12:28:13 +00:00
|
|
|
: ``}
|
2019-08-05 13:09:12 +00:00
|
|
|
`;
|
|
|
|
|
2019-08-05 16:05:03 +00:00
|
|
|
const BodyContainer = styled.div`
|
|
|
|
margin: 24px 16px 0px 16px;
|
|
|
|
`;
|
2019-08-05 13:09:12 +00:00
|
|
|
|
2019-08-06 09:04:01 +00:00
|
|
|
class TabContainer extends Component {
|
2019-08-05 13:09:12 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2019-08-07 08:14:12 +00:00
|
|
|
|
2019-11-20 11:10:35 +00:00
|
|
|
this.arrayRefs = [];
|
|
|
|
const countElements = props.children.length;
|
|
|
|
|
|
|
|
let item = countElements;
|
|
|
|
while (item !== 0) {
|
|
|
|
this.arrayRefs.push(React.createRef());
|
|
|
|
item--;
|
|
|
|
}
|
|
|
|
|
2019-08-05 13:09:12 +00:00
|
|
|
this.state = {
|
2019-11-25 09:32:18 +00:00
|
|
|
activeTab: this.props.selectedItem,
|
|
|
|
onScrollHide: true
|
2019-08-05 13:09:12 +00:00
|
|
|
};
|
2019-11-20 11:10:35 +00:00
|
|
|
|
|
|
|
this.scrollRef = React.createRef();
|
2019-08-05 13:09:12 +00:00
|
|
|
}
|
|
|
|
|
2019-11-20 11:10:35 +00:00
|
|
|
titleClick = (index, item, ref) => {
|
2019-08-07 08:14:12 +00:00
|
|
|
if (this.state.activeTab !== index) {
|
|
|
|
this.setState({ activeTab: index });
|
2019-08-07 11:43:24 +00:00
|
|
|
let newItem = Object.assign({}, item);
|
|
|
|
delete newItem.content;
|
|
|
|
this.props.onSelect && this.props.onSelect(newItem);
|
2019-11-20 11:10:35 +00:00
|
|
|
|
2019-11-25 06:23:02 +00:00
|
|
|
this.setTabPosition(index, ref);
|
2019-08-05 13:09:12 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-11-25 06:23:02 +00:00
|
|
|
getWidthElements = () => {
|
|
|
|
const arrayWidths = [];
|
|
|
|
const length = this.arrayRefs.length - 1;
|
|
|
|
let widthItem = 0;
|
|
|
|
while (length + 1 !== widthItem) {
|
|
|
|
arrayWidths.push(this.arrayRefs[widthItem].current.offsetWidth);
|
|
|
|
widthItem++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return arrayWidths;
|
|
|
|
};
|
|
|
|
|
2019-11-15 07:15:21 +00:00
|
|
|
shouldComponentUpdate(nextProps, nextState) {
|
2019-11-25 09:32:18 +00:00
|
|
|
const { activeTab, onScrollHide } = this.state;
|
2019-11-20 11:10:35 +00:00
|
|
|
const { isDisabled } = this.props;
|
|
|
|
if (
|
|
|
|
activeTab === nextState.activeTab &&
|
2019-11-25 09:32:18 +00:00
|
|
|
isDisabled === nextProps.isDisabled &&
|
|
|
|
onScrollHide === nextState.onScrollHide
|
2019-11-20 11:10:35 +00:00
|
|
|
) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2019-11-15 07:15:21 +00:00
|
|
|
}
|
|
|
|
|
2019-11-25 06:23:02 +00:00
|
|
|
componentDidMount() {
|
|
|
|
const { activeTab } = this.state;
|
|
|
|
if (activeTab !== 0 && this.arrayRefs[activeTab].current !== null) {
|
|
|
|
this.secondFunction(activeTab);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setTabPosition = (index, currentRef) => {
|
|
|
|
const arrayOfWidths = this.getWidthElements(); //get tabs widths
|
|
|
|
const scrollLeft = this.scrollRef.current.getScrollLeft(); // get scroll position relative to left side
|
|
|
|
const staticScroll = this.scrollRef.current.getScrollWidth(); //get static scroll width
|
|
|
|
const containerWidth = this.scrollRef.current.getClientWidth(); //get main container width
|
|
|
|
const currentTabWidth = currentRef.current.offsetWidth;
|
|
|
|
const marginRight = 8;
|
|
|
|
|
|
|
|
//get tabs of left side
|
|
|
|
let leftTabs = 0;
|
|
|
|
let leftFullWidth = 0;
|
|
|
|
while (leftTabs !== index) {
|
|
|
|
leftTabs++;
|
|
|
|
leftFullWidth += arrayOfWidths[leftTabs] + marginRight;
|
|
|
|
}
|
|
|
|
leftFullWidth += arrayOfWidths[0] + marginRight;
|
|
|
|
|
|
|
|
//get tabs of right side
|
|
|
|
let rightTabs = this.arrayRefs.length - 1;
|
|
|
|
let rightFullWidth = 0;
|
|
|
|
while (rightTabs !== index - 1) {
|
|
|
|
rightFullWidth += arrayOfWidths[rightTabs] + marginRight;
|
|
|
|
rightTabs--;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Out of range of left side
|
|
|
|
if (leftFullWidth > containerWidth + scrollLeft) {
|
|
|
|
let prevIndex = index - 1;
|
|
|
|
let widthBlocksInContainer = 0;
|
|
|
|
while (prevIndex !== -1) {
|
|
|
|
widthBlocksInContainer += arrayOfWidths[prevIndex] + marginRight;
|
|
|
|
prevIndex--;
|
|
|
|
}
|
|
|
|
|
|
|
|
const difference = containerWidth - widthBlocksInContainer;
|
|
|
|
const currentContainerWidth = currentTabWidth;
|
|
|
|
|
|
|
|
this.scrollRef.current.scrollLeft(
|
|
|
|
difference * -1 + currentContainerWidth + marginRight
|
|
|
|
);
|
|
|
|
}
|
|
|
|
//Out of range of left side
|
|
|
|
else if (rightFullWidth > staticScroll - scrollLeft) {
|
|
|
|
this.scrollRef.current.scrollLeft(staticScroll - rightFullWidth);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
secondFunction = index => {
|
|
|
|
const arrayOfWidths = this.getWidthElements(); //get tabs widths
|
|
|
|
const marginRight = 8;
|
|
|
|
let rightTabs = this.arrayRefs.length - 1;
|
|
|
|
let rightFullWidth = 0;
|
|
|
|
while (rightTabs !== index - 1) {
|
|
|
|
rightFullWidth += arrayOfWidths[rightTabs] + marginRight;
|
|
|
|
rightTabs--;
|
|
|
|
}
|
|
|
|
|
|
|
|
const staticScroll = this.scrollRef.current.getScrollWidth(); //get static scroll width
|
|
|
|
this.scrollRef.current.scrollLeft(staticScroll - rightFullWidth);
|
|
|
|
};
|
|
|
|
|
2019-11-25 09:32:18 +00:00
|
|
|
onMouseEnter = () => {
|
|
|
|
this.setState({ onScrollHide: false });
|
|
|
|
};
|
|
|
|
|
|
|
|
onMouseLeave = () => {
|
|
|
|
this.setState({ onScrollHide: true });
|
|
|
|
};
|
|
|
|
|
2019-08-06 15:46:16 +00:00
|
|
|
render() {
|
2019-11-15 07:15:21 +00:00
|
|
|
//console.log("Tabs container render");
|
2019-11-11 12:28:13 +00:00
|
|
|
|
|
|
|
const { isDisabled, children } = this.props;
|
2019-11-25 09:32:18 +00:00
|
|
|
const { activeTab, onScrollHide } = this.state;
|
2019-11-20 11:10:35 +00:00
|
|
|
|
2019-08-05 13:09:12 +00:00
|
|
|
return (
|
2019-11-25 09:32:18 +00:00
|
|
|
<>
|
|
|
|
<StyledScrollbar
|
|
|
|
autoHide={onScrollHide}
|
|
|
|
autoHideDuration={500}
|
|
|
|
autoHideTimeout={1000}
|
|
|
|
stype="preMediumBlack"
|
2019-11-20 11:10:35 +00:00
|
|
|
className="scrollbar"
|
|
|
|
ref={this.scrollRef}
|
|
|
|
>
|
2019-11-25 09:32:18 +00:00
|
|
|
<NavItem
|
|
|
|
onMouseMove={this.onMouseEnter}
|
|
|
|
onMouseLeave={this.onMouseLeave}
|
|
|
|
className="className_items"
|
|
|
|
>
|
2019-11-12 06:52:27 +00:00
|
|
|
{children.map((item, index) => (
|
|
|
|
<Label
|
2019-11-20 11:10:35 +00:00
|
|
|
ref={this.arrayRefs[index]}
|
|
|
|
onClick={this.titleClick.bind(
|
|
|
|
this,
|
|
|
|
index,
|
|
|
|
item,
|
|
|
|
this.arrayRefs[index]
|
|
|
|
)}
|
2019-11-12 06:52:27 +00:00
|
|
|
key={item.key}
|
2019-11-20 11:10:35 +00:00
|
|
|
selected={activeTab === index}
|
2019-11-12 06:52:27 +00:00
|
|
|
isDisabled={isDisabled}
|
|
|
|
>
|
|
|
|
<Text.Body className="title_style" fontSize={13}>
|
|
|
|
{item.title}
|
|
|
|
</Text.Body>
|
|
|
|
</Label>
|
|
|
|
))}
|
|
|
|
</NavItem>
|
2019-11-25 09:32:18 +00:00
|
|
|
</StyledScrollbar>
|
2019-11-20 11:10:35 +00:00
|
|
|
<BodyContainer>{children[activeTab].content}</BodyContainer>
|
2019-11-25 09:32:18 +00:00
|
|
|
</>
|
2019-08-05 13:09:12 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-06 09:04:01 +00:00
|
|
|
TabContainer.propTypes = {
|
2019-11-11 12:28:13 +00:00
|
|
|
children: PropTypes.PropTypes.arrayOf(PropTypes.object.isRequired).isRequired,
|
2019-08-06 15:46:16 +00:00
|
|
|
isDisabled: PropTypes.bool,
|
2019-08-07 11:43:24 +00:00
|
|
|
onSelect: PropTypes.func,
|
|
|
|
selectedItem: PropTypes.number
|
2019-08-05 13:09:12 +00:00
|
|
|
};
|
2019-08-05 16:05:03 +00:00
|
|
|
|
2019-08-07 11:43:24 +00:00
|
|
|
TabContainer.defaultProps = {
|
|
|
|
selectedItem: 0
|
2019-11-11 12:28:13 +00:00
|
|
|
};
|
2019-08-07 11:43:24 +00:00
|
|
|
|
2019-11-11 12:28:13 +00:00
|
|
|
export default TabContainer;
|