@wix/design-system
Version:
@wix/design-system
252 lines (250 loc) • 10.1 kB
JavaScript
;
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", "tooltipPlacement"];
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,
tooltipPlacement
} = _ref,
props = (0, _objectWithoutProperties2.default)(_ref, _excluded);
(0, _react.useEffect)(() => {
if (typeof tooltipPlacement !== 'undefined') {
(0, _deprecationLog.default)('<NumberInput/> - prop "tooltipPlacement" is deprecated and will be removed in next major release, please use "statusMessageTooltipProps" instead.');
}
}, [tooltipPlacement]);
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, {
tooltipPlacement: tooltipPlacement,
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: 266,
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: 269,
columnNumber: 15
}
})) : undefined,
__self: void 0,
__source: {
fileName: _jsxFileName,
lineNumber: 249,
columnNumber: 5
}
}));
};
NumberInput.displayName = 'NumberInput';
var _default = exports.default = NumberInput;
//# sourceMappingURL=NumberInput.js.map