@grafana/ui
Version:
Grafana Components Library
65 lines (62 loc) • 2.08 kB
JavaScript
import { jsx } from 'react/jsx-runtime';
import * as React from 'react';
import { useRef, useState, useLayoutEffect } from 'react';
import { useClickAway } from 'react-use';
import { selectors } from '@grafana/e2e-selectors';
import { Menu } from '../Menu/Menu.mjs';
import { Portal } from '../Portal/Portal.mjs';
const ContextMenu = React.memo(
({ x, y, onClose, focusOnOpen = true, renderMenuItems, renderHeader }) => {
const menuRef = useRef(null);
const [positionStyles, setPositionStyles] = useState({});
useLayoutEffect(() => {
const menuElement = menuRef.current;
if (menuElement) {
const rect = menuElement.getBoundingClientRect();
const OFFSET = 5;
const collisions = {
right: window.innerWidth < x + rect.width,
bottom: window.innerHeight < y + rect.height + OFFSET
};
setPositionStyles({
position: "fixed",
left: collisions.right ? x - rect.width - OFFSET : x - OFFSET,
top: Math.max(0, collisions.bottom ? y - rect.height - OFFSET : y + OFFSET)
});
}
}, [x, y]);
useClickAway(menuRef, () => {
onClose == null ? void 0 : onClose();
});
const header = renderHeader == null ? void 0 : renderHeader();
const menuItems = renderMenuItems == null ? void 0 : renderMenuItems();
const onOpen = (setFocusedItem) => {
if (focusOnOpen) {
setFocusedItem(0);
}
};
const onKeyDown = (e) => {
if (e.key === "Escape") {
e.preventDefault();
e.stopPropagation();
onClose == null ? void 0 : onClose();
}
};
return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
Menu,
{
header,
ref: menuRef,
style: positionStyles,
ariaLabel: selectors.components.Menu.MenuComponent("Context"),
onOpen,
onClick: onClose,
onKeyDown,
children: menuItems
}
) });
}
);
ContextMenu.displayName = "ContextMenu";
export { ContextMenu };
//# sourceMappingURL=ContextMenu.mjs.map