Skip to content

Instantly share code, notes, and snippets.

@chulanovskyi
Last active April 14, 2019 20:06
Show Gist options
  • Save chulanovskyi/d04a6f43773e9b2fbb7c8ed0d190025d to your computer and use it in GitHub Desktop.
Save chulanovskyi/d04a6f43773e9b2fbb7c8ed0d190025d to your computer and use it in GitHub Desktop.
useMenu hook
import { useState, useEffect } from 'react';
import * as React from 'react';
function useMenu<T extends HTMLElement>(
containerRef: React.RefObject<T>,
initState?: boolean
): {
isOpen: boolean;
onCloseMenu(): void;
onClickMenu(event: React.SyntheticEvent): void;
};
function useMenu(containerRef, initState) {
const [isOpen, setIsOpen] = useState(initState);
// clean up listener before component unmount
useEffect(() => () => document.removeEventListener('mousedown', onClickMenu), []);
useEffect(() => {
if (isOpen) {
document.addEventListener('mousedown', onClickMenu);
}
}, [isOpen]);
const onClickMenu = e => {
/** TODO: figure out, is it possible to not to handle the opening login outside
* i.e. :
* <div
* ref={containerRef}
* onClick={e => {
* !isOpen && onClickMenu(e);
* }}
* />
*
* this is required, to be able to use `onCloseMenu` function
*/
if (containerRef.current.contains(e.target)) {
setIsOpen(true);
return;
}
onCloseMenu();
};
// export this to be able to close menu after clicking inside container
const onCloseMenu = () => {
document.removeEventListener('mousedown', onClickMenu);
setIsOpen(false);
};
return { isOpen, onCloseMenu, onClickMenu };
}
export default useMenu;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment