"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.TabGroupDecorator = exports.TabGroupBase = exports.TabGroup = void 0;
var _handle = _interopRequireWildcard(require("@enact/core/handle"));
var _kind = _interopRequireDefault(require("@enact/core/kind"));
var _util = require("@enact/core/util");
var _Group = _interopRequireDefault(require("@enact/ui/Group"));
var _Layout = require("@enact/ui/Layout");
var _Slottable = _interopRequireDefault(require("@enact/ui/Slottable"));
var _Spottable = _interopRequireDefault(require("@enact/spotlight/Spottable"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _compose = _interopRequireDefault(require("ramda/src/compose"));
var _LabeledIcon = _interopRequireDefault(require("../LabeledIcon"));
var _Skinnable = _interopRequireDefault(require("../Skinnable"));
var _ToggleButton = _interopRequireDefault(require("../ToggleButton"));
var _TabGroupModule = _interopRequireDefault(require("./TabGroup.module.css"));
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["orientation", "style", "tabLabel"],
  _excluded2 = ["afterTabs", "beforeTabs", "className", "css", "labelPosition", "onSelect", "orientation", "selectedIndex", "style"];
/**
 * Provides an Agate-themed tab group.
 *
 * @example
 * <TabGroup tabPosition={'before'} tabs={[{title: 'Home'},{title: 'Settings'}]} />
 *
 * @module agate/TabGroup
 * @exports TabGroup
 * @exports TabGroupBase
 * @exports TabGroupDecorator
 */
/**
 * A Tab component.
 *
 * @class TabBase
 * @memberof agate/TabGroup
 * @ui
 * @private
 */
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(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; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
var TabBase = (0, _kind["default"])({
  name: 'Tab',
  propTypes: /** @lends agate/TabGroup.TabBase.prototype */{
    /**
     * Customizes the component by mapping the supplied collection of CSS class names to the
     * corresponding internal elements and states of this component.
     *
     * The following classes are supported:
     *
     * * `tab` - The root class name
     *
     * @type {Object}
     * @public
     */
    css: _propTypes["default"].object,
    /**
     * The icon displayed on the tab.
     *
     * @type {String}
     * @default 'star'
     * @public
     */
    icon: _propTypes["default"].string,
    /**
     * The position of the label on the tab.
     *
     * @type {String}
     * @public
     */
    labelPosition: _propTypes["default"].string,
    /**
     * Called when the tab is clicked.
     *
     * @type {Function}
     * @public
     */
    onTabClick: _propTypes["default"].func,
    /**
     * Orientation of the tab.
     *
     * * Values: `'horizontal'`, `'vertical'`
     *
     * @type {('horizontal'|'vertical')}
     * @public
     */
    orientation: _propTypes["default"].oneOf(['horizontal', 'vertical']),
    /**
     * Provides a way to call special interface attention to the tab. It will be "featured"
     * in some way by the theme's visual rules.
     *
     * @type {Boolean}
     * @public
     */
    selected: _propTypes["default"].bool
  },
  defaultProps: {
    icon: 'star'
  },
  styles: {
    css: _TabGroupModule["default"],
    className: 'tab'
  },
  handlers: {
    onClick: (0, _handle["default"])((0, _handle.forward)('onClick'), (0, _handle.forwardCustom)('onTabClick', function (ev, _ref) {
      var index = _ref.index;
      return {
        selected: index
      };
    }))
  },
  computed: {
    className: function className(_ref2) {
      var selected = _ref2.selected,
        styler = _ref2.styler;
      return styler.append({
        selected: selected
      });
    },
    tabLabel: function tabLabel(_ref3) {
      var children = _ref3.children,
        className = _ref3.className,
        css = _ref3.css,
        icon = _ref3.icon,
        labelPosition = _ref3.labelPosition,
        orientation = _ref3.orientation,
        selected = _ref3.selected;
      var inline;
      if (orientation === 'horizontal') {
        inline = true;
      }
      if (className.includes('copper') || className.includes('cobalt')) {
        return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
          "aria-label": children,
          className: css.labeledIcon,
          role: "region",
          children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ToggleButton["default"], {
            icon: icon,
            selected: selected
          }), children]
        });
      } else {
        return /*#__PURE__*/(0, _jsxRuntime.jsx)(_LabeledIcon["default"], {
          className: css.labeledIcon,
          icon: icon,
          inline: inline,
          labelPosition: labelPosition,
          children: children
        });
      }
    }
  },
  render: function render(_ref4) {
    var orientation = _ref4.orientation,
      _ref4$style = _ref4.style,
      style = _ref4$style === void 0 ? {} : _ref4$style,
      tabLabel = _ref4.tabLabel,
      rest = _objectWithoutProperties(_ref4, _excluded);
    delete rest.labelPosition;
    delete rest.onTabClick;
    delete rest.selected;
    if (orientation === 'horizontal') {
      style.textAlign = 'center';
    }
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, rest), {}, {
      style: style,
      children: tabLabel
    }));
  }
});
var Tab = (0, _Skinnable["default"])((0, _Spottable["default"])(TabBase));

/**
 * A Tab Group component.
 *
 * @class TabGroupBase
 * @memberof agate/TabGroup
 * @ui
 * @public
 */
var TabGroupBase = exports.TabGroupBase = (0, _kind["default"])({
  name: 'TabGroup',
  propTypes: /** @lends agate/TabGroup.TabGroupBase.prototype */{
    /**
     * The position of the TabGroup related to the tab contents.
     *
     * @type {String}
     * @required
     * @public
     */
    tabPosition: _propTypes["default"].string.isRequired,
    /**
     * The provided list of tabs.
     *
     * @type {Array}
     * @required
     * @public
     */
    tabs: _propTypes["default"].array.isRequired,
    /**
     * Nodes to be inserted after the tabs.
     *
     * @type {Node}
     * @public
     */
    afterTabs: _propTypes["default"].node,
    /**
     * Nodes to be inserted before the tabs.
     *
     * @type {Node}
     * @public
     */
    beforeTabs: _propTypes["default"].node,
    /**
     * Customizes the component by mapping the supplied collection of CSS class names to the
     * corresponding internal elements and states of this component.
     *
     * The following classes are supported:
     *
     * * `tabBar` - The root class name
     *
     * @type {Object}
     * @public
     */
    css: _propTypes["default"].object,
    /**
     * Called when an item is selected.
     *
     * The event payload will be an object with the following members:
     * * `data` - The value for the option as received in the `children` prop
     * * `selected` - Number representing the selected option, 0 indexed
     *
     * @type {Function}
     * @public
     */
    onSelect: _propTypes["default"].func,
    /**
     * Orientation of the tabs.
     *
     * * Values: `'horizontal'`, `'vertical'`
     *
     * @type {('horizontal'|'vertical')}
     * @public
     */
    orientation: _propTypes["default"].oneOf(['horizontal', 'vertical']),
    /**
     * Index of the selected tab.
     *
     * @type {Number}
     * @required
     */
    selectedIndex: _propTypes["default"].number
  },
  styles: {
    css: _TabGroupModule["default"],
    className: 'tabBar'
  },
  computed: {
    className: function className(_ref5) {
      var orientation = _ref5.orientation,
        tabPosition = _ref5.tabPosition,
        styler = _ref5.styler;
      return styler.append(orientation, ['position' + (0, _util.cap)(tabPosition)]);
    },
    labelPosition: function labelPosition(_ref6) {
      var orientation = _ref6.orientation,
        tabPosition = _ref6.tabPosition;
      // TODO: this keeps the label always between the icon and the panels, is it necessary?
      if (orientation === 'vertical') {
        if (tabPosition === 'before') {
          return 'after';
        } else {
          return 'before';
        }
      } else if (tabPosition === 'before') {
        return 'below';
      } else {
        return 'above';
      }
    },
    children: function children(_ref7) {
      var tabs = _ref7.tabs;
      return tabs.map(function (tab, i) {
        tab.key = 'tab' + i;
        tab.children = tab.title || tab.children;
        delete tab.title;
        return tab;
      });
    }
  },
  render: function render(_ref8) {
    var afterTabs = _ref8.afterTabs,
      beforeTabs = _ref8.beforeTabs,
      className = _ref8.className,
      css = _ref8.css,
      labelPosition = _ref8.labelPosition,
      onSelect = _ref8.onSelect,
      orientation = _ref8.orientation,
      selectedIndex = _ref8.selectedIndex,
      style = _ref8.style,
      rest = _objectWithoutProperties(_ref8, _excluded2);
    delete rest.tabPosition;
    delete rest.tabs;
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Layout.Layout, {
      orientation: orientation,
      className: className,
      align: "stretch",
      style: style,
      children: [beforeTabs ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
        className: css.tabEnds,
        shrink: true,
        children: beforeTabs
      }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
        children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Layout, _objectSpread(_objectSpread({}, rest), {}, {
          className: css.tabGroup,
          align: "stretch center",
          childComponent: Tab,
          component: _Group["default"],
          itemProps: {
            labelPosition: labelPosition,
            orientation: orientation,
            shrink: orientation === 'vertical'
          },
          onSelect: onSelect,
          orientation: orientation,
          select: "radio",
          selected: selectedIndex,
          selectedProp: "selected"
        }))
      }), afterTabs ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
        className: css.tabEnds,
        shrink: true,
        children: afterTabs
      }) : null]
    });
  }
});
TabGroupBase.defaultSlot = 'tabs';

/**
 * Applies Agate specific behaviors to {@link agate/TabGroup.TabGroupBase|TabGroup} components.
 *
 * @hoc
 * @memberof agate/TabGroup
 * @mixes agate/Skinnable.Skinnable
 * @mixes ui/Slottable.Slottable
 * @public
 */
var TabGroupDecorator = exports.TabGroupDecorator = (0, _compose["default"])(_Skinnable["default"], (0, _Slottable["default"])({
  slots: ['tabs', 'afterTabs', 'beforeTabs']
}));

/**
 * An Tab Group component, ready to use in Agate applications.
 *
 * Usage:
 * ```
 * <TabGroup
 *   tabPosition={'before'}
 *   tabs={[
 *     {title: 'Home', icon: 'home'},
 *     {title: 'Settings', icon: 'setting'},
 *     {title: 'Theme', icon: 'display'}
 *   ]}
 * />
 * ```
 *
 * @class TabGroup
 * @memberof agate/TabGroup
 * @extends agate/TabGroup.TabGroupBase
 * @mixes agate/TabGroup.TabGroupDecorator
 * @ui
 * @public
 */
var TabGroup = exports.TabGroup = TabGroupDecorator(TabGroupBase);
var _default = exports["default"] = TabGroup;