import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { cloneElement, useRef } from 'react';
import Box from '../box';
import { KeyboardKeys, vui } from '../core';
import FocusLock from '../focusLock';
import Portal from '../portal';
import { callAll, cs, mergeRefs } from '../utils';
import { ModalProvider } from './context';
import ModalBackdrop from './modalBackdrop';
import ModalContent from './modalContent';
import { manager, useModalManager } from './modalManager';
/**
 * Displays provided content on top of a dark backdrop element with fixed position.
 * By default uses Portal for content and closes when clicking backdrop or pressing 'Escape'.
 * Uses focus and scroll lock to achieve proper accessibility.
 * More about accessibility: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/dialog_role
 */
export const Modal = vui((props, ref) => {
    const { allowPinchZoom, animation = 'fadeDown', children, className, contentProps, disableAutoFocus, disableBackdropClose, disableEscClose, disablePortal, disableReturnFocus, disableScrollLock, disableTrapFocus, finalFocusRef, hideBackdrop, initialFocusRef, isOpen, onBackdropClick: onBackdropClickProp, onClose, onEsc, preserveScrollBar, size, variant, ...rest } = props;
    const modalRef = useRef(null);
    const mouseDownTarget = useRef(null);
    useModalManager(modalRef, isOpen, disableScrollLock);
    if (!isOpen)
        return null;
    const onBackdropClick = (e) => {
        e.stopPropagation();
        // Avoid closing modal when click starts inside the content and is released outside
        if (mouseDownTarget.current !== e.target)
            return;
        if (!manager.isTopModal(modalRef))
            return;
        if (!disableBackdropClose) {
            onClose?.();
            onBackdropClickProp?.(e);
        }
    };
    const onKeyDown = (e) => {
        if (e.key === KeyboardKeys.Escape) {
            e.stopPropagation();
            !disableEscClose && onClose?.();
            onEsc?.();
        }
    };
    const onMouseDown = (e) => (mouseDownTarget.current = e.target);
    const childProps = {
        onClick: (e) => {
            e.stopPropagation();
            children?.props?.onClick?.(e);
        },
        tabIndex: children?.props?.tabIndex ?? -1,
    };
    const context = { isOpen, onBackdropClick, onClose, size, variant };
    return (_jsx(ModalProvider, { value: context, children: _jsx(Portal, { disablePortal: disablePortal, children: _jsxs(Box, { className: cs('vui-modal', className), ref: mergeRefs(ref, modalRef), ...rest, onKeyDown: callAll(props.onKeyDown, onKeyDown), onMouseDown: callAll(props.onMouseDown, onMouseDown), children: [!hideBackdrop && _jsx(ModalBackdrop, {}), _jsx(FocusLock, { autoFocus: !disableAutoFocus, finalFocusRef: finalFocusRef, initialFocusRef: initialFocusRef, isDisabled: disableTrapFocus, returnFocus: !disableReturnFocus, children: _jsx(ModalContent, { animation: animation, ...contentProps, children: cloneElement(children, childProps) }) })] }) }) }));
});
Modal.Backdrop = ModalBackdrop;
Modal.Content = ModalContent;
Modal.displayName = 'Modal';
export default Modal;
//# sourceMappingURL=modal.js.map