"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.TabPanel = void 0;
var _react = _interopRequireWildcard(require("@ariakit/react"));
var Ariakit = _react;
var _clsx = _interopRequireDefault(require("clsx"));
var _element = require("@wordpress/element");
var _compose = require("@wordpress/compose");
var _i18n = require("@wordpress/i18n");
var _button = _interopRequireDefault(require("../button"));
var _jsxRuntime = require("react/jsx-runtime");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
 * External dependencies
 */

/**
 * WordPress dependencies
 */

/**
 * Internal dependencies
 */

// Separate the actual tab name from the instance ID. This is
// necessary because Ariakit internally uses the element ID when
// a new tab is selected, but our implementation looks specifically
// for the tab name to be passed to the `onSelect` callback.
const extractTabName = id => {
  if (typeof id === 'undefined' || id === null) {
    return;
  }
  return id.match(/^tab-panel-[0-9]*-(.*)/)?.[1];
};

/**
 * TabPanel is an ARIA-compliant tabpanel.
 *
 * TabPanels organize content across different screens, data sets, and interactions.
 * It has two sections: a list of tabs, and the view to show when tabs are chosen.
 *
 * ```jsx
 * import { TabPanel } from '@wordpress/components';
 *
 * const onSelect = ( tabName ) => {
 *   console.log( 'Selecting tab', tabName );
 * };
 *
 * const MyTabPanel = () => (
 *   <TabPanel
 *     className="my-tab-panel"
 *     activeClass="active-tab"
 *     onSelect={ onSelect }
 *     tabs={ [
 *       {
 *         name: 'tab1',
 *         title: 'Tab 1',
 *         className: 'tab-one',
 *       },
 *       {
 *         name: 'tab2',
 *         title: 'Tab 2',
 *         className: 'tab-two',
 *       },
 *     ] }
 *   >
 *     { ( tab ) => <p>{ tab.title }</p> }
 *   </TabPanel>
 * );
 * ```
 */
const UnforwardedTabPanel = ({
  className,
  children,
  tabs,
  selectOnMove = true,
  initialTabName,
  orientation = 'horizontal',
  activeClass = 'is-active',
  onSelect
}, ref) => {
  const instanceId = (0, _compose.useInstanceId)(TabPanel, 'tab-panel');
  const prependInstanceId = (0, _element.useCallback)(tabName => {
    if (typeof tabName === 'undefined') {
      return;
    }
    return `${instanceId}-${tabName}`;
  }, [instanceId]);
  const tabStore = Ariakit.useTabStore({
    setSelectedId: newTabValue => {
      if (typeof newTabValue === 'undefined' || newTabValue === null) {
        return;
      }
      const newTab = tabs.find(t => prependInstanceId(t.name) === newTabValue);
      if (newTab?.disabled || newTab === selectedTab) {
        return;
      }
      const simplifiedTabName = extractTabName(newTabValue);
      if (typeof simplifiedTabName === 'undefined') {
        return;
      }
      onSelect?.(simplifiedTabName);
    },
    orientation,
    selectOnMove,
    defaultSelectedId: prependInstanceId(initialTabName),
    rtl: (0, _i18n.isRTL)()
  });
  const selectedTabName = extractTabName((0, _react.useStoreState)(tabStore, 'selectedId'));
  const setTabStoreSelectedId = (0, _element.useCallback)(tabName => {
    tabStore.setState('selectedId', prependInstanceId(tabName));
  }, [prependInstanceId, tabStore]);
  const selectedTab = tabs.find(({
    name
  }) => name === selectedTabName);
  const previousSelectedTabName = (0, _compose.usePrevious)(selectedTabName);

  // Ensure `onSelect` is called when the initial tab is selected.
  (0, _element.useEffect)(() => {
    if (previousSelectedTabName !== selectedTabName && selectedTabName === initialTabName && !!selectedTabName) {
      onSelect?.(selectedTabName);
    }
  }, [selectedTabName, initialTabName, onSelect, previousSelectedTabName]);

  // Handle selecting the initial tab.
  (0, _element.useLayoutEffect)(() => {
    // If there's a selected tab, don't override it.
    if (selectedTab) {
      return;
    }
    const initialTab = tabs.find(tab => tab.name === initialTabName);
    // Wait for the denoted initial tab to be declared before making a
    // selection. This ensures that if a tab is declared lazily it can
    // still receive initial selection.
    if (initialTabName && !initialTab) {
      return;
    }
    if (initialTab && !initialTab.disabled) {
      // Select the initial tab if it's not disabled.
      setTabStoreSelectedId(initialTab.name);
    } else {
      // Fallback to the first enabled tab when the initial tab is
      // disabled or it can't be found.
      const firstEnabledTab = tabs.find(tab => !tab.disabled);
      if (firstEnabledTab) {
        setTabStoreSelectedId(firstEnabledTab.name);
      }
    }
  }, [tabs, selectedTab, initialTabName, instanceId, setTabStoreSelectedId]);

  // Handle the currently selected tab becoming disabled.
  (0, _element.useEffect)(() => {
    // This effect only runs when the selected tab is defined and becomes disabled.
    if (!selectedTab?.disabled) {
      return;
    }
    const firstEnabledTab = tabs.find(tab => !tab.disabled);
    // If the currently selected tab becomes disabled, select the first enabled tab.
    // (if there is one).
    if (firstEnabledTab) {
      setTabStoreSelectedId(firstEnabledTab.name);
    }
  }, [tabs, selectedTab?.disabled, setTabStoreSelectedId, instanceId]);
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
    className: className,
    ref: ref,
    children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Ariakit.TabList, {
      store: tabStore,
      className: "components-tab-panel__tabs",
      children: tabs.map(tab => {
        return /*#__PURE__*/(0, _jsxRuntime.jsx)(Ariakit.Tab, {
          id: prependInstanceId(tab.name),
          className: (0, _clsx.default)('components-tab-panel__tabs-item', tab.className, {
            [activeClass]: tab.name === selectedTabName
          }),
          disabled: tab.disabled,
          "aria-controls": `${prependInstanceId(tab.name)}-view`,
          render: /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.default, {
            __next40pxDefaultSize: true,
            icon: tab.icon,
            label: tab.icon && tab.title,
            showTooltip: !!tab.icon
          }),
          children: !tab.icon && tab.title
        }, tab.name);
      })
    }), selectedTab && /*#__PURE__*/(0, _jsxRuntime.jsx)(Ariakit.TabPanel, {
      id: `${prependInstanceId(selectedTab.name)}-view`,
      store: tabStore,
      tabId: prependInstanceId(selectedTab.name),
      className: "components-tab-panel__tab-content",
      children: children(selectedTab)
    })]
  });
};
const TabPanel = exports.TabPanel = (0, _element.forwardRef)(UnforwardedTabPanel);
var _default = exports.default = TabPanel;
//# sourceMappingURL=index.js.map