"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SupportedTabContentComps = exports.Content = exports.SupportedTabMenuComps = exports.Tab = exports.Tabs = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const rebass_1 = require("rebass");
const react_1 = require("react");
const join_1 = tslib_1.__importDefault(require("../utils/join"));
const useProperty_1 = tslib_1.__importDefault(require("../utils/useProperty"));
const TabContext = React.createContext({
    selectedIndex: 0,
    tabCount: 0,
    setSelectedIndex: (index) => { },
});
const isTab = (c) => {
    return c.type === exports.Tab || exports.SupportedTabMenuComps.has(c.type);
};
const isTabContent = (c) => {
    return c.type === exports.Content || exports.SupportedTabContentComps.has(c.type);
};
const Tabs = (props) => {
    const { autoFocus = true, children, onValueChange: _onValueChange, defaultValue: _defaultValue, value: _value, keyboardNavigation = true, selectedIndex: _selectedIndex, defaultSelectedIndex: _defaultSelectedIndex, onSelectedIndexChange: _onSelectedIndexChange, ...boxProps } = props;
    let [selectedIndex, doSetSelectedIndex] = (0, useProperty_1.default)(props, 'selectedIndex', 0);
    const [selectedValue, setSelectedValue] = (0, useProperty_1.default)(props, 'value', 0);
    const allChildren = React.Children.toArray(children);
    const values = [];
    const tabs = allChildren.filter(isTab).map((tab, index) => {
        values.push(tab.props.value);
        return React.cloneElement(tab, {
            // @ts-ignore ignore
            index,
            keyboardNavigation,
            autoFocus,
        });
    });
    const contents = allChildren.filter(isTabContent);
    const contentValues = contents.map((c) => c.props.value);
    const shouldUseValue = (props.value !== undefined || props.defaultValue !== undefined) &&
        props.selectedIndex === undefined &&
        props.defaultSelectedIndex === undefined;
    if (shouldUseValue) {
        const indexOfValue = values.indexOf(selectedValue);
        if (indexOfValue > -1) {
            selectedIndex = indexOfValue;
        }
        const reorderContents = contentValues.filter((contentValue) => values.indexOf(contentValue) != -1).length ===
            tabs.length;
        if (reorderContents) {
            contents.sort((c1, c2) => {
                const v1 = c1.props.value;
                const v2 = c2.props.value;
                return values.indexOf(v1) - values.indexOf(v2);
            });
        }
    }
    const setSelectedIndex = (index) => {
        if (shouldUseValue) {
            const selectedValue = values[index];
            setSelectedValue(selectedValue);
        }
        doSetSelectedIndex(index);
    };
    const currentContent = contents[selectedIndex];
    const { value, ...contentProps } = (currentContent?.props || {});
    return (React.createElement(TabContext.Provider, { value: {
            selectedIndex,
            tabCount: tabs.length,
            setSelectedIndex,
        } },
        React.createElement(rebass_1.Box, { ...boxProps, className: (0, join_1.default)(boxProps.className, 'ab-Tabs'), "data-selected-index": selectedIndex },
            React.createElement(rebass_1.Flex, { flexDirection: "row", className: "ab-Tabs__Strip" },
                React.createElement(rebass_1.Box, { className: "ab-Tabs__Filler" }),
                tabs,
                React.createElement(rebass_1.Flex, { flex: 1, className: "ab-Tabs__Filler" })),
            React.createElement(rebass_1.Box, { padding: 2, ...contentProps, className: `${contentProps.className || ''} ab-Tabs__Body` }, currentContent))));
};
exports.Tabs = Tabs;
const Tab = (props) => {
    const { index, autoFocus, keyboardNavigation = true, className: propsClassName, ...boxProps } = props;
    const context = React.useContext(TabContext);
    const baseClassName = 'ab-Tabs__Tab';
    const active = context.selectedIndex === props.index;
    const beforeActive = context.selectedIndex === props.index + 1;
    const className = (0, join_1.default)(propsClassName, baseClassName, active ? `${baseClassName}--active` : '', beforeActive ? `${baseClassName}--before-active` : '');
    const ref = (0, react_1.useRef)(null);
    React.useEffect(() => {
        if (active && autoFocus && keyboardNavigation) {
            ref.current?.focus();
        }
    }, [active, autoFocus]);
    return (React.createElement(rebass_1.Box, { ref: ref, padding: 2, tabIndex: active ? 0 : -1, ...boxProps, className: className, onClick: (event) => {
            context.setSelectedIndex(props.index);
            props.onClick?.(event);
        }, onKeyDown: (event) => {
            if (keyboardNavigation) {
                if (event.key === 'Enter') {
                    context.setSelectedIndex(props.index);
                }
                if (event.key === 'ArrowLeft') {
                    event.preventDefault();
                    let nextIndex = props.index - 1;
                    if (nextIndex < 0) {
                        nextIndex = context.tabCount - 1;
                    }
                    context.setSelectedIndex(nextIndex);
                }
                if (event.key === 'ArrowRight') {
                    event.preventDefault();
                    let nextIndex = props.index + 1;
                    if (nextIndex > context.tabCount - 1) {
                        nextIndex = 0;
                    }
                    context.setSelectedIndex(nextIndex);
                }
            }
            props.onKeyDown?.(event);
        } }));
};
exports.Tab = Tab;
exports.SupportedTabMenuComps = new Set();
exports.SupportedTabMenuComps.add(exports.Tab);
const Content = (props) => {
    return React.createElement(React.Fragment, null, props.children);
};
exports.Content = Content;
exports.SupportedTabContentComps = new Set();
exports.SupportedTabContentComps.add(exports.Content);
exports.Tabs.Tab = exports.Tab;
exports.Tabs.Content = exports.Content;
