import React, { useCallback, useRef } from 'react'; import { useDialogContext } from './dialog.context'; import { DialogOverlay } from './dialog-overlay'; import { DialogContentBase, DialogContentBaseProps, } from './dialog-content-base'; /*-- Types --*/ type BaseDialogContentProps = Omit< DialogContentBaseProps, 'onPointerDownOutside' | 'onEscapeKeyDown' | 'isScrollable' | 'modal' >; type OnPointerDownOutside = NonNullable< DialogContentBaseProps['onPointerDownOutside'] >; type OnEscapeKeyDown = NonNullable; type OnClickOverlay = NonNullable; export interface DialogContentProps extends BaseDialogContentProps { /** * Specifies where scroll should be on content overflow: * - `outside` - scroll is on the whole container (overlay). * - `inside` - scroll is on Dialog.Body. * */ scroll?: 'inside' | 'outside'; /** Defines whether Dialog should be closed on clicking overlay. */ closeOnOverlayClick?: boolean; /** Defines whether Dialog should be closed on pressing `Esc`. */ closeOnEsc?: boolean; onEsc?: OnEscapeKeyDown; onOverlayClick?: OnClickOverlay; children?: React.ReactNode; } /*-- Main --*/ export const DialogContent = React.forwardRef< HTMLDivElement, DialogContentProps >(function DialogContent( { children, scroll = 'outside', closeOnOverlayClick = true, closeOnEsc = true, onEsc, onOverlayClick, forceMount, ...rest }, ref, ) { const { modal, setOpen } = useDialogContext(); const overlayRef = useRef(null); const onPointerDownOutside: OnPointerDownOutside = useCallback(event => { event.preventDefault(); }, []); const onEscapeKeyDown: OnEscapeKeyDown = useCallback( event => { if (!closeOnEsc) { event.preventDefault(); } onEsc && onEsc(event); }, [closeOnEsc, onEsc], ); const handleOverlayClick: OnClickOverlay = useCallback( event => { if (event.target !== overlayRef.current) { return; } if (closeOnOverlayClick) { setOpen(false); } onOverlayClick && onOverlayClick(event); }, [setOpen, closeOnOverlayClick, onOverlayClick], ); const contentUi = ( {children} ); return modal ? ( {contentUi} ) : ( contentUi ); });