"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.IncrementSliderDecorator = exports.IncrementSliderBase = exports.IncrementSlider = exports["default"] = void 0;

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

var _handle = require("@enact/core/handle");

var _keymap = require("@enact/core/keymap");

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

var _util = require("@enact/core/util");

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

var _Changeable = _interopRequireDefault(require("@enact/ui/Changeable"));

var _IdProvider = _interopRequireDefault(require("@enact/ui/internal/IdProvider"));

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

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

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

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

var _$L = _interopRequireDefault(require("../internal/$L"));

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

var _Slider = require("../Slider");

var _utils = require("../Slider/utils");

var _SliderBehaviorDecorator = _interopRequireDefault(require("../Slider/SliderBehaviorDecorator"));

var _IncrementSliderButton = _interopRequireDefault(require("./IncrementSliderButton"));

var _IncrementSliderModule = _interopRequireDefault(require("./IncrementSlider.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; }

var isDown = (0, _keymap.is)('down');
var isLeft = (0, _keymap.is)('left');
var isRight = (0, _keymap.is)('right');
var isUp = (0, _keymap.is)('up');
var Slider = (0, _Spottable["default"])((0, _Skinnable["default"])(_Slider.SliderBase));

var forwardWithType = function forwardWithType(type, props) {
  return (0, _handle.forward)(type, {
    type: type
  }, props);
};
/**
 * A stateless Slider with IconButtons to increment and decrement the value. In most circumstances,
 * you will want to use the stateful version: {@link agate/IncrementSlider.IncrementSlider}.
 *
 * @class IncrementSliderBase
 * @memberof agate/IncrementSlider
 * @extends agate/Slider.SliderBase
 * @ui
 * @public
 */


var IncrementSliderBase = (0, _kind["default"])({
  name: 'IncrementSlider',
  propTypes:
  /** @lends agate/IncrementSlider.IncrementSliderBase.prototype */
  {
    /**
     * Sets the knob to selected state and allows it to move via 5-way controls.
     *
     * @type {Boolean}
     * @public
     */
    active: _propTypes["default"].bool,

    /**
     * Prevents read out of both the slider and the increment and decrement
     * buttons.
     *
     * @type {Boolean}
     * @public
     */
    'aria-hidden': _propTypes["default"].bool,

    /**
     * Overrides the `aria-valuetext` for the slider. By default, `aria-valuetext` is set
     * to the current value. This should only be used when the parent controls the value of
     * the slider directly through the props.
     *
     * @type {String|Number}
     * @public
     */
    'aria-valuetext': _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),

    /**
     * Background progress, as a proportion between `0` and `1`.
     *
     * @type {Number}
     * @default 0
     * @public
     */
    backgroundProgress: _propTypes["default"].number,

    /**
     * Customizes the component by mapping the supplied collection of CSS class names to the
     * corresponding internal elements and states of this component.
     *
     * @type {Object}
     * @private
     */
    css: _propTypes["default"].object,

    /**
    * Sets the hint string read when focusing the decrement button.
    *
    * @type {String}
    * @default 'press button to decrease the value'
    * @public
    */
    decrementAriaLabel: _propTypes["default"].string,

    /**
     * Assign a custom icon for the decrementer. All strings supported by [Icon]{@link agate/Icon.Icon} are
     * supported. Without a custom icon, the default is used, and is automatically changed when
     * [vertical]{@link agate/IncrementSlider.IncrementSlider#vertical} is changed.
     *
     * @type {String}
     * @default 'minus'
     * @public
     */
    decrementIcon: _propTypes["default"].string,

    /**
     * Disables the slider and prevents events from firing.
     *
     * @type {Boolean}
     * @public
     */
    disabled: _propTypes["default"].bool,

    /**
     * Indicates focused state.
     * @type {Boolean}
     * @public
     */
    focused: _propTypes["default"].bool,

    /**
     * The slider id reference for setting aria-controls.
     *
     * @type {String}
     * @private
     */
    id: _propTypes["default"].string,

    /**
    * Sets the hint string read when focusing the increment button.
    *
    * @default 'press button to increase the value'
    * @type {String}
    * @public
    */
    incrementAriaLabel: _propTypes["default"].string,

    /**
     * Assign a custom icon for the incrementer. All strings supported by [Icon]{@link agate/Icon.Icon} are
     * supported. Without a custom icon, the default is used, and is automatically changed when
     * [vertical]{@link agate/IncrementSlider.IncrementSlider#vertical} is changed.
     *
     * @type {String}
     * @default 'plus'
     * @public
     */
    incrementIcon: _propTypes["default"].string,

    /**
     * The amount to increment or decrement the position of the knob via 5-way controls.
     *
     * If not specified, `step` is used for the default value.
     *
     * @type {Number}
     * @public
     */
    knobStep: _propTypes["default"].number,

    /**
     * The maximum value of the increment slider.
     *
     * @type {Number}
     * @default 100
     * @public
     */
    max: _propTypes["default"].number,

    /**
     * The minimum value of the increment slider.
     *
     * @type {Number}
     * @default 0
     * @public
     */
    min: _propTypes["default"].number,

    /**
     * Hides the slider bar fill and prevents highlight when spotted.
     *
     * @type {Boolean}
     * @default false
     * @public
     */
    noFill: _propTypes["default"].bool,

    /**
     * Called when the knob is activated or deactivated by selecting it via 5-way.
     *
     * @type {Function}
     * @public
     */
    onActivate: _propTypes["default"].func,

    /**
     * Called when the value is changed.
     *
     * @type {Function}
     * @param {Object} event
     * @param {Number} event.value The current value
     * @public
     */
    onChange: _propTypes["default"].func,

    /**
     * Called run when the decrement button becomes disabled.
     *
     * @type {Function}
     * @private
     */
    onDecrementSpotlightDisappear: _propTypes["default"].func,

    /**
     * Forwarded from SliderBehaviorDecorator onto the internal slider.
     *
     * @type {Function}
     * @private
     */
    onDragEnd: _propTypes["default"].func,

    /**
     * Forwarded from SliderBehaviorDecorator onto the internal slider.
     *
     * @type {Function}
     * @private
     */
    onDragStart: _propTypes["default"].func,

    /**
     * Called when the increment button becomes disabled.
     *
     * @type {Function}
     * @private
     */
    onIncrementSpotlightDisappear: _propTypes["default"].func,

    /**
     * Called when the increment button becomes disabled.
     *
     * @type {Function}
     * @private
     */
    onSpotlightDirection: _propTypes["default"].func,

    /**
     * Called when the component is removed while retaining focus.
     *
     * @type {Function}
     * @param {Object} event
     * @public
     */
    onSpotlightDisappear: _propTypes["default"].func,

    /**
     * Called prior to focus leaving the component when the 5-way down key is pressed.
     *
     * @type {Function}
     * @param {Object} event
     * @public
     */
    onSpotlightDown: _propTypes["default"].func,

    /**
     * Called prior to focus leaving the component when the 5-way left key is pressed.
     *
     * @type {Function}
     * @param {Object} event
     * @public
     */
    onSpotlightLeft: _propTypes["default"].func,

    /**
     * Called prior to focus leaving the component when the 5-way right key is pressed.
     *
     * @type {Function}
     * @param {Object} event
     * @public
     */
    onSpotlightRight: _propTypes["default"].func,

    /**
     * Called prior to focus leaving the component when the 5-way up key is pressed.
     *
     * @type {Function}
     * @param {Object} event
     * @public
     */
    onSpotlightUp: _propTypes["default"].func,

    /**
     * Sets the orientation of the slider, whether the slider moves left and right or up and
     * down. Must be either `'horizontal'` or `'vertical'`.
     *
     * @type {String}
     * @default 'horizontal'
     * @public
     */
    orientation: _propTypes["default"].oneOf(['horizontal', 'vertical']),

    /**
     * Sets the point, as a proportion between 0 and 1, from which the slider is filled.
     *
     * Applies to both the slider's `value` and `backgroundProgress`. In both cases,
     * setting the value of `progressAnchor` will cause the slider to fill from that point
     * down, when `value` or `backgroundProgress` is proportionally less than the anchor, or up,
     * when `value` or `backgroundProgress` is proportionally greater than the anchor, rather
     * than always from the start of the slider.
     *
     * @type {Number}
     * @default 0
     * @public
     */
    progressAnchor: _propTypes["default"].number,

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

    /**
     * Disables spotlight navigation into the component.
     *
     * @type {Boolean}
     * @default false
     * @public
     */
    spotlightDisabled: _propTypes["default"].bool,

    /**
     * The amount to increment or decrement the value.
     *
     * @type {Number}
     * @default 1
     * @public
     */
    step: _propTypes["default"].number,

    /**
     * The value of the increment slider.
     *
     * Defaults to the value of `min`.
     *
     * @type {Number}
     * @public
     */
    value: _propTypes["default"].number
  },
  defaultProps: {
    backgroundProgress: 0,
    decrementIcon: 'minus',
    incrementIcon: 'plus',
    max: 100,
    min: 0,
    noFill: false,
    orientation: 'horizontal',
    progressAnchor: 0,
    size: 'large',
    spotlightDisabled: false,
    step: 1
  },
  styles: {
    css: _IncrementSliderModule["default"],
    className: 'incrementSlider',
    publicClassNames: ['incrementSlider']
  },
  handlers: {
    onDecrement: (0, _utils.emitChange)(-1),
    onIncrement: (0, _utils.emitChange)(1),
    onKeyDown: function onKeyDown(ev, props) {
      var orientation = props.orientation;
      (0, _handle.forward)('onKeyDown', ev, props); // if the source of the event is the slider, forward it along

      if (ev.target.classList.contains(_IncrementSliderModule["default"].slider)) {
        (0, _handle.forward)('onSpotlightDirection', ev, props);
        return;
      }

      var isIncrement = ev.target.classList.contains(_IncrementSliderModule["default"].incrementButton);
      var isDecrement = ev.target.classList.contains(_IncrementSliderModule["default"].decrementButton);

      if (isRight(ev.keyCode) && (isIncrement || orientation === 'vertical')) {
        forwardWithType('onSpotlightRight', props);
      } else if (isLeft(ev.keyCode) && (isDecrement || orientation === 'vertical')) {
        forwardWithType('onSpotlightLeft', props);
      } else if (isUp(ev.keyCode) && (isIncrement || orientation === 'horizontal')) {
        forwardWithType('onSpotlightUp', props);
      } else if (isDown(ev.keyCode) && (isDecrement || orientation === 'horizontal')) {
        forwardWithType('onSpotlightDown', props);
      }
    }
  },
  computed: {
    className: function className(_ref) {
      var orientation = _ref.orientation,
          size = _ref.size,
          styler = _ref.styler;
      return styler.append(orientation, size);
    },
    decrementDisabled: function decrementDisabled(_ref2) {
      var disabled = _ref2.disabled,
          min = _ref2.min,
          _ref2$value = _ref2.value,
          value = _ref2$value === void 0 ? min : _ref2$value;
      return disabled || value <= min;
    },
    incrementDisabled: function incrementDisabled(_ref3) {
      var disabled = _ref3.disabled,
          max = _ref3.max,
          min = _ref3.min,
          _ref3$value = _ref3.value,
          value = _ref3$value === void 0 ? min : _ref3$value;
      return disabled || value >= max;
    },
    decrementAriaLabel: function decrementAriaLabel(_ref4) {
      var valueText = _ref4['aria-valuetext'],
          _decrementAriaLabel = _ref4.decrementAriaLabel,
          min = _ref4.min,
          _ref4$value = _ref4.value,
          value = _ref4$value === void 0 ? min : _ref4$value;

      if (_decrementAriaLabel == null) {
        _decrementAriaLabel = (0, _$L["default"])('press button to decrease the value');
      }

      return "".concat(valueText != null ? valueText : value, " ").concat(_decrementAriaLabel);
    },
    incrementAriaLabel: function incrementAriaLabel(_ref5) {
      var valueText = _ref5['aria-valuetext'],
          _incrementAriaLabel = _ref5.incrementAriaLabel,
          min = _ref5.min,
          _ref5$value = _ref5.value,
          value = _ref5$value === void 0 ? min : _ref5$value;

      if (_incrementAriaLabel == null) {
        _incrementAriaLabel = (0, _$L["default"])('press button to increase the value');
      }

      return "".concat(valueText != null ? valueText : value, " ").concat(_incrementAriaLabel);
    }
  },
  render: function render(_ref6) {
    var active = _ref6.active,
        ariaHidden = _ref6['aria-hidden'],
        backgroundProgress = _ref6.backgroundProgress,
        css = _ref6.css,
        decrementAriaLabel = _ref6.decrementAriaLabel,
        decrementDisabled = _ref6.decrementDisabled,
        decrementIcon = _ref6.decrementIcon,
        disabled = _ref6.disabled,
        focused = _ref6.focused,
        id = _ref6.id,
        incrementAriaLabel = _ref6.incrementAriaLabel,
        incrementDisabled = _ref6.incrementDisabled,
        incrementIcon = _ref6.incrementIcon,
        knobStep = _ref6.knobStep,
        max = _ref6.max,
        min = _ref6.min,
        noFill = _ref6.noFill,
        onActivate = _ref6.onActivate,
        onChange = _ref6.onChange,
        onDecrement = _ref6.onDecrement,
        onDecrementSpotlightDisappear = _ref6.onDecrementSpotlightDisappear,
        onDragEnd = _ref6.onDragEnd,
        onDragStart = _ref6.onDragStart,
        onIncrement = _ref6.onIncrement,
        onIncrementSpotlightDisappear = _ref6.onIncrementSpotlightDisappear,
        onSpotlightDisappear = _ref6.onSpotlightDisappear,
        orientation = _ref6.orientation,
        progressAnchor = _ref6.progressAnchor,
        size = _ref6.size,
        spotlightDisabled = _ref6.spotlightDisabled,
        step = _ref6.step,
        value = _ref6.value,
        rest = _objectWithoutProperties(_ref6, ["active", "aria-hidden", "backgroundProgress", "css", "decrementAriaLabel", "decrementDisabled", "decrementIcon", "disabled", "focused", "id", "incrementAriaLabel", "incrementDisabled", "incrementIcon", "knobStep", "max", "min", "noFill", "onActivate", "onChange", "onDecrement", "onDecrementSpotlightDisappear", "onDragEnd", "onDragStart", "onIncrement", "onIncrementSpotlightDisappear", "onSpotlightDisappear", "orientation", "progressAnchor", "size", "spotlightDisabled", "step", "value"]);

    var ariaProps = (0, _util.extractAriaProps)(rest);
    delete rest.onSpotlightDirection;
    delete rest.onSpotlightDown;
    delete rest.onSpotlightLeft;
    delete rest.onSpotlightRight;
    delete rest.onSpotlightUp;
    return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", _objectSpread(_objectSpread({
      "aria-hidden": ariaHidden
    }, rest), {}, {
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_IncrementSliderButton["default"], {
        "aria-controls": !incrementDisabled ? id : null,
        "aria-label": decrementAriaLabel,
        className: css.decrementButton,
        disabled: decrementDisabled,
        icon: decrementIcon,
        onTap: onDecrement,
        onSpotlightDisappear: onDecrementSpotlightDisappear,
        orientation: orientation,
        size: size,
        spotlightDisabled: spotlightDisabled
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Slider, _objectSpread(_objectSpread({}, ariaProps), {}, {
        active: active,
        backgroundProgress: backgroundProgress,
        css: css,
        disabled: disabled,
        focused: focused,
        id: id,
        knobStep: knobStep,
        max: max,
        min: min,
        noFill: noFill,
        onActivate: onActivate,
        onChange: onChange,
        onDragEnd: onDragEnd,
        onDragStart: onDragStart,
        onSpotlightDisappear: onSpotlightDisappear,
        orientation: orientation,
        spotlightDisabled: spotlightDisabled,
        progressAnchor: progressAnchor,
        step: step,
        value: value
      })), /*#__PURE__*/(0, _jsxRuntime.jsx)(_IncrementSliderButton["default"], {
        "aria-controls": !decrementDisabled ? id : null,
        "aria-label": incrementAriaLabel,
        className: css.incrementButton,
        disabled: incrementDisabled,
        icon: incrementIcon,
        onSpotlightDisappear: onIncrementSpotlightDisappear,
        onTap: onIncrement,
        orientation: orientation,
        size: size,
        spotlightDisabled: spotlightDisabled
      })]
    }));
  }
});
/**
 * Applies Agate specific behaviors to [IncrementSliderBase]{@link agate/IncrementSlider.IncrementSliderBase}
 *
 * @hoc
 * @memberof agate/IncrementSlider
 * @mixes ui/Changeable.Changeable
 * @mixes agate/Skinnable.Skinnable
 * @mixes ui/Slottable.Slottable
 * @public
 */

exports.IncrementSliderBase = IncrementSliderBase;
var IncrementSliderDecorator = (0, _compose["default"])(_Pure["default"], _Changeable["default"], (0, _IdProvider["default"])({
  generateProp: null,
  prefix: 's_'
}), (0, _SliderBehaviorDecorator["default"])({
  emitSpotlightEvents: 'onSpotlightDirection'
}), _Skinnable["default"], (0, _Slottable["default"])({
  slots: ['knob']
}));
/**
 * An IncrementSlider with Agate styling and SliderDecorator applied with IconButtons to
 * increment and decrement the value.
 *
 * By default, `IncrementSlider` maintains the state of its `value` property. Supply the
 * `defaultValue` property to control its initial value. If you wish to directly control updates
 * to the component, supply a value to `value` at creation time and update it in response to
 * `onChange` events.
 *
 * @class IncrementSlider
 * @memberof agate/IncrementSlider
 * @extends agate/IncrementSlider.IncrementSliderBase
 * @mixes agate/IncrementSlider.IncrementSliderDecorator
 * @ui
 * @public
 */

exports.IncrementSliderDecorator = IncrementSliderDecorator;
var IncrementSlider = IncrementSliderDecorator(IncrementSliderBase);
exports.IncrementSlider = IncrementSlider;
var _default = IncrementSlider;
exports["default"] = _default;