'use strict';

var React = require('react');
var ReactDOM = require('react-dom');
var classnames = require('classnames');
var framerMotion = require('framer-motion');
var jobberHooks = require('@jobber/hooks');
var Heading = require('../Heading-cjs.js');
var Button = require('../Button-cjs.js');
var ButtonDismiss = require('../ButtonDismiss-cjs.js');
var noop = require('../noop-cjs.js');
var floatingUi_react = require('../floating-ui.react-cjs.js');
var identity = require('../identity-cjs.js');
var AtlantisPortalContent = require('../AtlantisPortalContent-cjs.js');
require('../Typography-cjs.js');
require('../tslib.es6-cjs.js');
require('react-router-dom');
require('../Icon-cjs.js');
require('@jobber/design');
require('../_commonjsHelpers-cjs.js');
require('../floating-ui.utils.dom-cjs.js');
require('../floating-ui.utils-cjs.js');
require('react/jsx-runtime');
require('../floating-ui.react-dom-cjs.js');
require('../isTypedArray-cjs.js');
require('../isObjectLike-cjs.js');
require('../AtlantisThemeContext-cjs.js');
require('../_baseAssignValue-cjs.js');
require('../_baseFor-cjs.js');
require('../keysIn-cjs.js');
require('../_isIterateeCall-cjs.js');
require('../_setToString-cjs.js');

var styles$1 = {"container":"y3M-9xoEnk0-","containerFullScreen":"IsN-kBe8icY-","overlay":"zkyJp1mib-U-","modal":"gMPgiggaud8-","header":"_5sBzUnyOqD0-","closeButton":"_4gw63G7IYG0-","actionBar":"cwVJrrJkNDg-","leftAction":"MkD4pNUKeAA-","rightAction":"C-yC8JKpQLg-","spinning":"_7hYqr6OrfHs-"};

var sizes = {"small":"BSZvIAUzFEU-","large":"-ydIALYVvGg-","fullScreen":"_9wD-TaKfDys-","spinning":"_10FfgKITqY0-"};

const MODAL_HEADER_ID = "ATL-Modal-Header";

function ModalLegacy({ open = false, title, size, dismissible = true, children, primaryAction, secondaryAction, tertiaryAction, onRequestClose, ariaLabel, }) {
    const modalClassName = classnames(styles$1.modal, size && sizes[size]);
    const containerClassName = classnames(styles$1.container, size === "fullScreen" && styles$1.containerFullScreen);
    jobberHooks.useRefocusOnActivator(open);
    const modalRef = jobberHooks.useFocusTrap(open);
    jobberHooks.useOnKeyDown(handleRequestClose, "Escape");
    const template = (React.createElement(framerMotion.AnimatePresence, null, open && (React.createElement("div", { ref: modalRef, role: "dialog", className: containerClassName, tabIndex: 0, "aria-modal": "true", "aria-labelledby": title ? MODAL_HEADER_ID : undefined, "aria-label": ariaLabel },
        React.createElement(framerMotion.motion.div, { key: styles$1.overlay, className: styles$1.overlay, onClick: onRequestClose, initial: { opacity: 0 }, animate: { opacity: 0.8 }, exit: { opacity: 0 }, transition: { duration: 0.2 } }),
        React.createElement(framerMotion.motion.div, { key: styles$1.modal, className: modalClassName, initial: { scale: 0.9, opacity: 0 }, animate: { scale: 1, opacity: 1 }, exit: { scale: 0.9, opacity: 0 }, transition: {
                duration: 0.2,
                ease: "easeInOut",
            } },
            title != undefined && (React.createElement(Header, { title: title, dismissible: dismissible, onRequestClose: onRequestClose })),
            children,
            React.createElement(Actions, { primary: primaryAction, secondary: secondaryAction, tertiary: tertiaryAction }))))));
    return (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document)
        ? ReactDOM.createPortal(template, document.body)
        : template;
    function handleRequestClose() {
        if (open && onRequestClose) {
            onRequestClose();
        }
    }
}
function Header({ title, dismissible, onRequestClose }) {
    return (React.createElement("div", { className: styles$1.header, "data-testid": "modal-header" },
        React.createElement(Heading.Heading, { level: 2, id: MODAL_HEADER_ID }, title),
        dismissible && (React.createElement("div", { className: styles$1.closeButton },
            React.createElement(ButtonDismiss.ButtonDismiss, { onClick: onRequestClose, ariaLabel: "Close modal" })))));
}
function Actions({ primary, secondary, tertiary }) {
    const shouldShow = primary != undefined || secondary != undefined || tertiary != undefined;
    if (secondary != undefined) {
        secondary = Object.assign({ type: "primary", variation: "subtle" }, secondary);
    }
    if (tertiary != undefined) {
        tertiary = Object.assign({ type: "secondary", variation: "destructive" }, tertiary);
    }
    return (React.createElement(React.Fragment, null, shouldShow && (React.createElement("div", { className: styles$1.actionBar },
        React.createElement("div", { className: styles$1.rightAction },
            primary && React.createElement(Button.Button, Object.assign({}, primary)),
            secondary && React.createElement(Button.Button, Object.assign({}, secondary))),
        tertiary && (React.createElement("div", { className: styles$1.leftAction },
            React.createElement(Button.Button, Object.assign({}, tertiary))))))));
}

function useModal({ open, activatorRef: refProp, onRequestClose, startedInsideRef, }) {
    const nodeId = floatingUi_react.useFloatingNodeId();
    const defaultActivatorRef = React.useRef(null);
    const activatorRef = refProp !== null && refProp !== void 0 ? refProp : defaultActivatorRef;
    const { refs: floatingRefs, context: floatingContext } = floatingUi_react.useFloating({
        elements: { reference: activatorRef === null || activatorRef === void 0 ? void 0 : activatorRef.current },
        nodeId,
        onOpenChange: (newOpen) => {
            if (!newOpen)
                onRequestClose === null || onRequestClose === void 0 ? void 0 : onRequestClose();
        },
        open: open,
    });
    React.useEffect(() => {
        if (!startedInsideRef)
            return;
        if (open) {
            // Ensure the first interaction after open is treated as inside
            startedInsideRef.current = true;
        }
        else {
            // Reset on close
            startedInsideRef.current = false;
        }
    }, [open, startedInsideRef]);
    const dismiss = floatingUi_react.useDismiss(floatingContext, {
        // Use pointerdown so the dialog/overlay capture handlers run first and set intent
        outsidePressEvent: "pointerdown",
        outsidePress: () => {
            var _a;
            const startedInside = (_a = startedInsideRef === null || startedInsideRef === void 0 ? void 0 : startedInsideRef.current) !== null && _a !== void 0 ? _a : true;
            return !startedInside;
        },
        escapeKey: true,
        bubbles: false,
    });
    const role = floatingUi_react.useRole(floatingContext);
    const { getFloatingProps } = floatingUi_react.useInteractions([dismiss, role]);
    const parentId = floatingUi_react.useFloatingParentNodeId();
    return {
        floatingRefs,
        floatingContext,
        nodeId,
        activatorRef,
        parentId,
        getFloatingProps,
    };
}

const ModalContext = React.createContext({
    open: false,
    onRequestClose: noop.noop,
    activatorRef: { current: null },
    floatingRefs: null,
    floatingContext: {},
    size: undefined,
    floatingNodeId: undefined,
    dismissible: true,
    getFloatingProps: identity.identity,
});
function ModalProvider({ children, open = false, size, onRequestClose = noop.noop, activatorRef: refProp, dismissible = true, modalLabelledBy = MODAL_HEADER_ID, ariaLabel, }) {
    const startedInsideRef = React.useRef(true);
    const { floatingRefs, floatingContext, nodeId, activatorRef, parentId, getFloatingProps, } = useModal({
        open,
        activatorRef: refProp,
        onRequestClose,
        startedInsideRef,
    });
    const content = (React.createElement(ModalContext.Provider, { value: {
            onRequestClose,
            activatorRef,
            floatingRefs,
            floatingContext,
            size,
            open,
            floatingNodeId: nodeId,
            dismissible,
            modalLabelledBy,
            ariaLabel,
            getFloatingProps,
            startedInsideRef,
        } }, children));
    if (parentId) {
        return content;
    }
    return React.createElement(floatingUi_react.FloatingTree, null, content);
}
function useModalContext() {
    return React.useContext(ModalContext);
}

var styles = {"overlay":"cRhQeXmZobs-","overlayBackground":"PO6ZUDxQoFE-","modal":"OiqCKNmbHZ0-","modalWithStickyRegions":"_6dGKr5VVf9Y-","stickyHeaderRegion":"uo6BCADQuLU-","stickyActionsRegion":"Vq0y9ggAxtI-","modalBody":"zM9SWwAd5Dg-","header":"GDWGHwmjgAc-","closeButton":"KJlGo4z-E6Q-","actionBar":"ZGrhWCAymCw-","leftAction":"hOiEWds2Vq8-","rightAction":"K31NzxPZP9s-","spinning":"SKeimJFlB-g-"};

function useModalStyles(size) {
    return {
        modal: classnames(styles.modal, size && sizes[size]),
        overlay: styles.overlay,
        header: styles.header,
        dismissButton: styles.closeButton,
        actionBar: styles.actionBar,
        leftAction: styles.leftAction,
        rightAction: styles.rightAction,
        overlayBackground: styles.overlayBackground,
    };
}

function ModalHeader({ title, children }) {
    const { header, dismissButton } = useModalStyles();
    const { dismissible, onRequestClose, modalLabelledBy } = useModalContext();
    if (children) {
        return React.createElement(React.Fragment, null, children);
    }
    return (React.createElement("div", { className: header, "data-testid": MODAL_HEADER_ID },
        React.createElement(Heading.Heading, { level: 2, id: modalLabelledBy }, title),
        dismissible && (React.createElement("div", { className: dismissButton },
            React.createElement(ButtonDismiss.ButtonDismiss, { onClick: onRequestClose, ariaLabel: "Close modal" })))));
}
function ModalActions({ primary, secondary, tertiary, }) {
    const { actionBar, rightAction, leftAction } = useModalStyles();
    const shouldShow = primary != undefined || secondary != undefined || tertiary != undefined;
    return (React.createElement(React.Fragment, null, shouldShow && (React.createElement("div", { className: actionBar, "data-testid": "ATL-Modal-Actions" },
        React.createElement("div", { className: rightAction },
            primary && React.createElement(Button.Button, Object.assign({}, primary)),
            secondary && (React.createElement(Button.Button, Object.assign({ type: "primary", variation: "subtle" }, secondary)))),
        tertiary && (React.createElement("div", { className: leftAction },
            React.createElement(Button.Button, Object.assign({ type: "secondary", variation: "destructive" }, tertiary))))))));
}
function ModalActivator({ children }) {
    const { activatorRef } = useModalContext();
    return (React.createElement("span", { ref: activatorRef, style: { display: "contents" } }, children));
}
/**
 * Background overlay for the modal. Used in the ModalContent.
 */
function ModalOverlay({ children }) {
    const { overlay, overlayBackground } = useModalStyles();
    const { floatingNodeId, startedInsideRef } = useModalContext();
    return (React.createElement(floatingUi_react.FloatingOverlay, { lockScroll: true, className: overlay, "data-modal-node-id": floatingNodeId },
        React.createElement(framerMotion.motion.div, { "aria-hidden": "true", className: overlayBackground, initial: { opacity: 0 }, animate: { opacity: 0.8 }, exit: { opacity: 0 }, transition: { duration: 0.2 }, "data-modal-node-id": floatingNodeId, onPointerDownCapture: () => {
                // Interaction began on overlay: mark as outside for the next click
                if (startedInsideRef)
                    startedInsideRef.current = false;
            } }),
        children));
}
function ModalContent({ children }) {
    const { open, floatingContext, activatorRef, floatingRefs, size, floatingNodeId, modalLabelledBy, ariaLabel, getFloatingProps, startedInsideRef, } = useModalContext();
    const { modal } = useModalStyles(size);
    const childrenArray = React.Children.toArray(children);
    const { sticky: stickyHeaders, rest: afterHeaders } = extractSticky(childrenArray, ModalHeader, props => props.variant === "sticky");
    const { sticky: stickyActions, rest: bodyChildren } = extractSticky(afterHeaders, ModalActions, props => props.variant === "sticky");
    const hasStickyRegions = stickyHeaders.length > 0 || stickyActions.length > 0;
    return (React.createElement(framerMotion.AnimatePresence, null, open && (React.createElement(floatingUi_react.FloatingNode, { id: floatingNodeId },
        React.createElement(floatingUi_react.FloatingPortal, null,
            React.createElement(AtlantisPortalContent.AtlantisPortalContent, null,
                React.createElement(ModalOverlay, null,
                    React.createElement(floatingUi_react.FloatingFocusManager, { context: floatingContext, returnFocus: (activatorRef === null || activatorRef === void 0 ? void 0 : activatorRef.current) ? activatorRef : true, order: ["floating", "content"] },
                        React.createElement(framerMotion.motion.div, Object.assign({ initial: { scale: 0.9, opacity: 0 }, animate: { scale: 1, opacity: 1 }, exit: { scale: 0.9, opacity: 0 }, transition: {
                                duration: 0.2,
                                ease: "easeInOut",
                            }, ref: floatingRefs === null || floatingRefs === void 0 ? void 0 : floatingRefs.setFloating, "data-modal-node-id": floatingNodeId }, getFloatingProps({
                            role: "dialog",
                            className: hasStickyRegions
                                ? `${modal} ${styles.modalWithStickyRegions}`
                                : modal,
                            "aria-labelledby": modalLabelledBy,
                            "aria-label": ariaLabel,
                            "aria-modal": true,
                        }), { onPointerDownCapture: () => {
                                // Interaction began inside dialog
                                if (startedInsideRef)
                                    startedInsideRef.current = true;
                            } }),
                            stickyHeaders.length > 0 && (React.createElement("div", { className: styles.stickyHeaderRegion }, stickyHeaders)),
                            React.createElement("div", { className: styles.modalBody, tabIndex: -1 }, bodyChildren),
                            stickyActions.length > 0 && (React.createElement("div", { className: styles.stickyActionsRegion }, stickyActions)))))))))));
}
function extractSticky(children, componentType, match) {
    const sticky = [];
    const rest = children.filter(child => {
        if (React.isValidElement(child) &&
            child.type === componentType &&
            match(child.props)) {
            sticky.push(child);
            return false;
        }
        return true;
    });
    return { sticky, rest };
}

function Modal(props) {
    return React.createElement(ModalLegacy, Object.assign({}, props));
}
Modal.Header = ModalHeader;
Modal.Actions = ModalActions;
Modal.Activator = ModalActivator;
Modal.Provider = ModalProvider;
Modal.Content = ModalContent;

exports.Modal = Modal;
exports.useModalContext = useModalContext;
exports.useModalStyles = useModalStyles;
