Files
react.dev/beta/src/components/useMenu.tsx
Rachel Nabors 981db3397e Initial check-in of new React docs and website
Co-authored-by: Dan Abramov <dan.abramov@me.com>
Co-authored-by: Sylwia Vargas <sylwia.vargas@gmail.com>
Co-authored-by: Dan Lebowitz <dan.lebo@me.com>
Co-authored-by: Razvan Gradinar <grazvan@fb.com>
Co-authored-by: Jared Palmer <jared@palmer.net>
Co-authored-by: Dane Grant <danecando@gmail.com>
Co-authored-by: Dustin Goodman <dustin.s.goodman@gmail.com>
Co-authored-by: Rick Hanlon <rickhanlonii@gmail.com>
Co-authored-by: Maggie Appleton <maggie.fm.appleton@gmail.com>
Co-authored-by: Alex Moldovan <alex.n.moldovan@gmail.com>
Co-authored-by: Ives van Hoorne <ives.v.h@gmail.com>
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
Co-authored-by: Dmitri Pavlutin <dpavlutin@gmail.com>
2021-10-28 21:33:41 +01:00

70 lines
1.6 KiB
TypeScript

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {
clearAllBodyScrollLocks,
disableBodyScroll,
enableBodyScroll,
} from 'body-scroll-lock';
import {useRouter} from 'next/router';
type SidebarNav = 'root' | 'docs' | 'reference';
/**
* Menu toggle that enables body scroll locking (for
* iOS Mobile and Tablet, Android, desktop Safari/Chrome/Firefox)
* without breaking scrolling of a target
* element.
*/
export const useMenu = () => {
const [isOpen, setIsOpen] = React.useState(false);
const menuRef = React.useRef<HTMLDivElement>(null);
const router = useRouter();
const showSidebar = React.useCallback(() => {
setIsOpen(true);
if (menuRef.current != null) {
disableBodyScroll(menuRef.current);
}
}, []);
const hideSidebar = React.useCallback(() => {
setIsOpen(false);
if (menuRef.current != null) {
enableBodyScroll(menuRef.current);
}
}, []);
const toggleOpen = React.useCallback(() => {
if (isOpen) {
hideSidebar();
} else {
showSidebar();
}
}, [showSidebar, hideSidebar, isOpen]);
React.useEffect(() => {
hideSidebar();
return () => {
clearAllBodyScrollLocks();
};
}, [router.pathname, hideSidebar]);
return {
hideSidebar,
showSidebar,
toggleOpen,
menuRef,
isOpen,
};
};
export const MenuContext = React.createContext<ReturnType<typeof useMenu>>(
{} as ReturnType<typeof useMenu>
);
export function MenuProvider(props: {children: React.ReactNode}) {
return <MenuContext.Provider value={useMenu()} {...props} />;
}