import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useRef, useEffect, useLayoutEffect } from 'react';
import styled from 'styled-components';
import { useConsolidatedRef, useContentTabIndex, useEscape, useI18n, useOuterEvent, useUID } from '../../hooks';
import { getActiveElement, getFocusables } from '../../utils';
import Button from '../Button';
import Text from '../Text';
import Progress from '../Progress';
import Flex from '../Flex';
import { StyledChildrenWrap, StyledDialogContent, StyledDialogFooter, StyledDialogHeader } from './Dialog.styles';
import Dialog from './Dialog';
export const StyledFormDialog = styled(Dialog) ``;
const FormDialog = forwardRef(function FormDialog({ arrow = true, target, heading, 'aria-label': ariaLabel, children, progress, onDismiss, onCancel, onSubmit, ...restProps }, ref) {
    const t = useI18n();
    const headingId = useUID();
    const dialogRef = useConsolidatedRef(ref);
    const dialogContentRef = useRef(null);
    const cancelButtonRef = useRef(null);
    const contentTabIndex = useContentTabIndex(dialogRef, dialogContentRef, [cancelButtonRef], [progress]);
    const setFocus = () => {
        if (progress)
            return;
        const focusables = getFocusables(dialogRef);
        const focusable = focusables.find(el => {
            return dialogContentRef.current?.contains(el);
        }) ??
            cancelButtonRef.current ??
            focusables[0];
        focusable?.focus();
    };
    const onCancelHandler = typeof onCancel === 'function' ? onCancel : onCancel.handler;
    useEscape(e => {
        if (onDismiss) {
            onDismiss();
        }
        else {
            onCancelHandler();
        }
        e.stopPropagation();
    }, dialogRef, [onDismiss, onCancelHandler]);
    useOuterEvent('mousedown', [target, dialogRef], () => {
        if (onDismiss) {
            onDismiss();
        }
        else {
            onCancelHandler();
        }
    });
    // Using layout effect to capture the focused element prior to dialog elements taking focus.
    useLayoutEffect(() => {
        const initiatorElement = getActiveElement();
        return () => {
            if (initiatorElement instanceof HTMLElement && initiatorElement.isConnected) {
                initiatorElement.focus();
            }
        };
    }, []);
    useEffect(() => {
        if (!progress) {
            setFocus();
        }
    }, [progress]);
    useEffect(() => {
        const closeDialog = () => {
            setTimeout(() => {
                if (onDismiss) {
                    onDismiss();
                }
                else {
                    onCancelHandler();
                }
                // The 0 timeout ensures that the dialog will not re-open immediately after the close event is triggered.
            }, 0);
        };
        target.addEventListener('click', closeDialog);
        return () => {
            target.removeEventListener('click', closeDialog);
        };
    }, []);
    return (_jsxs(StyledFormDialog, { ...restProps, ...(heading === undefined
            ? { 'aria-label': ariaLabel }
            : { 'aria-labelledby': headingId }), arrow: arrow, target: target, progress: progress, ref: dialogRef, children: [heading !== undefined && (_jsx(Flex, { container: { alignItems: 'center', justify: 'between', pad: 2 }, item: { shrink: 0 }, as: StyledDialogHeader, children: _jsx(Text, { id: headingId, variant: 'h2', children: heading }) })), _jsxs(Flex, { item: { grow: 1 }, as: StyledDialogContent, ref: dialogContentRef, tabIndex: contentTabIndex, children: [children && (_jsx(StyledChildrenWrap, { inert: progress ? '' : undefined, children: children })), _jsx(Progress, { visible: !!progress, focusOnVisible: true, placement: 'local', message: typeof progress === 'string' ? progress : undefined })] }), _jsxs(Flex, { container: { alignItems: 'center', justify: 'between', pad: 2 }, item: { shrink: 0 }, as: StyledDialogFooter, children: [_jsx(Button, { onClick: () => {
                            onCancelHandler();
                        }, disabled: typeof onCancel !== 'function' ? onCancel.disabled : undefined, ref: cancelButtonRef, children: typeof onCancel !== 'function' && onCancel.text ? onCancel.text : t('cancel') }), _jsx(Button, { variant: 'primary', onClick: () => {
                            (typeof onSubmit !== 'function' ? onSubmit.handler : onSubmit)();
                        }, disabled: typeof onSubmit !== 'function' ? onSubmit.disabled : undefined, children: typeof onSubmit !== 'function' && onSubmit.text ? onSubmit.text : t('submit') })] })] }));
});
export default FormDialog;
//# sourceMappingURL=FormDialog.js.map