UNPKG

@adaptabletools/adaptable

Version:

Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

120 lines (119 loc) 5.31 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from 'react'; import { cn } from '../../lib/utils'; import { useRef, useEffect } from 'react'; import contains from '../utils/contains'; import captureTabNavigation from '../utils/captureTabNavigation'; import { Modal } from '../Modal'; import useIsOpen from './useIsOpen'; import useAutoFocus from '../utils/useAutoFocus'; import { Icon } from '../icons'; import { WindowModal } from '../WindowModal'; import { Box } from '../Flex'; import { targetOwn } from '../twUtils'; const baseClassName = 'ab-Dialog'; export const Dialog = React.forwardRef((props, dialogRef) => { let { modal, fixed, focusOnBrowserVisible = false, autoFocus = true, className, children, modalProps, dismissOnClickOutside = false, onDismiss, windowModal, windowModalProps, showCloseButton = true, isOpen: _isOpenProp, ...boxProps } = props; modal = props.modal === undefined ? true : props.modal; fixed = props.fixed === undefined ? true : props.fixed; const [isOpen, setIsOpen] = useIsOpen(props); const boxRef = useRef(null); useAutoFocus({ isOpen, autoFocus: props.autoFocus, previous: ({ autoFocus }) => autoFocus && isOpen, shouldFocus: ({ autoFocus }) => autoFocus && isOpen, }, boxRef); const onKeyDown = (e) => { if (props.onKeyDown) { props.onKeyDown(e); } captureTabNavigation(boxRef.current, e); if (e.key === 'Escape') { if (e.nativeEvent.anotherModalClosed) { return; } e.nativeEvent.anotherModalClosed = true; const activeElement = document.activeElement; const ignoreTags = { input: 1, a: 1, button: 1, }; if (activeElement && !!ignoreTags[activeElement.tagName]) { return; } setIsOpen(false); } captureTabNavigation(boxRef.current, event); }; useEffect(() => { if (dismissOnClickOutside && isOpen) { const dismissDialog = (e) => { requestAnimationFrame(() => { if (e.preventDialogDismiss) { return; } setIsOpen(false); }); }; document.documentElement.addEventListener('click', dismissDialog, { passive: true, capture: false, }); return () => { document.documentElement.removeEventListener('click', dismissDialog); }; } }, [isOpen, dismissOnClickOutside]); const bringToFront = React.useCallback(() => { if (boxRef.current && boxRef.current.focus && (!document.activeElement || !contains(boxRef.current, document.activeElement))) { boxRef.current.focus(); } }, [boxRef]); React.useImperativeHandle(dialogRef, () => ({ bringToFront, })); useEffect(() => { let listener; if (focusOnBrowserVisible) { listener = () => { if (document.visibilityState === 'visible' && autoFocus && focusOnBrowserVisible) { bringToFront(); } }; document.addEventListener('visibilitychange', listener); } return () => { if (listener) { document.removeEventListener('visibilitychange', listener); } }; }, [autoFocus, focusOnBrowserVisible]); if (!isOpen) { return null; } const closeButton = showCloseButton ? (_jsx(Box, { title: "Close dialog", onClick: () => setIsOpen(false), className: cn(`${baseClassName}__close-button twa:p-1`, 'twa:text-accentlight', 'twa:text-shadow-[0_1px_0_#fff]', `twa:text-3 twa:cursor-pointer twa:leading-none twa:font-bold`, 'twa:absolute twa:top-[6px] twa:right-[6px]'), children: _jsx(Icon, { size: 20, name: "close" }) })) : null; const setPreventDismissFlag = (e) => { if (dismissOnClickOutside) { e.nativeEvent.preventDialogDismiss = true; } }; const box = (_jsxs(Box, { ...boxProps, onClick: (e) => { setPreventDismissFlag(e); if (boxProps && boxProps.onClick) { boxProps.onClick(e); } }, onKeyDown: onKeyDown, className: cn('twa:relative', 'twa:bg-background', 'twa:text-foreground', 'twa:fill-foreground', 'twa:rounded-standard', 'twa:flex twa:flex-col', targetOwn.focusOutline, targetOwn.focusWithinOutline, baseClassName, modal ? `${baseClassName}--modal` : `${baseClassName}--not-modal`, className), ref: boxRef, children: [children, closeButton] })); const content = fixed ? (_jsx("div", { onClick: setPreventDismissFlag, className: cn(`${baseClassName}-fixed-wrapper`, 'twa:fixed twa:inset-0', 'twa:m-auto', 'twa:flex twa:items-center twa:justify-center'), children: box })) : (box); if (windowModal) { return _jsx(WindowModal, { ...windowModalProps, children: content }); } if (modal) { return (_jsx(Modal, { ...modalProps, isOpen: isOpen, onBringToFront: bringToFront, children: box })); } return content; }); export default Dialog;