From fdb5d399bfaf4c2853b5197518c1b830eaade68d Mon Sep 17 00:00:00 2001 From: Jan Hassel Date: Mon, 30 Nov 2020 15:04:11 +0100 Subject: [PATCH] feat(context-menu): add props.onClose --- .../ContextMenu/ContextMenu-story.js | 10 +++- .../src/components/ContextMenu/ContextMenu.js | 52 ++++++++++++------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/react/src/components/ContextMenu/ContextMenu-story.js b/packages/react/src/components/ContextMenu/ContextMenu-story.js index 3c724d330cb4..d5dc6536e267 100644 --- a/packages/react/src/components/ContextMenu/ContextMenu-story.js +++ b/packages/react/src/components/ContextMenu/ContextMenu-story.js @@ -23,7 +23,7 @@ export default { }; export const _ContextMenu = () => { - const [open, setOpen] = useState(true); + const [open, setOpen] = useState(false); const [position, setPosition] = useState([0, 0]); function openContextMenu(e) { @@ -44,7 +44,13 @@ export const _ContextMenu = () => { }); return ( - + { + setOpen(false); + }}> {}, ...rest }) { const rootRef = useRef(null); const [shouldReverse, setShouldReverse] = useState(false); + const isRootMenu = open !== undefined; function resetFocus() { Array.from( - rootRef?.current?.querySelectorAll('[tabindex="0"]') ?? [] + rootRef?.current?.element.querySelectorAll('[tabindex="0"]') ?? [] ).forEach((node) => { node.tabIndex = -1; }); } - function focusNode(node, focus = true) { + function focusNode(node) { if (node) { resetFocus(); node.tabIndex = 0; - - if (focus) { - node.focus(); - } + node.focus(); } } function getValidNodes(list) { - const nodes = Array.from(list.childNodes ?? []).reduce((acc, child) => { + const nodes = Array.from(list?.childNodes ?? []).reduce((acc, child) => { if (child.tagName === 'LI') { return [...acc, child]; } @@ -100,6 +100,10 @@ const ContextMenu = function ContextMenu({ function handleKeyDown(event) { event.stopPropagation(); + if (match(event, keys.Escape)) { + onClose(); + } + const currentNode = event.target.parentNode; let nodeToFocus; @@ -120,8 +124,12 @@ const ContextMenu = function ContextMenu({ } } + function handleClickOutside() { + onClose(); + } + function willFit() { - if (rootRef?.current) { + if (rootRef?.current?.element) { const bodyWidth = document.body.clientWidth; const reverseMap = [...Array(level)].reduce( @@ -151,10 +159,10 @@ const ContextMenu = function ContextMenu({ } useEffect(() => { - const topLevelNodes = getValidNodes(rootRef?.current); + const topLevelNodes = getValidNodes(rootRef?.current?.element); if (topLevelNodes && topLevelNodes.length > 0) { - focusNode(topLevelNodes[0].firstChild, false); + focusNode(topLevelNodes[0].firstChild); } setShouldReverse(!willFit()); @@ -183,15 +191,16 @@ const ContextMenu = function ContextMenu({ }); return ( -
    - {options} -
+ +
    + {options} +
+
); }; @@ -206,6 +215,11 @@ ContextMenu.propTypes = { */ level: PropTypes.number, + /** + * Function called when the menu is closed + */ + onClose: PropTypes.func, + /** * Specify whether the ContextMenu is currently open */