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;
};
import React from 'react';
import invariant from 'invariant';
import { ResizeDetector } from '../../internal/ResizeDetector/index.js';
import { isKeyArrow, isKeyArrowLeft, isKeyArrowUp } from '../../lib/events/keyboard/identifiers.js';
import { KeyListener } from '../../lib/events/keyListener.js';
import { isFunctionalComponent } 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 { createPropsGetter } from '../../lib/createPropsGetter.js';
import { getVisualStateDataAttributes } from '../../internal/CommonWrapper/utils/getVisualStateDataAttributes.js';
import { withRenderEnvironment } from '../../lib/renderEnvironment/index.js';
import { TabsContext, TabsContextDefaultValue } from './TabsContext.js';
import { globalClasses, getHorizontalStyles, getStyles, getVerticalStyles } from './Tab.styles.js';
export var TabDataTids = {
    root: 'Tab__root',
};
/**
 * Табы группируют контент и помогают в навигации.
 *
 * Для создания группы табов используйте специальный контейнер - компонент [Tabs](https://tech.skbkontur.ru/kontur-ui/?path=/docs/react-ui_display-data-tabs-tabs--docs).
 */
var Tab = /** @class */ (function (_super) {
    __extends(Tab, _super);
    function Tab(props) {
        var _this = _super.call(this, props) || this;
        _this.context = _this.context;
        _this.getProps = createPropsGetter(Tab_1.defaultProps);
        _this.state = {
            focusedByKeyboard: false,
        };
        _this.tabComponent = null;
        _this.getId = function () { return _this.props.id || _this.getProps().href; };
        _this.refTabComponent = function (instance) {
            _this.tabComponent = instance;
        };
        _this.getTabInstance = function () { return _this; };
        _this.switchTab = function (event) {
            if (_this.props.disabled) {
                event.preventDefault();
                return;
            }
            var _a = _this.getProps(), href = _a.href, component = _a.component;
            var id = _this.props.id || href;
            if (_this.props.onClick) {
                _this.props.onClick(event);
                if (event.defaultPrevented) {
                    return;
                }
            }
            if (typeof id === 'string') {
                _this.context.switchTab(id);
            }
            if (component === 'a' && !href) {
                event.preventDefault();
            }
        };
        _this.handleKeyDown = function (e) {
            if (_this.props.disabled) {
                return;
            }
            if (_this.props.onKeyDown) {
                _this.props.onKeyDown(e);
                if (e.defaultPrevented) {
                    return;
                }
            }
            var id = _this.getId();
            if (typeof id !== 'string') {
                return;
            }
            if (!isKeyArrow(e)) {
                return;
            }
            e.preventDefault();
            var delta = isKeyArrowLeft(e) || isKeyArrowUp(e) ? -1 : 1;
            _this.context.shiftFocus(id, delta);
        };
        _this.handleFocus = function () {
            var _a, _b;
            if (_this.props.disabled) {
                return;
            }
            // focus event fires before keyDown eventlistener
            // so we should check focusKeyPressed in async way
            (_b = (_a = _this.globalObject).requestAnimationFrame) === null || _b === void 0 ? void 0 : _b.call(_a, function () {
                if (_this.keyListener.isTabPressed || _this.keyListener.isArrowPressed) {
                    _this.setState({ focusedByKeyboard: true });
                }
            });
        };
        _this.handleBlur = function () {
            if (_this.props.disabled) {
                return;
            }
            _this.setState({ focusedByKeyboard: false });
        };
        invariant(_this.context !== TabsContextDefaultValue, 'Tab should be placed inside Tabs component');
        return _this;
    }
    Tab_1 = Tab;
    Tab.prototype.componentDidMount = function () {
        this.keyListener = new KeyListener(this.globalObject);
        var id = this.getId();
        if (typeof id === 'string') {
            this.context.addTab(id, this.getTabInstance);
        }
    };
    Tab.prototype.componentDidUpdate = function () {
        if (this.context.activeTab === this.props.id) {
            this.context.notifyUpdate();
        }
    };
    Tab.prototype.componentWillUnmount = function () {
        var id = this.getId();
        if (typeof id === 'string') {
            this.context.removeTab(id);
        }
    };
    Tab.prototype.render = function () {
        var _this = this;
        this.styles = getStyles(this.emotion);
        this.horizontalStyles = getHorizontalStyles(this.emotion);
        this.verticalStyles = getVerticalStyles(this.emotion);
        return (React.createElement(ThemeContext.Consumer, null, function (theme) {
            _this.theme = theme;
            return _this.renderMain();
        }));
    };
    Tab.prototype.getIndicators = function () {
        return {
            error: Boolean(this.props.error),
            warning: Boolean(this.props.warning),
            success: Boolean(this.props.success),
            primary: Boolean(this.props.primary),
            disabled: Boolean(this.props.disabled),
        };
    };
    Tab.prototype.getUnderlyingNode = function () {
        return this.tabComponent;
    };
    Tab.prototype.renderMain = function () {
        var _a, _b;
        var _c = this.props, children = _c.children, disabled = _c.disabled, error = _c.error, warning = _c.warning, success = _c.success, primary = _c.primary, ariaDescribedby = _c["aria-describedby"], ariaLabel = _c["aria-label"];
        var _d = this.getProps(), Component = _d.component, href = _d.href;
        var isActive = false;
        var isVertical = false;
        var id = this.getId();
        if (typeof id === 'string') {
            isActive = this.context.activeTab === this.getId();
            isVertical = this.context.vertical;
        }
        var orientationStyles = isVertical ? this.verticalStyles : this.horizontalStyles;
        return (React.createElement(CommonWrapper, __assign({ rootNodeRef: this.setRootNode }, getVisualStateDataAttributes({ active: isActive, disabled: disabled }), this.props),
            React.createElement(Component, { "data-tid": TabDataTids.root, className: this.cx((_a = {},
                    _a[this.styles.rootSmall(this.theme)] = this.context.size === 'small',
                    _a[this.styles.rootMedium(this.theme)] = this.context.size === 'medium',
                    _a[this.styles.rootLarge(this.theme)] = this.context.size === 'large',
                    _a[this.styles.verticalSmall(this.theme)] = !!isVertical && this.context.size === 'small',
                    _a[this.styles.verticalMedium(this.theme)] = !!isVertical && this.context.size === 'medium',
                    _a[this.styles.verticalLarge(this.theme)] = !!isVertical && this.context.size === 'large',
                    _a[orientationStyles.primary(this.theme)] = !!primary,
                    _a[orientationStyles.success(this.theme)] = !!success,
                    _a[orientationStyles.warning(this.theme)] = !!warning,
                    _a[orientationStyles.error(this.theme)] = !!error,
                    _a[this.styles.active()] = !!isActive,
                    _a[orientationStyles.active(this.theme)] = !!isActive,
                    _a[this.styles.disabled(this.theme)] = !!disabled,
                    _a[orientationStyles.disabled()] = !!disabled,
                    _a)), onBlur: this.handleBlur, onClick: this.switchTab, onFocus: this.handleFocus, onKeyDown: this.handleKeyDown, tabIndex: disabled ? -1 : 0, ref: isFunctionalComponent(Component) ? null : this.refTabComponent, href: href, "aria-describedby": ariaDescribedby, "aria-label": ariaLabel },
                React.createElement(ResizeDetector, { onResize: this.context.notifyUpdate }, children),
                this.state.focusedByKeyboard && (React.createElement("div", { className: this.cx(globalClasses.focus, (_b = {},
                        _b[this.styles.focusSmall(this.theme)] = this.context.size === 'small',
                        _b[this.styles.focusMedium(this.theme)] = this.context.size === 'medium',
                        _b[this.styles.focusLarge(this.theme)] = this.context.size === 'large',
                        _b)) })))));
    };
    var Tab_1;
    Tab.__KONTUR_REACT_UI__ = 'Tab';
    Tab.displayName = 'Tab';
    Tab.contextType = TabsContext;
    Tab.defaultProps = {
        component: 'a',
        href: '',
    };
    Tab = Tab_1 = __decorate([
        withRenderEnvironment,
        rootNode
    ], Tab);
    return Tab;
}(React.Component));
export { Tab };
//# sourceMappingURL=Tab.js.map