@activecollab/components
Version:
ActiveCollab Components
300 lines (297 loc) • 14.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useInputNumber = void 0;
var _react = require("react");
var _utils = require("../utils");
var _currencyUtils = require("../utils/currencyUtils");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var useInputNumber = exports.useInputNumber = function useInputNumber(_ref, inputRef) {
var _ref$decimalSeparator = _ref.decimalSeparator,
decimalSeparator = _ref$decimalSeparator === void 0 ? "." : _ref$decimalSeparator,
_ref$thousandSeparato = _ref.thousandSeparator,
thousandSeparator = _ref$thousandSeparato === void 0 ? "," : _ref$thousandSeparato,
disableAbbreviation = _ref.disableAbbreviation,
disableMacros = _ref.disableMacros,
decimalLength = _ref.decimalLength,
_ref$value = _ref.value,
value = _ref$value === void 0 ? undefined : _ref$value,
onChange = _ref.onChange,
onSave = _ref.onSave,
onEnterKeyPress = _ref.onEnterKeyPress,
onClick = _ref.onClick,
onCancel = _ref.onCancel,
allowEmptyValue = _ref.allowEmptyValue,
_ref$step = _ref.step,
step = _ref$step === void 0 ? 1 : _ref$step,
_ref$trimDecimals = _ref.trimDecimals,
trimDecimals = _ref$trimDecimals === void 0 ? true : _ref$trimDecimals,
limit = _ref.limit,
_ref$validation = _ref.validation,
validation = _ref$validation === void 0 ? _utils.validateNumberInput : _ref$validation,
min = _ref.min,
max = _ref.max,
onBlur = _ref.onBlur,
update = _ref.update,
_ref$shortenThreshold = _ref.shortenThreshold,
shortenThreshold = _ref$shortenThreshold === void 0 ? 1000 : _ref$shortenThreshold;
var isMaxValid = max === undefined || min === undefined || Number(max) >= Number(min);
if (!isMaxValid) {
console.warn("Warning: The maximum value is set to be lower than the minimum value. The maximum value will be ignored.");
}
var _useState = (0, _react.useState)(function () {
return value;
}),
_useState2 = _slicedToArray(_useState, 2),
numericValue = _useState2[0],
setNumericValue = _useState2[1];
var _useState3 = (0, _react.useState)(function () {
return value;
}),
_useState4 = _slicedToArray(_useState3, 2),
prevNumericValue = _useState4[0],
setPrevNumericValue = _useState4[1];
var _useState5 = (0, _react.useState)(function () {
return (0, _currencyUtils.formatNumber)(value, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation ? "long" : "short", shortenThreshold);
}),
_useState6 = _slicedToArray(_useState5, 2),
currentValue = _useState6[0],
setCurrentValue = _useState6[1];
var _useState7 = (0, _react.useState)(function () {
return (0, _currencyUtils.formatNumber)(value, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation ? "long" : "short", shortenThreshold);
}),
_useState8 = _slicedToArray(_useState7, 2),
prevValue = _useState8[0],
setPrevValue = _useState8[1];
var _useState9 = (0, _react.useState)(function () {
return (0, _currencyUtils.formatNumber)(value, "", decimalSeparator, false, decimalLength, "long", shortenThreshold);
}),
_useState10 = _slicedToArray(_useState9, 2),
unformattedValue = _useState10[0],
setUnformattedValue = _useState10[1];
var _useState11 = (0, _react.useState)(function () {
return (0, _currencyUtils.formatNumber)(value, "", decimalSeparator, false, decimalLength, "long", shortenThreshold);
}),
_useState12 = _slicedToArray(_useState11, 2),
unformattedPrevValue = _useState12[0],
setUnformattedPrevValue = _useState12[1];
var _useState13 = (0, _react.useState)(false),
_useState14 = _slicedToArray(_useState13, 2),
focused = _useState14[0],
setFocused = _useState14[1];
(0, _react.useEffect)(function () {
if (value !== prevNumericValue && (!focused || update)) {
setCurrentValue((0, _currencyUtils.formatNumber)(value, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation ? "long" : "short", shortenThreshold));
setPrevValue((0, _currencyUtils.formatNumber)(value, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation ? "long" : "short", shortenThreshold));
setUnformattedValue((0, _currencyUtils.formatNumber)(value, "", decimalSeparator, false, decimalLength, "long", shortenThreshold));
setUnformattedPrevValue((0, _currencyUtils.formatNumber)(value, "", decimalSeparator, false, decimalLength, "long", shortenThreshold));
setNumericValue(value);
setPrevNumericValue(value);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [disableAbbreviation, thousandSeparator, decimalSeparator, decimalLength, trimDecimals, value, focused]);
var escapeRef = (0, _react.useRef)(false);
var handleBlur = (0, _react.useCallback)(function (e) {
if (escapeRef.current) {
setCurrentValue(prevValue);
setUnformattedValue(unformattedPrevValue);
setNumericValue(prevNumericValue);
if (onChange) onChange(prevNumericValue);
} else {
if (e.target.value.trim().length > 0 && prevValue !== e.target.value) {
var _value = (0, _currencyUtils.formatNumber)(currentValue, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation ? "long" : "short", shortenThreshold);
var _unformatedValue = (0, _currencyUtils.formatNumber)(currentValue, "", decimalSeparator, false, decimalLength, "long", shortenThreshold);
var _numericValue = (0, _currencyUtils.getNumberFromString)(_unformatedValue, thousandSeparator, decimalSeparator);
setPrevValue(_value);
setUnformattedPrevValue(_unformatedValue);
setUnformattedValue(_unformatedValue);
setNumericValue(_numericValue);
setPrevNumericValue(_numericValue);
if (_numericValue !== prevNumericValue) onChange === null || onChange === void 0 || onChange(_numericValue);
setCurrentValue(_value);
typeof onSave === "function" && onSave(e);
} else {
if (!allowEmptyValue) {
setCurrentValue(prevValue);
setUnformattedValue(unformattedPrevValue);
setNumericValue(prevNumericValue);
onChange === null || onChange === void 0 || onChange(prevNumericValue);
typeof onCancel === "function" && onCancel(e);
} else {
if (prevValue !== e.target.value) {
onSave === null || onSave === void 0 || onSave(e);
} else {
typeof onCancel === "function" && onCancel(e);
}
}
}
}
setFocused(false);
typeof onBlur === "function" && onBlur(e);
}, [currentValue, onBlur, prevValue, unformattedPrevValue, prevNumericValue, onChange, thousandSeparator, decimalSeparator, trimDecimals, decimalLength, disableAbbreviation, shortenThreshold, onSave, allowEmptyValue, onCancel]);
var updateValue = (0, _react.useCallback)(function (type) {
if (max !== undefined && Number(numericValue) > max || min !== undefined && Number(numericValue) < min) {
return;
}
var newValue = numericValue;
if (type === "increment") {
if (max === undefined || Number(numericValue) + step <= max) {
newValue = Number(numericValue) + step;
} else if (Number(numericValue) < max) {
newValue = max;
} else {
return;
}
} else if (type === "decrement") {
if (min === undefined || Number(numericValue) - step >= min) {
newValue = Number(numericValue) - step;
} else if (Number(numericValue) > min) {
newValue = min;
} else {
return;
}
}
var formattedValue;
if (decimalLength !== undefined) {
formattedValue = Number(newValue).toFixed(decimalLength);
} else {
formattedValue = Number(newValue).toFixed(2);
}
if (decimalLength !== undefined && decimalLength === 0) {
formattedValue = Math.round(Number(newValue)).toString();
}
if (formattedValue.includes(".") || formattedValue.includes(",")) {
formattedValue = formattedValue.replace(".", decimalSeparator);
}
setNumericValue(newValue);
setPrevNumericValue(newValue);
setUnformattedValue(formattedValue);
setCurrentValue(formattedValue);
if (onChange) onChange(newValue);
}, [max, numericValue, min, decimalLength, onChange, step, decimalSeparator]);
var handleKeyDown = (0, _react.useCallback)(function (e) {
if (e.key === "Enter") {
e.target.blur();
if (typeof onEnterKeyPress === "function") onEnterKeyPress(numericValue);
}
if (e.key === "ArrowLeft") {
return;
}
if (e.key === "ArrowRight") {
return;
}
if (e.key === "ArrowUp") {
e.preventDefault();
updateValue("increment");
}
if (e.key === "ArrowDown") {
e.preventDefault();
updateValue("decrement");
}
if (e.key === "Escape") {
escapeRef.current = true;
e.target.blur();
typeof onCancel === "function" && onCancel(e);
escapeRef.current = false;
}
if (e.key === "Backspace") {
return;
}
if (e.key === "Delete") {
return;
}
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
var _inputRef$current;
(_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 || _inputRef$current.select();
return;
}
if (e.key === "Tab") {
return;
}
if ((e.metaKey || e.ctrlKey) && e.key === "v") {
e.preventDefault();
return;
}
// Disallow "-" if min is 0 or greater
if (e.key === "-" && min !== undefined && Number(min) >= 0) {
e.preventDefault();
return;
}
// Disallow decimal separator if decimalLength is 0
if (e.key === decimalSeparator && decimalLength === 0) {
e.preventDefault();
return;
}
var input = e.target;
var currentValue = input.value;
var start = input.selectionStart;
var end = input.selectionEnd;
var newValue = currentValue.substring(0, start) + e.key + currentValue.substring(end);
if (!validation(newValue, Boolean(disableMacros), decimalSeparator, decimalLength !== null && decimalLength !== void 0 ? decimalLength : 0, limit)) {
e.preventDefault();
return;
}
}, [decimalLength, decimalSeparator, disableMacros, inputRef, limit, min, numericValue, onCancel, onEnterKeyPress, updateValue, validation]);
var handleChange = (0, _react.useCallback)(function (e) {
var inputValue = e.target.value;
var numericNewValue = undefined;
var numericInput = disableMacros ? inputValue : inputValue.replace(/(\d+(?:[.,]\d+)?)([kmbtKMBT])/, function (_, num, unit) {
var normalizedNum = num.replace(",", ".");
var parts = normalizedNum.split(".");
var integerPart = parts[0];
var fractionalPart = parts[1];
var newInteger = parseInt(integerPart, 10) * _currencyUtils.currencyMultiplier[unit.toLowerCase()];
numericNewValue = parseFloat("".concat(newInteger ? newInteger : 0, ".").concat(fractionalPart ? fractionalPart : 0));
var result = newInteger.toString();
if (fractionalPart !== undefined) {
result += decimalSeparator + fractionalPart;
}
return result;
});
if (numericNewValue === undefined) {
if (inputValue) {
numericNewValue = parseFloat(inputValue.replace(",", "."));
} else {
numericNewValue = undefined;
}
}
setCurrentValue(numericInput);
setUnformattedValue(numericInput);
setNumericValue(numericNewValue);
if (onChange && numericNewValue !== numericValue) onChange(numericNewValue);
}, [disableMacros, onChange, numericValue, decimalSeparator]);
var handleClick = (0, _react.useCallback)(function (e) {
if (typeof onClick === "function") {
onClick(e);
}
}, [onClick]);
var handleFocus = (0, _react.useCallback)(function () {
setCurrentValue(unformattedValue);
setFocused(true);
}, [unformattedValue]);
var handleDoubleClick = (0, _react.useCallback)(function () {
if (inputRef.current) {
var _inputRef$current2;
(_inputRef$current2 = inputRef.current) === null || _inputRef$current2 === void 0 || _inputRef$current2.select();
}
}, [inputRef]);
return {
value: currentValue,
onBlur: handleBlur,
onKeyDown: handleKeyDown,
onChange: handleChange,
onClick: handleClick,
onDoubleClick: handleDoubleClick,
onFocus: handleFocus,
focused,
unformattedValue,
numericValue
};
};
//# sourceMappingURL=useInputNumber.js.map