uui-components/src/overlays/ModalBlocker.tsx (49 lines of code) (raw):

import React, { useContext, useEffect } from 'react'; import FocusLock from 'react-focus-lock'; import css from './ModalBlocker.module.scss'; import { ModalBlockerProps, UuiContext, cx, uuiElement } from '@epam/uui-core'; export const ModalBlocker = React.forwardRef<HTMLDivElement, ModalBlockerProps>((props, ref) => { const context = useContext(UuiContext); useEffect(() => { let unsubscribeFromRouter: () => void | null = null; document.body.style.overflow = 'hidden'; !props.disableCloseByEsc && window.addEventListener('keydown', keydownHandler); if (!props.disableCloseOnRouterChange) { unsubscribeFromRouter = context.uuiRouter.listen(() => { urlChangeHandler(); }); } return () => { !props.disableCloseByEsc && window.removeEventListener('keydown', keydownHandler); if (!context.uuiModals.getOperations().length) { document.body.style.overflow = 'visible'; } if (unsubscribeFromRouter) { unsubscribeFromRouter(); } }; }, []); const urlChangeHandler = () => { !props.disableCloseOnRouterChange && context.uuiModals.closeAll(); }; const keydownHandler = (e: KeyboardEvent) => { if (e.key === 'Escape') { props.abort(); } }; const handleBlockerClick = () => { if (!props.disallowClickOutside) { props.abort(); } }; return ( <div className={ cx(css.container, props.cx) } style={ { zIndex: props.zIndex } } ref={ ref } { ...props.rawProps }> <div className={ uuiElement.modalBlocker } onClick={ handleBlockerClick } aria-label="Click to close a modal" /> <FocusLock autoFocus={ true } returnFocus={ { preventScroll: true } } disabled={ props.disableFocusLock }> {props.children} </FocusLock> </div> ); });