"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ItemDecorator = exports.ItemBase = exports.Item = exports["default"] = void 0;

var _jsxRuntime = require("react/jsx-runtime");

var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types"));

var _kind = _interopRequireDefault(require("@enact/core/kind"));

var _Spottable = _interopRequireDefault(require("@enact/spotlight/Spottable"));

var _Pure = _interopRequireDefault(require("@enact/ui/internal/Pure"));

var _Item = require("@enact/ui/Item");

var _Layout = require("@enact/ui/Layout");

var _Slottable = _interopRequireDefault(require("@enact/ui/Slottable"));

var _propTypes2 = _interopRequireDefault(require("prop-types"));

var _compose = _interopRequireDefault(require("ramda/src/compose"));

var _Marquee = require("../Marquee");

var _Skinnable = _interopRequireDefault(require("../Skinnable"));

var _ItemModule = _interopRequireDefault(require("./Item.module.css"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }

function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }

/**
 * Renders the Item content.
 *
 * @class ItemContent
 * @memberof agate/Item
 * @ui
 * @private
 */
var ItemContent = (0, _kind["default"])({
  name: 'ItemContent',
  propTypes:
  /** @lends agate/Item.ItemContent.prototype */
  {
    /**
     * Centers the content.
     *
     * @type {Boolean}
     * @public
     */
    centered: _propTypes2["default"].bool,

    /**
     * Text displayed when passed as children.
     *
     * @type {*}
     * @public
     */
    content: _propTypes2["default"].any,

    /**
     * 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:
     *
     * `label` - The label class name
     *
     * @type {Object}
     * @public
     */
    css: _propTypes2["default"].object,

    /**
     * Text displayed when passed in `label` prop.
     *
     * @type {*}
     * @public
     */
    label: _propTypes2["default"].any,

    /**
     * The position of the label relative to the primary content, `content`.
     *
     * @type {('above'|'after'|'before'|'below')}
     * @default 'below'
     * @public
     */
    labelPosition: _propTypes2["default"].oneOf(['above', 'after', 'before', 'below']),

    /**
     * Determines what triggers the marquee to start its animation.
     *
     * @type {('focus'|'hover'|'render')}
     * @public
     */
    marqueeOn: _propTypes2["default"].oneOf(['focus', 'hover', 'render'])
  },
  defaultProps: {
    labelPosition: 'below'
  },
  styles: {
    className: 'itemContent',
    css: _ItemModule["default"],
    publicClassNames: ['label']
  },
  computed: {
    className: function className(_ref) {
      var labelPosition = _ref.labelPosition,
          styler = _ref.styler;
      return styler.append({
        labelAbove: labelPosition === 'above',
        labelAfter: labelPosition === 'after',
        labelBefore: labelPosition === 'before',
        labelBelow: labelPosition === 'below'
      });
    },
    orientation: function orientation(_ref2) {
      var labelPosition = _ref2.labelPosition;
      return labelPosition === 'above' || labelPosition === 'below' ? 'vertical' : 'horizontal';
    }
  },
  // eslint-disable-next-line enact/prop-types
  render: function render(_ref3) {
    var centered = _ref3.centered,
        content = _ref3.content,
        css = _ref3.css,
        marqueeOn = _ref3.marqueeOn,
        label = _ref3.label,
        orientation = _ref3.orientation,
        styler = _ref3.styler,
        rest = _objectWithoutProperties(_ref3, ["centered", "content", "css", "marqueeOn", "label", "orientation", "styler"]);

    delete rest.labelPosition;

    if (!label) {
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, rest), {}, {
        component: _Marquee.Marquee,
        className: styler.append(css.content),
        marqueeOn: marqueeOn,
        children: content
      }));
    } else {
      return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, _objectSpread(_objectSpread({}, rest), {}, {
        children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Layout.Layout, {
          orientation: orientation,
          children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
            component: _Marquee.Marquee,
            className: css.content,
            marqueeOn: marqueeOn,
            shrink: orientation === 'vertical' || centered,
            children: content
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
            component: _Marquee.Marquee,
            className: css.label,
            marqueeOn: marqueeOn,
            shrink: true,
            children: label
          })]
        })
      }));
    }
  }
});
/**
 * Renders an Agate-styled Item without any behavior.
 *
 * @class ItemBase
 * @memberof agate/Item
 * @extends ui/Item.ItemBase
 * @ui
 * @public
 */

var ItemBase = (0, _kind["default"])({
  name: 'Item',
  propTypes:
  /** @lends agate/Item.ItemBase.prototype */
  {
    /**
     * Centers the slots and content.
     *
     * @type {Boolean}
     * @public
     */
    centered: _propTypes2["default"].bool,

    /**
     * Called with a reference to the root component.
     *
     * @type {Function|Object}
     * @public
     */
    componentRef: _propTypes["default"].ref,

    /**
     * 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:
     *
     * `item` - The root class name
     * `slotBefore` - The slot (container) preceding the text of this component
     * `slotAfter` - The slot (container) following the text of this component
     * `selected` - Applied to a `selected` button
     *
     * @type {Object}
     * @public
     */
    css: _propTypes2["default"].object,

    /**
     * Applies a disabled style and the control becomes non-interactive.
     *
     * @type {Boolean}
     * @public
     */
    disabled: _propTypes2["default"].bool,

    /**
     * Applies inline styling to the item.
     *
     * @type {Boolean}
     * @public
     */
    inline: _propTypes2["default"].bool,

    /**
     * The label to be displayed along with the text.
     *
     * @type {Node}
     * @public
     */
    label: _propTypes2["default"].node,

    /**
     * The position of the label relative to the primary content, `children`.
     *
     * @type {('above'|'after'|'before'|'below')}
     * @default 'below'
     * @public
     */
    labelPosition: _propTypes2["default"].oneOf(['above', 'after', 'before', 'below']),

    /**
     * Determines what triggers the marquee to start its animation.
     *
     * @type {('focus'|'hover'|'render')}
     * @public
     */
    marqueeOn: _propTypes2["default"].oneOf(['focus', 'hover', 'render']),

    /**
     * Applies a selected style to the component.
     *
     * @type {Boolean}
     * @private
     */
    selected: _propTypes2["default"].bool,

    /**
     * The size of the item.
     *
     * @type {('small'|'large')}
     * @default 'large'
     * @public
     */
    size: _propTypes2["default"].oneOf(['small', 'large']),

    /**
     * Nodes to be inserted after `children`.
     *
     * For LTR locales, the nodes are inserted to the right of the primary content. For RTL
     * locales, the nodes are inserted to the left. If nothing is specified, nothing, not even
     * an empty container, is rendered in this place.
     *
     * @type {Node}
     * @public
     */
    slotAfter: _propTypes2["default"].node,

    /**
     * Nodes to be inserted before `children` and `label`.
     *
     * For LTR locales, the nodes are inserted to the left of the primary content. For RTL
     * locales, the nodes are inserted to the right. If nothing is specified, nothing, not even
     * an empty container, is rendered in this place.
     *
     * @type {Node}
     * @public
     */
    slotBefore: _propTypes2["default"].node
  },
  defaultProps: {
    labelPosition: 'below',
    size: 'large'
  },
  styles: {
    css: _ItemModule["default"],
    publicClassNames: ['item', 'label', 'slotAfter', 'slotBefore']
  },
  computed: {
    className: function className(_ref4) {
      var centered = _ref4.centered,
          label = _ref4.label,
          selected = _ref4.selected,
          size = _ref4.size,
          styler = _ref4.styler;
      return styler.append({
        hasLabel: label != null,
        selected: selected,
        centered: centered
      }, size);
    },
    label: function label(_ref5) {
      var _label = _ref5.label;
      return typeof _label === 'number' ? _label.toString() : _label;
    }
  },
  render: function render(_ref6) {
    var centered = _ref6.centered,
        children = _ref6.children,
        componentRef = _ref6.componentRef,
        css = _ref6.css,
        inline = _ref6.inline,
        label = _ref6.label,
        labelPosition = _ref6.labelPosition,
        marqueeOn = _ref6.marqueeOn,
        slotAfter = _ref6.slotAfter,
        slotBefore = _ref6.slotBefore,
        rest = _objectWithoutProperties(_ref6, ["centered", "children", "componentRef", "css", "inline", "label", "labelPosition", "marqueeOn", "slotAfter", "slotBefore"]);

    delete rest.size;
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Item.ItemBase, _objectSpread(_objectSpread({
      component: _Layout.Row,
      align: centered ? 'center center' : 'center',
      ref: componentRef
    }, rest), {}, {
      inline: inline,
      css: css,
      children: [slotBefore ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
        className: css.slotBefore,
        shrink: true,
        children: slotBefore
      }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(ItemContent, {
        centered: centered,
        content: children,
        css: css,
        label: label,
        labelPosition: labelPosition,
        marqueeOn: marqueeOn,
        shrink: inline
      }), slotAfter ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Layout.Cell, {
        className: css.slotAfter,
        shrink: true,
        children: slotAfter
      }) : null]
    }));
  }
});
/**
 * Agate specific behaviors to apply to [Item]{@link agate/Item.ItemBase}.
 *
 * @class ItemDecorator
 * @hoc
 * @memberof agate/Item
 * @mixes ui/Item.ItemDecorator
 * @mixes agate/Marquee.MarqueeController
 * @mixes ui/Slottable.Slottable
 * @mixes agate/Skinnable.Skinnable
 * @mixes spotlight/Spottable.Spottable
 * @public
 */

exports.ItemBase = ItemBase;
var ItemDecorator = (0, _compose["default"])(_Item.ItemDecorator, (0, _Slottable["default"])({
  slots: ['label', 'slotAfter', 'slotBefore']
}), _Spottable["default"], (0, _Marquee.MarqueeController)({
  marqueeOnFocus: true,
  invalidateProps: ['inline']
}), _Skinnable["default"]);
/**
 * An item component with Agate behaviors applied.
 *
 * Usage:
 * ```
 * <Item>Item Content</Item>
 * ```
 *
 * @class Item
 * @memberof agate/Item
 * @extends agate/Item.ItemBase
 * @mixes agate/Item.ItemDecorator
 * @ui
 * @public
 */

exports.ItemDecorator = ItemDecorator;
var Item = (0, _Pure["default"])(ItemDecorator(ItemBase));
exports.Item = Item;
var _default = Item;
exports["default"] = _default;