2020-10-14 14:38:20 +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";
|
|
|
|
import throttle from "lodash/throttle";
|
|
|
|
import { isArrayEqual } from "../../utils/array";
|
2020-11-09 09:24:40 +00:00
|
|
|
import { tablet, desktop } from "../../utils/device";
|
2019-06-17 08:58:02 +00:00
|
|
|
|
|
|
|
const StyledGroupButtonsMenu = styled.div`
|
2020-10-14 14:38:20 +00:00
|
|
|
box-sizing: border-box;
|
|
|
|
position: sticky;
|
2020-11-09 09:24:40 +00:00
|
|
|
top: 1px;
|
2020-10-14 14:38:20 +00:00
|
|
|
background: #ffffff;
|
|
|
|
box-shadow: 0px 10px 18px -8px rgba(0, 0, 0, 0.100306);
|
2020-11-03 13:58:02 +00:00
|
|
|
height: 56px;
|
2020-10-14 14:38:20 +00:00
|
|
|
list-style: none;
|
|
|
|
padding: 0 18px 19px 0;
|
2020-10-30 11:21:56 +00:00
|
|
|
width: 100%;
|
2020-10-14 14:38:20 +00:00
|
|
|
white-space: nowrap;
|
2020-11-09 09:24:40 +00:00
|
|
|
|
2020-10-16 13:16:01 +00:00
|
|
|
display: ${(props) => (props.visible ? "block" : "none")};
|
2020-10-14 14:38:20 +00:00
|
|
|
z-index: 189;
|
2020-11-09 09:24:40 +00:00
|
|
|
|
|
|
|
@media ${desktop} {
|
|
|
|
margin-top: 1px;
|
|
|
|
}
|
2019-06-17 08:58:02 +00:00
|
|
|
`;
|
|
|
|
|
2019-06-25 15:01:04 +00:00
|
|
|
const CloseButton = styled.div`
|
2020-10-14 14:38:20 +00:00
|
|
|
position: absolute;
|
2020-11-03 13:58:02 +00:00
|
|
|
right: 11px;
|
2020-10-14 14:38:20 +00:00
|
|
|
top: 10px;
|
|
|
|
width: 20px;
|
|
|
|
height: 20px;
|
|
|
|
padding: 8px;
|
|
|
|
|
|
|
|
@media ${tablet} {
|
2020-11-03 13:58:02 +00:00
|
|
|
right: 3px;
|
2020-10-14 14:38:20 +00:00
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
&:hover {
|
|
|
|
cursor: pointer;
|
2019-12-26 09:17:35 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
&:before,
|
|
|
|
&:after {
|
|
|
|
background-color: #555f65;
|
2019-06-25 15:01:04 +00:00
|
|
|
}
|
2020-10-14 14:38:20 +00:00
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
&:before,
|
|
|
|
&:after {
|
|
|
|
position: absolute;
|
|
|
|
left: 15px;
|
|
|
|
content: " ";
|
|
|
|
height: 20px;
|
|
|
|
width: 1px;
|
|
|
|
background-color: #d0d5da;
|
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
&:before {
|
|
|
|
transform: rotate(45deg);
|
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
&:after {
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
}
|
2019-06-25 15:01:04 +00:00
|
|
|
`;
|
|
|
|
|
2019-07-31 11:43:05 +00:00
|
|
|
const GroupMenuWrapper = styled.div`
|
|
|
|
display: inline-block;
|
|
|
|
`;
|
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
class GroupButtonsMenu extends React.Component {
|
2019-07-30 11:17:19 +00:00
|
|
|
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: [],
|
2020-10-16 13:16:01 +00:00
|
|
|
visible: props.visible,
|
2020-10-14 14:38:20 +00:00
|
|
|
};
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2020-10-30 11:21:56 +00:00
|
|
|
this.throttledResize = throttle(this.updateMenu, 200);
|
2019-07-30 11:17:19 +00:00
|
|
|
}
|
2019-07-25 11:00:03 +00:00
|
|
|
|
2020-10-16 13:16:01 +00:00
|
|
|
closeMenu = (e) => {
|
2019-07-31 11:43:05 +00:00
|
|
|
this.setState({ visible: false });
|
|
|
|
this.props.onClose && this.props.onClose(e);
|
|
|
|
};
|
|
|
|
|
2020-10-16 13:16:01 +00:00
|
|
|
groupButtonClick = (e) => {
|
2020-08-11 08:03:29 +00:00
|
|
|
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);
|
|
|
|
};
|
|
|
|
|
2020-10-16 13:16:01 +00:00
|
|
|
groupMoreMenuButtonClick = (e) => {
|
2020-08-11 08:03:29 +00:00
|
|
|
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
|
|
|
|
2020-10-16 13:16:01 +00:00
|
|
|
this.widthsArray = groupMenuItemsArray.map((item) => item.offsetWidth);
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
window.addEventListener("resize", this.throttledResize);
|
|
|
|
window.addEventListener("orientationchange", 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)) {
|
2020-10-14 14:38:20 +00:00
|
|
|
this.setState({ priorityItems: this.props.menuItems });
|
2019-11-05 11:28:44 +00:00
|
|
|
}
|
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
if (
|
2020-10-30 11:21:56 +00:00
|
|
|
this.props.sectionWidth !== prevProps.sectionWidth ||
|
2020-10-14 14:38:20 +00:00
|
|
|
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) => {
|
2020-10-14 14:38:20 +00:00
|
|
|
const itemsArray = array || [];
|
2020-11-03 13:58:02 +00:00
|
|
|
let total = (moreWidth || 0) + 10;
|
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 = () => {
|
2020-10-30 11:21:56 +00:00
|
|
|
const { sectionWidth } = this.props;
|
|
|
|
let groupMenuOuterWidth = sectionWidth;
|
|
|
|
|
|
|
|
if (!sectionWidth) {
|
|
|
|
const groupMenuOuterElement = document.getElementById("groupMenuOuter");
|
|
|
|
const groupMenuOuterValues =
|
|
|
|
groupMenuOuterElement && groupMenuOuterElement.getBoundingClientRect();
|
|
|
|
const screenWidth = window.innerWidth;
|
|
|
|
const xWidth = groupMenuOuterValues && groupMenuOuterValues.x;
|
|
|
|
groupMenuOuterWidth = screenWidth - xWidth;
|
|
|
|
}
|
2019-07-30 11:17:19 +00:00
|
|
|
const moreMenuElement = document.getElementById("moreMenu");
|
2020-10-14 14:38:20 +00:00
|
|
|
const moreMenuWidth =
|
|
|
|
moreMenuElement && moreMenuElement.getBoundingClientRect().width;
|
|
|
|
const visibleItemsCount = this.countMenuItems(
|
|
|
|
this.widthsArray,
|
|
|
|
groupMenuOuterWidth,
|
|
|
|
moreMenuWidth
|
|
|
|
);
|
2019-08-22 08:05:03 +00:00
|
|
|
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);
|
2020-10-14 14:38:20 +00:00
|
|
|
const moreItems =
|
|
|
|
priorityItems.length !== navItemsCopy.length
|
|
|
|
? navItemsCopy.slice(visibleItemsCount, navItemsCopy.length)
|
|
|
|
: [];
|
2019-07-30 11:17:19 +00:00
|
|
|
|
|
|
|
this.setState({
|
|
|
|
priorityItems: priorityItems,
|
2020-08-18 10:20:06 +00:00
|
|
|
moreItems: moreItems,
|
2019-07-30 11:17:19 +00:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
2020-10-14 14:38:20 +00:00
|
|
|
window.removeEventListener("resize", this.throttledResize);
|
|
|
|
window.removeEventListener("orientationchange", this.throttledResize);
|
2019-07-30 11:17:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
//console.log("GroupButtonsMenu render");
|
2020-10-14 14:57:38 +00:00
|
|
|
const {
|
|
|
|
selected,
|
|
|
|
moreLabel,
|
|
|
|
closeTitle,
|
|
|
|
checked,
|
|
|
|
isIndeterminate,
|
2020-10-16 13:16:01 +00:00
|
|
|
onChange,
|
2020-10-14 14:57:38 +00:00
|
|
|
} = this.props;
|
2020-10-30 11:21:56 +00:00
|
|
|
const { priorityItems, moreItems, visible } = this.state;
|
2019-11-05 11:28:44 +00:00
|
|
|
|
2019-07-30 11:17:19 +00:00
|
|
|
return (
|
2020-10-30 11:21:56 +00:00
|
|
|
<StyledGroupButtonsMenu id="groupMenuOuter" visible={visible}>
|
2019-07-31 11:43:05 +00:00
|
|
|
<GroupMenuWrapper id="groupMenu">
|
2020-10-14 14:38:20 +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}
|
2020-10-14 14:38:20 +00:00
|
|
|
activated={item.activated}
|
2020-10-14 14:57:38 +00:00
|
|
|
checked={checked}
|
2020-10-14 14:38:20 +00:00
|
|
|
dropDownMaxHeight={item.dropDownMaxHeight}
|
|
|
|
hovered={item.hovered}
|
2020-10-14 14:57:38 +00:00
|
|
|
isIndeterminate={isIndeterminate}
|
|
|
|
onChange={onChange}
|
2020-10-14 14:38:20 +00:00
|
|
|
opened={item.opened}
|
2019-07-31 11:43:05 +00:00
|
|
|
>
|
2019-07-30 11:17:19 +00:00
|
|
|
{item.children}
|
|
|
|
</GroupButton>
|
2020-10-14 14:38:20 +00:00
|
|
|
))}
|
2019-07-31 11:43:05 +00:00
|
|
|
</GroupMenuWrapper>
|
2020-10-14 14:38:20 +00:00
|
|
|
{moreItems.length > 0 && (
|
|
|
|
<GroupButton id="moreMenu" 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
|
|
|
/>
|
2020-10-14 14:38:20 +00:00
|
|
|
))}
|
2019-07-30 11:17:19 +00:00
|
|
|
</GroupButton>
|
2020-10-14 14:38:20 +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,
|
2020-10-14 14:57:38 +00:00
|
|
|
isIndeterminate: PropTypes.bool,
|
2019-07-30 11:17:19 +00:00
|
|
|
selected: PropTypes.string,
|
|
|
|
visible: PropTypes.bool,
|
|
|
|
moreLabel: PropTypes.string,
|
2020-10-16 13:16:01 +00:00
|
|
|
closeTitle: PropTypes.string,
|
2020-10-30 11:21:56 +00:00
|
|
|
sectionWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
2020-10-14 14:38:20 +00:00
|
|
|
};
|
2019-07-22 07:59:31 +00:00
|
|
|
|
2019-09-09 13:08:07 +00:00
|
|
|
GroupButtonsMenu.defaultProps = {
|
|
|
|
checked: false,
|
2020-10-14 14:38:20 +00:00
|
|
|
selected: "Select",
|
2019-11-05 11:28:44 +00:00
|
|
|
visible: true,
|
2020-10-14 14:38:20 +00:00
|
|
|
moreLabel: "More",
|
2020-10-16 13:16:01 +00:00
|
|
|
closeTitle: "Close",
|
2020-10-14 14:38:20 +00:00
|
|
|
};
|
2019-09-09 13:08:07 +00:00
|
|
|
|
2020-10-14 14:38:20 +00:00
|
|
|
export default GroupButtonsMenu;
|