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