"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.TabPanels = exports.TabPanel = exports.Tab = exports.TabList = exports.Tabs = exports.TabContext = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));

var _autoId = require("@reach/auto-id");

var _react = _interopRequireWildcard(require("react"));

var _Box = require("../Box");

var _Flex = require("../Flex");

var _useVariantColorWarning = require("../hooks/useVariantColorWarning");

var _Link = require("../Link");

var _PseudoBox = require("../PseudoBox");

var _assignRef = require("../utils/assignRef");

var _router = require("../utils/router");

var _styles = _interopRequireWildcard(require("./styles"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var __jsx = _react["default"].createElement;
var TabContext = /*#__PURE__*/(0, _react.createContext)({});
exports.TabContext = TabContext;
var Tab = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
  var href = props.href,
      _props$exact = props.exact,
      exact = _props$exact === void 0 ? true : _props$exact,
      onClick = props.onClick,
      pathname = props.pathname,
      isSelected = props.isSelected,
      isDisabled = props.isDisabled,
      id = props.id,
      activeProps = props.activeProps,
      rest = (0, _objectWithoutProperties2["default"])(props, ["href", "exact", "onClick", "pathname", "isSelected", "isDisabled", "id", "activeProps"]);
  (0, _react.useEffect)(function () {
    if (href) {
      if ((exact && href === pathname || !exact && pathname.indexOf(href) > -1) && !isSelected) {
        onClick(null);
      }
    }
  }, [pathname]);

  var _useContext = (0, _react.useContext)(TabContext),
      orientation = _useContext.orientation,
      variant = _useContext.variant,
      isFitted = _useContext.isFitted,
      color = _useContext.color,
      size = _useContext.size;

  var tabStyleProps = (0, _styles["default"])({
    color: color,
    orientation: orientation,
    variant: variant,
    size: size,
    isFitted: isFitted
  });
  return __jsx(_PseudoBox.PseudoBox, (0, _extends2["default"])({
    ref: ref,
    role: "tab",
    tabIndex: isSelected ? 0 : -1,
    id: "tab:".concat(id),
    outline: "none",
    as: href ? _Link.Link : 'button',
    href: href,
    type: "button",
    disabled: isDisabled,
    "aria-selected": isSelected,
    "aria-disabled": isDisabled,
    "aria-controls": "panel:".concat(id),
    onClick: onClick
  }, tabStyleProps, rest, isSelected ? activeProps : {}));
});
exports.Tab = Tab;
var TabList = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
  var children = props.children,
      onKeyDown = props.onKeyDown,
      onClick = props.onClick,
      _props$containerStyle = props.containerStyle,
      containerStyle = _props$containerStyle === void 0 ? {} : _props$containerStyle,
      rest = (0, _objectWithoutProperties2["default"])(props, ["children", "onKeyDown", "onClick", "containerStyle"]);

  var _useContext2 = (0, _react.useContext)(TabContext),
      id = _useContext2.id,
      selectedIndex = _useContext2.index,
      manualIndex = _useContext2.manualIndex,
      onManualTabChange = _useContext2.onManualTabChange,
      isManual = _useContext2.isManual,
      onChangeTab = _useContext2.onChangeTab,
      onFocusPanel = _useContext2.onFocusPanel,
      orientation = _useContext2.orientation,
      showScrollbar = _useContext2.showScrollbar,
      variant = _useContext2.variant,
      align = _useContext2.align;

  var _useRouter = (0, _router.useRouter)(),
      pathname = _useRouter.pathname;

  var _useTabListStyle = (0, _styles.useTabListStyle)({
    orientation: orientation,
    variant: variant,
    align: align,
    showScrollbar: showScrollbar
  }),
      tabListStyleProps = _useTabListStyle.root,
      tabListContainerStyleProps = _useTabListStyle.container;

  var tabListRef = (0, _react.useRef)();
  var tabContainerRef = (0, _react.useRef)();
  var allNodes = (0, _react.useRef)([]);

  var focusableIndexes = _react.Children.map(children, function (child, index) {
    if ( /*#__PURE__*/(0, _react.isValidElement)(child)) {
      return child.props.isDisabled === true ? null : index;
    }

    return null;
  }).filter(function (index) {
    return index != null;
  });

  var enabledSelectedIndex = focusableIndexes.indexOf(selectedIndex);
  var count = focusableIndexes.length;

  var enableSmartScrolling = function enableSmartScrolling(index) {
    var _tabListRef$current;

    // smart tab scrolling to center active tab
    var currentTab = allNodes.current[index].getBoundingClientRect();
    var tabListProps = tabListRef === null || tabListRef === void 0 ? void 0 : (_tabListRef$current = tabListRef.current) === null || _tabListRef$current === void 0 ? void 0 : _tabListRef$current.getBoundingClientRect();
    var containerProps = tabContainerRef === null || tabContainerRef === void 0 ? void 0 : tabContainerRef.current;

    if (containerProps && tabListProps && currentTab) {
      var _tabListRef$current2;

      var tabCenter = currentTab && (currentTab.left + currentTab.right) / 2;
      var screenCenter = containerProps && Number((containerProps.clientWidth + (tabListRef === null || tabListRef === void 0 ? void 0 : (_tabListRef$current2 = tabListRef.current) === null || _tabListRef$current2 === void 0 ? void 0 : _tabListRef$current2.scrollLeft)) / 2) || 0;
      var scrolledLeft = (containerProps === null || containerProps === void 0 ? void 0 : containerProps.scrollLeft) || 0; // If the selected tab is at the beginning of the list, scroll all the way left

      if (tabCenter + scrolledLeft < screenCenter) {
        containerProps.scrollTo({
          left: 0,
          behavior: 'smooth'
        });
      } // If the selected tab is at the end of the list, scroll all the way right


      if (tabCenter + scrolledLeft > tabListProps.width - screenCenter) {
        containerProps.scrollTo({
          left: tabListProps.width - screenCenter,
          behavior: 'smooth'
        });
      } // if the selected tab is to the right of center, scroll right


      if (tabListRef && tabListRef.current) {
        containerProps.scrollTo({
          left: scrolledLeft + (tabCenter - screenCenter),
          behavior: 'smooth'
        });
      }
    }
  };

  var updateIndex = function updateIndex(index) {
    var childIndex = focusableIndexes[index];
    allNodes.current[childIndex].focus();
    enableSmartScrolling(index);

    if (onChangeTab) {
      onChangeTab(childIndex);
    }
  };

  var handleKeyDown = function handleKeyDown(event) {
    if (event.key === 'ArrowRight') {
      event.preventDefault();
      var nextIndex = (enabledSelectedIndex + 1) % count;
      updateIndex(nextIndex);
    }

    if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
      event.preventDefault();

      var _nextIndex = (enabledSelectedIndex - 1 + count) % count;

      updateIndex(_nextIndex);
    }

    if (event.key === 'Home') {
      event.preventDefault();
      updateIndex(0);
    }

    if (event.key === 'End') {
      event.preventDefault();
      updateIndex(count - 1);
    }

    if (event.key === 'ArrowDown') {
      event.preventDefault();

      if (onFocusPanel) {
        onFocusPanel();
      }
    }

    if (onKeyDown) {
      onKeyDown(event);
    }
  };

  var clones = _react.Children.map(children, function (child, index) {
    var isSelected = isManual ? index === manualIndex : index === selectedIndex;

    var handleClick = function handleClick(event) {
      // Hack for Safari. Buttons don't receive focus on click on Safari
      // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
      allNodes.current[index].focus();
      onManualTabChange(index);
      onChangeTab(index);
      enableSmartScrolling(index);

      if (child.props.onClick) {
        child.props.onClick(event);
      }
    };

    if ( /*#__PURE__*/(0, _react.isValidElement)(child)) {
      return /*#__PURE__*/(0, _react.cloneElement)(child, {
        //  @ts-ignore
        ref: function ref(node) {
          allNodes.current[index] = node;
        },
        isSelected: isSelected,
        onClick: handleClick,
        id: "".concat(id, "-").concat(index),
        pathname: pathname
      });
    }

    return null;
  });

  return __jsx(_PseudoBox.PseudoBox, (0, _extends2["default"])({
    ref: tabContainerRef
  }, tabListContainerStyleProps, containerStyle), __jsx(_Flex.Flex, (0, _extends2["default"])({
    onKeyDown: handleKeyDown,
    ref: tabListRef,
    role: "tablist",
    "aria-orientation": orientation
  }, tabListStyleProps, rest), clones));
});
exports.TabList = TabList;
var TabPanel = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, _ref2) {
  var children = _ref.children,
      isSelected = _ref.isSelected,
      selectedPanelRef = _ref.selectedPanelRef,
      id = _ref.id,
      rest = (0, _objectWithoutProperties2["default"])(_ref, ["children", "isSelected", "selectedPanelRef", "id"]);
  return __jsx(_Box.Box, (0, _extends2["default"])({
    ref: function ref(node) {
      if (isSelected) {
        (0, _assignRef.assignRef)(selectedPanelRef, node);
      }

      (0, _assignRef.assignRef)(_ref2, node);
    },
    role: "tabpanel",
    tabIndex: -1,
    "aria-labelledby": "tab:".concat(id),
    hidden: !isSelected,
    id: "panel:".concat(id),
    outline: 0
  }, rest), children);
});
exports.TabPanel = TabPanel;
var TabPanels = /*#__PURE__*/(0, _react.forwardRef)(function (_ref3, ref) {
  var children = _ref3.children,
      rest = (0, _objectWithoutProperties2["default"])(_ref3, ["children"]);

  var _useContext3 = (0, _react.useContext)(TabContext),
      selectedIndex = _useContext3.index,
      selectedPanelRef = _useContext3.selectedPanelRef,
      id = _useContext3.id,
      isManual = _useContext3.isManual,
      manualIndex = _useContext3.manualIndex;

  var clones = _react.Children.map(children, function (child, index) {
    if (! /*#__PURE__*/(0, _react.isValidElement)(child)) {
      return null;
    }

    return /*#__PURE__*/(0, _react.cloneElement)(child, {
      isSelected: isManual ? index === manualIndex : index === selectedIndex,
      selectedPanelRef: selectedPanelRef,
      id: "".concat(id, "-").concat(index)
    });
  });

  return __jsx(_Box.Box, (0, _extends2["default"])({
    tabIndex: -1,
    ref: ref
  }, rest), clones);
});
exports.TabPanels = TabPanels;
var Tabs = /*#__PURE__*/(0, _react.forwardRef)(function (_ref4, ref) {
  var children = _ref4.children,
      onChange = _ref4.onChange,
      controlledIndex = _ref4.index,
      defaultIndex = _ref4.defaultIndex,
      isManual = _ref4.isManual,
      _ref4$variant = _ref4.variant,
      variant = _ref4$variant === void 0 ? 'line' : _ref4$variant,
      variantColor = _ref4.variantColor,
      align = _ref4.align,
      _ref4$size = _ref4.size,
      size = _ref4$size === void 0 ? 'md' : _ref4$size,
      _ref4$orientation = _ref4.orientation,
      orientation = _ref4$orientation === void 0 ? 'horizontal' : _ref4$orientation,
      showScrollbar = _ref4.showScrollbar,
      isFitted = _ref4.isFitted,
      props = (0, _objectWithoutProperties2["default"])(_ref4, ["children", "onChange", "index", "defaultIndex", "isManual", "variant", "variantColor", "align", "size", "orientation", "showScrollbar", "isFitted"]);
  // Wrong usage of `variantColor` prop is quite common
  // Let's add a warning hook that validates the passed variantColor
  (0, _useVariantColorWarning.useVariantColorWarning)('Tabs', variantColor);

  var _useState = (0, _react.useState)(controlledIndex || defaultIndex || 0),
      manualIndex = _useState[0],
      setManualIndex = _useState[1];

  var _useRef = (0, _react.useRef)(controlledIndex != null),
      isControlled = _useRef.current;

  var selectedPanelRef = (0, _react.useRef)();

  var getInitialIndex = function getInitialIndex() {
    if (!isManual) {
      return defaultIndex || 0;
    }

    return controlledIndex || defaultIndex || 0;
  };

  var _useState2 = (0, _react.useState)(getInitialIndex),
      selectedIndex = _useState2[0],
      setSelectedIndex = _useState2[1];

  var getActualIdx = function getActualIdx() {
    if (isManual) {
      return selectedIndex;
    }

    return isControlled ? controlledIndex : selectedIndex;
  };

  var actualIdx = getActualIdx();
  var manualIdx = isControlled ? controlledIndex : manualIndex;

  var onChangeTab = function onChangeTab(index) {
    if (!isControlled) {
      setSelectedIndex(index);
    }

    if (isControlled && isManual) {
      setSelectedIndex(index);
    }

    if (!isManual && onChange) {
      onChange(index);
    }
  };

  var onManualTabChange = function onManualTabChange(index) {
    if (!isControlled) {
      setManualIndex(index);
    }

    if (isManual && onChange) {
      onChange(index);
    }
  };

  var onFocusPanel = function onFocusPanel() {
    if (selectedPanelRef.current) {
      selectedPanelRef.current.focus();
    }
  };

  var id = (0, _autoId.useId)();
  var context = {
    id: id,
    index: actualIdx,
    manualIndex: manualIdx,
    onManualTabChange: onManualTabChange,
    isManual: isManual,
    onChangeTab: onChangeTab,
    selectedPanelRef: selectedPanelRef,
    onFocusPanel: onFocusPanel,
    color: variantColor,
    size: size,
    showScrollbar: showScrollbar,
    align: align,
    variant: variant,
    isFitted: isFitted,
    orientation: orientation
  };
  return (// @ts-ignore
    __jsx(TabContext.Provider, {
      value: context
    }, __jsx(_Box.Box, (0, _extends2["default"])({
      ref: ref,
      w: "100%"
    }, props), children))
  );
});
exports.Tabs = Tabs;
//# sourceMappingURL=Tabs.js.map