You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
1.6 KiB
React
55 lines
1.6 KiB
React
4 years ago
|
"use strict";
|
||
|
|
||
|
const React = require("react");
|
||
|
const { useDebounce } = require("@react-hook/debounce");
|
||
|
|
||
|
const MenuItemContext = require("../../contexts/menu-item");
|
||
|
const MenuPositionContext = require("../../contexts/menu-position");
|
||
|
const useTheme = require("../../util/themeable");
|
||
|
const defaultStyle = require("./style.css");
|
||
|
|
||
|
// FIXME: Use flexbox to deal with overflow of long menus
|
||
|
|
||
|
module.exports = function Menu({ children }) {
|
||
|
let { withTheme } = useTheme({ control: "menu", defaultStyle });
|
||
|
let parentItemContext = React.useContext(MenuItemContext);
|
||
|
let menuPosition = React.useContext(MenuPositionContext);
|
||
|
// FIXME: We don't want a debounce, but a delay timer for submenu (dis)appearance? Separate from hover effect for the menu item itself. Debounce is insufficient because if one keeps moving the submenu never disappears
|
||
|
let [ selectedItem, setSelectedItem ] = useDebounce([], 150);
|
||
|
|
||
|
let itemContext = {
|
||
|
menuType: "menu",
|
||
|
selectedPath: selectedItem,
|
||
|
isActive: parentItemContext.isActive,
|
||
|
onMouseEnter: (path) => {
|
||
|
setSelectedItem(path);
|
||
|
},
|
||
|
onClick: (path, hasMenu, _isInMenu) => {
|
||
|
// Items with submenus should not be considered clickable
|
||
|
if (!hasMenu) {
|
||
|
parentItemContext.onClick(path, false, true);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// FIXME: Is there ever a case where this *can* validly be null?
|
||
|
let style = (menuPosition != null)
|
||
|
? {
|
||
|
left: menuPosition.x,
|
||
|
top: menuPosition.y
|
||
|
}
|
||
|
: null;
|
||
|
|
||
|
if (parentItemContext.isActive) {
|
||
|
return (
|
||
|
<MenuItemContext.Provider value={itemContext}>
|
||
|
<div className={withTheme("menu")} style={style}>
|
||
|
{children}
|
||
|
</div>
|
||
|
</MenuItemContext.Provider>
|
||
|
);
|
||
|
} else {
|
||
|
return null;
|
||
|
}
|
||
|
};
|