import React, { useCallback, useRef } from 'react' import { createPortal } from 'react-dom' import FocusTrap from 'focus-trap-react' import { dialogBoxTheme } from './dialogbox.theme' /* Import components here */ import { Body, Close, CloseIcon, Footer, Header, StyledCloseButton, StyledDialogBox, Overlay as StyledOverlay, TopSection, } from './dialogbox.styles' /* Import interfaces here */ import { DialogBoxProps, FooterProps } from './dialogbox.interfaces' /* Import utilities here */ const CloseButton = ({ onClick }: { onClick: () => void }): JSX.Element => ( Close ) /** * * Overlay is used as an clickable overlay */ const Overlay = (props: { className?: string onClick: () => void children: React.ReactChild | React.ReactChild[] }): JSX.Element => { const { className, children /*onClick*/ } = props const ref = useRef(null) const clickStatusRef = useRef(false) const handleMouseDown = useCallback((e: React.MouseEvent) => { if (e.target === ref.current) { clickStatusRef.current = true } }, []) const handleMouseUp = useCallback((e: React.MouseEvent) => { try { if (e.target === ref.current && clickStatusRef.current) { // TODO: Fix correct clickAway // onClick() } } finally { clickStatusRef.current = false } }, []) return ( {children} ) } const focusTrapOptions = { clickOutsideDeactivates: false } export const DialogBox = ({ className, children, hasBackdrop = true, onClose, show: showProp, showCloseButton = true, header, footer, inPortal: inPortalProp = true, }: DialogBoxProps): JSX.Element | React.ReactPortal | null => { const show = showProp === undefined ? true : showProp const inPortal = inPortalProp === undefined ? true : inPortalProp const handleClose = useCallback(() => { if (onClose) onClose() }, [onClose]) const innerDialog = ( {showCloseButton && } {header &&
{header}
}
{children} {footer}
) const outerDialog = {innerDialog} const dialog = hasBackdrop ? outerDialog : innerDialog if (show) { return inPortal ? createPortal(dialog, document.body) : dialog } return null } const DialogFooter = ({ children, justify: justifyProp }: FooterProps): JSX.Element => { // Let justify default on "evenly" if there is only one child const justify = React.Children.count(children) === 1 ? justifyProp || 'evenly' : justifyProp return } DialogBox.Footer = DialogFooter DialogBox.defaultTheme = dialogBoxTheme