"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Modal = void 0;
const react_1 = __importStar(require("react"));
const css_utilities_1 = require("@shopify/css-utilities");
const responsiveValue_1 = require("../../utilities/responsiveValue");
const AppContext_1 = require("../AppContext");
const FocusTrap_1 = require("../FocusTrap");
const Portal_1 = require("../Portal");
const Heading_1 = require("../Heading");
const Icon_1 = require("../Icon");
const units_1 = require("../../utilities/units");
const transition_1 = require("../../utilities/transition");
const id_1 = require("../../utilities/id");
const Modal_css_1 = __importDefault(require("./Modal.css"));
const createId = id_1.createIdCreator('ModalHeading');
const IFRAME_HEIGHT_NOT_ACCESSIBLE = -1;
function Modal(_a) {
    var { maxInlineSize, blockSize, open, title, titleHidden, source, noMountTransition = false, children } = _a, rest = __rest(_a, ["maxInlineSize", "blockSize", "open", "title", "titleHidden", "source", "noMountTransition", "children"]);
    const blocking = rest.blocking;
    const onClose = rest.blocking ? undefined : rest.onClose;
    const translate = AppContext_1.useTranslate();
    const [iframeHeight, setIframeHeight] = react_1.useState();
    const activatorRef = react_1.useRef(null);
    const modalRef = react_1.useRef(null);
    const modalHeadingId = id_1.useId(undefined, createId);
    const transition = transition_1.useTransition(open, 'fast', !noMountTransition);
    const transitionClassName = Modal_css_1.default[css_utilities_1.variationName('transition', transition)];
    const isMobile = responsiveValue_1.useResponsiveValue({
        base: true,
        medium: false,
    });
    react_1.useEffect(() => {
        if (transition === 'enter') {
            document.body.style.overflow = 'hidden';
            activatorRef.current = document.activeElement;
        }
        if (transition === 'exited') {
            document.body.style.overflow = 'auto';
            if ((activatorRef === null || activatorRef === void 0 ? void 0 : activatorRef.current) instanceof HTMLElement)
                activatorRef.current.focus();
            setIframeHeight(undefined);
        }
    }, [transition]);
    const handleDialogFocus = () => {
        // workaround for browsers that don't support `preventScroll` for `focus`
        setTimeout(() => {
            const modal = modalRef.current;
            modal && modal.scrollTo(0, 0);
        }, 0);
    };
    react_1.useEffect(() => {
        const handleKeyDown = (event) => {
            if ((event.key === 'Escape' || event.key === 'Esc') && !blocking) {
                onClose && onClose();
            }
        };
        document.addEventListener('keydown', handleKeyDown, false);
        return () => {
            document.removeEventListener('keydown', handleKeyDown, false);
        };
    }, [blocking, onClose]);
    const handleIFrameLoad = react_1.useCallback((evt) => {
        const iframe = evt.target;
        if (iframe && iframe.contentWindow) {
            try {
                setIframeHeight(iframe.contentWindow.document.body.scrollHeight);
            }
            catch (_a) {
                setIframeHeight(IFRAME_HEIGHT_NOT_ACCESSIBLE);
            }
        }
    }, []);
    function handleBackdropClick() {
        onClose && onClose();
    }
    if (transition === 'exited')
        return null;
    const ariaLabelOrLabelledby = titleHidden
        ? { 'aria-label': title }
        : { 'aria-labelledby': modalHeadingId };
    const titleMarkup = titleHidden ? (
    // `null` breaks close button's right alignment
    <span />) : (<Heading_1.Heading level={1} id={modalHeadingId}>
      {title}
    </Heading_1.Heading>);
    const header = (!titleHidden || !blocking) && (<header className={Modal_css_1.default.Header}>
      {titleMarkup}
      {!blocking && (<button type="button" className={Modal_css_1.default.CloseButton} onClick={onClose} aria-label={translate('close') || 'Close'}>
          <Icon_1.Icon source="close" size="large"/>
        </button>)}
    </header>);
    const content = source ? (<iframe src={source} title={title} className={Modal_css_1.default.IFrame} {...(iframeHeight && iframeHeight > 0 && { style: { height: iframeHeight } })} {...(!blockSize && { onLoad: handleIFrameLoad })}/>) : (<div className={Modal_css_1.default.Content} {...((blockSize || isMobile) && { tabIndex: 0 })}>
      {children}
    </div>);
    return (<Portal_1.Portal>
      <div className={Modal_css_1.default.Modal} ref={modalRef}>
        
        <div className={css_utilities_1.classNames(Modal_css_1.default.Backdrop, transitionClassName)} onClick={handleBackdropClick}/>
        <FocusTrap_1.FocusTrap onContainerFocus={handleDialogFocus}>
          <div className={css_utilities_1.classNames(Modal_css_1.default.Dialog, transitionClassName, {
        [Modal_css_1.default['Dialog-blockSizeFill']]: blockSize === 'fill' || iframeHeight === -1,
    })} role="dialog" aria-modal style={Object.assign({}, (maxInlineSize && {
        maxWidth: units_1.pixelOrPercent(maxInlineSize === 'fill' ? 1 : maxInlineSize),
    }))} {...ariaLabelOrLabelledby}>
            {header}
            {content}
          </div>
        </FocusTrap_1.FocusTrap>
      </div>
    </Portal_1.Portal>);
}
exports.Modal = Modal;
