var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
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;
};
import React from 'react';
import { isBrowser } from '../../lib/globalObject.js';
import { scrollYCenterIntoNearestScrollable } from '../../lib/dom/scrollYCenterIntoNearestScrollable.js';
import { isExternalLink, isFunction, isNonNullable, isReactUIComponent } from '../../lib/utils.js';
import { ThemeContext } from '../../lib/theming/ThemeContext.js';
import { CommonWrapper } from '../../internal/CommonWrapper/index.js';
import { rootNode } from '../../lib/rootNode/index.js';
import { MenuContext } from '../../internal/Menu/MenuContext.js';
import { getVisualStateDataAttributes } from '../../internal/CommonWrapper/utils/getVisualStateDataAttributes.js';
import { withRenderEnvironment } from '../../lib/renderEnvironment/index.js';
import { getStyles } from './MenuItem.styles.js';
export var MenuItemDataTids = {
    root: 'MenuItem__root',
    content: 'MenuItem__content',
    comment: 'MenuItem__comment',
};
/**
 * `MenuItem` - это вложенный компонент, задающий базовые стили для элемента меню и позволяющий навигироваться по элементам меню с помощью клавиатуры.
 *
 * Сущности в которых может быть использован `MenuItem`: DropdownMenu, Kebab, TooltipMenu и Select.
 */
var MenuItem = /** @class */ (function (_super) {
    __extends(MenuItem, _super);
    function MenuItem() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.state = {
            iconOffsetTop: 0,
            highlighted: false,
        };
        _this.mouseEntered = false;
        _this.rootRef = null;
        _this.contentRef = React.createRef();
        _this.highlight = function () {
            _this.setState({ highlighted: true });
        };
        _this.unhighlight = function () {
            _this.setState({ highlighted: false });
        };
        _this.select = function (event) {
            _this.handleClick(event);
        };
        _this.isEnabled = function () {
            return !_this.props.disabled;
        };
        _this.navigate = function () {
            var _a, _b;
            if (!_this.props.href) {
                return;
            }
            if (_this.props.target) {
                (_b = (_a = _this.globalObject).open) === null || _b === void 0 ? void 0 : _b.call(_a, _this.props.href, _this.props.target);
            }
            else if (_this.globalObject.location) {
                _this.globalObject.location.href = _this.props.href;
            }
        };
        _this.renderMain = function () {
            var _a, _b, _c, _d;
            var _e = _this.props, comment = _e.comment, icon = _e.icon, loose = _e.loose, state = _e.state, size = _e.size, _enableIconPadding = _e._enableIconPadding, component = _e.component, onMouseEnter = _e.onMouseEnter, onMouseLeave = _e.onMouseLeave, isMobile = _e.isMobile, href = _e.href, disabled = _e.disabled, scrollIntoView = _e.scrollIntoView, _f = _e.rel, rel = _f === void 0 ? href && isExternalLink(href, _this.globalObject) ? 'noopener noreferrer' : _this.props.rel : _f, isNotSelectable = _e.isNotSelectable, children = _e.children, unusedClasses = _e.className, style = _e.style, dataTid = _e["data-tid"], rest = __rest(_e, ["comment", "icon", "loose", "state", "size", "_enableIconPadding", "component", "onMouseEnter", "onMouseLeave", "isMobile", "href", "disabled", "scrollIntoView", "rel", "isNotSelectable", "children", "className", "style", 'data-tid']);
            var iconElement = null;
            if (icon) {
                iconElement = (React.createElement("div", { style: { top: _this.state.iconOffsetTop }, className: _this.cx((_a = {},
                        _a[_this.styles.icon()] = true,
                        _a[_this.getIconSizeClassName()] = true,
                        _a)) }, icon));
            }
            var className = _this.cx((_b = {},
                _b[_this.styles.root(_this.theme)] = true,
                _b[_this.getRootSizeClassName()] = true,
                _b[_this.styles.rootMobile(_this.theme)] = isMobile,
                _b[_this.styles.loose()] = !!loose,
                _b[_this.styles.hover(_this.theme)] = _this.isHover,
                _b[_this.styles.selected(_this.theme)] = _this.isSelected,
                _b[_this.getWithIconSizeClassName()] = Boolean(iconElement) || !!_enableIconPadding || _this.context.enableIconPadding,
                _b[_this.styles.nonSelectable()] = !!isNotSelectable,
                _b[_this.styles.disabled(_this.theme)] = !!disabled,
                _b));
            var content = children;
            if (isFunction(children)) {
                content = children(_this.activeState);
            }
            var Component = _this.getComponent();
            return (React.createElement(CommonWrapper, __assign({ rootNodeRef: _this.setRootNode }, getVisualStateDataAttributes({
                hover: _this.isHover,
                selected: _this.isSelected,
            }), _this.props),
                React.createElement(Component, __assign({ ref: _this.setRootRef, "data-tid": MenuItemDataTids.root }, rest, { disabled: disabled, state: _this.activeState, onMouseOver: _this.handleMouseEnterFix, onMouseLeave: _this.handleMouseLeave, onClick: _this.handleClick, className: className, href: href, rel: href ? rel : undefined, tabIndex: -1 }),
                    iconElement,
                    React.createElement("span", { className: _this.cx((_c = {},
                            _c[_this.styles.mobileContentWithIcon()] = isMobile && isNonNullable(icon),
                            _c)), ref: _this.contentRef, "data-tid": MenuItemDataTids.content }, typeof content === 'function' ? content() : content),
                    comment && (React.createElement("div", { "data-tid": MenuItemDataTids.comment, className: _this.cx((_d = {},
                            _d[_this.styles.comment(_this.theme)] = true,
                            _d[_this.styles.commentHover(_this.theme)] = _this.isHover,
                            _d)) }, comment)))));
        };
        // https://github.com/facebook/react/issues/10109
        // Mouseenter event not triggered when cursor moves from disabled button
        _this.handleMouseEnterFix = function (e) {
            var _a, _b, _c;
            if (!_this.mouseEntered) {
                _this.mouseEntered = true;
                (_b = (_a = _this.props).onMouseEnter) === null || _b === void 0 ? void 0 : _b.call(_a, e);
                !_this.props.isNotSelectable && ((_c = _this.context.navigation) === null || _c === void 0 ? void 0 : _c.highlight(_this));
            }
        };
        _this.handleMouseLeave = function (e) {
            var _a, _b, _c;
            _this.mouseEntered = false;
            (_b = (_a = _this.props).onMouseLeave) === null || _b === void 0 ? void 0 : _b.call(_a, e);
            !_this.props.isNotSelectable && ((_c = _this.context.navigation) === null || _c === void 0 ? void 0 : _c.unhighlight());
        };
        _this.handleClick = function (e) {
            var _a, _b, _c, _d;
            if (_this.props.isNotSelectable) {
                return;
            }
            (_b = (_a = _this.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e);
            (_d = (_c = _this.context).onItemClick) === null || _d === void 0 ? void 0 : _d.call(_c, e);
        };
        _this.setRootRef = function (element) {
            _this.rootRef = element;
        };
        _this.getComponent = function () {
            var _a = _this.props, disabled = _a.disabled, component = _a.component, href = _a.href;
            if (component) {
                return component;
            }
            if (disabled) {
                return 'button';
            }
            if (href) {
                return 'a';
            }
            return 'button';
        };
        _this.hasIconAmongItems = function () {
            var _a;
            return Boolean((_a = _this.context.navigation) === null || _a === void 0 ? void 0 : _a.items.some(function (item) { return item.props.icon; }));
        };
        return _this;
    }
    MenuItem.prototype.render = function () {
        var _this = this;
        this.styles = getStyles(this.emotion);
        return (React.createElement(ThemeContext.Consumer, null, function (theme) {
            _this.theme = theme;
            return _this.renderMain();
        }));
    };
    MenuItem.prototype.componentDidMount = function () {
        var _a, _b, _c;
        if (this.props.scrollIntoView && this.rootRef) {
            scrollYCenterIntoNearestScrollable(this.rootRef);
        }
        if (this.rootRef && isBrowser(this.globalObject)) {
            this.setState({
                iconOffsetTop: this.globalObject.getComputedStyle(this.rootRef).getPropertyValue('padding-top'),
            });
        }
        if (this.contentRef.current && !this.props.isNotSelectable) {
            (_a = this.context.navigation) === null || _a === void 0 ? void 0 : _a.add(this.contentRef.current, this);
        }
        if (this.props.icon) {
            (_c = (_b = this.context).setEnableIconPadding) === null || _c === void 0 ? void 0 : _c.call(_b, true);
        }
    };
    MenuItem.prototype.componentWillUnmount = function () {
        var _a, _b, _c;
        if (this.contentRef.current) {
            !this.props.isNotSelectable && ((_a = this.context.navigation) === null || _a === void 0 ? void 0 : _a.remove(this.contentRef.current));
            (_c = (_b = this.context).setEnableIconPadding) === null || _c === void 0 ? void 0 : _c.call(_b, this.hasIconAmongItems());
        }
    };
    MenuItem.prototype.componentDidUpdate = function (prevProps) {
        var _a, _b, _c, _d;
        if (prevProps.icon !== this.props.icon) {
            (_b = (_a = this.context).setEnableIconPadding) === null || _b === void 0 ? void 0 : _b.call(_a, !!this.props.icon || this.hasIconAmongItems());
        }
        if (this.contentRef.current && prevProps.isNotSelectable !== this.props.isNotSelectable) {
            if (this.props.isNotSelectable) {
                this.unhighlight();
                (_c = this.context.navigation) === null || _c === void 0 ? void 0 : _c.remove(this.contentRef.current);
            }
            else {
                (_d = this.context.navigation) === null || _d === void 0 ? void 0 : _d.add(this.contentRef.current, this);
            }
        }
    };
    MenuItem.prototype.getRootSizeClassName = function () {
        switch (this.props.size) {
            case 'large':
                return this.styles.rootLarge(this.theme);
            case 'medium':
                return this.styles.rootMedium(this.theme);
            case 'small':
            default:
                return this.styles.rootSmall(this.theme);
        }
    };
    MenuItem.prototype.getIconSizeClassName = function () {
        switch (this.props.size) {
            case 'large':
                return this.styles.iconLarge(this.theme);
            case 'medium':
                return this.styles.iconMedium(this.theme);
            case 'small':
            default:
                return this.styles.iconSmall(this.theme);
        }
    };
    MenuItem.prototype.getWithIconSizeClassName = function () {
        switch (this.props.size) {
            case 'large':
                return this.styles.withIconLarge(this.theme);
            case 'medium':
                return this.styles.withIconMedium(this.theme);
            case 'small':
            default:
                return this.styles.withIconSmall(this.theme);
        }
    };
    Object.defineProperty(MenuItem.prototype, "activeState", {
        get: function () {
            return this.state.highlighted ? 'hover' : this.props.state;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MenuItem.prototype, "isHover", {
        get: function () {
            return (this.state.highlighted || this.props.state === 'hover') && !this.props.disabled;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(MenuItem.prototype, "isSelected", {
        get: function () {
            return this.props.state === 'selected' && !this.state.highlighted;
        },
        enumerable: false,
        configurable: true
    });
    MenuItem.__KONTUR_REACT_UI__ = 'MenuItem';
    MenuItem.displayName = 'MenuItem';
    MenuItem.__MENU_ITEM__ = true;
    MenuItem.contextType = MenuContext;
    MenuItem = __decorate([
        withRenderEnvironment,
        rootNode
    ], MenuItem);
    return MenuItem;
}(React.Component));
export { MenuItem };
export var isMenuItem = isReactUIComponent('MenuItem');
//# sourceMappingURL=MenuItem.js.map