2019-07-30 11:17:19 +00:00
|
|
|
import React from 'react';
|
|
|
|
import styled from 'styled-components';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import GroupButton from '../group-button';
|
|
|
|
import DropDownItem from '../drop-down-item';
|
2019-08-22 08:05:03 +00:00
|
|
|
import throttle from 'lodash/throttle';
|
2019-08-26 13:08:50 +00:00
|
|
|
import { isArrayEqual } from '../../utils/array';
|
2019-12-17 13:30:18 +00:00
|
|
|
import { tablet } from '../../utils/device'
|
2019-06-17 08:58:02 +00:00
|
|
|
|
|
|
|
const StyledGroupButtonsMenu = styled.div`
|
2019-12-05 12:12:32 +00:00
|
|
|
box-sizing: border-box;
|
2019-06-17 08:58:02 +00:00
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
2019-06-25 15:01:04 +00:00
|
|
|
background: #FFFFFF;
|
2019-12-17 13:30:18 +00:00
|
|
|
box-shadow: 0px 10px 18px -8px rgba(0, 0, 0, 0.100306);
|
|
|
|
height: 57px;
|
2019-06-17 08:58:02 +00:00
|
|
|
list-style: none;
|
2019-06-25 15:01:04 +00:00
|
|
|
padding: 0 18px 19px 0;
|
2019-07-08 07:12:43 +00:00
|
|
|
width: 100%;
|
|
|
|
white-space: nowrap;
|
2019-08-22 08:05:03 +00:00
|
|
|
display: ${props => props.visible ? 'block' : 'none'};
|
2019-11-25 13:36:09 +00:00
|
|
|
z-index: 195;
|
2019-06-17 08:58:02 +00:00
|
|
|
`;
|
|
|
|
|
2019-06-25 15:01:04 +00:00
|
|
|
const CloseButton = styled.div`
|
|
|
|
position: absolute;
|
2019-12-17 13:30:18 +00:00
|
|
|
right: 12px;
|
|
|
|
top: 10px;
|
2019-06-25 15:01:04 +00:00
|
|
|
width: 20px;
|
|
|
|
height: 20px;
|
2019-12-17 13:30:18 +00:00
|
|
|
padding: 8px;
|
|
|
|
|
2020-08-11 08:03:29 +00:00
|
|
|
@media ${tablet} {
|
2019-12-17 13:30:18 +00:00
|
|
|
right: 4px;
|
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
|
|
|
|
&:hover{
|
|
|
|
cursor: pointer;
|
2019-12-26 09:17:35 +00:00
|
|
|
|
|
|
|
&:before, &:after {
|
|
|
|
background-color: #555F65;
|
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
&:before, &:after {
|
|
|
|
position: absolute;
|
|
|
|
left: 15px;
|
|
|
|
content: ' ';
|
|
|
|
height: 20px;
|
|
|
|
width: 1px;
|
2019-12-17 13:30:18 +00:00
|
|
|
background-color: #D0D5DA;
|
2019-06-25 15:01:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
&:before {
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
|
|
|
|
|
|
|
&:after {
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
2019-07-31 11:43:05 +00:00
|
|
|
const GroupMenuWrapper = styled.div`
|
|
|
|
display: inline-block;
|
|
|
|
`;
|
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
class GroupButtonsMenu extends React.PureComponent {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2019-06-17 08:58:02 +00:00
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
this.state = {
|
|
|
|
priorityItems: props.menuItems,
|
|
|
|
moreItems: [],
|
2019-11-05 11:28:44 +00:00
|
|
|
visible: props.visible
|
2019-06-17 08:58:02 +00:00
|
|
|
}
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2019-08-22 12:26:48 +00:00
|
|
|
this.throttledResize = throttle(this.updateMenu, 300);
|
2019-07-30 11:17:19 +00:00
|
|
|
}
|
2019-07-25 11:00:03 +00:00
|
|
|
|
2019-07-31 11:43:05 +00:00
|
|
|
closeMenu = (e) => {
|
|
|
|
this.setState({ visible: false });
|
|
|
|
this.props.onClose && this.props.onClose(e);
|
|
|
|
};
|
|
|
|
|
2020-08-11 08:03:29 +00:00
|
|
|
groupButtonClick = (e) => {
|
|
|
|
const { priorityItems } = this.state;
|
|
|
|
const index = e.currentTarget.dataset.index;
|
|
|
|
const item = priorityItems[index];
|
|
|
|
|
2019-08-21 11:44:30 +00:00
|
|
|
if (item.disabled) return;
|
2020-08-11 08:03:29 +00:00
|
|
|
|
|
|
|
item.onClick && item.onClick(e);
|
|
|
|
};
|
|
|
|
|
|
|
|
groupMoreMenuButtonClick = (e) => {
|
|
|
|
const { moreItems } = this.state;
|
|
|
|
const index = e.currentTarget.dataset.index;
|
|
|
|
const item = moreItems[index];
|
|
|
|
|
|
|
|
if (item.disabled) return;
|
|
|
|
|
|
|
|
item.onClick && item.onClick(e);
|
2019-07-31 11:43:05 +00:00
|
|
|
};
|
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
componentDidMount() {
|
2019-11-05 11:28:44 +00:00
|
|
|
const groupMenuElement = document.getElementById("groupMenu");
|
|
|
|
|
|
|
|
const groupMenuItems = groupMenuElement ? groupMenuElement.children : [0];
|
2019-09-09 13:08:07 +00:00
|
|
|
const groupMenuItemsArray = [...groupMenuItems];
|
2019-08-22 08:05:03 +00:00
|
|
|
|
2019-11-05 11:28:44 +00:00
|
|
|
this.widthsArray = groupMenuItemsArray.map(item => item.offsetWidth);
|
|
|
|
|
2019-08-22 08:05:03 +00:00
|
|
|
window.addEventListener('resize', this.throttledResize);
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
this.updateMenu();
|
|
|
|
}
|
2019-06-17 08:58:02 +00:00
|
|
|
|
2019-11-05 11:28:44 +00:00
|
|
|
componentDidUpdate(prevProps, prevState) {
|
2019-07-30 11:17:19 +00:00
|
|
|
if (this.props.visible !== prevProps.visible) {
|
|
|
|
this.setState({ visible: this.props.visible });
|
2019-07-08 07:12:43 +00:00
|
|
|
}
|
2019-08-22 08:05:03 +00:00
|
|
|
|
2019-11-05 11:28:44 +00:00
|
|
|
if (!isArrayEqual(this.props.menuItems, prevProps.menuItems)) {
|
2019-08-21 14:05:43 +00:00
|
|
|
this.setState({ priorityItems: this.props.menuItems, });
|
2019-11-05 11:28:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (this.state.priorityItems.length !== prevState.priorityItems.length || this.state.moreItems.length !== prevState.moreItems.length) {
|
2019-08-22 08:05:03 +00:00
|
|
|
this.updateMenu();
|
2019-08-21 14:05:43 +00:00
|
|
|
}
|
2019-09-08 13:36:39 +00:00
|
|
|
}
|
2019-07-30 11:17:19 +00:00
|
|
|
|
2019-11-05 11:28:44 +00:00
|
|
|
countMenuItems = (array, outerWidth, moreWidth) => {
|
|
|
|
const itemsArray = array || []
|
2020-01-30 13:21:27 +00:00
|
|
|
let total = (moreWidth || 0) + 80;
|
2019-11-05 11:28:44 +00:00
|
|
|
|
|
|
|
for (let i = 0, len = itemsArray.length; i < len; i++) {
|
2020-01-30 13:21:27 +00:00
|
|
|
if (total + itemsArray[i] > outerWidth) {
|
2019-07-30 11:17:19 +00:00
|
|
|
return i < 1 ? 1 : i;
|
|
|
|
} else {
|
2020-01-30 13:21:27 +00:00
|
|
|
total += itemsArray[i];
|
2019-07-30 11:17:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
updateMenu = () => {
|
|
|
|
const moreMenuElement = document.getElementById("moreMenu");
|
2019-07-31 11:43:05 +00:00
|
|
|
const groupMenuOuterElement = document.getElementById("groupMenuOuter");
|
2019-08-22 08:05:03 +00:00
|
|
|
|
2019-11-05 11:28:44 +00:00
|
|
|
const moreMenuWidth = moreMenuElement && moreMenuElement.getBoundingClientRect().width;
|
|
|
|
const groupMenuOuterWidth = groupMenuOuterElement && groupMenuOuterElement.getBoundingClientRect().width;
|
2019-08-22 08:05:03 +00:00
|
|
|
|
|
|
|
const visibleItemsCount = this.countMenuItems(this.widthsArray, groupMenuOuterWidth, moreMenuWidth);
|
|
|
|
const navItemsCopy = this.props.menuItems;
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2019-08-22 08:05:03 +00:00
|
|
|
const priorityItems = navItemsCopy.slice(0, visibleItemsCount);
|
|
|
|
const moreItems = priorityItems.length !== navItemsCopy.length ? navItemsCopy.slice(visibleItemsCount, navItemsCopy.length) : [];
|
2019-07-30 11:17:19 +00:00
|
|
|
|
|
|
|
this.setState({
|
|
|
|
priorityItems: priorityItems,
|
2019-08-22 08:05:03 +00:00
|
|
|
moreItems: moreItems
|
2019-07-30 11:17:19 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
2019-08-22 08:05:03 +00:00
|
|
|
window.removeEventListener('resize', this.throttledResize);
|
2019-07-30 11:17:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
//console.log("GroupButtonsMenu render");
|
2019-08-22 08:05:03 +00:00
|
|
|
const { selected, moreLabel, closeTitle } = this.props;
|
|
|
|
const { priorityItems, moreItems, visible } = this.state;
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
return (
|
2019-08-22 08:05:03 +00:00
|
|
|
<StyledGroupButtonsMenu id="groupMenuOuter" visible={visible} >
|
2019-07-31 11:43:05 +00:00
|
|
|
<GroupMenuWrapper id="groupMenu">
|
2019-08-22 08:05:03 +00:00
|
|
|
{priorityItems.map((item, i) =>
|
2019-11-05 11:28:44 +00:00
|
|
|
<GroupButton
|
2019-08-22 08:05:03 +00:00
|
|
|
key={`navItem-${i}`}
|
2019-07-30 11:17:19 +00:00
|
|
|
label={item.label}
|
|
|
|
isDropdown={item.isDropdown}
|
|
|
|
isSeparator={item.isSeparator}
|
|
|
|
isSelect={item.isSelect}
|
|
|
|
onSelect={item.onSelect}
|
2019-08-22 08:05:03 +00:00
|
|
|
selected={selected}
|
2019-07-30 11:17:19 +00:00
|
|
|
fontWeight={item.fontWeight}
|
2019-08-21 11:44:30 +00:00
|
|
|
disabled={item.disabled}
|
2020-08-11 08:03:29 +00:00
|
|
|
onClick={this.groupButtonClick}
|
|
|
|
data-index={i}
|
2019-09-05 13:19:24 +00:00
|
|
|
{...this.props}
|
2019-07-31 11:43:05 +00:00
|
|
|
>
|
2019-07-30 11:17:19 +00:00
|
|
|
{item.children}
|
|
|
|
</GroupButton>
|
|
|
|
)}
|
2019-07-31 11:43:05 +00:00
|
|
|
</GroupMenuWrapper>
|
2019-08-22 08:05:03 +00:00
|
|
|
{moreItems.length > 0 &&
|
2019-11-05 11:28:44 +00:00
|
|
|
<GroupButton
|
|
|
|
id="moreMenu"
|
2019-08-22 08:05:03 +00:00
|
|
|
isDropdown={true}
|
|
|
|
label={moreLabel}
|
|
|
|
>
|
|
|
|
{moreItems.map((item, i) =>
|
2019-07-30 11:17:19 +00:00
|
|
|
<DropDownItem
|
|
|
|
key={`moreNavItem-${i}`}
|
|
|
|
label={item.label}
|
2019-08-21 11:44:30 +00:00
|
|
|
disabled={item.disabled}
|
2020-08-11 08:03:29 +00:00
|
|
|
onClick={this.groupMoreMenuButtonClick}
|
|
|
|
data-index={i}
|
2019-07-30 11:17:19 +00:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</GroupButton>
|
2019-07-25 11:00:03 +00:00
|
|
|
}
|
2019-08-22 08:05:03 +00:00
|
|
|
<CloseButton title={closeTitle} onClick={this.closeMenu} />
|
2019-07-30 11:17:19 +00:00
|
|
|
</StyledGroupButtonsMenu>
|
|
|
|
);
|
|
|
|
}
|
2019-06-17 08:58:02 +00:00
|
|
|
}
|
|
|
|
|
2019-07-25 11:00:03 +00:00
|
|
|
GroupButtonsMenu.propTypes = {
|
2019-07-30 11:17:19 +00:00
|
|
|
onClick: PropTypes.func,
|
|
|
|
onClose: PropTypes.func,
|
|
|
|
onChange: PropTypes.func,
|
|
|
|
onSelect: PropTypes.func,
|
|
|
|
menuItems: PropTypes.array,
|
|
|
|
checked: PropTypes.bool,
|
|
|
|
selected: PropTypes.string,
|
|
|
|
visible: PropTypes.bool,
|
|
|
|
moreLabel: PropTypes.string,
|
|
|
|
closeTitle: PropTypes.string
|
2019-07-22 07:59:31 +00:00
|
|
|
}
|
|
|
|
|
2019-09-09 13:08:07 +00:00
|
|
|
GroupButtonsMenu.defaultProps = {
|
|
|
|
checked: false,
|
|
|
|
selected: 'Select',
|
2019-11-05 11:28:44 +00:00
|
|
|
visible: true,
|
2019-09-09 13:08:07 +00:00
|
|
|
moreLabel: 'More',
|
|
|
|
closeTitle: 'Close'
|
|
|
|
}
|
|
|
|
|
2019-06-17 08:58:02 +00:00
|
|
|
export default GroupButtonsMenu;
|