/**
 * amis-ui v6.12.0-beta.0
 * Copyright 2018-2025 fex
 */

import { __extends, __decorate, __metadata } from 'tslib';
import React__default from 'react';
import Transition, { ENTERING, ENTERED, EXITED } from 'react-transition-group/Transition';
import Portal from 'react-overlays/Portal';
import { Icon } from './icons.js';
import cx from 'classnames';
import { addModal, current, removeModal } from './ModalManager.js';
import { getScrollbarWidth, autobind, themeable } from 'amis-core';
import { getContainerWithFullscreen } from './Modal.js';

/**
 * @file Drawer
 * @description
 * @author fex
 */
var _a;
var fadeStyles = (_a = {},
    _a[ENTERING] = 'in',
    _a[ENTERED] = 'in',
    _a);
var Drawer = /** @class */ (function (_super) {
    __extends(Drawer, _super);
    function Drawer() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.isRootClosed = false;
        _this.resizer = React__default.createRef();
        _this.resizeCoord = 0;
        _this.contentRef = function (ref) { return (_this.contentDom = ref); };
        _this.handleEnter = function () {
            document.body.classList.add("is-modalOpened");
            if (window.innerWidth - document.documentElement.clientWidth > 0 ||
                document.body.scrollHeight > document.body.clientHeight) {
                var scrollbarWidth = getScrollbarWidth();
                if (scrollbarWidth) {
                    document.body.style.width = "calc(100% - ".concat(scrollbarWidth, "px)");
                }
            }
        };
        _this.handleEntered = function () {
            var onEntered = _this.props.onEntered;
            document.body.addEventListener('mousedown', _this.handleRootMouseDownCapture, true);
            document.body.addEventListener('mouseup', _this.handleRootMouseUpCapture, true);
            document.body.addEventListener('mouseup', _this.handleRootMouseUp);
            onEntered && onEntered();
        };
        _this.handleExited = function () {
            var _a, _b;
            var onExited = _this.props.onExited;
            document.activeElement && ((_b = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.blur) === null || _b === void 0 ? void 0 : _b.call(_a));
            document.body.removeEventListener('mouseup', _this.handleRootMouseUp);
            document.body.removeEventListener('mouseup', _this.handleRootMouseUpCapture, true);
            document.body.removeEventListener('mousedown', _this.handleRootMouseDownCapture, true);
            onExited && onExited();
            setTimeout(function () {
                if (!document.querySelector('.amis-dialog-widget')) {
                    document.body.classList.remove("is-modalOpened");
                    document.body.style.width = '';
                }
            }, 200);
        };
        _this.modalRef = function (ref) {
            _this.modalDom = ref;
            if (ref) {
                addModal(_this);
                ref.classList.add("".concat(_this.props.classPrefix, "Modal--").concat(current(), "th"));
            }
            else {
                removeModal(_this);
            }
        };
        return _this;
    }
    Drawer.prototype.componentDidMount = function () {
        if (this.props.show) {
            this.handleEntered();
        }
    };
    Drawer.prototype.componentDidUpdate = function (prevProps) {
        var _this = this;
        // jest 里面没有触发 entered 导致后续的逻辑错误，
        // 所以直接 300 ms 后触发
        if (typeof jest !== 'undefined' &&
            prevProps.show !== this.props.show &&
            this.props.show) {
            setTimeout(function () {
                _this.handleEntered();
            }, 300);
        }
    };
    Drawer.prototype.componentWillUnmount = function () {
        if (this.props.show) {
            this.handleExited();
        }
    };
    Drawer.prototype.handleRootMouseDownCapture = function (e) {
        var target = e.target;
        var _a = this.props, closeOnOutside = _a.closeOnOutside, ns = _a.classPrefix, mobileUI = _a.mobileUI;
        var isLeftButton = (e.button === 1 && window.event !== null) || e.button === 0;
        this.isRootClosed = !!(isLeftButton &&
            closeOnOutside &&
            target &&
            this.modalDom &&
            ((!mobileUI &&
                !this.modalDom.contains(target) &&
                !target.closest('[role=dialog]')) ||
                (target.matches(".".concat(ns, "Drawer-overlay")) &&
                    target.parentElement === this.modalDom))); // 干脆过滤掉来自弹框里面的点击
    };
    Drawer.prototype.handleRootMouseUpCapture = function (e) {
        // mousedown 的时候不在弹窗里面，则不需要判断了
        if (!this.isRootClosed) {
            return;
        }
        // 再判断 mouseup 的时候是不是在弹窗里面
        this.handleRootMouseDownCapture(e);
    };
    Drawer.prototype.handleRootMouseUp = function (e) {
        var onHide = this.props.onHide;
        this.isRootClosed && !e.defaultPrevented && onHide(e);
    };
    Drawer.prototype.getDrawerStyle = function () {
        var _a = this.props, width = _a.width, height = _a.height, position = _a.position;
        var offsetStyle = {};
        if ((position === 'left' || position === 'right') && width !== undefined) {
            offsetStyle.width = width;
        }
        else if ((position === 'top' || position === 'bottom') &&
            height !== undefined) {
            offsetStyle.height = height;
        }
        return offsetStyle;
    };
    Drawer.prototype.resizeMouseDown = function (e) {
        var _a = this.props, position = _a.position; _a.classPrefix;
        var drawer = this.contentDom;
        var resizer = this.resizer.current;
        var drawerWidth = getComputedStyle(drawer).width;
        var drawerHeight = getComputedStyle(drawer).height;
        this.resizeCoord =
            (position === 'left' &&
                e.clientX -
                    resizer.offsetWidth -
                    parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
                (position === 'right' &&
                    document.body.offsetWidth -
                        e.clientX -
                        resizer.offsetWidth -
                        parseInt(drawerWidth.substring(0, drawerWidth.length - 2))) ||
                (position === 'top' &&
                    e.clientY -
                        resizer.offsetHeight -
                        parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
                (position === 'bottom' &&
                    document.body.offsetHeight -
                        e.clientY -
                        resizer.offsetHeight -
                        parseInt(drawerHeight.substring(0, drawerHeight.length - 2))) ||
                0;
        document.body.addEventListener('mousemove', this.bindResize);
        document.body.addEventListener('mouseup', this.removeResize);
    };
    Drawer.prototype.bindResize = function (e) {
        var position = this.props.position;
        var maxWH = 'calc(100% - 50px)';
        var drawer = this.contentDom;
        var drawerStyle = drawer.style;
        var wh = (position === 'left' && e.clientX) ||
            (position === 'right' && document.body.offsetWidth - e.clientX) ||
            (position === 'top' && e.clientY) ||
            (position === 'bottom' && document.body.offsetHeight - e.clientY) ||
            0;
        wh = wh - this.resizeCoord + 'px';
        if (position === 'left' || position === 'right') {
            drawerStyle.maxWidth = maxWH;
            drawerStyle.width = wh;
        }
        if (position === 'top' || position === 'bottom') {
            drawerStyle.maxHeight = maxWH;
            drawerStyle.height = wh;
        }
    };
    Drawer.prototype.removeResize = function () {
        document.body.removeEventListener('mousemove', this.bindResize);
        document.body.removeEventListener('mouseup', this.removeResize);
    };
    Drawer.prototype.renderResizeCtrl = function () {
        var cx = this.props.classnames;
        return (React__default.createElement("div", { className: cx('Drawer-resizeCtrl'), ref: this.resizer, onMouseDown: this.resizeMouseDown },
            React__default.createElement("div", { className: cx('Drawer-resizeIcon') }, "\u00B7\u00B7\u00B7")));
    };
    Drawer.prototype.render = function () {
        var _this = this;
        var _a = this.props, ns = _a.classPrefix, className = _a.className, children = _a.children, container = _a.container, show = _a.show, showCloseButton = _a.showCloseButton, position = _a.position, size = _a.size, onHide = _a.onHide, disabled = _a.disabled, overlay = _a.overlay, bodyClassName = _a.bodyClassName, resizable = _a.resizable, drawerClassName = _a.drawerClassName, drawerMaskClassName = _a.drawerMaskClassName;
        var bodyStyle = this.getDrawerStyle();
        return (React__default.createElement(Portal, { container: getContainerWithFullscreen(container) },
            React__default.createElement(Transition, { mountOnEnter: true, unmountOnExit: true, appear: true, in: show, timeout: 500, onEnter: this.handleEnter, onExited: this.handleExited, onEntered: this.handleEntered }, function (status) {
                var _a;
                if (status === ENTERING) {
                    // force reflow
                    // 由于从 mount 进来到加上 in 这个 class 估计是时间太短，上次的样式还没应用进去，所以这里强制reflow一把。
                    // 否则看不到动画。
                    _this.contentDom.offsetWidth;
                }
                return (React__default.createElement("div", { ref: _this.modalRef, role: "dialog", className: cx("amis-dialog-widget ".concat(ns, "Drawer"), (_a = {},
                        _a["".concat(ns, "Drawer--").concat(position)] = position,
                        _a["".concat(ns, "Drawer--").concat(size)] = size,
                        _a["".concat(ns, "Drawer--noOverlay")] = !overlay,
                        _a), className) },
                    overlay ? (React__default.createElement("div", { className: cx("".concat(ns, "Drawer-overlay"), fadeStyles[status], drawerMaskClassName) })) : null,
                    React__default.createElement("div", { ref: _this.contentRef, style: bodyStyle, className: cx("".concat(ns, "Drawer-content"), bodyClassName, fadeStyles[status], drawerClassName) },
                        show && showCloseButton ? (React__default.createElement("a", { onClick: disabled ? undefined : onHide, className: "".concat(ns, "Drawer-close") },
                            React__default.createElement(Icon, { icon: "close", className: "icon", iconContent: "Drawer-close" }))) : null,
                        status === EXITED ? null : children,
                        resizable ? _this.renderResizeCtrl() : null)));
            })));
    };
    Drawer.defaultProps = {
        container: document.body,
        position: 'left',
        size: 'md',
        showCloseButton: true,
        overlay: true
    };
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "handleRootMouseDownCapture", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "handleRootMouseUpCapture", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "handleRootMouseUp", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "resizeMouseDown", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [Object]),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "bindResize", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", []),
        __metadata("design:returntype", void 0)
    ], Drawer.prototype, "removeResize", null);
    return Drawer;
}(React__default.Component));
var Drawer$1 = themeable(Drawer);

export { Drawer, Drawer$1 as default };
