"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _Input = _interopRequireDefault(require("../Input"));
var _utils = require("./utils");
var _constants = require("./constants");
var _deprecationLog = _interopRequireDefault(require("../utils/deprecationLog"));
var _excluded = ["suffix", "defaultValue", "strict", "max", "min", "hideStepper", "value", "inputRef", "step", "status", "invalidMessage", "statusMessage", "onChange", "onInvalid", "onKeyDown", "type", "disabled"];
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/NumberInput/NumberInput.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
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) { (0, _defineProperty2.default)(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; }
var NumberInput = _ref => {
  var {
      suffix,
      defaultValue,
      strict = false,
      max,
      min,
      hideStepper = false,
      value: givenValue,
      inputRef,
      step = 1,
      status,
      invalidMessage,
      statusMessage,
      onChange,
      onInvalid,
      onKeyDown,
      type,
      disabled
    } = _ref,
    props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
  var initialState = {
    hasError: false,
    localValue: ''
  };
  var [state, setState] = _react.default.useReducer((currentState, newState) => _objectSpread(_objectSpread({}, currentState), newState), initialState);
  var [inputDOM, setInputDOM] = _react.default.useState(null);
  var shouldShowError = state.hasError && invalidMessage;
  var isControlled = givenValue !== undefined && givenValue !== null && onChange;
  var hasPredefinedSteps = Array.isArray(step);
  var getCurrentValue = () => {
    var currentValue = isControlled ? givenValue : state.localValue;
    return Number(currentValue);
  };
  var getStepperDisabledState = () => {
    if (disabled) {
      return [true, true];
    }
    var currentValue = getCurrentValue();
    if (hasPredefinedSteps) {
      var sortedSteps = [...step].sort((a, b) => a - b);
      var minStep = sortedSteps[0];
      var maxStep = sortedSteps[sortedSteps.length - 1];
      var effectiveMin = min !== undefined ? Math.max(min, minStep) : minStep;
      var effectiveMax = max !== undefined ? Math.min(max, maxStep) : maxStep;
      return [currentValue >= effectiveMax, currentValue <= effectiveMin];
    }
    return [max !== undefined && currentValue >= max, min !== undefined && currentValue <= min];
  };
  var [isUpDisabled, isDownDisabled] = getStepperDisabledState();
  var setValueAndValidate = _ref2 => {
    var {
      value,
      shouldCallOnChangeCallback = true
    } = _ref2;
    var {
      numberValue,
      stringValue
    } = (0, _utils.normalizeValues)(value);
    var {
      hasError,
      validationType
    } = (0, _utils.validateValue)({
      value: stringValue,
      minValue: min,
      maxValue: max
    });
    setState({
      hasError,
      localValue: stringValue
    });
    var isControlledValidNumber = isControlled && !Number.isNaN(numberValue);
    if (hasError ? isControlledValidNumber : shouldCallOnChangeCallback) {
      onChange == null || onChange(numberValue, stringValue);
    }
    if (hasError) {
      onInvalid == null || onInvalid(stringValue, {
        validationType,
        value: stringValue
      });
    }
  };
  (0, _react.useEffect)(() => {
    if (strict) {
      (0, _deprecationLog.default)('<NumberInput/> - prop strict is deprecated and not needed anymore. By using min and max it will enforce strict both for the ticker and input automatically.');
    }
  }, [strict]);
  (0, _react.useEffect)(() => {
    var newLocalValue = (0, _utils.defaultValueToNullIfEmpty)(givenValue, defaultValue);
    setValueAndValidate({
      value: newLocalValue,
      shouldCallOnChangeCallback: false
    });
    // TODO: fix ESLint error
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [givenValue, defaultValue]);
  var increment = () => {
    var currentValue = getCurrentValue();
    var stringValue = String(currentValue || (inputDOM == null ? void 0 : inputDOM.value) || '').replace(',', '.');
    var numberValue = parseFloat(stringValue) || 0;
    var updatedValue = hasPredefinedSteps ? (0, _utils.getClosestValue)(numberValue, step, 'up') : Number((numberValue + step).toPrecision(12));
    if ((0, _utils.isInRange)({
      value: updatedValue,
      minValue: min,
      maxValue: max
    })) {
      setValueAndValidate({
        value: updatedValue
      });
    } else if (min !== undefined && updatedValue <= min) {
      setValueAndValidate({
        value: min
      });
    }
    inputDOM == null || inputDOM.focus();
  };
  var decrement = () => {
    var currentValue = getCurrentValue();
    var stringValue = String(currentValue || (inputDOM == null ? void 0 : inputDOM.value) || '').replace(',', '.');
    var numberValue = parseFloat(stringValue) || 0;
    var updatedValue = hasPredefinedSteps ? (0, _utils.getClosestValue)(numberValue, step, 'down') : Number((numberValue - step).toPrecision(12));
    if ((0, _utils.isInRange)({
      value: updatedValue,
      minValue: min,
      maxValue: max
    })) {
      setValueAndValidate({
        value: updatedValue
      });
    } else if (max !== undefined && updatedValue >= max) {
      setValueAndValidate({
        value: max
      });
    }
    inputDOM == null || inputDOM.focus();
  };
  var getInputRef = (0, _react.useCallback)(inputElement => {
    setInputDOM(inputElement);
    if (typeof inputRef === 'function') {
      inputElement && inputRef(inputElement);
    } else if (inputRef && 'current' in inputRef) {
      inputRef.current = inputElement;
    }
  }, [inputRef]);
  var getStatusMessage = () => {
    if (shouldShowError) {
      return invalidMessage;
    }
    return statusMessage;
  };
  var onInputValueChange = event => {
    var {
      value
    } = event.target;

    // matches numbers, i.e. 123 or -123
    if (/^-?\d*[.,]?\d*$/.test(value)) {
      setValueAndValidate({
        value
      });
    } else {
      setState({
        localValue: state.localValue
      });
    }
  };
  var incrementOrDecrementValue = e => {
    if (e.key === 'ArrowUp') {
      increment();
      e.preventDefault();
    }
    if (e.key === 'ArrowDown') {
      decrement();
      e.preventDefault();
    }
    onKeyDown == null || onKeyDown(e);
  };
  var shouldRenderGivenValue = isControlled &&
  // to catch values like 0. or 1. and so on and so on
  givenValue !== Number(state.localValue) &&
  // to allow entering a negative number
  state.localValue !== '-';
  return /*#__PURE__*/_react.default.createElement(_Input.default, (0, _extends2.default)({}, props, {
    disabled: disabled,
    max: max,
    min: min,
    type: type || 'text',
    value: shouldRenderGivenValue ? givenValue : state.localValue,
    onChange: onInputValueChange,
    inputRef: getInputRef,
    status: shouldShowError ? 'error' : status,
    statusMessage: getStatusMessage(),
    onKeyDown: incrementOrDecrementValue,
    ariaRoledescription: "spin button",
    inputmode: "numeric",
    suffix: suffix || !hideStepper ? /*#__PURE__*/_react.default.createElement(_Input.default.Group, {
      __self: void 0,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 256,
        columnNumber: 11
      }
    }, suffix, !hideStepper && /*#__PURE__*/_react.default.createElement(_Input.default.Ticker, {
      onUp: increment,
      onDown: decrement,
      dataHook: _constants.dataHooks.numberInputTicker,
      upDisabled: isUpDisabled,
      downDisabled: isDownDisabled,
      onMouseDown: e => e.preventDefault(),
      __self: void 0,
      __source: {
        fileName: _jsxFileName,
        lineNumber: 259,
        columnNumber: 15
      }
    })) : undefined,
    __self: void 0,
    __source: {
      fileName: _jsxFileName,
      lineNumber: 240,
      columnNumber: 5
    }
  }));
};
NumberInput.displayName = 'NumberInput';
var _default = exports.default = NumberInput;
//# sourceMappingURL=NumberInput.js.map