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
JavaScript

"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;
}
};