// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/no-explicit-any */
import * as React from 'react';
import { useBoolean, useMergedRefs, useConst, useSetTimeout, useId, useUnmount } from '@fluentui/react-hooks';
import { allowOverscrollOnElement, allowScrollOnElement, AnimationVariables, classNamesFunction, DirectionalHint, elementContains, EventGroup, FocusTrapZone, getGlobalClassNames, getPropsWithDefaults, Icon, KeyCodes, Layer, memoizeFunction, mergeStyles, on, Overlay, Popup, ResponsiveMode, styled, useResponsiveMode, ZIndexes } from '@fluentui/react';
const animationDuration = AnimationVariables.durationValue2;
const ZERO = {
    x: 0,
    y: 0
};
const DEFAULT_PROPS = {
    isOpen: false,
    isDarkOverlay: true,
    className: '',
    containerClassName: '',
    enableAriaHiddenSiblings: true
};
const getModalClassNames = classNamesFunction();
const getMoveDelta = (ev) => {
    let delta = 10;
    if (ev.shiftKey) {
        if (!ev.ctrlKey) {
            delta = 50;
        }
    }
    else if (ev.ctrlKey) {
        delta = 1;
    }
    return delta;
};
const useComponentRef = (props, focusTrapZone) => {
    React.useImperativeHandle(props.componentRef, () => ({
        focus() {
            if (focusTrapZone.current) {
                focusTrapZone.current.focus();
            }
        }
    }), [focusTrapZone]);
};
const ModalBase = React.forwardRef((propsWithoutDefaults, ref) => {
    var _a;
    const props = getPropsWithDefaults(DEFAULT_PROPS, propsWithoutDefaults);
    const { allowTouchBodyScroll, className, children, containerClassName, scrollableContentClassName, elementToFocusOnDismiss, firstFocusableSelector, forceFocusInsideTrap, ignoreExternalFocusing, isBlocking, isAlert, isClickableOutsideFocusTrap, isDarkOverlay, onDismiss, layerProps, overlay, isOpen, titleAriaId, styles, subtitleAriaId, theme, topOffsetFixed, responsiveMode, onLayerDidMount, isModeless, dragOptions, onDismissed, minDragPosition, maxDragPosition, dataUiId, keyEventElement = window } = props;
    const rootRef = React.useRef(null);
    const focusTrapZone = React.useRef(null);
    const focusTrapZoneElm = React.useRef(null);
    const mergedRef = useMergedRefs(rootRef, ref);
    const modalResponsiveMode = useResponsiveMode(mergedRef);
    const focusTrapZoneId = useId('ModalFocusTrapZone');
    const { setTimeout, clearTimeout } = useSetTimeout();
    const [isModalOpen, setIsModalOpen] = React.useState(isOpen);
    const [isVisible, setIsVisible] = React.useState(isOpen);
    const [coordinates, setCoordinates] = React.useState(ZERO);
    const [modalRectangleTop, setModalRectangleTop] = React.useState();
    const [isModalMenuOpen, { setTrue: setModalMenuOpen, setFalse: setModalMenuClose }] = useBoolean(false);
    const [_, forceUpdate] = React.useState(0);
    const forceUpdateCallback = React.useCallback(() => forceUpdate(prev => prev + 1), []);
    const internalState = useConst(() => ({
        onModalCloseTimer: 0,
        allowTouchBodyScroll,
        scrollableContent: null,
        lastSetCoordinates: ZERO,
        events: new EventGroup({})
    }));
    const { keepInBounds } = dragOptions || {};
    const isAlertRole = isAlert !== null && isAlert !== void 0 ? isAlert : (isBlocking && !isModeless);
    const layerClassName = layerProps === undefined ? '' : layerProps.className;
    const classNames = getModalClassNames(styles, {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        theme: theme,
        className,
        containerClassName,
        scrollableContentClassName,
        isOpen,
        isVisible,
        hasBeenOpened: internalState.hasBeenOpened,
        modalRectangleTop,
        topOffsetFixed,
        isModeless,
        layerClassName,
        windowInnerHeight: window === null || window === void 0 ? void 0 : window.innerHeight,
        isDefaultDragHandle: dragOptions && !dragOptions.dragHandleSelector
    });
    const mergedLayerProps = Object.assign(Object.assign({ eventBubblingEnabled: false }, layerProps), { onLayerDidMount: layerProps && layerProps.onLayerDidMount ? layerProps.onLayerDidMount : onLayerDidMount, insertFirst: isModeless, className: classNames.layer });
    // Allow the user to scroll within the modal but not on the body
    const allowScrollOnModal = React.useCallback((elt) => {
        if (elt) {
            if (internalState.allowTouchBodyScroll) {
                allowOverscrollOnElement(elt, internalState.events);
            }
            else {
                allowScrollOnElement(elt, internalState.events);
            }
        }
        else {
            internalState.events.off(internalState.scrollableContent);
        }
        internalState.scrollableContent = elt;
    }, [internalState]);
    const registerInitialModalPosition = () => {
        const dialogMain = focusTrapZoneElm.current;
        const modalRectangle = dialogMain === null || dialogMain === void 0 ? void 0 : dialogMain.getBoundingClientRect();
        if (modalRectangle) {
            if (topOffsetFixed) {
                setModalRectangleTop(modalRectangle.top);
            }
            if (keepInBounds) {
                // x/y are unavailable in IE, so use the equivalent left/top
                internalState.minPosition = minDragPosition !== null && minDragPosition !== void 0 ? minDragPosition : {
                    x: -modalRectangle.left,
                    y: -modalRectangle.top
                };
                internalState.maxPosition = maxDragPosition !== null && maxDragPosition !== void 0 ? maxDragPosition : {
                    x: modalRectangle.left,
                    y: modalRectangle.top
                };
                // Make sure the initial co-ordinates are within clamp bounds.
                setCoordinates({
                    x: getClampedAxis('x', coordinates.x),
                    y: getClampedAxis('y', coordinates.y)
                });
            }
        }
    };
    /**
     * Clamps an axis to a specified min and max position.
     *
     * @param axis A string that represents the axis (x/y).
     * @param position The position on the axis.
     */
    const getClampedAxis = React.useCallback((axis, position) => {
        const { minPosition, maxPosition } = internalState;
        if (keepInBounds && minPosition && maxPosition) {
            position = Math.max(minPosition[axis], position);
            position = Math.min(maxPosition[axis], position);
        }
        return position;
    }, [keepInBounds, internalState]);
    const handleModalClose = () => {
        var _a;
        internalState.lastSetCoordinates = ZERO;
        setModalMenuClose();
        internalState.isInKeyboardMoveMode = false;
        setIsModalOpen(false);
        setCoordinates(ZERO);
        (_a = internalState.disposeOnKeyUp) === null || _a === void 0 ? void 0 : _a.call(internalState);
        onDismissed === null || onDismissed === void 0 ? void 0 : onDismissed();
    };
    const handleDragStart = React.useCallback(() => {
        setModalMenuClose();
        internalState.isInKeyboardMoveMode = false;
    }, [internalState, setModalMenuClose]);
    const handleDrag = React.useCallback((ev, dragData) => {
        setCoordinates(prevValue => ({
            x: getClampedAxis('x', prevValue.x + dragData.delta.x),
            y: getClampedAxis('y', prevValue.y + dragData.delta.y)
        }));
    }, [getClampedAxis]);
    const handleDragStop = React.useCallback(() => {
        if (focusTrapZone.current) {
            focusTrapZone.current.focus();
        }
    }, []);
    const handleEnterKeyboardMoveMode = () => {
        // We need a global handleKeyDown event when we are in the move mode so that we can
        // handle the key presses and the components inside the modal do not get the events
        const handleKeyDown = (event) => {
            const ev = event;
            if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) {
                // CTRL + ALT + SPACE is handled during keyUp
                ev.preventDefault();
                ev.stopPropagation();
                return;
            }
            const newLocal = ev.altKey || ev.keyCode === KeyCodes.escape;
            if (isModalMenuOpen && newLocal) {
                setModalMenuClose();
            }
            if (internalState.isInKeyboardMoveMode && (ev.keyCode === KeyCodes.escape || ev.keyCode === KeyCodes.enter)) {
                internalState.isInKeyboardMoveMode = false;
                forceUpdateCallback();
                ev.preventDefault();
                ev.stopPropagation();
            }
            if (internalState.isInKeyboardMoveMode) {
                let handledEvent = true;
                const delta = getMoveDelta(ev);
                switch (ev.keyCode) {
                    /* eslint-disable no-fallthrough */
                    case KeyCodes.escape:
                        setCoordinates(internalState.lastSetCoordinates);
                    case KeyCodes.enter:
                        {
                            // TODO: determine if fallthrough was intentional
                            /* eslint-enable no-fallthrough */
                            internalState.lastSetCoordinates = ZERO;
                            // setIsInKeyboardMoveMode(false);
                            break;
                        }
                    case KeyCodes.up:
                        {
                            setCoordinates(prevValue => ({
                                x: prevValue.x,
                                y: getClampedAxis('y', prevValue.y - delta)
                            }));
                            break;
                        }
                    case KeyCodes.down:
                        {
                            setCoordinates(prevValue => ({
                                x: prevValue.x,
                                y: getClampedAxis('y', prevValue.y + delta)
                            }));
                            break;
                        }
                    case KeyCodes.left:
                        {
                            setCoordinates(prevValue => ({
                                x: getClampedAxis('x', prevValue.x - delta),
                                y: prevValue.y
                            }));
                            break;
                        }
                    case KeyCodes.right:
                        {
                            setCoordinates(prevValue => ({
                                x: getClampedAxis('x', prevValue.x + delta),
                                y: prevValue.y
                            }));
                            break;
                        }
                    default:
                        {
                            handledEvent = false;
                        }
                }
                if (handledEvent) {
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            }
        };
        internalState.lastSetCoordinates = coordinates;
        setModalMenuClose();
        internalState.isInKeyboardMoveMode = true;
        keyEventElement.addEventListener('keydown', handleKeyDown, true /* useCapture */);
        internalState.disposeOnKeyDown = () => {
            keyEventElement.removeEventListener('keydown', handleKeyDown, true /* useCapture */);
            internalState.disposeOnKeyDown = undefined;
        };
    };
    const handleExitKeyboardMoveMode = () => {
        var _a;
        internalState.lastSetCoordinates = ZERO;
        internalState.isInKeyboardMoveMode = false;
        (_a = internalState.disposeOnKeyDown) === null || _a === void 0 ? void 0 : _a.call(internalState);
    };
    const registerForKeyUp = () => {
        const handleKeyUp = (event) => {
            const ev = event;
            // Needs to handle the CTRL + ALT + SPACE key during keyup due to FireFox bug:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
            if (ev.altKey && ev.ctrlKey && ev.keyCode === KeyCodes.space) {
                if (elementContains(internalState.scrollableContent, ev.target)) {
                    setModalMenuOpen();
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            }
        };
        if (!internalState.disposeOnKeyUp) {
            keyEventElement.addEventListener('keyup', handleKeyUp, true /* useCapture */);
            internalState.disposeOnKeyUp = () => {
                keyEventElement.removeEventListener('keyup', handleKeyUp, true /* useCapture */);
                internalState.disposeOnKeyUp = undefined;
            };
        }
    };
    React.useEffect(() => {
        clearTimeout(internalState.onModalCloseTimer);
        // Opening the dialog
        if (isOpen) {
            // This must be done after the modal content has rendered
            requestAnimationFrame(() => setTimeout(registerInitialModalPosition, 0));
            setIsModalOpen(true);
            // Add a keyUp handler for all key up events once the dialog is open.
            if (dragOptions) {
                registerForKeyUp();
            }
            internalState.hasBeenOpened = true;
            setIsVisible(true);
        }
        // Closing the dialog
        if (!isOpen && isModalOpen) {
            internalState.onModalCloseTimer = setTimeout(handleModalClose, parseFloat(animationDuration) * 1000);
            setIsVisible(false);
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps -- should only run if isModalOpen or isOpen mutates or if min/max drag bounds are updated.
    }, [isModalOpen, isOpen, minDragPosition, maxDragPosition]);
    useUnmount(() => {
        internalState.events.dispose();
    });
    useComponentRef(props, focusTrapZone);
    const modalContent = React.createElement(FocusTrapZone, Object.assign({ disabled: true, id: focusTrapZoneId, ref: focusTrapZoneElm, componentRef: focusTrapZone, className: classNames.main, elementToFocusOnDismiss: elementToFocusOnDismiss, isClickableOutsideFocusTrap: isModeless || isClickableOutsideFocusTrap || !isBlocking, ignoreExternalFocusing: ignoreExternalFocusing, forceFocusInsideTrap: forceFocusInsideTrap && !isModeless, firstFocusableSelector: firstFocusableSelector, focusPreviouslyFocusedInnerElement: true, onBlur: internalState.isInKeyboardMoveMode ? handleExitKeyboardMoveMode : undefined, "data-ui-id": dataUiId }, (_a = props.focusTrapZoneProps) !== null && _a !== void 0 ? _a : {}),
        dragOptions && internalState.isInKeyboardMoveMode && React.createElement("div", { className: classNames.keyboardMoveIconContainer }, dragOptions.keyboardMoveIconProps ? React.createElement(Icon, Object.assign({}, dragOptions.keyboardMoveIconProps)) : React.createElement(Icon, { iconName: "move", className: classNames.keyboardMoveIcon })),
        React.createElement("div", { ref: allowScrollOnModal, className: classNames.scrollableContent, "data-is-scrollable": true },
            dragOptions && isModalMenuOpen && React.createElement(dragOptions.menu, { items: [{
                        key: 'move',
                        text: dragOptions.moveMenuItemText,
                        onClick: handleEnterKeyboardMoveMode
                    }, {
                        key: 'close',
                        text: dragOptions.closeMenuItemText,
                        onClick: handleModalClose
                    }], onDismiss: setModalMenuClose, alignTargetEdge: true, coverTarget: true, directionalHint: DirectionalHint.topLeftEdge, directionalHintFixed: true, shouldFocusOnMount: true, target: internalState.scrollableContent }),
            children));
    return (
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    isModalOpen && modalResponsiveMode >= (responsiveMode || ResponsiveMode.small) && React.createElement(Layer, Object.assign({ ref: mergedRef }, mergedLayerProps),
        React.createElement(Popup, { role: isAlertRole ? 'alertdialog' : 'dialog', ariaLabelledBy: titleAriaId, ariaDescribedBy: subtitleAriaId, 
            // onDismiss={onDismiss}
            shouldRestoreFocus: !ignoreExternalFocusing, "aria-modal": !isModeless },
            React.createElement("div", { className: classNames.root, role: !isModeless ? 'document' : undefined },
                !isModeless && React.createElement(Overlay, Object.assign({ "aria-hidden": true, isDarkThemed: isDarkOverlay, onClick: isBlocking ? undefined : onDismiss, allowTouchBodyScroll: allowTouchBodyScroll }, overlay)),
                dragOptions ? React.createElement(DraggableZone, { handleSelector: dragOptions.dragHandleSelector || `#${focusTrapZoneId}`, preventDragSelector: "button", onStart: handleDragStart, onDragChange: handleDrag, onStop: handleDragStop, position: coordinates }, modalContent) : modalContent))) || null);
});
ModalBase.displayName = 'ModalBase';
const getDraggableZoneClassNames = memoizeFunction((className, isDragging) => {
    return {
        root: mergeStyles(className, isDragging && {
            touchAction: 'none',
            selectors: {
                '& *': {
                    userSelect: 'none'
                }
            }
        })
    };
});
const eventMapping = {
    touch: {
        start: 'touchstart',
        move: 'touchmove',
        stop: 'touchend'
    },
    mouse: {
        start: 'mousedown',
        move: 'mousemove',
        stop: 'mouseup'
    }
};
class DraggableZone extends React.Component {
    constructor(props) {
        super(props);
        this._currentEventType = eventMapping.mouse;
        this._events = [];
        this._onMouseDown = (event) => {
            const onMouseDown = React.Children.only(this.props.children).props.onMouseDown;
            if (onMouseDown) {
                onMouseDown(event);
            }
            this._currentEventType = eventMapping.mouse;
            return this._onDragStart(event);
        };
        this._onMouseUp = (event) => {
            const onMouseUp = React.Children.only(this.props.children).props.onMouseUp;
            if (onMouseUp) {
                onMouseUp(event);
            }
            this._currentEventType = eventMapping.mouse;
            return this._onDragStop(event);
        };
        this._onTouchStart = (event) => {
            const onTouchStart = React.Children.only(this.props.children).props.onTouchStart;
            if (onTouchStart) {
                onTouchStart(event);
            }
            this._currentEventType = eventMapping.touch;
            return this._onDragStart(event);
        };
        this._onTouchEnd = (event) => {
            const onTouchEnd = React.Children.only(this.props.children).props.onTouchEnd;
            if (onTouchEnd) {
                onTouchEnd(event);
            }
            this._currentEventType = eventMapping.touch;
            this._onDragStop(event);
        };
        this._onDragStart = (event) => {
            // Only handle left click for dragging
            if (typeof event.button === 'number' && event.button !== 0) {
                return false;
            }
            // If the target doesn't match the handleSelector OR
            // if the target does match the preventDragSelector, bail out
            if (this.props.handleSelector && !this._matchesSelector(event.target, this.props.handleSelector) || this.props.preventDragSelector && this._matchesSelector(event.target, this.props.preventDragSelector)) {
                return;
            }
            // Remember the touch identifier if this is a touch event so we can
            // distinguish between individual touches in multitouch scenarios
            // by remembering which touch point we were given
            this._touchId = this._getTouchId(event);
            const position = this._getControlPosition(event);
            if (position === undefined) {
                return;
            }
            const dragData = this._createDragDataFromPosition(position);
            this.props.onStart && this.props.onStart(event, dragData);
            this.setState({
                isDragging: true,
                lastPosition: position
            });
            // hook up the appropriate mouse/touch events to the body to ensure
            // smooth dragging
            this._events = [on(document.body, this._currentEventType.move, this._onDrag, true /* use capture phase */), on(document.body, this._currentEventType.stop, this._onDragStop, true /* use capture phase */)];
            return;
        };
        this._onDrag = (event) => {
            // Prevent scrolling on mobile devices
            if (event.type === 'touchmove') {
                event.preventDefault();
            }
            const position = this._getControlPosition(event);
            if (!position) {
                return;
            }
            // create the updated drag data from the position data
            const updatedData = this._createUpdatedDragData(this._createDragDataFromPosition(position));
            const updatedPosition = updatedData.position;
            this.props.onDragChange && this.props.onDragChange(event, updatedData);
            this.setState({
                position: updatedPosition,
                lastPosition: position
            });
        };
        this._onDragStop = (event) => {
            if (!this.state.isDragging) {
                return;
            }
            const position = this._getControlPosition(event);
            if (!position) {
                return;
            }
            const baseDragData = this._createDragDataFromPosition(position);
            // Set dragging to false and reset the lastPosition
            this.setState({
                isDragging: false,
                lastPosition: undefined
            });
            this.props.onStop && this.props.onStop(event, baseDragData);
            if (this.props.position) {
                this.setState({
                    position: this.props.position
                });
            }
            // Remove event handlers
            this._events.forEach(dispose => dispose());
        };
        this.state = {
            isDragging: false,
            position: this.props.position || {
                x: 0,
                y: 0
            },
            lastPosition: undefined
        };
    }
    componentDidUpdate(prevProps) {
        if (this.props.position && (!prevProps.position || this.props.position !== prevProps.position)) {
            this.setState({
                position: this.props.position
            });
        }
    }
    componentWillUnmount() {
        this._events.forEach(dispose => dispose());
    }
    render() {
        const child = React.Children.only(this.props.children);
        const { props } = child;
        const { position } = this.props;
        const { position: statePosition, isDragging } = this.state;
        let x = statePosition.x;
        let y = statePosition.y;
        if (position && !isDragging) {
            x = position.x;
            y = position.y;
        }
        return React.cloneElement(child, {
            style: Object.assign(Object.assign({}, props.style), { transform: `translate(${x}px, ${y}px)` }),
            className: getDraggableZoneClassNames(props.className, this.state.isDragging).root,
            onMouseDown: this._onMouseDown,
            onMouseUp: this._onMouseUp,
            onTouchStart: this._onTouchStart,
            onTouchEnd: this._onTouchEnd
        });
    }
    /**
     * Get the control position based off the event that fired
     * @param event - The event to get offsets from
     */
    _getControlPosition(event) {
        const touchObj = this._getActiveTouch(event);
        // did we get the right touch?
        if (this._touchId !== undefined && !touchObj) {
            return undefined;
        }
        const eventToGetOffset = touchObj || event;
        return {
            x: eventToGetOffset.clientX,
            y: eventToGetOffset.clientY
        };
    }
    /**
     * Get the active touch point that we have saved from the event's TouchList
     * @param event - The event used to get the TouchList for the active touch point
     */
    _getActiveTouch(event) {
        return event.targetTouches && this._findTouchInTouchList(event.targetTouches) || event.changedTouches && this._findTouchInTouchList(event.changedTouches);
    }
    /**
     * Get the initial touch identifier associated with the given event
     * @param event - The event that contains the TouchList
     */
    _getTouchId(event) {
        const touch = event.targetTouches && event.targetTouches[0] || event.changedTouches && event.changedTouches[0];
        if (touch) {
            return touch.identifier;
        }
        return;
    }
    /**
     * Returns if an element (or any of the element's parents) match the given selector
     */
    _matchesSelector(element, selector) {
        if (!element || element === document.body) {
            return false;
        }
        // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
        const matchesSelectorFn = element.matches || element.webkitMatchesSelector || element.msMatchesSelector; /* for IE */
        if (!matchesSelectorFn) {
            return false;
        }
        return matchesSelectorFn.call(element, selector) || this._matchesSelector(element.parentElement, selector);
    }
    /**
     * Attempts to find the Touch that matches the identifier  we stored in dragStart
     * @param touchList The TouchList to look for the stored identifier from dragStart
     */
    _findTouchInTouchList(touchList) {
        var _a;
        if (this._touchId === undefined) {
            return;
        }
        for (let i = 0; i < touchList.length; i++) {
            if (((_a = touchList[i]) === null || _a === void 0 ? void 0 : _a.identifier) === this._touchId) {
                return touchList[i];
            }
        }
        return undefined;
    }
    /**
     * Create DragData based off of the last known position and the new position passed in
     * @param position The new position as part of the drag
     */
    _createDragDataFromPosition(position) {
        const { lastPosition } = this.state;
        // If we have no lastPosition, use the given position
        // for last position
        if (lastPosition === undefined) {
            return {
                delta: {
                    x: 0,
                    y: 0
                },
                lastPosition: position,
                position
            };
        }
        return {
            delta: {
                x: position.x - lastPosition.x,
                y: position.y - lastPosition.y
            },
            lastPosition,
            position
        };
    }
    /**
     * Creates an updated DragData based off the current position and given baseDragData
     * @param baseDragData The base DragData (from _createDragDataFromPosition) used to calculate the updated positions
     */
    _createUpdatedDragData(baseDragData) {
        const { position } = this.state;
        return {
            position: {
                x: position.x + baseDragData.delta.x,
                y: position.y + baseDragData.delta.y
            },
            delta: baseDragData.delta,
            lastPosition: position
        };
    }
}
const globalClassNames = {
    root: 'ms-Modal',
    main: 'ms-Dialog-main',
    scrollableContent: 'ms-Modal-scrollableContent',
    isOpen: 'is-open',
    layer: 'ms-Modal-Layer'
};
const getStyles = (props) => {
    const { className, containerClassName, scrollableContentClassName, isOpen, isVisible, hasBeenOpened, modalRectangleTop, theme, topOffsetFixed, isModeless, layerClassName, isDefaultDragHandle, windowInnerHeight } = props;
    const { palette, effects, fonts } = theme;
    const classNames = getGlobalClassNames(globalClassNames, theme);
    return {
        root: [classNames.root, fonts.medium, {
                backgroundColor: 'transparent',
                position: isModeless ? 'absolute' : 'fixed',
                height: '100%',
                width: '100%',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                opacity: 0,
                pointerEvents: 'none',
                transition: `opacity ${animationDuration}`
            }, topOffsetFixed && typeof modalRectangleTop === 'number' && hasBeenOpened && {
                alignItems: 'flex-start'
            }, isOpen && classNames.isOpen, isVisible && {
                opacity: 1,
                pointerEvents: 'auto'
            }, className],
        main: [classNames.main, {
                boxShadow: effects.elevation64,
                borderRadius: effects.roundedCorner2,
                backgroundColor: palette.white,
                boxSizing: 'border-box',
                position: 'relative',
                textAlign: 'left',
                outline: '3px solid transparent',
                maxHeight: 'calc(100% - 32px)',
                maxWidth: 'calc(100% - 32px)',
                minHeight: '176px',
                minWidth: '288px',
                overflowY: 'auto',
                zIndex: isModeless ? ZIndexes.Layer : undefined
            }, topOffsetFixed && typeof modalRectangleTop === 'number' && hasBeenOpened && {
                top: modalRectangleTop
            }, isDefaultDragHandle && {
                cursor: 'move'
            }, containerClassName],
        scrollableContent: [classNames.scrollableContent, {
                overflowY: 'auto',
                flexGrow: 1,
                maxHeight: '100vh',
                selectors: {
                    ['@supports (-webkit-overflow-scrolling: touch)']: {
                        maxHeight: windowInnerHeight
                    }
                }
            }, scrollableContentClassName],
        layer: isModeless && [layerClassName, classNames.layer, {
                position: 'static',
                width: 'unset',
                height: 'unset'
            }],
        keyboardMoveIconContainer: {
            position: 'absolute',
            display: 'flex',
            justifyContent: 'center',
            width: '100%',
            padding: '3px 0px'
        },
        keyboardMoveIcon: {
            fontSize: fonts.xLargePlus.fontSize,
            width: '24px'
        }
    };
};
/** @internal */
export const _ModalClone = styled(ModalBase, getStyles, undefined, {
    scope: 'Modal',
    fields: ['theme', 'styles', 'enableAriaHiddenSiblings']
});
_ModalClone.displayName = 'Modal';
//# sourceMappingURL=ModalClone.js.map