Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-number-format

Package Overview
Dependencies
Maintainers
1
Versions
120
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-number-format - npm Package Compare versions

Comparing version 4.5.3 to 4.5.4

.prettierrc

1853

dist/react-number-format.es.js
/**
* react-number-format - 4.5.3
* react-number-format - 4.5.4
* Author : Sudhanshu Yadav

@@ -10,89 +10,2 @@ * Copyright (c) 2016, 2021 to Sudhanshu Yadav, released under the MIT license.

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function createCommonjsModule(fn, module) {

@@ -180,2 +93,6 @@ return module = { exports: {} }, fn(module, module.exports), module.exports;

//
// basic noop function

@@ -186,19 +103,21 @@ function noop() {}

}
function charIsNumber(_char) {
return !!(_char || '').match(/\d/);
function charIsNumber(char ) {
return !!(char || '').match(/\d/);
}
function isNil(val) {
function isNil(val ) {
return val === null || val === undefined;
}
function escapeRegExp(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
function escapeRegExp(str ) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
function getThousandsGroupRegex(thousandsGroupStyle) {
function getThousandsGroupRegex(thousandsGroupStyle ) {
switch (thousandsGroupStyle) {
case 'lakh':
return /(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/g;
case 'wan':
return /(\d)(?=(\d{4})+(?!\d))/g;
case 'thousand':

@@ -209,17 +128,29 @@ default:

}
function applyThousandSeparator(str, thousandSeparator, thousandsGroupStyle) {
function applyThousandSeparator(
str ,
thousandSeparator ,
thousandsGroupStyle
) {
var thousandsGroupRegex = getThousandsGroupRegex(thousandsGroupStyle);
var index = str.search(/[1-9]/);
index = index === -1 ? str.length : index;
return str.substring(0, index) + str.substring(index, str.length).replace(thousandsGroupRegex, '$1' + thousandSeparator);
} //spilt a float number into different parts beforeDecimal, afterDecimal, and negation
return (
str.substring(0, index) +
str.substring(index, str.length).replace(thousandsGroupRegex, '$1' + thousandSeparator)
);
}
function splitDecimal(numStr) {
var allowNegative = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
//spilt a float number into different parts beforeDecimal, afterDecimal, and negation
function splitDecimal(numStr , allowNegative) {
if ( allowNegative === void 0 ) allowNegative = true;
var hasNagation = numStr[0] === '-';
var addNegation = hasNagation && allowNegative;
numStr = numStr.replace('-', '');
var parts = numStr.split('.');
var beforeDecimal = parts[0];
var afterDecimal = parts[1] || '';
return {

@@ -229,14 +160,17 @@ beforeDecimal: beforeDecimal,

hasNagation: hasNagation,
addNegation: addNegation
addNegation: addNegation,
};
}
function fixLeadingZero(numStr) {
if (!numStr) return numStr;
function fixLeadingZero(numStr ) {
if (!numStr) { return numStr; }
var isNegative = numStr[0] === '-';
if (isNegative) numStr = numStr.substring(1, numStr.length);
if (isNegative) { numStr = numStr.substring(1, numStr.length); }
var parts = numStr.split('.');
var beforeDecimal = parts[0].replace(/^0+/, '') || '0';
var afterDecimal = parts[1] || '';
return "".concat(isNegative ? '-' : '').concat(beforeDecimal).concat(afterDecimal ? ".".concat(afterDecimal) : '');
return ("" + (isNegative ? '-' : '') + beforeDecimal + (afterDecimal ? ("." + afterDecimal) : ''));
}
/**

@@ -246,13 +180,58 @@ * limit decimal numbers to given scale

*/
function limitToScale(numStr, scale, fixedDecimalScale) {
function limitToScale(numStr , scale , fixedDecimalScale ) {
var str = '';
var filler = fixedDecimalScale ? '0' : '';
for (var i = 0; i <= scale - 1; i++) {
str += numStr[i] || filler;
}
return str;
}
function repeat(str, count) {
return Array(count + 1).join(str)
}
function toNumericString(num) {
num += ''; // typecast number to string
// store the sign and remove it from the number.
var sign = num[0] === '-' ? '-' : '';
if (sign) { num = num.substring(1); }
// split the number into cofficient and exponent
var ref = num.split(/[eE]/g);
var coefficient = ref[0];
var exponent = ref[1];
// covert exponent to number;
exponent = Number(exponent);
// if there is no exponent part or its 0, return the coffiecient with sign
if (!exponent) { return sign + coefficient; }
coefficient = coefficient.replace('.', '');
/**
* for scientific notation the current decimal index will be after first number (index 0)
* So effective decimal index will always be 1 + exponent value
*/
var decimalIndex = 1 + exponent;
var coffiecientLn = coefficient.length;
if (decimalIndex < 0) {
// if decimal index is less then 0 add preceding 0s
// add 1 as join will have
coefficient = '0.' + repeat('0', Math.abs(decimalIndex)) + coefficient;
} else if (decimalIndex >= coffiecientLn) {
// if decimal index is less then 0 add leading 0s
coefficient = coefficient + repeat('0', decimalIndex - coffiecientLn);
} else {
// else add decimal point at proper index
coefficient = (coefficient.substring(0, decimalIndex) || '0') + '.' + coefficient.substring(decimalIndex);
}
return sign + coefficient;
}
/**

@@ -262,42 +241,52 @@ * This method is required to round prop value to given scale.

*/
function roundToPrecision(numStr , scale , fixedDecimalScale ) {
//if number is empty don't do anything return empty string
if (['', '-'].indexOf(numStr) !== -1) { return numStr; }
function roundToPrecision(numStr, scale, fixedDecimalScale) {
//if number is empty don't do anything return empty string
if (['', '-'].indexOf(numStr) !== -1) return numStr;
var shoudHaveDecimalSeparator = numStr.indexOf('.') !== -1 && scale;
var _splitDecimal = splitDecimal(numStr),
beforeDecimal = _splitDecimal.beforeDecimal,
afterDecimal = _splitDecimal.afterDecimal,
hasNagation = _splitDecimal.hasNagation;
var floatValue = parseFloat("0.".concat(afterDecimal || '0'));
var floatValueStr = afterDecimal.length <= scale ? floatValue.toString() : floatValue.toFixed(scale);
var ref = splitDecimal(numStr);
var beforeDecimal = ref.beforeDecimal;
var afterDecimal = ref.afterDecimal;
var hasNagation = ref.hasNagation;
var floatValue = parseFloat(("0." + (afterDecimal || '0')));
var floatValueStr =
afterDecimal.length <= scale ? toNumericString(floatValue) : floatValue.toFixed(scale);
var roundedDecimalParts = floatValueStr.split('.');
var intPart = beforeDecimal.split('').reverse().reduce(function (roundedStr, current, idx) {
if (roundedStr.length > idx) {
return (Number(roundedStr[0]) + Number(current)).toString() + roundedStr.substring(1, roundedStr.length);
}
var intPart = beforeDecimal
.split('')
.reverse()
.reduce(function (roundedStr, current, idx) {
if (roundedStr.length > idx) {
return (
(Number(roundedStr[0]) + Number(current)).toString() +
roundedStr.substring(1, roundedStr.length)
);
}
return current + roundedStr;
}, roundedDecimalParts[0]);
return current + roundedStr;
}, roundedDecimalParts[0]);
var decimalPart = limitToScale(roundedDecimalParts[1] || '', Math.min(scale, afterDecimal.length), fixedDecimalScale);
var decimalPart = limitToScale(
roundedDecimalParts[1] || '',
Math.min(scale, afterDecimal.length),
fixedDecimalScale
);
var negation = hasNagation ? '-' : '';
var decimalSeparator = shoudHaveDecimalSeparator ? '.' : '';
return "".concat(negation).concat(intPart).concat(decimalSeparator).concat(decimalPart);
return ("" + negation + intPart + decimalSeparator + decimalPart);
}
function omit(obj, keyMaps) {
function omit(obj , keyMaps ) {
var filteredObj = {};
Object.keys(obj).forEach(function (key) {
if (!keyMaps[key]) filteredObj[key] = obj[key];
if (!keyMaps[key]) { filteredObj[key] = obj[key]; }
});
return filteredObj;
}
/** set the caret positon in an input field **/
function setCaretPosition(el, caretPos) {
el.value = el.value; // ^ this is used to not only get "focus", but
function setCaretPosition(el , caretPos ) {
el.value = el.value;
// ^ this is used to not only get 'focus', but
// to make sure we don't have it everything -selected-
// (it causes an issue in chrome, and having it doesn't hurt any other browser)
if (el !== null) {

@@ -309,5 +298,4 @@ if (el.createTextRange) {

return true;
} // (el.selectionStart === 0 added for Firefox bug)
}
// (el.selectionStart === 0 added for Firefox bug)
if (el.selectionStart || el.selectionStart === 0) {

@@ -317,5 +305,5 @@ el.focus();

return true;
} // fail city, fortunately this never happens (as far as I've tested) :)
}
// fail city, fortunately this never happens (as far as I've tested) :)
el.focus();

@@ -325,2 +313,3 @@ return false;

}
/**

@@ -332,38 +321,40 @@ Given previous value and newValue it returns the index

*/
function findChangedIndex(prevValue, newValue) {
function findChangedIndex(prevValue , newValue ) {
var i = 0,
j = 0;
j = 0;
var prevLength = prevValue.length;
var newLength = newValue.length;
while (prevValue[i] === newValue[i] && i < prevLength) { i++; }
while (prevValue[i] === newValue[i] && i < prevLength) {
i++;
} //check what has been changed from last
while (prevValue[prevLength - 1 - j] === newValue[newLength - 1 - j] && newLength - j > i && prevLength - j > i) {
//check what has been changed from last
while (
prevValue[prevLength - 1 - j] === newValue[newLength - 1 - j] &&
newLength - j > i &&
prevLength - j > i
) {
j++;
}
return {
start: i,
end: prevLength - j
};
return { start: i, end: prevLength - j };
}
/*
Returns a number whose value is limited to the given range
*/
function clamp(num, min, max) {
function clamp(num , min , max ) {
return Math.min(Math.max(num, min), max);
}
function getCurrentCaretPosition(el) {
function getCurrentCaretPosition(el ) {
/*Max of selectionStart and selectionEnd is taken for the patch of pixel and other mobile device caret bug*/
return Math.max(el.selectionStart, el.selectionEnd);
}
function addInputMode(format) {
function addInputMode(format ) {
return format || !(navigator.platform && /iPhone|iPod/.test(navigator.platform));
}
//
var propTypes$1 = {

@@ -379,7 +370,16 @@ thousandSeparator: propTypes.oneOfType([propTypes.string, propTypes.oneOf([true])]),

suffix: propTypes.string,
format: propTypes.oneOfType([propTypes.string, propTypes.func]),
format: propTypes.oneOfType([
propTypes.string,
propTypes.func
]),
removeFormatting: propTypes.func,
mask: propTypes.oneOfType([propTypes.string, propTypes.arrayOf(propTypes.string)]),
value: propTypes.oneOfType([propTypes.number, propTypes.string]),
defaultValue: propTypes.oneOfType([propTypes.number, propTypes.string]),
value: propTypes.oneOfType([
propTypes.number,
propTypes.string
]),
defaultValue: propTypes.oneOfType([
propTypes.number,
propTypes.string
]),
isNumericString: propTypes.bool,

@@ -399,7 +399,8 @@ customInput: propTypes.elementType,

renderText: propTypes.func,
getInputRef: propTypes.oneOfType([propTypes.func, // for legacy refs
propTypes.shape({
current: propTypes.any
})])
getInputRef: propTypes.oneOfType([
propTypes.func, // for legacy refs
propTypes.shape({ current: propTypes.any })
])
};
var defaultProps = {

@@ -425,969 +426,965 @@ displayType: 'input',

};
var NumberFormat = /*@__PURE__*/(function (superclass) {
function NumberFormat(props ) {
superclass.call(this, props);
var NumberFormat =
/*#__PURE__*/
function (_React$Component) {
_inherits(NumberFormat, _React$Component);
var defaultValue = props.defaultValue;
function NumberFormat(props) {
var _this;
//validate props
this.validateProps();
_classCallCheck(this, NumberFormat);
var formattedValue = this.formatValueProp(defaultValue);
_this = _possibleConstructorReturn(this, _getPrototypeOf(NumberFormat).call(this, props));
var defaultValue = props.defaultValue; //validate props
_this.validateProps();
var formattedValue = _this.formatValueProp(defaultValue);
_this.state = {
this.state = {
value: formattedValue,
numAsString: _this.removeFormatting(formattedValue),
mounted: false
numAsString: this.removeFormatting(formattedValue),
mounted: false,
};
_this.selectionBeforeInput = {
this.selectionBeforeInput = {
selectionStart: 0,
selectionEnd: 0
};
_this.onChange = _this.onChange.bind(_assertThisInitialized(_this));
_this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this));
_this.onMouseUp = _this.onMouseUp.bind(_assertThisInitialized(_this));
_this.onFocus = _this.onFocus.bind(_assertThisInitialized(_this));
_this.onBlur = _this.onBlur.bind(_assertThisInitialized(_this));
return _this;
this.onChange = this.onChange.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
}
_createClass(NumberFormat, [{
key: "componentDidMount",
value: function componentDidMount() {
// set mounted state
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({
mounted: true
});
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
this.updateValueIfRequired(prevProps);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
clearTimeout(this.focusTimeout);
}
}, {
key: "updateValueIfRequired",
value: function updateValueIfRequired(prevProps) {
var props = this.props,
state = this.state,
focusedElm = this.focusedElm;
var stateValue = state.value,
_state$numAsString = state.numAsString,
lastNumStr = _state$numAsString === void 0 ? '' : _state$numAsString; // If only state changed no need to do any thing
if ( superclass ) NumberFormat.__proto__ = superclass;
NumberFormat.prototype = Object.create( superclass && superclass.prototype );
NumberFormat.prototype.constructor = NumberFormat;
if (prevProps !== props) {
//validate props
this.validateProps();
var lastValueWithNewFormat = this.formatNumString(lastNumStr);
var formattedValue = isNil(props.value) ? lastValueWithNewFormat : this.formatValueProp();
var numAsString = this.removeFormatting(formattedValue);
var floatValue = parseFloat(numAsString);
var lastFloatValue = parseFloat(lastNumStr);
NumberFormat.prototype.componentDidMount = function componentDidMount () {
// set mounted state
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({
mounted: true
});
};
if ( //while typing set state only when float value changes
(!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue || //can also set state when float value is same and the format props changes
lastValueWithNewFormat !== stateValue || //set state always when not in focus and formatted value is changed
focusedElm === null && formattedValue !== stateValue) {
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
input: focusedElm
});
}
}
}
/** Misc methods **/
NumberFormat.prototype.componentDidUpdate = function componentDidUpdate (prevProps ) {
this.updateValueIfRequired(prevProps);
};
}, {
key: "getFloatString",
value: function getFloatString() {
var num = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var decimalScale = this.props.decimalScale;
NumberFormat.prototype.componentWillUnmount = function componentWillUnmount () {
clearTimeout(this.focusTimeout);
};
var _this$getSeparators = this.getSeparators(),
decimalSeparator = _this$getSeparators.decimalSeparator;
NumberFormat.prototype.updateValueIfRequired = function updateValueIfRequired (prevProps ) {
var ref = this;
var props = ref.props;
var state = ref.state;
var focusedElm = ref.focusedElm;
var stateValue = state.value;
var lastNumStr = state.numAsString; if ( lastNumStr === void 0 ) lastNumStr = '';
var numRegex = this.getNumberRegex(true); //remove negation for regex check
// If only state changed no need to do any thing
if(prevProps !== props) {
//validate props
this.validateProps();
var hasNegation = num[0] === '-';
if (hasNegation) num = num.replace('-', ''); //if decimal scale is zero remove decimal and number after decimalSeparator
var lastValueWithNewFormat = this.formatNumString(lastNumStr);
if (decimalSeparator && decimalScale === 0) {
num = num.split(decimalSeparator)[0];
var formattedValue = isNil(props.value) ? lastValueWithNewFormat : this.formatValueProp();
var numAsString = this.removeFormatting(formattedValue);
var floatValue = parseFloat(numAsString);
var lastFloatValue = parseFloat(lastNumStr);
if (
//while typing set state only when float value changes
((!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue) ||
//can also set state when float value is same and the format props changes
lastValueWithNewFormat !== stateValue ||
//set state always when not in focus and formatted value is changed
(focusedElm === null && formattedValue !== stateValue)
) {
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, input: focusedElm });
}
}
};
num = (num.match(numRegex) || []).join('').replace(decimalSeparator, '.'); //remove extra decimals
/** Misc methods **/
NumberFormat.prototype.getFloatString = function getFloatString (num) {
if ( num === void 0 ) num = '';
var firstDecimalIndex = num.indexOf('.');
var ref = this.props;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
var numRegex = this.getNumberRegex(true);
if (firstDecimalIndex !== -1) {
num = "".concat(num.substring(0, firstDecimalIndex), ".").concat(num.substring(firstDecimalIndex + 1, num.length).replace(new RegExp(escapeRegExp(decimalSeparator), 'g'), ''));
} //add negation back
//remove negation for regex check
var hasNegation = num[0] === '-';
if(hasNegation) { num = num.replace('-', ''); }
//if decimal scale is zero remove decimal and number after decimalSeparator
if (decimalSeparator && decimalScale === 0) {
num = num.split(decimalSeparator)[0];
}
if (hasNegation) num = '-' + num;
return num;
} //returned regex assumes decimalSeparator is as per prop
num = (num.match(numRegex) || []).join('').replace(decimalSeparator, '.');
}, {
key: "getNumberRegex",
value: function getNumberRegex(g, ignoreDecimalSeparator) {
var _this$props = this.props,
format = _this$props.format,
decimalScale = _this$props.decimalScale;
//remove extra decimals
var firstDecimalIndex = num.indexOf('.');
var _this$getSeparators2 = this.getSeparators(),
decimalSeparator = _this$getSeparators2.decimalSeparator;
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined);
if (firstDecimalIndex !== -1) {
num = (num.substring(0, firstDecimalIndex)) + "." + (num.substring(firstDecimalIndex + 1, num.length).replace(new RegExp(escapeRegExp(decimalSeparator), 'g'), ''));
}
}, {
key: "getSeparators",
value: function getSeparators() {
var decimalSeparator = this.props.decimalSeparator;
var _this$props2 = this.props,
thousandSeparator = _this$props2.thousandSeparator,
allowedDecimalSeparators = _this$props2.allowedDecimalSeparators;
if (thousandSeparator === true) {
thousandSeparator = ',';
}
//add negation back
if(hasNegation) { num = '-' + num; }
if (!allowedDecimalSeparators) {
allowedDecimalSeparators = [decimalSeparator, '.'];
}
return num;
};
return {
decimalSeparator: decimalSeparator,
thousandSeparator: thousandSeparator,
allowedDecimalSeparators: allowedDecimalSeparators
};
}
}, {
key: "getMaskAtIndex",
value: function getMaskAtIndex(index) {
var _this$props$mask = this.props.mask,
mask = _this$props$mask === void 0 ? ' ' : _this$props$mask;
//returned regex assumes decimalSeparator is as per prop
NumberFormat.prototype.getNumberRegex = function getNumberRegex (g , ignoreDecimalSeparator ) {
var ref = this.props;
var format = ref.format;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined);
};
if (typeof mask === 'string') {
return mask;
}
NumberFormat.prototype.getSeparators = function getSeparators () {
var ref = this.props;
var decimalSeparator = ref.decimalSeparator;
var ref$1 = this.props;
var thousandSeparator = ref$1.thousandSeparator;
var allowedDecimalSeparators = ref$1.allowedDecimalSeparators;
return mask[index] || ' ';
if (thousandSeparator === true) {
thousandSeparator = ',';
}
}, {
key: "getValueObject",
value: function getValueObject(formattedValue, numAsString) {
var floatValue = parseFloat(numAsString);
return {
formattedValue: formattedValue,
value: numAsString,
floatValue: isNaN(floatValue) ? undefined : floatValue
};
if (!allowedDecimalSeparators) {
allowedDecimalSeparators = [decimalSeparator, '.'];
}
}, {
key: "validateProps",
value: function validateProps() {
var mask = this.props.mask; //validate decimalSeparator and thousandSeparator
var _this$getSeparators3 = this.getSeparators(),
decimalSeparator = _this$getSeparators3.decimalSeparator,
thousandSeparator = _this$getSeparators3.thousandSeparator;
return {
decimalSeparator: decimalSeparator,
thousandSeparator: thousandSeparator,
allowedDecimalSeparators: allowedDecimalSeparators,
}
};
if (decimalSeparator === thousandSeparator) {
throw new Error("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: ".concat(thousandSeparator, " (thousandSeparator = {true} is same as thousandSeparator = \",\")\n decimalSeparator: ").concat(decimalSeparator, " (default value for decimalSeparator is .)\n "));
} //validate mask
NumberFormat.prototype.getMaskAtIndex = function getMaskAtIndex (index ) {
var ref = this.props;
var mask = ref.mask; if ( mask === void 0 ) mask = ' ';
if (typeof mask === 'string') {
return mask;
}
return mask[index] || ' ';
};
if (mask) {
var maskAsStr = mask === 'string' ? mask : mask.toString();
NumberFormat.prototype.getValueObject = function getValueObject (formattedValue , numAsString ) {
var floatValue = parseFloat(numAsString);
if (maskAsStr.match(/\d/g)) {
throw new Error("\n Mask ".concat(mask, " should not contain numeric character;\n "));
}
}
}
/** Misc methods end **/
return {
formattedValue: formattedValue,
value: numAsString,
floatValue: isNaN(floatValue) ? undefined : floatValue
};
/** caret specific methods **/
};
}, {
key: "setPatchedCaretPosition",
value: function setPatchedCaretPosition(el, caretPos, currentValue) {
/* setting caret position within timeout of 0ms is required for mobile chrome,
otherwise browser resets the caret position after we set it
We are also setting it without timeout so that in normal browser we don't see the flickering */
setCaretPosition(el, caretPos);
setTimeout(function () {
if (el.value === currentValue) setCaretPosition(el, caretPos);
}, 0);
NumberFormat.prototype.validateProps = function validateProps () {
var ref = this.props;
var mask = ref.mask;
//validate decimalSeparator and thousandSeparator
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
var thousandSeparator = ref$1.thousandSeparator;
if (decimalSeparator === thousandSeparator) {
throw new Error(("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: " + thousandSeparator + " (thousandSeparator = {true} is same as thousandSeparator = \",\")\n decimalSeparator: " + decimalSeparator + " (default value for decimalSeparator is .)\n "));
}
/* This keeps the caret within typing area so people can't type in between prefix or suffix */
}, {
key: "correctCaretPosition",
value: function correctCaretPosition(value, caretPos, direction) {
var _this$props3 = this.props,
prefix = _this$props3.prefix,
suffix = _this$props3.suffix,
format = _this$props3.format; //if value is empty return 0
//validate mask
if (mask) {
var maskAsStr = mask === 'string' ? mask : mask.toString();
if (maskAsStr.match(/\d/g)) {
throw new Error(("\n Mask " + mask + " should not contain numeric character;\n "))
}
}
if (value === '') return 0; //caret position should be between 0 and value length
};
/** Misc methods end **/
caretPos = clamp(caretPos, 0, value.length); //in case of format as number limit between prefix and suffix
/** caret specific methods **/
NumberFormat.prototype.setPatchedCaretPosition = function setPatchedCaretPosition (el , caretPos , currentValue ) {
/* setting caret position within timeout of 0ms is required for mobile chrome,
otherwise browser resets the caret position after we set it
We are also setting it without timeout so that in normal browser we don't see the flickering */
setCaretPosition(el, caretPos);
setTimeout(function () {
if(el.value === currentValue) { setCaretPosition(el, caretPos); }
}, 0);
};
if (!format) {
var hasNegation = value[0] === '-';
return clamp(caretPos, prefix.length + (hasNegation ? 1 : 0), value.length - suffix.length);
} //in case if custom format method don't do anything
/* This keeps the caret within typing area so people can't type in between prefix or suffix */
NumberFormat.prototype.correctCaretPosition = function correctCaretPosition (value , caretPos , direction ) {
var ref = this.props;
var prefix = ref.prefix;
var suffix = ref.suffix;
var format = ref.format;
//if value is empty return 0
if (value === '') { return 0; }
if (typeof format === 'function') return caretPos;
/* in case format is string find the closest # position from the caret position */
//in case the caretPos have input value on it don't do anything
//caret position should be between 0 and value length
caretPos = clamp(caretPos, 0, value.length);
if (format[caretPos] === '#' && charIsNumber(value[caretPos])) return caretPos; //if caretPos is just after input value don't do anything
//in case of format as number limit between prefix and suffix
if (!format) {
var hasNegation = value[0] === '-';
return clamp(caretPos, prefix.length + (hasNegation ? 1 : 0), value.length - suffix.length);
}
if (format[caretPos - 1] === '#' && charIsNumber(value[caretPos - 1])) return caretPos; //find the nearest caret position
//in case if custom format method don't do anything
if (typeof format === 'function') { return caretPos; }
var firstHashPosition = format.indexOf('#');
var lastHashPosition = format.lastIndexOf('#'); //limit the cursor between the first # position and the last # position
/* in case format is string find the closest # position from the caret position */
caretPos = clamp(caretPos, firstHashPosition, lastHashPosition + 1);
var nextPos = format.substring(caretPos, format.length).indexOf('#');
var caretLeftBound = caretPos;
var caretRightBound = caretPos + (nextPos === -1 ? 0 : nextPos); //get the position where the last number is present
//in case the caretPos have input value on it don't do anything
if (format[caretPos] === '#' && charIsNumber(value[caretPos])) { return caretPos; }
while (caretLeftBound > firstHashPosition && (format[caretLeftBound] !== '#' || !charIsNumber(value[caretLeftBound]))) {
caretLeftBound -= 1;
}
//if caretPos is just after input value don't do anything
if (format[caretPos - 1] === '#' && charIsNumber(value[caretPos - 1])) { return caretPos; }
var goToLeft = !charIsNumber(value[caretRightBound]) || direction === 'left' && caretPos !== firstHashPosition || caretPos - caretLeftBound < caretRightBound - caretPos;
//find the nearest caret position
var firstHashPosition = format.indexOf('#');
var lastHashPosition = format.lastIndexOf('#');
if (goToLeft) {
//check if number should be taken after the bound or after it
//if number preceding a valid number keep it after
return charIsNumber(value[caretLeftBound]) ? caretLeftBound + 1 : caretLeftBound;
}
//limit the cursor between the first # position and the last # position
caretPos = clamp(caretPos, firstHashPosition, lastHashPosition + 1);
return caretRightBound;
var nextPos = format.substring(caretPos, format.length).indexOf('#');
var caretLeftBound = caretPos;
var caretRightBound = caretPos + (nextPos === -1 ? 0 : nextPos);
//get the position where the last number is present
while (caretLeftBound > firstHashPosition && (format[caretLeftBound] !== '#' || !charIsNumber(value[caretLeftBound]))) {
caretLeftBound -= 1;
}
}, {
key: "getCaretPosition",
value: function getCaretPosition(inputValue, formattedValue, caretPos) {
var format = this.props.format;
var stateValue = this.state.value;
var numRegex = this.getNumberRegex(true);
var inputNumber = (inputValue.match(numRegex) || []).join('');
var formattedNumber = (formattedValue.match(numRegex) || []).join('');
var j, i;
j = 0;
for (i = 0; i < caretPos; i++) {
var currentInputChar = inputValue[i] || '';
var currentFormatChar = formattedValue[j] || ''; //no need to increase new cursor position if formatted value does not have those characters
//case inputValue = 1a23 and formattedValue = 123
var goToLeft = !charIsNumber(value[caretRightBound])
|| (direction === 'left' && caretPos !== firstHashPosition)
|| (caretPos - caretLeftBound < caretRightBound - caretPos);
if (!currentInputChar.match(numRegex) && currentInputChar !== currentFormatChar) continue; //When we are striping out leading zeros maintain the new cursor position
//Case inputValue = 00023 and formattedValue = 23;
if (goToLeft) {
//check if number should be taken after the bound or after it
//if number preceding a valid number keep it after
return charIsNumber(value[caretLeftBound]) ? caretLeftBound + 1 : caretLeftBound;
}
if (currentInputChar === '0' && currentFormatChar.match(numRegex) && currentFormatChar !== '0' && inputNumber.length !== formattedNumber.length) continue; //we are not using currentFormatChar because j can change here
return caretRightBound;
};
while (currentInputChar !== formattedValue[j] && j < formattedValue.length) {
j++;
}
NumberFormat.prototype.getCaretPosition = function getCaretPosition (inputValue , formattedValue , caretPos ) {
var ref = this.props;
var format = ref.format;
var stateValue = this.state.value;
var numRegex = this.getNumberRegex(true);
var inputNumber = (inputValue.match(numRegex) || []).join('');
var formattedNumber = (formattedValue.match(numRegex) || []).join('');
var j, i;
j++;
}
j = 0;
if (typeof format === 'string' && !stateValue) {
//set it to the maximum value so it goes after the last number
j = formattedValue.length;
} //correct caret position if its outside of editable area
for(i=0; i<caretPos; i++){
var currentInputChar = inputValue[i] || '';
var currentFormatChar = formattedValue[j] || '';
//no need to increase new cursor position if formatted value does not have those characters
//case inputValue = 1a23 and formattedValue = 123
if(!currentInputChar.match(numRegex) && currentInputChar !== currentFormatChar) { continue; }
//When we are striping out leading zeros maintain the new cursor position
//Case inputValue = 00023 and formattedValue = 23;
if (currentInputChar === '0' && currentFormatChar.match(numRegex) && currentFormatChar !== '0' && inputNumber.length !== formattedNumber.length) { continue; }
j = this.correctCaretPosition(formattedValue, j);
return j;
//we are not using currentFormatChar because j can change here
while(currentInputChar !== formattedValue[j] && j < formattedValue.length) { j++; }
j++;
}
/** caret specific methods ends **/
/** methods to remove formattting **/
if ((typeof format === 'string' && !stateValue)) {
//set it to the maximum value so it goes after the last number
j = formattedValue.length;
}
}, {
key: "removePrefixAndSuffix",
value: function removePrefixAndSuffix(val) {
var _this$props4 = this.props,
format = _this$props4.format,
prefix = _this$props4.prefix,
suffix = _this$props4.suffix; //remove prefix and suffix
//correct caret position if its outside of editable area
j = this.correctCaretPosition(formattedValue, j);
if (!format && val) {
var isNegative = val[0] === '-'; //remove negation sign
return j;
};
/** caret specific methods ends **/
if (isNegative) val = val.substring(1, val.length); //remove prefix
val = prefix && val.indexOf(prefix) === 0 ? val.substring(prefix.length, val.length) : val; //remove suffix
/** methods to remove formattting **/
NumberFormat.prototype.removePrefixAndSuffix = function removePrefixAndSuffix (val ) {
var ref = this.props;
var format = ref.format;
var prefix = ref.prefix;
var suffix = ref.suffix;
var suffixLastIndex = val.lastIndexOf(suffix);
val = suffix && suffixLastIndex !== -1 && suffixLastIndex === val.length - suffix.length ? val.substring(0, suffixLastIndex) : val; //add negation sign back
//remove prefix and suffix
if (!format && val) {
var isNegative = val[0] === '-';
if (isNegative) val = '-' + val;
}
//remove negation sign
if (isNegative) { val = val.substring(1, val.length); }
return val;
//remove prefix
val = prefix && val.indexOf(prefix) === 0 ? val.substring(prefix.length, val.length) : val;
//remove suffix
var suffixLastIndex = val.lastIndexOf(suffix);
val = suffix && suffixLastIndex !== -1 && suffixLastIndex === val.length - suffix.length ? val.substring(0, suffixLastIndex) : val;
//add negation sign back
if (isNegative) { val = '-' + val; }
}
}, {
key: "removePatternFormatting",
value: function removePatternFormatting(val) {
var format = this.props.format;
var formatArray = format.split('#').filter(function (str) {
return str !== '';
});
var start = 0;
var numStr = '';
for (var i = 0, ln = formatArray.length; i <= ln; i++) {
var part = formatArray[i] || ''; //if i is the last fragment take the index of end of the value
//For case like +1 (911) 911 91 91 having pattern +1 (###) ### ## ##
return val;
};
var index = i === ln ? val.length : val.indexOf(part, start);
/* in any case if we don't find the pattern part in the value assume the val as numeric string
This will be also in case if user has started typing, in any other case it will not be -1
unless wrong prop value is provided */
NumberFormat.prototype.removePatternFormatting = function removePatternFormatting (val ) {
var ref = this.props;
var format = ref.format;
var formatArray = format.split('#').filter(function (str) { return str !== ''; });
var start = 0;
var numStr = '';
if (index === -1) {
numStr = val;
break;
} else {
numStr += val.substring(start, index);
start = index + part.length;
}
}
for (var i=0, ln=formatArray.length; i <= ln; i++) {
var part = formatArray[i] || '';
return (numStr.match(/\d/g) || []).join('');
}
}, {
key: "removeFormatting",
value: function removeFormatting(val) {
var _this$props5 = this.props,
format = _this$props5.format,
removeFormatting = _this$props5.removeFormatting;
if (!val) return val;
//if i is the last fragment take the index of end of the value
//For case like +1 (911) 911 91 91 having pattern +1 (###) ### ## ##
var index = i === ln ? val.length : val.indexOf(part, start);
if (!format) {
val = this.removePrefixAndSuffix(val);
val = this.getFloatString(val);
} else if (typeof format === 'string') {
val = this.removePatternFormatting(val);
} else if (typeof removeFormatting === 'function') {
//condition need to be handled if format method is provide,
val = removeFormatting(val);
/* in any case if we don't find the pattern part in the value assume the val as numeric string
This will be also in case if user has started typing, in any other case it will not be -1
unless wrong prop value is provided */
if (index === -1) {
numStr = val;
break;
} else {
val = (val.match(/\d/g) || []).join('');
numStr += val.substring(start, index);
start = index + part.length;
}
return val;
}
/** methods to remove formattting end **/
/*** format specific methods start ***/
return (numStr.match(/\d/g) || []).join('');
};
/**
* Format when # based string is provided
* @param {string} numStr Numeric String
* @return {string} formatted Value
*/
NumberFormat.prototype.removeFormatting = function removeFormatting (val ) {
var ref = this.props;
var format = ref.format;
var removeFormatting = ref.removeFormatting;
if (!val) { return val; }
}, {
key: "formatWithPattern",
value: function formatWithPattern(numStr) {
var format = this.props.format;
var hashCount = 0;
var formattedNumberAry = format.split('');
if (!format) {
val = this.removePrefixAndSuffix(val);
val = this.getFloatString(val);
} else if (typeof format === 'string') {
val = this.removePatternFormatting(val);
} else if (typeof removeFormatting === 'function') { //condition need to be handled if format method is provide,
val = removeFormatting(val);
} else {
val = (val.match(/\d/g) || []).join('');
}
return val;
};
/** methods to remove formattting end **/
for (var i = 0, ln = format.length; i < ln; i++) {
if (format[i] === '#') {
formattedNumberAry[i] = numStr[hashCount] || this.getMaskAtIndex(hashCount);
hashCount += 1;
}
/*** format specific methods start ***/
/**
* Format when # based string is provided
* @param {string} numStr Numeric String
* @return {string} formatted Value
*/
NumberFormat.prototype.formatWithPattern = function formatWithPattern (numStr ) {
var ref = this.props;
var format = ref.format;
var hashCount = 0;
var formattedNumberAry = format.split('');
for (var i = 0, ln = format.length; i < ln; i++) {
if (format[i] === '#') {
formattedNumberAry[i] = numStr[hashCount] || this.getMaskAtIndex(hashCount);
hashCount += 1;
}
return formattedNumberAry.join('');
}
/**
* @param {string} numStr Numeric string/floatString] It always have decimalSeparator as .
* @return {string} formatted Value
*/
return formattedNumberAry.join('');
};
/**
* @param {string} numStr Numeric string/floatString] It always have decimalSeparator as .
* @return {string} formatted Value
*/
NumberFormat.prototype.formatAsNumber = function formatAsNumber (numStr ) {
var ref = this.props;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var prefix = ref.prefix;
var suffix = ref.suffix;
var allowNegative = ref.allowNegative;
var thousandsGroupStyle = ref.thousandsGroupStyle;
var ref$1 = this.getSeparators();
var thousandSeparator = ref$1.thousandSeparator;
var decimalSeparator = ref$1.decimalSeparator;
}, {
key: "formatAsNumber",
value: function formatAsNumber(numStr) {
var _this$props6 = this.props,
decimalScale = _this$props6.decimalScale,
fixedDecimalScale = _this$props6.fixedDecimalScale,
prefix = _this$props6.prefix,
suffix = _this$props6.suffix,
allowNegative = _this$props6.allowNegative,
thousandsGroupStyle = _this$props6.thousandsGroupStyle;
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || (decimalScale && fixedDecimalScale);
var ref$2 = splitDecimal(numStr, allowNegative);
var beforeDecimal = ref$2.beforeDecimal;
var afterDecimal = ref$2.afterDecimal;
var addNegation = ref$2.addNegation; // eslint-disable-line prefer-const
var _this$getSeparators4 = this.getSeparators(),
thousandSeparator = _this$getSeparators4.thousandSeparator,
decimalSeparator = _this$getSeparators4.decimalSeparator;
//apply decimal precision if its defined
if (decimalScale !== undefined) { afterDecimal = limitToScale(afterDecimal, decimalScale, fixedDecimalScale); }
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalScale && fixedDecimalScale;
if(thousandSeparator) {
beforeDecimal = applyThousandSeparator(beforeDecimal, thousandSeparator, thousandsGroupStyle);
}
var _splitDecimal = splitDecimal(numStr, allowNegative),
beforeDecimal = _splitDecimal.beforeDecimal,
afterDecimal = _splitDecimal.afterDecimal,
addNegation = _splitDecimal.addNegation; // eslint-disable-line prefer-const
//apply decimal precision if its defined
//add prefix and suffix
if(prefix) { beforeDecimal = prefix + beforeDecimal; }
if(suffix) { afterDecimal = afterDecimal + suffix; }
//restore negation sign
if (addNegation) { beforeDecimal = '-' + beforeDecimal; }
if (decimalScale !== undefined) afterDecimal = limitToScale(afterDecimal, decimalScale, fixedDecimalScale);
numStr = beforeDecimal + (hasDecimalSeparator && decimalSeparator || '') + afterDecimal;
if (thousandSeparator) {
beforeDecimal = applyThousandSeparator(beforeDecimal, thousandSeparator, thousandsGroupStyle);
} //add prefix and suffix
return numStr;
};
NumberFormat.prototype.formatNumString = function formatNumString (numStr) {
if ( numStr === void 0 ) numStr = '';
if (prefix) beforeDecimal = prefix + beforeDecimal;
if (suffix) afterDecimal = afterDecimal + suffix; //restore negation sign
var ref = this.props;
var format = ref.format;
var allowEmptyFormatting = ref.allowEmptyFormatting;
var formattedValue = numStr;
if (addNegation) beforeDecimal = '-' + beforeDecimal;
numStr = beforeDecimal + (hasDecimalSeparator && decimalSeparator || '') + afterDecimal;
return numStr;
if (numStr === '' && !allowEmptyFormatting) {
formattedValue = '';
} else if (numStr === '-' && !format) {
formattedValue = '-';
} else if (typeof format === 'string') {
formattedValue = this.formatWithPattern(formattedValue);
} else if (typeof format === 'function') {
formattedValue = format(formattedValue);
} else {
formattedValue = this.formatAsNumber(formattedValue);
}
}, {
key: "formatNumString",
value: function formatNumString() {
var numStr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var _this$props7 = this.props,
format = _this$props7.format,
allowEmptyFormatting = _this$props7.allowEmptyFormatting;
var formattedValue = numStr;
if (numStr === '' && !allowEmptyFormatting) {
formattedValue = '';
} else if (numStr === '-' && !format) {
formattedValue = '-';
} else if (typeof format === 'string') {
formattedValue = this.formatWithPattern(formattedValue);
} else if (typeof format === 'function') {
formattedValue = format(formattedValue);
} else {
formattedValue = this.formatAsNumber(formattedValue);
}
return formattedValue;
};
return formattedValue;
}
}, {
key: "formatValueProp",
value: function formatValueProp(defaultValue) {
var _this$props8 = this.props,
format = _this$props8.format,
decimalScale = _this$props8.decimalScale,
fixedDecimalScale = _this$props8.fixedDecimalScale,
allowEmptyFormatting = _this$props8.allowEmptyFormatting;
var _this$props9 = this.props,
value = _this$props9.value,
isNumericString = _this$props9.isNumericString; // if value is undefined or null, use defaultValue instead
NumberFormat.prototype.formatValueProp = function formatValueProp (defaultValue ) {
var ref = this.props;
var format = ref.format;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var allowEmptyFormatting = ref.allowEmptyFormatting;
var ref$1 = this.props;
var value = ref$1.value;
var isNumericString = ref$1.isNumericString;
value = isNil(value) ? defaultValue : value;
var isNonNumericFalsy = !value && value !== 0;
// if value is undefined or null, use defaultValue instead
value = isNil(value) ? defaultValue : value;
if (isNonNumericFalsy && allowEmptyFormatting) {
value = '';
} // if value is not defined return empty string
var isNonNumericFalsy = !value && value !== 0;
if (isNonNumericFalsy && allowEmptyFormatting) {
value = '';
}
if (isNonNumericFalsy && !allowEmptyFormatting) return '';
// if value is not defined return empty string
if (isNonNumericFalsy && !allowEmptyFormatting) { return ''; }
if (typeof value === 'number') {
value = value.toString();
isNumericString = true;
} //change infinity value to empty string
if (typeof value === 'number') {
value = toNumericString(value);
isNumericString = true;
}
//change infinity value to empty string
if (value === 'Infinity' && isNumericString) {
value = '';
}
if (value === 'Infinity' && isNumericString) {
value = '';
} //round the number based on decimalScale
//format only if non formatted value is provided
//round the number based on decimalScale
//format only if non formatted value is provided
if (isNumericString && !format && typeof decimalScale === 'number') {
value = roundToPrecision(value, decimalScale, fixedDecimalScale);
}
var formattedValue = isNumericString ? this.formatNumString(value) : this.formatInput(value);
if (isNumericString && !format && typeof decimalScale === 'number') {
value = roundToPrecision(value, decimalScale, fixedDecimalScale);
}
return formattedValue;
};
var formattedValue = isNumericString ? this.formatNumString(value) : this.formatInput(value);
return formattedValue;
}
}, {
key: "formatNegation",
value: function formatNegation() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var allowNegative = this.props.allowNegative;
var negationRegex = new RegExp('(-)');
var doubleNegationRegex = new RegExp('(-)(.)*(-)'); // Check number has '-' value
NumberFormat.prototype.formatNegation = function formatNegation (value) {
if ( value === void 0 ) value = '';
var hasNegation = negationRegex.test(value); // Check number has 2 or more '-' values
var ref = this.props;
var allowNegative = ref.allowNegative;
var negationRegex = new RegExp('(-)');
var doubleNegationRegex = new RegExp('(-)(.)*(-)');
var removeNegation = doubleNegationRegex.test(value); //remove negation
// Check number has '-' value
var hasNegation = negationRegex.test(value);
value = value.replace(/-/g, '');
// Check number has 2 or more '-' values
var removeNegation = doubleNegationRegex.test(value);
if (hasNegation && !removeNegation && allowNegative) {
value = '-' + value;
}
//remove negation
value = value.replace(/-/g, '');
return value;
if (hasNegation && !removeNegation && allowNegative) {
value = '-' + value;
}
}, {
key: "formatInput",
value: function formatInput() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var format = this.props.format; //format negation only if we are formatting as number
if (!format) {
value = this.removePrefixAndSuffix(value);
value = this.formatNegation(value);
} //remove formatting from number
return value;
};
NumberFormat.prototype.formatInput = function formatInput (value) {
if ( value === void 0 ) value = '';
value = this.removeFormatting(value);
return this.formatNumString(value);
var ref = this.props;
var format = ref.format;
//format negation only if we are formatting as number
if (!format) {
value = this.removePrefixAndSuffix(value);
value = this.formatNegation(value);
}
/*** format specific methods end ***/
}, {
key: "isCharacterAFormat",
value: function isCharacterAFormat(caretPos, value) {
var _this$props10 = this.props,
format = _this$props10.format,
prefix = _this$props10.prefix,
suffix = _this$props10.suffix,
decimalScale = _this$props10.decimalScale,
fixedDecimalScale = _this$props10.fixedDecimalScale;
//remove formatting from number
value = this.removeFormatting(value);
var _this$getSeparators5 = this.getSeparators(),
decimalSeparator = _this$getSeparators5.decimalSeparator; //check within format pattern
return this.formatNumString(value);
};
/*** format specific methods end ***/
NumberFormat.prototype.isCharacterAFormat = function isCharacterAFormat (caretPos , value ) {
var ref = this.props;
var format = ref.format;
var prefix = ref.prefix;
var suffix = ref.suffix;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
if (typeof format === 'string' && format[caretPos] !== '#') return true; //check in number format
//check within format pattern
if (typeof format === 'string' && format[caretPos] !== '#') { return true; }
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator)) {
return true;
}
//check in number format
if (!format && (caretPos < prefix.length
|| caretPos >= value.length - suffix.length
|| (decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator))
) {
return true;
}
return false;
return false;
};
NumberFormat.prototype.checkIfFormatGotDeleted = function checkIfFormatGotDeleted (start , end , value ) {
for (var i = start; i < end; i++) {
if (this.isCharacterAFormat(i, value)) { return true; }
}
}, {
key: "checkIfFormatGotDeleted",
value: function checkIfFormatGotDeleted(start, end, value) {
for (var i = start; i < end; i++) {
if (this.isCharacterAFormat(i, value)) return true;
}
return false;
};
return false;
/**
* This will check if any formatting got removed by the delete or backspace and reset the value
* It will also work as fallback if android chome keyDown handler does not work
**/
NumberFormat.prototype.correctInputValue = function correctInputValue (caretPos , lastValue , value ) {
var ref = this.props;
var format = ref.format;
var allowNegative = ref.allowNegative;
var prefix = ref.prefix;
var suffix = ref.suffix;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var allowedDecimalSeparators = ref$1.allowedDecimalSeparators;
var decimalSeparator = ref$1.decimalSeparator;
var lastNumStr = this.state.numAsString || '';
var ref$2 = this.selectionBeforeInput;
var selectionStart = ref$2.selectionStart;
var selectionEnd = ref$2.selectionEnd;
var ref$3 = findChangedIndex(lastValue, value);
var start = ref$3.start;
var end = ref$3.end;
/** Check for any allowed decimal separator is added in the numeric format and replace it with decimal separator */
if (!format && start === end && allowedDecimalSeparators.indexOf(value[selectionStart]) !== -1 ) {
var separator = decimalScale === 0 ? '' : decimalSeparator;
return value.substr(0, selectionStart) + separator + value.substr(selectionStart + 1, value.length);
}
/**
* This will check if any formatting got removed by the delete or backspace and reset the value
* It will also work as fallback if android chome keyDown handler does not work
**/
}, {
key: "correctInputValue",
value: function correctInputValue(caretPos, lastValue, value) {
var _this$props11 = this.props,
format = _this$props11.format,
allowNegative = _this$props11.allowNegative,
prefix = _this$props11.prefix,
suffix = _this$props11.suffix,
decimalScale = _this$props11.decimalScale;
var _this$getSeparators6 = this.getSeparators(),
allowedDecimalSeparators = _this$getSeparators6.allowedDecimalSeparators,
decimalSeparator = _this$getSeparators6.decimalSeparator;
var leftBound = !!format ? 0 : prefix.length;
var rightBound = lastValue.length - (!!format ? 0 : suffix.length);
var lastNumStr = this.state.numAsString || '';
var _this$selectionBefore = this.selectionBeforeInput,
selectionStart = _this$selectionBefore.selectionStart,
selectionEnd = _this$selectionBefore.selectionEnd;
if (
// don't do anything if something got added
value.length > lastValue.length ||
// or if the new value is an empty string
!value.length ||
// or if nothing has changed, in which case start will be same as end
start === end ||
// or in case if whole input is selected and new value is typed
(selectionStart === 0 && selectionEnd === lastValue.length) ||
// or in case if the whole content is replaced by browser, example (autocomplete)
(start === 0 && end === lastValue.length) ||
// or if charcters between prefix and suffix is selected.
// For numeric inputs we apply the format so, prefix and suffix can be ignored
(selectionStart === leftBound && selectionEnd === rightBound)
) {
return value;
}
var _findChangedIndex = findChangedIndex(lastValue, value),
start = _findChangedIndex.start,
end = _findChangedIndex.end;
/** Check for any allowed decimal separator is added in the numeric format and replace it with decimal separator */
//if format got deleted reset the value to last value
if (this.checkIfFormatGotDeleted(start, end, lastValue)) {
value = lastValue;
}
//for numbers check if beforeDecimal got deleted and there is nothing after decimal,
//clear all numbers in such case while keeping the - sign
if (!format) {
var numericString = this.removeFormatting(value);
var ref$4 = splitDecimal(numericString, allowNegative);
var beforeDecimal = ref$4.beforeDecimal;
var afterDecimal = ref$4.afterDecimal;
var addNegation = ref$4.addNegation; // eslint-disable-line prefer-const
if (!format && start === end && allowedDecimalSeparators.indexOf(value[selectionStart]) !== -1) {
var separator = decimalScale === 0 ? '' : decimalSeparator;
return value.substr(0, selectionStart) + separator + value.substr(selectionStart + 1, value.length);
//clear only if something got deleted
var isBeforeDecimalPoint = caretPos < value.indexOf(decimalSeparator) + 1;
if (numericString.length < lastNumStr.length && isBeforeDecimalPoint && beforeDecimal === '' && !parseFloat(afterDecimal)) {
return addNegation ? '-' : '';
}
/* don't do anyhting if something got added,
or if value is empty string (when whole input is cleared)
or whole input is replace with a number
*/
}
return value;
};
var leftBound = !!format ? 0 : prefix.length;
var rightBound = lastValue.length - (!!format ? 0 : suffix.length);
/** Update value and caret position */
NumberFormat.prototype.updateValue = function updateValue (params
) {
var formattedValue = params.formattedValue;
var input = params.input;
var setCaretPosition = params.setCaretPosition; if ( setCaretPosition === void 0 ) setCaretPosition = true;
var numAsString = params.numAsString;
var caretPos = params.caretPos;
var ref = this.props;
var onValueChange = ref.onValueChange;
var ref$1 = this.state;
var lastValue = ref$1.value;
if (value.length > lastValue.length || !value.length || start === end || selectionStart === 0 && selectionEnd === lastValue.length || start === 0 && end === lastValue.length || selectionStart === leftBound && selectionEnd === rightBound) {
return value;
} //if format got deleted reset the value to last value
if (input) {
//set caret position, and value imperatively when element is provided
if (setCaretPosition) {
//calculate caret position if not defined
if (!caretPos) {
var inputValue = params.inputValue || input.value;
if (this.checkIfFormatGotDeleted(start, end, lastValue)) {
value = lastValue;
} //for numbers check if beforeDecimal got deleted and there is nothing after decimal,
//clear all numbers in such case while keeping the - sign
var currentCaretPosition = getCurrentCaretPosition(input);
/**
* set the value imperatively, this is required for IE fix
* This is also required as if new caret position is beyond the previous value.
* Caret position will not be set correctly
*/
input.value = formattedValue;
if (!format) {
var numericString = this.removeFormatting(value);
//get the caret position
caretPos = this.getCaretPosition(inputValue, formattedValue, currentCaretPosition);
}
var _splitDecimal2 = splitDecimal(numericString, allowNegative),
beforeDecimal = _splitDecimal2.beforeDecimal,
afterDecimal = _splitDecimal2.afterDecimal,
addNegation = _splitDecimal2.addNegation; // eslint-disable-line prefer-const
//clear only if something got deleted
//set caret position
this.setPatchedCaretPosition(input, caretPos, formattedValue);
} else {
/**
* if we are not setting caret position set the value imperatively.
* This is required on onBlur method
*/
input.value = formattedValue;
}
}
var isBeforeDecimalPoint = caretPos < value.indexOf(decimalSeparator) + 1;
//calculate numeric string if not passed
if (numAsString === undefined) {
numAsString = this.removeFormatting(formattedValue);
}
if (numericString.length < lastNumStr.length && isBeforeDecimalPoint && beforeDecimal === '' && !parseFloat(afterDecimal)) {
return addNegation ? '-' : '';
}
}
//update state if value is changed
if (formattedValue !== lastValue) {
this.setState({ value : formattedValue, numAsString: numAsString });
return value;
// trigger onValueChange synchronously, so parent is updated along with the number format. Fix for #277, #287
onValueChange(this.getValueObject(formattedValue, numAsString));
}
/** Update value and caret position */
};
}, {
key: "updateValue",
value: function updateValue(params) {
var formattedValue = params.formattedValue,
input = params.input,
_params$setCaretPosit = params.setCaretPosition,
setCaretPosition = _params$setCaretPosit === void 0 ? true : _params$setCaretPosit;
var numAsString = params.numAsString,
caretPos = params.caretPos;
var onValueChange = this.props.onValueChange;
var lastValue = this.state.value;
NumberFormat.prototype.onChange = function onChange (e ) {
var el = e.target;
var inputValue = el.value;
var ref = this;
var state = ref.state;
var props = ref.props;
var isAllowed = props.isAllowed;
var lastValue = state.value || '';
if (input) {
//set caret position, and value imperatively when element is provided
if (setCaretPosition) {
//calculate caret position if not defined
if (!caretPos) {
var inputValue = params.inputValue || input.value;
var currentCaretPosition = getCurrentCaretPosition(input);
/**
* set the value imperatively, this is required for IE fix
* This is also required as if new caret position is beyond the previous value.
* Caret position will not be set correctly
*/
var currentCaretPosition = getCurrentCaretPosition(el);
input.value = formattedValue; //get the caret position
inputValue = this.correctInputValue(currentCaretPosition, lastValue, inputValue);
caretPos = this.getCaretPosition(inputValue, formattedValue, currentCaretPosition);
} //set caret position
var formattedValue = this.formatInput(inputValue) || '';
var numAsString = this.removeFormatting(formattedValue);
var valueObj = this.getValueObject(formattedValue, numAsString);
var isChangeAllowed = isAllowed(valueObj);
this.setPatchedCaretPosition(input, caretPos, formattedValue);
} else {
/**
* if we are not setting caret position set the value imperatively.
* This is required on onBlur method
*/
input.value = formattedValue;
}
} //calculate numeric string if not passed
if (!isChangeAllowed) {
formattedValue = lastValue;
}
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, inputValue: inputValue, input: el });
if (numAsString === undefined) {
numAsString = this.removeFormatting(formattedValue);
} //update state if value is changed
if(isChangeAllowed) {
props.onChange(e);
}
};
NumberFormat.prototype.onBlur = function onBlur (e ) {
var ref = this;
var props = ref.props;
var state = ref.state;
var format = props.format;
var onBlur = props.onBlur;
var allowLeadingZeros = props.allowLeadingZeros;
var numAsString = state.numAsString;
var lastValue = state.value;
this.focusedElm = null;
if (formattedValue !== lastValue) {
this.setState({
value: formattedValue,
numAsString: numAsString
}); // trigger onValueChange synchronously, so parent is updated along with the number format. Fix for #277, #287
clearTimeout(this.focusTimeout);
onValueChange(this.getValueObject(formattedValue, numAsString));
if (!format) {
// if the numAsString is not a valid number reset it to empty
if (isNaN(parseFloat(numAsString))) {
numAsString = '';
}
}
}, {
key: "onChange",
value: function onChange(e) {
var el = e.target;
var inputValue = el.value;
var state = this.state,
props = this.props;
var isAllowed = props.isAllowed;
var lastValue = state.value || '';
var currentCaretPosition = getCurrentCaretPosition(el);
inputValue = this.correctInputValue(currentCaretPosition, lastValue, inputValue);
var formattedValue = this.formatInput(inputValue) || '';
var numAsString = this.removeFormatting(formattedValue);
var valueObj = this.getValueObject(formattedValue, numAsString);
var isChangeAllowed = isAllowed(valueObj);
if (!isChangeAllowed) {
formattedValue = lastValue;
if (!allowLeadingZeros) {
numAsString = fixLeadingZero(numAsString);
}
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
inputValue: inputValue,
input: el
});
var formattedValue = this.formatNumString(numAsString);
if (isChangeAllowed) {
props.onChange(e);
//change the state
if (formattedValue !== lastValue) {
// the event needs to be persisted because its properties can be accessed in an asynchronous way
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, input: e.target, setCaretPosition: false });
onBlur(e);
return;
}
}
}, {
key: "onBlur",
value: function onBlur(e) {
var props = this.props,
state = this.state;
var format = props.format,
onBlur = props.onBlur,
allowLeadingZeros = props.allowLeadingZeros;
var numAsString = state.numAsString;
var lastValue = state.value;
this.focusedElm = null;
clearTimeout(this.focusTimeout);
onBlur(e);
};
if (!format) {
// if the numAsString is not a valid number reset it to empty
if (isNaN(parseFloat(numAsString))) {
numAsString = '';
}
NumberFormat.prototype.onKeyDown = function onKeyDown (e ) {
var el = e.target;
var key = e.key;
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
var expectedCaretPosition;
var ref = this.props;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var prefix = ref.prefix;
var suffix = ref.suffix;
var format = ref.format;
var onKeyDown = ref.onKeyDown;
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
var negativeRegex = new RegExp('-');
var isPatternFormat = typeof format === 'string';
if (!allowLeadingZeros) {
numAsString = fixLeadingZero(numAsString);
}
this.selectionBeforeInput = {
selectionStart: selectionStart,
selectionEnd: selectionEnd
};
var formattedValue = this.formatNumString(numAsString); //change the state
//Handle backspace and delete against non numerical/decimal characters or arrow keys
if (key === 'ArrowLeft' || key === 'Backspace') {
expectedCaretPosition = selectionStart - 1;
} else if (key === 'ArrowRight') {
expectedCaretPosition = selectionStart + 1;
} else if (key === 'Delete') {
expectedCaretPosition = selectionStart;
}
if (formattedValue !== lastValue) {
// the event needs to be persisted because its properties can be accessed in an asynchronous way
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
input: e.target,
setCaretPosition: false
});
onBlur(e);
return;
}
//if expectedCaretPosition is not set it means we don't want to Handle keyDown
//also if multiple characters are selected don't handle
if (expectedCaretPosition === undefined || selectionStart !== selectionEnd) {
onKeyDown(e);
return;
}
var newCaretPosition = expectedCaretPosition;
var leftBound = isPatternFormat ? format.indexOf('#') : prefix.length;
var rightBound = isPatternFormat ? format.lastIndexOf('#') + 1 : value.length - suffix.length;
if (key === 'ArrowLeft' || key === 'ArrowRight') {
var direction = key === 'ArrowLeft' ? 'left' : 'right';
newCaretPosition = this.correctCaretPosition(value, expectedCaretPosition, direction);
} else if (key === 'Delete' && !numRegex.test(value[expectedCaretPosition]) && !negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition]) && newCaretPosition < rightBound) { newCaretPosition++; }
} else if (key === 'Backspace' && !numRegex.test(value[expectedCaretPosition])) {
/* NOTE: This is special case when backspace is pressed on a
negative value while the cursor position is after prefix. We can't handle it on onChange because
we will not have any information of keyPress
*/
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
var newValue = value.substring(1);
this.updateValue({formattedValue: newValue, caretPos: newCaretPosition, input: el});
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound){ newCaretPosition--; }
newCaretPosition = this.correctCaretPosition(value, newCaretPosition, 'left');
}
}
onBlur(e);
if (newCaretPosition !== expectedCaretPosition || expectedCaretPosition < leftBound || expectedCaretPosition > rightBound) {
e.preventDefault();
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
}, {
key: "onKeyDown",
value: function onKeyDown(e) {
var el = e.target;
var key = e.key;
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value = el.value,
value = _el$value === void 0 ? '' : _el$value;
var expectedCaretPosition;
var _this$props12 = this.props,
decimalScale = _this$props12.decimalScale,
fixedDecimalScale = _this$props12.fixedDecimalScale,
prefix = _this$props12.prefix,
suffix = _this$props12.suffix,
format = _this$props12.format,
onKeyDown = _this$props12.onKeyDown;
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
var negativeRegex = new RegExp('-');
var isPatternFormat = typeof format === 'string';
this.selectionBeforeInput = {
selectionStart: selectionStart,
selectionEnd: selectionEnd
}; //Handle backspace and delete against non numerical/decimal characters or arrow keys
if (key === 'ArrowLeft' || key === 'Backspace') {
expectedCaretPosition = selectionStart - 1;
} else if (key === 'ArrowRight') {
expectedCaretPosition = selectionStart + 1;
} else if (key === 'Delete') {
expectedCaretPosition = selectionStart;
} //if expectedCaretPosition is not set it means we don't want to Handle keyDown
//also if multiple characters are selected don't handle
/* NOTE: this is just required for unit test as we need to get the newCaretPosition,
Remove this when you find different solution */
if (e.isUnitTestRun) {
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
if (expectedCaretPosition === undefined || selectionStart !== selectionEnd) {
onKeyDown(e);
return;
}
onKeyDown(e);
var newCaretPosition = expectedCaretPosition;
var leftBound = isPatternFormat ? format.indexOf('#') : prefix.length;
var rightBound = isPatternFormat ? format.lastIndexOf('#') + 1 : value.length - suffix.length;
};
if (key === 'ArrowLeft' || key === 'ArrowRight') {
var direction = key === 'ArrowLeft' ? 'left' : 'right';
newCaretPosition = this.correctCaretPosition(value, expectedCaretPosition, direction);
} else if (key === 'Delete' && !numRegex.test(value[expectedCaretPosition]) && !negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition]) && newCaretPosition < rightBound) {
newCaretPosition++;
}
} else if (key === 'Backspace' && !numRegex.test(value[expectedCaretPosition])) {
/* NOTE: This is special case when backspace is pressed on a
negative value while the cursor position is after prefix. We can't handle it on onChange because
we will not have any information of keyPress
*/
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
var newValue = value.substring(1);
this.updateValue({
formattedValue: newValue,
caretPos: newCaretPosition,
input: el
});
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound) {
newCaretPosition--;
}
/** required to handle the caret position when click anywhere within the input **/
NumberFormat.prototype.onMouseUp = function onMouseUp (e ) {
var el = e.target;
newCaretPosition = this.correctCaretPosition(value, newCaretPosition, 'left');
}
}
/**
* NOTE: we have to give default value for value as in case when custom input is provided
* value can come as undefined when nothing is provided on value prop.
*/
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
if (newCaretPosition !== expectedCaretPosition || expectedCaretPosition < leftBound || expectedCaretPosition > rightBound) {
e.preventDefault();
this.setPatchedCaretPosition(el, newCaretPosition, value);
if (selectionStart === selectionEnd) {
var caretPosition = this.correctCaretPosition(value, selectionStart);
if (caretPosition !== selectionStart) {
this.setPatchedCaretPosition(el, caretPosition, value);
}
/* NOTE: this is just required for unit test as we need to get the newCaretPosition,
Remove this when you find different solution */
}
this.props.onMouseUp(e);
};
if (e.isUnitTestRun) {
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
NumberFormat.prototype.onFocus = function onFocus (e ) {
var this$1 = this;
onKeyDown(e);
}
/** required to handle the caret position when click anywhere within the input **/
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
// (onFocus event target selectionStart is always 0 before setTimeout)
e.persist();
}, {
key: "onMouseUp",
value: function onMouseUp(e) {
this.focusedElm = e.target;
this.focusTimeout = setTimeout(function () {
var el = e.target;
/**
* NOTE: we have to give default value for value as in case when custom input is provided
* value can come as undefined when nothing is provided on value prop.
*/
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value2 = el.value,
value = _el$value2 === void 0 ? '' : _el$value2;
var caretPosition = this$1.correctCaretPosition(value, selectionStart);
if (selectionStart === selectionEnd) {
var caretPosition = this.correctCaretPosition(value, selectionStart);
if (caretPosition !== selectionStart) {
this.setPatchedCaretPosition(el, caretPosition, value);
}
//setPatchedCaretPosition only when everything is not selected on focus (while tabbing into the field)
if (caretPosition !== selectionStart && !(selectionStart === 0 && selectionEnd === value.length)) {
this$1.setPatchedCaretPosition(el, caretPosition, value);
}
this.props.onMouseUp(e);
}
}, {
key: "onFocus",
value: function onFocus(e) {
var _this2 = this;
this$1.props.onFocus(e);
}, 0);
};
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
// (onFocus event target selectionStart is always 0 before setTimeout)
e.persist();
this.focusedElm = e.target;
this.focusTimeout = setTimeout(function () {
var el = e.target;
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value3 = el.value,
value = _el$value3 === void 0 ? '' : _el$value3;
NumberFormat.prototype.render = function render () {
var ref = this.props;
var type = ref.type;
var displayType = ref.displayType;
var customInput = ref.customInput;
var renderText = ref.renderText;
var getInputRef = ref.getInputRef;
var format = ref.format;
var ref$1 = this.state;
var value = ref$1.value;
var mounted = ref$1.mounted;
var caretPosition = _this2.correctCaretPosition(value, selectionStart); //setPatchedCaretPosition only when everything is not selected on focus (while tabbing into the field)
var otherProps = omit(this.props, propTypes$1);
// add input mode on element based on format prop and device once the component is mounted
var inputMode = mounted && addInputMode(format) ? 'numeric' : undefined;
if (caretPosition !== selectionStart && !(selectionStart === 0 && selectionEnd === value.length)) {
_this2.setPatchedCaretPosition(el, caretPosition, value);
}
var inputProps = Object.assign({ inputMode: inputMode }, otherProps, {
type: type,
value: value,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
onMouseUp: this.onMouseUp,
onFocus: this.onFocus,
onBlur: this.onBlur
});
_this2.props.onFocus(e);
}, 0);
if( displayType === 'text'){
return renderText ? (renderText(value, otherProps) || null) : React.createElement( 'span', Object.assign({}, otherProps, { ref: getInputRef }), value);
}
}, {
key: "render",
value: function render() {
var _this$props13 = this.props,
type = _this$props13.type,
displayType = _this$props13.displayType,
customInput = _this$props13.customInput,
renderText = _this$props13.renderText,
getInputRef = _this$props13.getInputRef,
format = _this$props13.format;
var _this$state = this.state,
value = _this$state.value,
mounted = _this$state.mounted;
var otherProps = omit(this.props, propTypes$1); // add input mode on element based on format prop and device once the component is mounted
var inputMode = mounted && addInputMode(format) ? 'numeric' : undefined;
else if (customInput) {
var CustomInput = customInput;
return (
React.createElement( CustomInput, Object.assign({},
inputProps, { ref: getInputRef }))
)
}
var inputProps = _extends({
inputMode: inputMode
}, otherProps, {
type: type,
value: value,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
onMouseUp: this.onMouseUp,
onFocus: this.onFocus,
onBlur: this.onBlur
});
return (
React.createElement( 'input', Object.assign({},
inputProps, { ref: getInputRef }))
)
};
if (displayType === 'text') {
return renderText ? renderText(value, otherProps) || null : React.createElement("span", _extends({}, otherProps, {
ref: getInputRef
}), value);
} else if (customInput) {
var CustomInput = customInput;
return React.createElement(CustomInput, _extends({}, inputProps, {
ref: getInputRef
}));
}
return React.createElement("input", _extends({}, inputProps, {
ref: getInputRef
}));
}
}]);
return NumberFormat;
}(React.Component);
}(React.Component));

@@ -1394,0 +1391,0 @@ NumberFormat.propTypes = propTypes$1;

/**
* react-number-format - 4.5.3
* react-number-format - 4.5.4
* Author : Sudhanshu Yadav

@@ -9,1384 +9,1381 @@ * Copyright (c) 2016, 2021 to Sudhanshu Yadav, released under the MIT license.

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
typeof define === 'function' && define.amd ? define(['react'], factory) :
(global = global || self, global.NumberFormat = factory(global.React));
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
typeof define === 'function' && define.amd ? define(['react'], factory) :
(global = global || self, global.NumberFormat = factory(global.React));
}(this, function (React) { 'use strict';
React = React && React.hasOwnProperty('default') ? React['default'] : React;
React = React && React.hasOwnProperty('default') ? React['default'] : React;
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
var ReactPropTypesSecret_1 = ReactPropTypesSecret;
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;
return target;
};
var factoryWithThrowingShims = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret_1) {
// It is still safe when called from React.
return;
}
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use PropTypes.checkPropTypes() to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
} shim.isRequired = shim;
function getShim() {
return shim;
} // Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,
return _extends.apply(this, arguments);
}
any: shim,
arrayOf: getShim,
element: shim,
elementType: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim,
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
ReactPropTypes.PropTypes = ReactPropTypes;
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
return ReactPropTypes;
};
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
var propTypes = createCommonjsModule(function (module) {
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
return _setPrototypeOf(o, p);
}
{
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = factoryWithThrowingShims();
}
});
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
//
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
// basic noop function
function noop() {}
function returnTrue() {
return true;
}
return _assertThisInitialized(self);
}
function charIsNumber(char ) {
return !!(char || '').match(/\d/);
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
function isNil(val ) {
return val === null || val === undefined;
}
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function escapeRegExp(str ) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
function getThousandsGroupRegex(thousandsGroupStyle ) {
switch (thousandsGroupStyle) {
case 'lakh':
return /(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/g;
case 'wan':
return /(\d)(?=(\d{4})+(?!\d))/g;
case 'thousand':
default:
return /(\d)(?=(\d{3})+(?!\d))/g;
}
}
var ReactPropTypesSecret_1 = ReactPropTypesSecret;
function applyThousandSeparator(
str ,
thousandSeparator ,
thousandsGroupStyle
) {
var thousandsGroupRegex = getThousandsGroupRegex(thousandsGroupStyle);
var index = str.search(/[1-9]/);
index = index === -1 ? str.length : index;
return (
str.substring(0, index) +
str.substring(index, str.length).replace(thousandsGroupRegex, '$1' + thousandSeparator)
);
}
function emptyFunction() {}
function emptyFunctionWithReset() {}
emptyFunctionWithReset.resetWarningCache = emptyFunction;
//spilt a float number into different parts beforeDecimal, afterDecimal, and negation
function splitDecimal(numStr , allowNegative) {
if ( allowNegative === void 0 ) allowNegative = true;
var factoryWithThrowingShims = function() {
function shim(props, propName, componentName, location, propFullName, secret) {
if (secret === ReactPropTypesSecret_1) {
// It is still safe when called from React.
return;
}
var err = new Error(
'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +
'Use PropTypes.checkPropTypes() to call them. ' +
'Read more at http://fb.me/use-check-prop-types'
);
err.name = 'Invariant Violation';
throw err;
} shim.isRequired = shim;
function getShim() {
return shim;
} // Important!
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.
var ReactPropTypes = {
array: shim,
bool: shim,
func: shim,
number: shim,
object: shim,
string: shim,
symbol: shim,
var hasNagation = numStr[0] === '-';
var addNegation = hasNagation && allowNegative;
numStr = numStr.replace('-', '');
any: shim,
arrayOf: getShim,
element: shim,
elementType: shim,
instanceOf: getShim,
node: shim,
objectOf: getShim,
oneOf: getShim,
oneOfType: getShim,
shape: getShim,
exact: getShim,
var parts = numStr.split('.');
var beforeDecimal = parts[0];
var afterDecimal = parts[1] || '';
checkPropTypes: emptyFunctionWithReset,
resetWarningCache: emptyFunction
};
return {
beforeDecimal: beforeDecimal,
afterDecimal: afterDecimal,
hasNagation: hasNagation,
addNegation: addNegation,
};
}
ReactPropTypes.PropTypes = ReactPropTypes;
function fixLeadingZero(numStr ) {
if (!numStr) { return numStr; }
var isNegative = numStr[0] === '-';
if (isNegative) { numStr = numStr.substring(1, numStr.length); }
var parts = numStr.split('.');
var beforeDecimal = parts[0].replace(/^0+/, '') || '0';
var afterDecimal = parts[1] || '';
return ReactPropTypes;
};
return ("" + (isNegative ? '-' : '') + beforeDecimal + (afterDecimal ? ("." + afterDecimal) : ''));
}
var propTypes = createCommonjsModule(function (module) {
/**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* limit decimal numbers to given scale
* Not used .fixedTo because that will break with big numbers
*/
function limitToScale(numStr , scale , fixedDecimalScale ) {
var str = '';
var filler = fixedDecimalScale ? '0' : '';
for (var i = 0; i <= scale - 1; i++) {
str += numStr[i] || filler;
}
return str;
}
{
// By explicitly using `prop-types` you are opting into new production behavior.
// http://fb.me/prop-types-in-prod
module.exports = factoryWithThrowingShims();
}
});
function repeat(str, count) {
return Array(count + 1).join(str)
}
// basic noop function
function noop() {}
function returnTrue() {
return true;
}
function charIsNumber(_char) {
return !!(_char || '').match(/\d/);
}
function isNil(val) {
return val === null || val === undefined;
}
function escapeRegExp(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
}
function getThousandsGroupRegex(thousandsGroupStyle) {
switch (thousandsGroupStyle) {
case 'lakh':
return /(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/g;
function toNumericString(num) {
num += ''; // typecast number to string
case 'wan':
return /(\d)(?=(\d{4})+(?!\d))/g;
// store the sign and remove it from the number.
var sign = num[0] === '-' ? '-' : '';
if (sign) { num = num.substring(1); }
case 'thousand':
default:
return /(\d)(?=(\d{3})+(?!\d))/g;
}
}
function applyThousandSeparator(str, thousandSeparator, thousandsGroupStyle) {
var thousandsGroupRegex = getThousandsGroupRegex(thousandsGroupStyle);
var index = str.search(/[1-9]/);
index = index === -1 ? str.length : index;
return str.substring(0, index) + str.substring(index, str.length).replace(thousandsGroupRegex, '$1' + thousandSeparator);
} //spilt a float number into different parts beforeDecimal, afterDecimal, and negation
// split the number into cofficient and exponent
var ref = num.split(/[eE]/g);
var coefficient = ref[0];
var exponent = ref[1];
function splitDecimal(numStr) {
var allowNegative = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var hasNagation = numStr[0] === '-';
var addNegation = hasNagation && allowNegative;
numStr = numStr.replace('-', '');
var parts = numStr.split('.');
var beforeDecimal = parts[0];
var afterDecimal = parts[1] || '';
return {
beforeDecimal: beforeDecimal,
afterDecimal: afterDecimal,
hasNagation: hasNagation,
addNegation: addNegation
};
}
function fixLeadingZero(numStr) {
if (!numStr) return numStr;
var isNegative = numStr[0] === '-';
if (isNegative) numStr = numStr.substring(1, numStr.length);
var parts = numStr.split('.');
var beforeDecimal = parts[0].replace(/^0+/, '') || '0';
var afterDecimal = parts[1] || '';
return "".concat(isNegative ? '-' : '').concat(beforeDecimal).concat(afterDecimal ? ".".concat(afterDecimal) : '');
}
/**
* limit decimal numbers to given scale
* Not used .fixedTo because that will break with big numbers
*/
// covert exponent to number;
exponent = Number(exponent);
function limitToScale(numStr, scale, fixedDecimalScale) {
var str = '';
var filler = fixedDecimalScale ? '0' : '';
// if there is no exponent part or its 0, return the coffiecient with sign
if (!exponent) { return sign + coefficient; }
for (var i = 0; i <= scale - 1; i++) {
str += numStr[i] || filler;
}
coefficient = coefficient.replace('.', '');
return str;
}
/**
* This method is required to round prop value to given scale.
* Not used .round or .fixedTo because that will break with big numbers
*/
/**
* for scientific notation the current decimal index will be after first number (index 0)
* So effective decimal index will always be 1 + exponent value
*/
var decimalIndex = 1 + exponent;
function roundToPrecision(numStr, scale, fixedDecimalScale) {
//if number is empty don't do anything return empty string
if (['', '-'].indexOf(numStr) !== -1) return numStr;
var shoudHaveDecimalSeparator = numStr.indexOf('.') !== -1 && scale;
var coffiecientLn = coefficient.length;
var _splitDecimal = splitDecimal(numStr),
beforeDecimal = _splitDecimal.beforeDecimal,
afterDecimal = _splitDecimal.afterDecimal,
hasNagation = _splitDecimal.hasNagation;
if (decimalIndex < 0) {
// if decimal index is less then 0 add preceding 0s
// add 1 as join will have
coefficient = '0.' + repeat('0', Math.abs(decimalIndex)) + coefficient;
} else if (decimalIndex >= coffiecientLn) {
// if decimal index is less then 0 add leading 0s
coefficient = coefficient + repeat('0', decimalIndex - coffiecientLn);
} else {
// else add decimal point at proper index
coefficient = (coefficient.substring(0, decimalIndex) || '0') + '.' + coefficient.substring(decimalIndex);
}
var floatValue = parseFloat("0.".concat(afterDecimal || '0'));
var floatValueStr = afterDecimal.length <= scale ? floatValue.toString() : floatValue.toFixed(scale);
var roundedDecimalParts = floatValueStr.split('.');
var intPart = beforeDecimal.split('').reverse().reduce(function (roundedStr, current, idx) {
if (roundedStr.length > idx) {
return (Number(roundedStr[0]) + Number(current)).toString() + roundedStr.substring(1, roundedStr.length);
}
return sign + coefficient;
}
return current + roundedStr;
}, roundedDecimalParts[0]);
var decimalPart = limitToScale(roundedDecimalParts[1] || '', Math.min(scale, afterDecimal.length), fixedDecimalScale);
var negation = hasNagation ? '-' : '';
var decimalSeparator = shoudHaveDecimalSeparator ? '.' : '';
return "".concat(negation).concat(intPart).concat(decimalSeparator).concat(decimalPart);
}
function omit(obj, keyMaps) {
var filteredObj = {};
Object.keys(obj).forEach(function (key) {
if (!keyMaps[key]) filteredObj[key] = obj[key];
});
return filteredObj;
}
/** set the caret positon in an input field **/
/**
* This method is required to round prop value to given scale.
* Not used .round or .fixedTo because that will break with big numbers
*/
function roundToPrecision(numStr , scale , fixedDecimalScale ) {
//if number is empty don't do anything return empty string
if (['', '-'].indexOf(numStr) !== -1) { return numStr; }
function setCaretPosition(el, caretPos) {
el.value = el.value; // ^ this is used to not only get "focus", but
// to make sure we don't have it everything -selected-
// (it causes an issue in chrome, and having it doesn't hurt any other browser)
var shoudHaveDecimalSeparator = numStr.indexOf('.') !== -1 && scale;
var ref = splitDecimal(numStr);
var beforeDecimal = ref.beforeDecimal;
var afterDecimal = ref.afterDecimal;
var hasNagation = ref.hasNagation;
var floatValue = parseFloat(("0." + (afterDecimal || '0')));
var floatValueStr =
afterDecimal.length <= scale ? toNumericString(floatValue) : floatValue.toFixed(scale);
var roundedDecimalParts = floatValueStr.split('.');
var intPart = beforeDecimal
.split('')
.reverse()
.reduce(function (roundedStr, current, idx) {
if (roundedStr.length > idx) {
return (
(Number(roundedStr[0]) + Number(current)).toString() +
roundedStr.substring(1, roundedStr.length)
);
}
return current + roundedStr;
}, roundedDecimalParts[0]);
if (el !== null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move('character', caretPos);
range.select();
return true;
} // (el.selectionStart === 0 added for Firefox bug)
var decimalPart = limitToScale(
roundedDecimalParts[1] || '',
Math.min(scale, afterDecimal.length),
fixedDecimalScale
);
var negation = hasNagation ? '-' : '';
var decimalSeparator = shoudHaveDecimalSeparator ? '.' : '';
return ("" + negation + intPart + decimalSeparator + decimalPart);
}
function omit(obj , keyMaps ) {
var filteredObj = {};
Object.keys(obj).forEach(function (key) {
if (!keyMaps[key]) { filteredObj[key] = obj[key]; }
});
return filteredObj;
}
if (el.selectionStart || el.selectionStart === 0) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
return true;
} // fail city, fortunately this never happens (as far as I've tested) :)
/** set the caret positon in an input field **/
function setCaretPosition(el , caretPos ) {
el.value = el.value;
// ^ this is used to not only get 'focus', but
// to make sure we don't have it everything -selected-
// (it causes an issue in chrome, and having it doesn't hurt any other browser)
if (el !== null) {
if (el.createTextRange) {
var range = el.createTextRange();
range.move('character', caretPos);
range.select();
return true;
}
// (el.selectionStart === 0 added for Firefox bug)
if (el.selectionStart || el.selectionStart === 0) {
el.focus();
el.setSelectionRange(caretPos, caretPos);
return true;
}
// fail city, fortunately this never happens (as far as I've tested) :)
el.focus();
return false;
}
}
el.focus();
return false;
}
}
/**
Given previous value and newValue it returns the index
start - end to which values have changed.
This function makes assumption about only consecutive
characters are changed which is correct assumption for caret input.
*/
/**
Given previous value and newValue it returns the index
start - end to which values have changed.
This function makes assumption about only consecutive
characters are changed which is correct assumption for caret input.
*/
function findChangedIndex(prevValue , newValue ) {
var i = 0,
j = 0;
var prevLength = prevValue.length;
var newLength = newValue.length;
while (prevValue[i] === newValue[i] && i < prevLength) { i++; }
function findChangedIndex(prevValue, newValue) {
var i = 0,
j = 0;
var prevLength = prevValue.length;
var newLength = newValue.length;
//check what has been changed from last
while (
prevValue[prevLength - 1 - j] === newValue[newLength - 1 - j] &&
newLength - j > i &&
prevLength - j > i
) {
j++;
}
while (prevValue[i] === newValue[i] && i < prevLength) {
i++;
} //check what has been changed from last
return { start: i, end: prevLength - j };
}
/*
Returns a number whose value is limited to the given range
*/
function clamp(num , min , max ) {
return Math.min(Math.max(num, min), max);
}
while (prevValue[prevLength - 1 - j] === newValue[newLength - 1 - j] && newLength - j > i && prevLength - j > i) {
j++;
}
function getCurrentCaretPosition(el ) {
/*Max of selectionStart and selectionEnd is taken for the patch of pixel and other mobile device caret bug*/
return Math.max(el.selectionStart, el.selectionEnd);
}
return {
start: i,
end: prevLength - j
};
}
/*
Returns a number whose value is limited to the given range
*/
function addInputMode(format ) {
return format || !(navigator.platform && /iPhone|iPod/.test(navigator.platform));
}
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function getCurrentCaretPosition(el) {
/*Max of selectionStart and selectionEnd is taken for the patch of pixel and other mobile device caret bug*/
return Math.max(el.selectionStart, el.selectionEnd);
}
function addInputMode(format) {
return format || !(navigator.platform && /iPhone|iPod/.test(navigator.platform));
}
//
var propTypes$1 = {
thousandSeparator: propTypes.oneOfType([propTypes.string, propTypes.oneOf([true])]),
decimalSeparator: propTypes.string,
allowedDecimalSeparators: propTypes.arrayOf(propTypes.string),
thousandsGroupStyle: propTypes.oneOf(['thousand', 'lakh', 'wan']),
decimalScale: propTypes.number,
fixedDecimalScale: propTypes.bool,
displayType: propTypes.oneOf(['input', 'text']),
prefix: propTypes.string,
suffix: propTypes.string,
format: propTypes.oneOfType([propTypes.string, propTypes.func]),
removeFormatting: propTypes.func,
mask: propTypes.oneOfType([propTypes.string, propTypes.arrayOf(propTypes.string)]),
value: propTypes.oneOfType([propTypes.number, propTypes.string]),
defaultValue: propTypes.oneOfType([propTypes.number, propTypes.string]),
isNumericString: propTypes.bool,
customInput: propTypes.elementType,
allowNegative: propTypes.bool,
allowEmptyFormatting: propTypes.bool,
allowLeadingZeros: propTypes.bool,
onValueChange: propTypes.func,
onKeyDown: propTypes.func,
onMouseUp: propTypes.func,
onChange: propTypes.func,
onFocus: propTypes.func,
onBlur: propTypes.func,
type: propTypes.oneOf(['text', 'tel', 'password']),
isAllowed: propTypes.func,
renderText: propTypes.func,
getInputRef: propTypes.oneOfType([propTypes.func, // for legacy refs
propTypes.shape({
current: propTypes.any
})])
};
var defaultProps = {
displayType: 'input',
decimalSeparator: '.',
thousandsGroupStyle: 'thousand',
fixedDecimalScale: false,
prefix: '',
suffix: '',
allowNegative: true,
allowEmptyFormatting: false,
allowLeadingZeros: false,
isNumericString: false,
type: 'text',
onValueChange: noop,
onChange: noop,
onKeyDown: noop,
onMouseUp: noop,
onFocus: noop,
onBlur: noop,
isAllowed: returnTrue
};
var NumberFormat =
/*#__PURE__*/
function (_React$Component) {
_inherits(NumberFormat, _React$Component);
var propTypes$1 = {
thousandSeparator: propTypes.oneOfType([propTypes.string, propTypes.oneOf([true])]),
decimalSeparator: propTypes.string,
allowedDecimalSeparators: propTypes.arrayOf(propTypes.string),
thousandsGroupStyle: propTypes.oneOf(['thousand', 'lakh', 'wan']),
decimalScale: propTypes.number,
fixedDecimalScale: propTypes.bool,
displayType: propTypes.oneOf(['input', 'text']),
prefix: propTypes.string,
suffix: propTypes.string,
format: propTypes.oneOfType([
propTypes.string,
propTypes.func
]),
removeFormatting: propTypes.func,
mask: propTypes.oneOfType([propTypes.string, propTypes.arrayOf(propTypes.string)]),
value: propTypes.oneOfType([
propTypes.number,
propTypes.string
]),
defaultValue: propTypes.oneOfType([
propTypes.number,
propTypes.string
]),
isNumericString: propTypes.bool,
customInput: propTypes.elementType,
allowNegative: propTypes.bool,
allowEmptyFormatting: propTypes.bool,
allowLeadingZeros: propTypes.bool,
onValueChange: propTypes.func,
onKeyDown: propTypes.func,
onMouseUp: propTypes.func,
onChange: propTypes.func,
onFocus: propTypes.func,
onBlur: propTypes.func,
type: propTypes.oneOf(['text', 'tel', 'password']),
isAllowed: propTypes.func,
renderText: propTypes.func,
getInputRef: propTypes.oneOfType([
propTypes.func, // for legacy refs
propTypes.shape({ current: propTypes.any })
])
};
function NumberFormat(props) {
var _this;
var defaultProps = {
displayType: 'input',
decimalSeparator: '.',
thousandsGroupStyle: 'thousand',
fixedDecimalScale: false,
prefix: '',
suffix: '',
allowNegative: true,
allowEmptyFormatting: false,
allowLeadingZeros: false,
isNumericString: false,
type: 'text',
onValueChange: noop,
onChange: noop,
onKeyDown: noop,
onMouseUp: noop,
onFocus: noop,
onBlur: noop,
isAllowed: returnTrue
};
var NumberFormat = /*@__PURE__*/(function (superclass) {
function NumberFormat(props ) {
superclass.call(this, props);
_classCallCheck(this, NumberFormat);
var defaultValue = props.defaultValue;
_this = _possibleConstructorReturn(this, _getPrototypeOf(NumberFormat).call(this, props));
var defaultValue = props.defaultValue; //validate props
//validate props
this.validateProps();
_this.validateProps();
var formattedValue = this.formatValueProp(defaultValue);
var formattedValue = _this.formatValueProp(defaultValue);
this.state = {
value: formattedValue,
numAsString: this.removeFormatting(formattedValue),
mounted: false,
};
_this.state = {
value: formattedValue,
numAsString: _this.removeFormatting(formattedValue),
mounted: false
};
_this.selectionBeforeInput = {
selectionStart: 0,
selectionEnd: 0
};
_this.onChange = _this.onChange.bind(_assertThisInitialized(_this));
_this.onKeyDown = _this.onKeyDown.bind(_assertThisInitialized(_this));
_this.onMouseUp = _this.onMouseUp.bind(_assertThisInitialized(_this));
_this.onFocus = _this.onFocus.bind(_assertThisInitialized(_this));
_this.onBlur = _this.onBlur.bind(_assertThisInitialized(_this));
return _this;
}
this.selectionBeforeInput = {
selectionStart: 0,
selectionEnd: 0
};
_createClass(NumberFormat, [{
key: "componentDidMount",
value: function componentDidMount() {
// set mounted state
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({
mounted: true
});
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
this.updateValueIfRequired(prevProps);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
clearTimeout(this.focusTimeout);
}
}, {
key: "updateValueIfRequired",
value: function updateValueIfRequired(prevProps) {
var props = this.props,
state = this.state,
focusedElm = this.focusedElm;
var stateValue = state.value,
_state$numAsString = state.numAsString,
lastNumStr = _state$numAsString === void 0 ? '' : _state$numAsString; // If only state changed no need to do any thing
this.onChange = this.onChange.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
this.onFocus = this.onFocus.bind(this);
this.onBlur = this.onBlur.bind(this);
}
if (prevProps !== props) {
//validate props
this.validateProps();
var lastValueWithNewFormat = this.formatNumString(lastNumStr);
var formattedValue = isNil(props.value) ? lastValueWithNewFormat : this.formatValueProp();
var numAsString = this.removeFormatting(formattedValue);
var floatValue = parseFloat(numAsString);
var lastFloatValue = parseFloat(lastNumStr);
if ( superclass ) NumberFormat.__proto__ = superclass;
NumberFormat.prototype = Object.create( superclass && superclass.prototype );
NumberFormat.prototype.constructor = NumberFormat;
if ( //while typing set state only when float value changes
(!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue || //can also set state when float value is same and the format props changes
lastValueWithNewFormat !== stateValue || //set state always when not in focus and formatted value is changed
focusedElm === null && formattedValue !== stateValue) {
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
input: focusedElm
});
}
}
}
/** Misc methods **/
NumberFormat.prototype.componentDidMount = function componentDidMount () {
// set mounted state
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({
mounted: true
});
};
}, {
key: "getFloatString",
value: function getFloatString() {
var num = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var decimalScale = this.props.decimalScale;
NumberFormat.prototype.componentDidUpdate = function componentDidUpdate (prevProps ) {
this.updateValueIfRequired(prevProps);
};
var _this$getSeparators = this.getSeparators(),
decimalSeparator = _this$getSeparators.decimalSeparator;
NumberFormat.prototype.componentWillUnmount = function componentWillUnmount () {
clearTimeout(this.focusTimeout);
};
var numRegex = this.getNumberRegex(true); //remove negation for regex check
NumberFormat.prototype.updateValueIfRequired = function updateValueIfRequired (prevProps ) {
var ref = this;
var props = ref.props;
var state = ref.state;
var focusedElm = ref.focusedElm;
var stateValue = state.value;
var lastNumStr = state.numAsString; if ( lastNumStr === void 0 ) lastNumStr = '';
var hasNegation = num[0] === '-';
if (hasNegation) num = num.replace('-', ''); //if decimal scale is zero remove decimal and number after decimalSeparator
// If only state changed no need to do any thing
if(prevProps !== props) {
//validate props
this.validateProps();
if (decimalSeparator && decimalScale === 0) {
num = num.split(decimalSeparator)[0];
}
var lastValueWithNewFormat = this.formatNumString(lastNumStr);
num = (num.match(numRegex) || []).join('').replace(decimalSeparator, '.'); //remove extra decimals
var formattedValue = isNil(props.value) ? lastValueWithNewFormat : this.formatValueProp();
var numAsString = this.removeFormatting(formattedValue);
var firstDecimalIndex = num.indexOf('.');
var floatValue = parseFloat(numAsString);
var lastFloatValue = parseFloat(lastNumStr);
if (firstDecimalIndex !== -1) {
num = "".concat(num.substring(0, firstDecimalIndex), ".").concat(num.substring(firstDecimalIndex + 1, num.length).replace(new RegExp(escapeRegExp(decimalSeparator), 'g'), ''));
} //add negation back
if (
//while typing set state only when float value changes
((!isNaN(floatValue) || !isNaN(lastFloatValue)) && floatValue !== lastFloatValue) ||
//can also set state when float value is same and the format props changes
lastValueWithNewFormat !== stateValue ||
//set state always when not in focus and formatted value is changed
(focusedElm === null && formattedValue !== stateValue)
) {
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, input: focusedElm });
}
}
};
/** Misc methods **/
NumberFormat.prototype.getFloatString = function getFloatString (num) {
if ( num === void 0 ) num = '';
if (hasNegation) num = '-' + num;
return num;
} //returned regex assumes decimalSeparator is as per prop
var ref = this.props;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
var numRegex = this.getNumberRegex(true);
}, {
key: "getNumberRegex",
value: function getNumberRegex(g, ignoreDecimalSeparator) {
var _this$props = this.props,
format = _this$props.format,
decimalScale = _this$props.decimalScale;
//remove negation for regex check
var hasNegation = num[0] === '-';
if(hasNegation) { num = num.replace('-', ''); }
var _this$getSeparators2 = this.getSeparators(),
decimalSeparator = _this$getSeparators2.decimalSeparator;
//if decimal scale is zero remove decimal and number after decimalSeparator
if (decimalSeparator && decimalScale === 0) {
num = num.split(decimalSeparator)[0];
}
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined);
}
}, {
key: "getSeparators",
value: function getSeparators() {
var decimalSeparator = this.props.decimalSeparator;
var _this$props2 = this.props,
thousandSeparator = _this$props2.thousandSeparator,
allowedDecimalSeparators = _this$props2.allowedDecimalSeparators;
num = (num.match(numRegex) || []).join('').replace(decimalSeparator, '.');
if (thousandSeparator === true) {
thousandSeparator = ',';
}
//remove extra decimals
var firstDecimalIndex = num.indexOf('.');
if (!allowedDecimalSeparators) {
allowedDecimalSeparators = [decimalSeparator, '.'];
}
if (firstDecimalIndex !== -1) {
num = (num.substring(0, firstDecimalIndex)) + "." + (num.substring(firstDecimalIndex + 1, num.length).replace(new RegExp(escapeRegExp(decimalSeparator), 'g'), ''));
}
return {
decimalSeparator: decimalSeparator,
thousandSeparator: thousandSeparator,
allowedDecimalSeparators: allowedDecimalSeparators
};
}
}, {
key: "getMaskAtIndex",
value: function getMaskAtIndex(index) {
var _this$props$mask = this.props.mask,
mask = _this$props$mask === void 0 ? ' ' : _this$props$mask;
//add negation back
if(hasNegation) { num = '-' + num; }
if (typeof mask === 'string') {
return mask;
}
return num;
};
return mask[index] || ' ';
}
}, {
key: "getValueObject",
value: function getValueObject(formattedValue, numAsString) {
var floatValue = parseFloat(numAsString);
return {
formattedValue: formattedValue,
value: numAsString,
floatValue: isNaN(floatValue) ? undefined : floatValue
};
}
}, {
key: "validateProps",
value: function validateProps() {
var mask = this.props.mask; //validate decimalSeparator and thousandSeparator
//returned regex assumes decimalSeparator is as per prop
NumberFormat.prototype.getNumberRegex = function getNumberRegex (g , ignoreDecimalSeparator ) {
var ref = this.props;
var format = ref.format;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined);
};
var _this$getSeparators3 = this.getSeparators(),
decimalSeparator = _this$getSeparators3.decimalSeparator,
thousandSeparator = _this$getSeparators3.thousandSeparator;
NumberFormat.prototype.getSeparators = function getSeparators () {
var ref = this.props;
var decimalSeparator = ref.decimalSeparator;
var ref$1 = this.props;
var thousandSeparator = ref$1.thousandSeparator;
var allowedDecimalSeparators = ref$1.allowedDecimalSeparators;
if (decimalSeparator === thousandSeparator) {
throw new Error("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: ".concat(thousandSeparator, " (thousandSeparator = {true} is same as thousandSeparator = \",\")\n decimalSeparator: ").concat(decimalSeparator, " (default value for decimalSeparator is .)\n "));
} //validate mask
if (thousandSeparator === true) {
thousandSeparator = ',';
}
if (!allowedDecimalSeparators) {
allowedDecimalSeparators = [decimalSeparator, '.'];
}
return {
decimalSeparator: decimalSeparator,
thousandSeparator: thousandSeparator,
allowedDecimalSeparators: allowedDecimalSeparators,
}
};
if (mask) {
var maskAsStr = mask === 'string' ? mask : mask.toString();
NumberFormat.prototype.getMaskAtIndex = function getMaskAtIndex (index ) {
var ref = this.props;
var mask = ref.mask; if ( mask === void 0 ) mask = ' ';
if (typeof mask === 'string') {
return mask;
}
if (maskAsStr.match(/\d/g)) {
throw new Error("\n Mask ".concat(mask, " should not contain numeric character;\n "));
}
}
}
/** Misc methods end **/
return mask[index] || ' ';
};
/** caret specific methods **/
NumberFormat.prototype.getValueObject = function getValueObject (formattedValue , numAsString ) {
var floatValue = parseFloat(numAsString);
}, {
key: "setPatchedCaretPosition",
value: function setPatchedCaretPosition(el, caretPos, currentValue) {
/* setting caret position within timeout of 0ms is required for mobile chrome,
otherwise browser resets the caret position after we set it
We are also setting it without timeout so that in normal browser we don't see the flickering */
setCaretPosition(el, caretPos);
setTimeout(function () {
if (el.value === currentValue) setCaretPosition(el, caretPos);
}, 0);
}
/* This keeps the caret within typing area so people can't type in between prefix or suffix */
return {
formattedValue: formattedValue,
value: numAsString,
floatValue: isNaN(floatValue) ? undefined : floatValue
};
}, {
key: "correctCaretPosition",
value: function correctCaretPosition(value, caretPos, direction) {
var _this$props3 = this.props,
prefix = _this$props3.prefix,
suffix = _this$props3.suffix,
format = _this$props3.format; //if value is empty return 0
};
if (value === '') return 0; //caret position should be between 0 and value length
NumberFormat.prototype.validateProps = function validateProps () {
var ref = this.props;
var mask = ref.mask;
caretPos = clamp(caretPos, 0, value.length); //in case of format as number limit between prefix and suffix
//validate decimalSeparator and thousandSeparator
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
var thousandSeparator = ref$1.thousandSeparator;
if (!format) {
var hasNegation = value[0] === '-';
return clamp(caretPos, prefix.length + (hasNegation ? 1 : 0), value.length - suffix.length);
} //in case if custom format method don't do anything
if (decimalSeparator === thousandSeparator) {
throw new Error(("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: " + thousandSeparator + " (thousandSeparator = {true} is same as thousandSeparator = \",\")\n decimalSeparator: " + decimalSeparator + " (default value for decimalSeparator is .)\n "));
}
//validate mask
if (mask) {
var maskAsStr = mask === 'string' ? mask : mask.toString();
if (maskAsStr.match(/\d/g)) {
throw new Error(("\n Mask " + mask + " should not contain numeric character;\n "))
}
}
if (typeof format === 'function') return caretPos;
/* in case format is string find the closest # position from the caret position */
//in case the caretPos have input value on it don't do anything
};
/** Misc methods end **/
if (format[caretPos] === '#' && charIsNumber(value[caretPos])) return caretPos; //if caretPos is just after input value don't do anything
/** caret specific methods **/
NumberFormat.prototype.setPatchedCaretPosition = function setPatchedCaretPosition (el , caretPos , currentValue ) {
/* setting caret position within timeout of 0ms is required for mobile chrome,
otherwise browser resets the caret position after we set it
We are also setting it without timeout so that in normal browser we don't see the flickering */
setCaretPosition(el, caretPos);
setTimeout(function () {
if(el.value === currentValue) { setCaretPosition(el, caretPos); }
}, 0);
};
if (format[caretPos - 1] === '#' && charIsNumber(value[caretPos - 1])) return caretPos; //find the nearest caret position
/* This keeps the caret within typing area so people can't type in between prefix or suffix */
NumberFormat.prototype.correctCaretPosition = function correctCaretPosition (value , caretPos , direction ) {
var ref = this.props;
var prefix = ref.prefix;
var suffix = ref.suffix;
var format = ref.format;
var firstHashPosition = format.indexOf('#');
var lastHashPosition = format.lastIndexOf('#'); //limit the cursor between the first # position and the last # position
//if value is empty return 0
if (value === '') { return 0; }
caretPos = clamp(caretPos, firstHashPosition, lastHashPosition + 1);
var nextPos = format.substring(caretPos, format.length).indexOf('#');
var caretLeftBound = caretPos;
var caretRightBound = caretPos + (nextPos === -1 ? 0 : nextPos); //get the position where the last number is present
//caret position should be between 0 and value length
caretPos = clamp(caretPos, 0, value.length);
while (caretLeftBound > firstHashPosition && (format[caretLeftBound] !== '#' || !charIsNumber(value[caretLeftBound]))) {
caretLeftBound -= 1;
}
//in case of format as number limit between prefix and suffix
if (!format) {
var hasNegation = value[0] === '-';
return clamp(caretPos, prefix.length + (hasNegation ? 1 : 0), value.length - suffix.length);
}
var goToLeft = !charIsNumber(value[caretRightBound]) || direction === 'left' && caretPos !== firstHashPosition || caretPos - caretLeftBound < caretRightBound - caretPos;
//in case if custom format method don't do anything
if (typeof format === 'function') { return caretPos; }
if (goToLeft) {
//check if number should be taken after the bound or after it
//if number preceding a valid number keep it after
return charIsNumber(value[caretLeftBound]) ? caretLeftBound + 1 : caretLeftBound;
}
/* in case format is string find the closest # position from the caret position */
return caretRightBound;
}
}, {
key: "getCaretPosition",
value: function getCaretPosition(inputValue, formattedValue, caretPos) {
var format = this.props.format;
var stateValue = this.state.value;
var numRegex = this.getNumberRegex(true);
var inputNumber = (inputValue.match(numRegex) || []).join('');
var formattedNumber = (formattedValue.match(numRegex) || []).join('');
var j, i;
j = 0;
//in case the caretPos have input value on it don't do anything
if (format[caretPos] === '#' && charIsNumber(value[caretPos])) { return caretPos; }
for (i = 0; i < caretPos; i++) {
var currentInputChar = inputValue[i] || '';
var currentFormatChar = formattedValue[j] || ''; //no need to increase new cursor position if formatted value does not have those characters
//case inputValue = 1a23 and formattedValue = 123
//if caretPos is just after input value don't do anything
if (format[caretPos - 1] === '#' && charIsNumber(value[caretPos - 1])) { return caretPos; }
if (!currentInputChar.match(numRegex) && currentInputChar !== currentFormatChar) continue; //When we are striping out leading zeros maintain the new cursor position
//Case inputValue = 00023 and formattedValue = 23;
//find the nearest caret position
var firstHashPosition = format.indexOf('#');
var lastHashPosition = format.lastIndexOf('#');
if (currentInputChar === '0' && currentFormatChar.match(numRegex) && currentFormatChar !== '0' && inputNumber.length !== formattedNumber.length) continue; //we are not using currentFormatChar because j can change here
//limit the cursor between the first # position and the last # position
caretPos = clamp(caretPos, firstHashPosition, lastHashPosition + 1);
while (currentInputChar !== formattedValue[j] && j < formattedValue.length) {
j++;
}
var nextPos = format.substring(caretPos, format.length).indexOf('#');
var caretLeftBound = caretPos;
var caretRightBound = caretPos + (nextPos === -1 ? 0 : nextPos);
j++;
}
//get the position where the last number is present
while (caretLeftBound > firstHashPosition && (format[caretLeftBound] !== '#' || !charIsNumber(value[caretLeftBound]))) {
caretLeftBound -= 1;
}
if (typeof format === 'string' && !stateValue) {
//set it to the maximum value so it goes after the last number
j = formattedValue.length;
} //correct caret position if its outside of editable area
var goToLeft = !charIsNumber(value[caretRightBound])
|| (direction === 'left' && caretPos !== firstHashPosition)
|| (caretPos - caretLeftBound < caretRightBound - caretPos);
if (goToLeft) {
//check if number should be taken after the bound or after it
//if number preceding a valid number keep it after
return charIsNumber(value[caretLeftBound]) ? caretLeftBound + 1 : caretLeftBound;
}
j = this.correctCaretPosition(formattedValue, j);
return j;
}
/** caret specific methods ends **/
return caretRightBound;
};
/** methods to remove formattting **/
NumberFormat.prototype.getCaretPosition = function getCaretPosition (inputValue , formattedValue , caretPos ) {
var ref = this.props;
var format = ref.format;
var stateValue = this.state.value;
var numRegex = this.getNumberRegex(true);
var inputNumber = (inputValue.match(numRegex) || []).join('');
var formattedNumber = (formattedValue.match(numRegex) || []).join('');
var j, i;
}, {
key: "removePrefixAndSuffix",
value: function removePrefixAndSuffix(val) {
var _this$props4 = this.props,
format = _this$props4.format,
prefix = _this$props4.prefix,
suffix = _this$props4.suffix; //remove prefix and suffix
j = 0;
if (!format && val) {
var isNegative = val[0] === '-'; //remove negation sign
for(i=0; i<caretPos; i++){
var currentInputChar = inputValue[i] || '';
var currentFormatChar = formattedValue[j] || '';
//no need to increase new cursor position if formatted value does not have those characters
//case inputValue = 1a23 and formattedValue = 123
if(!currentInputChar.match(numRegex) && currentInputChar !== currentFormatChar) { continue; }
if (isNegative) val = val.substring(1, val.length); //remove prefix
//When we are striping out leading zeros maintain the new cursor position
//Case inputValue = 00023 and formattedValue = 23;
if (currentInputChar === '0' && currentFormatChar.match(numRegex) && currentFormatChar !== '0' && inputNumber.length !== formattedNumber.length) { continue; }
val = prefix && val.indexOf(prefix) === 0 ? val.substring(prefix.length, val.length) : val; //remove suffix
//we are not using currentFormatChar because j can change here
while(currentInputChar !== formattedValue[j] && j < formattedValue.length) { j++; }
j++;
}
var suffixLastIndex = val.lastIndexOf(suffix);
val = suffix && suffixLastIndex !== -1 && suffixLastIndex === val.length - suffix.length ? val.substring(0, suffixLastIndex) : val; //add negation sign back
if ((typeof format === 'string' && !stateValue)) {
//set it to the maximum value so it goes after the last number
j = formattedValue.length;
}
if (isNegative) val = '-' + val;
}
//correct caret position if its outside of editable area
j = this.correctCaretPosition(formattedValue, j);
return val;
}
}, {
key: "removePatternFormatting",
value: function removePatternFormatting(val) {
var format = this.props.format;
var formatArray = format.split('#').filter(function (str) {
return str !== '';
});
var start = 0;
var numStr = '';
return j;
};
/** caret specific methods ends **/
for (var i = 0, ln = formatArray.length; i <= ln; i++) {
var part = formatArray[i] || ''; //if i is the last fragment take the index of end of the value
//For case like +1 (911) 911 91 91 having pattern +1 (###) ### ## ##
var index = i === ln ? val.length : val.indexOf(part, start);
/* in any case if we don't find the pattern part in the value assume the val as numeric string
This will be also in case if user has started typing, in any other case it will not be -1
unless wrong prop value is provided */
/** methods to remove formattting **/
NumberFormat.prototype.removePrefixAndSuffix = function removePrefixAndSuffix (val ) {
var ref = this.props;
var format = ref.format;
var prefix = ref.prefix;
var suffix = ref.suffix;
if (index === -1) {
numStr = val;
break;
} else {
numStr += val.substring(start, index);
start = index + part.length;
}
}
//remove prefix and suffix
if (!format && val) {
var isNegative = val[0] === '-';
return (numStr.match(/\d/g) || []).join('');
}
}, {
key: "removeFormatting",
value: function removeFormatting(val) {
var _this$props5 = this.props,
format = _this$props5.format,
removeFormatting = _this$props5.removeFormatting;
if (!val) return val;
//remove negation sign
if (isNegative) { val = val.substring(1, val.length); }
if (!format) {
val = this.removePrefixAndSuffix(val);
val = this.getFloatString(val);
} else if (typeof format === 'string') {
val = this.removePatternFormatting(val);
} else if (typeof removeFormatting === 'function') {
//condition need to be handled if format method is provide,
val = removeFormatting(val);
} else {
val = (val.match(/\d/g) || []).join('');
}
//remove prefix
val = prefix && val.indexOf(prefix) === 0 ? val.substring(prefix.length, val.length) : val;
return val;
}
/** methods to remove formattting end **/
//remove suffix
var suffixLastIndex = val.lastIndexOf(suffix);
val = suffix && suffixLastIndex !== -1 && suffixLastIndex === val.length - suffix.length ? val.substring(0, suffixLastIndex) : val;
/*** format specific methods start ***/
//add negation sign back
if (isNegative) { val = '-' + val; }
}
/**
* Format when # based string is provided
* @param {string} numStr Numeric String
* @return {string} formatted Value
*/
return val;
};
}, {
key: "formatWithPattern",
value: function formatWithPattern(numStr) {
var format = this.props.format;
var hashCount = 0;
var formattedNumberAry = format.split('');
NumberFormat.prototype.removePatternFormatting = function removePatternFormatting (val ) {
var ref = this.props;
var format = ref.format;
var formatArray = format.split('#').filter(function (str) { return str !== ''; });
var start = 0;
var numStr = '';
for (var i = 0, ln = format.length; i < ln; i++) {
if (format[i] === '#') {
formattedNumberAry[i] = numStr[hashCount] || this.getMaskAtIndex(hashCount);
hashCount += 1;
}
}
for (var i=0, ln=formatArray.length; i <= ln; i++) {
var part = formatArray[i] || '';
return formattedNumberAry.join('');
}
/**
* @param {string} numStr Numeric string/floatString] It always have decimalSeparator as .
* @return {string} formatted Value
*/
//if i is the last fragment take the index of end of the value
//For case like +1 (911) 911 91 91 having pattern +1 (###) ### ## ##
var index = i === ln ? val.length : val.indexOf(part, start);
}, {
key: "formatAsNumber",
value: function formatAsNumber(numStr) {
var _this$props6 = this.props,
decimalScale = _this$props6.decimalScale,
fixedDecimalScale = _this$props6.fixedDecimalScale,
prefix = _this$props6.prefix,
suffix = _this$props6.suffix,
allowNegative = _this$props6.allowNegative,
thousandsGroupStyle = _this$props6.thousandsGroupStyle;
/* in any case if we don't find the pattern part in the value assume the val as numeric string
This will be also in case if user has started typing, in any other case it will not be -1
unless wrong prop value is provided */
if (index === -1) {
numStr = val;
break;
} else {
numStr += val.substring(start, index);
start = index + part.length;
}
}
var _this$getSeparators4 = this.getSeparators(),
thousandSeparator = _this$getSeparators4.thousandSeparator,
decimalSeparator = _this$getSeparators4.decimalSeparator;
return (numStr.match(/\d/g) || []).join('');
};
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalScale && fixedDecimalScale;
NumberFormat.prototype.removeFormatting = function removeFormatting (val ) {
var ref = this.props;
var format = ref.format;
var removeFormatting = ref.removeFormatting;
if (!val) { return val; }
var _splitDecimal = splitDecimal(numStr, allowNegative),
beforeDecimal = _splitDecimal.beforeDecimal,
afterDecimal = _splitDecimal.afterDecimal,
addNegation = _splitDecimal.addNegation; // eslint-disable-line prefer-const
//apply decimal precision if its defined
if (!format) {
val = this.removePrefixAndSuffix(val);
val = this.getFloatString(val);
} else if (typeof format === 'string') {
val = this.removePatternFormatting(val);
} else if (typeof removeFormatting === 'function') { //condition need to be handled if format method is provide,
val = removeFormatting(val);
} else {
val = (val.match(/\d/g) || []).join('');
}
return val;
};
/** methods to remove formattting end **/
if (decimalScale !== undefined) afterDecimal = limitToScale(afterDecimal, decimalScale, fixedDecimalScale);
/*** format specific methods start ***/
/**
* Format when # based string is provided
* @param {string} numStr Numeric String
* @return {string} formatted Value
*/
NumberFormat.prototype.formatWithPattern = function formatWithPattern (numStr ) {
var ref = this.props;
var format = ref.format;
var hashCount = 0;
var formattedNumberAry = format.split('');
for (var i = 0, ln = format.length; i < ln; i++) {
if (format[i] === '#') {
formattedNumberAry[i] = numStr[hashCount] || this.getMaskAtIndex(hashCount);
hashCount += 1;
}
}
return formattedNumberAry.join('');
};
/**
* @param {string} numStr Numeric string/floatString] It always have decimalSeparator as .
* @return {string} formatted Value
*/
NumberFormat.prototype.formatAsNumber = function formatAsNumber (numStr ) {
var ref = this.props;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var prefix = ref.prefix;
var suffix = ref.suffix;
var allowNegative = ref.allowNegative;
var thousandsGroupStyle = ref.thousandsGroupStyle;
var ref$1 = this.getSeparators();
var thousandSeparator = ref$1.thousandSeparator;
var decimalSeparator = ref$1.decimalSeparator;
if (thousandSeparator) {
beforeDecimal = applyThousandSeparator(beforeDecimal, thousandSeparator, thousandsGroupStyle);
} //add prefix and suffix
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || (decimalScale && fixedDecimalScale);
var ref$2 = splitDecimal(numStr, allowNegative);
var beforeDecimal = ref$2.beforeDecimal;
var afterDecimal = ref$2.afterDecimal;
var addNegation = ref$2.addNegation; // eslint-disable-line prefer-const
//apply decimal precision if its defined
if (decimalScale !== undefined) { afterDecimal = limitToScale(afterDecimal, decimalScale, fixedDecimalScale); }
if (prefix) beforeDecimal = prefix + beforeDecimal;
if (suffix) afterDecimal = afterDecimal + suffix; //restore negation sign
if(thousandSeparator) {
beforeDecimal = applyThousandSeparator(beforeDecimal, thousandSeparator, thousandsGroupStyle);
}
if (addNegation) beforeDecimal = '-' + beforeDecimal;
numStr = beforeDecimal + (hasDecimalSeparator && decimalSeparator || '') + afterDecimal;
return numStr;
}
}, {
key: "formatNumString",
value: function formatNumString() {
var numStr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var _this$props7 = this.props,
format = _this$props7.format,
allowEmptyFormatting = _this$props7.allowEmptyFormatting;
var formattedValue = numStr;
//add prefix and suffix
if(prefix) { beforeDecimal = prefix + beforeDecimal; }
if(suffix) { afterDecimal = afterDecimal + suffix; }
if (numStr === '' && !allowEmptyFormatting) {
formattedValue = '';
} else if (numStr === '-' && !format) {
formattedValue = '-';
} else if (typeof format === 'string') {
formattedValue = this.formatWithPattern(formattedValue);
} else if (typeof format === 'function') {
formattedValue = format(formattedValue);
} else {
formattedValue = this.formatAsNumber(formattedValue);
}
//restore negation sign
if (addNegation) { beforeDecimal = '-' + beforeDecimal; }
return formattedValue;
}
}, {
key: "formatValueProp",
value: function formatValueProp(defaultValue) {
var _this$props8 = this.props,
format = _this$props8.format,
decimalScale = _this$props8.decimalScale,
fixedDecimalScale = _this$props8.fixedDecimalScale,
allowEmptyFormatting = _this$props8.allowEmptyFormatting;
var _this$props9 = this.props,
value = _this$props9.value,
isNumericString = _this$props9.isNumericString; // if value is undefined or null, use defaultValue instead
numStr = beforeDecimal + (hasDecimalSeparator && decimalSeparator || '') + afterDecimal;
value = isNil(value) ? defaultValue : value;
var isNonNumericFalsy = !value && value !== 0;
return numStr;
};
if (isNonNumericFalsy && allowEmptyFormatting) {
value = '';
} // if value is not defined return empty string
NumberFormat.prototype.formatNumString = function formatNumString (numStr) {
if ( numStr === void 0 ) numStr = '';
var ref = this.props;
var format = ref.format;
var allowEmptyFormatting = ref.allowEmptyFormatting;
var formattedValue = numStr;
if (isNonNumericFalsy && !allowEmptyFormatting) return '';
if (numStr === '' && !allowEmptyFormatting) {
formattedValue = '';
} else if (numStr === '-' && !format) {
formattedValue = '-';
} else if (typeof format === 'string') {
formattedValue = this.formatWithPattern(formattedValue);
} else if (typeof format === 'function') {
formattedValue = format(formattedValue);
} else {
formattedValue = this.formatAsNumber(formattedValue);
}
if (typeof value === 'number') {
value = value.toString();
isNumericString = true;
} //change infinity value to empty string
return formattedValue;
};
NumberFormat.prototype.formatValueProp = function formatValueProp (defaultValue ) {
var ref = this.props;
var format = ref.format;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var allowEmptyFormatting = ref.allowEmptyFormatting;
var ref$1 = this.props;
var value = ref$1.value;
var isNumericString = ref$1.isNumericString;
if (value === 'Infinity' && isNumericString) {
value = '';
} //round the number based on decimalScale
//format only if non formatted value is provided
// if value is undefined or null, use defaultValue instead
value = isNil(value) ? defaultValue : value;
var isNonNumericFalsy = !value && value !== 0;
if (isNumericString && !format && typeof decimalScale === 'number') {
value = roundToPrecision(value, decimalScale, fixedDecimalScale);
}
if (isNonNumericFalsy && allowEmptyFormatting) {
value = '';
}
var formattedValue = isNumericString ? this.formatNumString(value) : this.formatInput(value);
return formattedValue;
}
}, {
key: "formatNegation",
value: function formatNegation() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var allowNegative = this.props.allowNegative;
var negationRegex = new RegExp('(-)');
var doubleNegationRegex = new RegExp('(-)(.)*(-)'); // Check number has '-' value
// if value is not defined return empty string
if (isNonNumericFalsy && !allowEmptyFormatting) { return ''; }
var hasNegation = negationRegex.test(value); // Check number has 2 or more '-' values
if (typeof value === 'number') {
value = toNumericString(value);
isNumericString = true;
}
var removeNegation = doubleNegationRegex.test(value); //remove negation
//change infinity value to empty string
if (value === 'Infinity' && isNumericString) {
value = '';
}
value = value.replace(/-/g, '');
//round the number based on decimalScale
//format only if non formatted value is provided
if (isNumericString && !format && typeof decimalScale === 'number') {
value = roundToPrecision(value, decimalScale, fixedDecimalScale);
}
if (hasNegation && !removeNegation && allowNegative) {
value = '-' + value;
}
var formattedValue = isNumericString ? this.formatNumString(value) : this.formatInput(value);
return value;
}
}, {
key: "formatInput",
value: function formatInput() {
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var format = this.props.format; //format negation only if we are formatting as number
return formattedValue;
};
if (!format) {
value = this.removePrefixAndSuffix(value);
value = this.formatNegation(value);
} //remove formatting from number
NumberFormat.prototype.formatNegation = function formatNegation (value) {
if ( value === void 0 ) value = '';
var ref = this.props;
var allowNegative = ref.allowNegative;
var negationRegex = new RegExp('(-)');
var doubleNegationRegex = new RegExp('(-)(.)*(-)');
value = this.removeFormatting(value);
return this.formatNumString(value);
}
/*** format specific methods end ***/
// Check number has '-' value
var hasNegation = negationRegex.test(value);
}, {
key: "isCharacterAFormat",
value: function isCharacterAFormat(caretPos, value) {
var _this$props10 = this.props,
format = _this$props10.format,
prefix = _this$props10.prefix,
suffix = _this$props10.suffix,
decimalScale = _this$props10.decimalScale,
fixedDecimalScale = _this$props10.fixedDecimalScale;
// Check number has 2 or more '-' values
var removeNegation = doubleNegationRegex.test(value);
var _this$getSeparators5 = this.getSeparators(),
decimalSeparator = _this$getSeparators5.decimalSeparator; //check within format pattern
//remove negation
value = value.replace(/-/g, '');
if (hasNegation && !removeNegation && allowNegative) {
value = '-' + value;
}
if (typeof format === 'string' && format[caretPos] !== '#') return true; //check in number format
return value;
};
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator)) {
return true;
}
NumberFormat.prototype.formatInput = function formatInput (value) {
if ( value === void 0 ) value = '';
return false;
}
}, {
key: "checkIfFormatGotDeleted",
value: function checkIfFormatGotDeleted(start, end, value) {
for (var i = start; i < end; i++) {
if (this.isCharacterAFormat(i, value)) return true;
}
var ref = this.props;
var format = ref.format;
return false;
}
/**
* This will check if any formatting got removed by the delete or backspace and reset the value
* It will also work as fallback if android chome keyDown handler does not work
**/
//format negation only if we are formatting as number
if (!format) {
value = this.removePrefixAndSuffix(value);
value = this.formatNegation(value);
}
}, {
key: "correctInputValue",
value: function correctInputValue(caretPos, lastValue, value) {
var _this$props11 = this.props,
format = _this$props11.format,
allowNegative = _this$props11.allowNegative,
prefix = _this$props11.prefix,
suffix = _this$props11.suffix,
decimalScale = _this$props11.decimalScale;
//remove formatting from number
value = this.removeFormatting(value);
var _this$getSeparators6 = this.getSeparators(),
allowedDecimalSeparators = _this$getSeparators6.allowedDecimalSeparators,
decimalSeparator = _this$getSeparators6.decimalSeparator;
return this.formatNumString(value);
};
var lastNumStr = this.state.numAsString || '';
var _this$selectionBefore = this.selectionBeforeInput,
selectionStart = _this$selectionBefore.selectionStart,
selectionEnd = _this$selectionBefore.selectionEnd;
/*** format specific methods end ***/
NumberFormat.prototype.isCharacterAFormat = function isCharacterAFormat (caretPos , value ) {
var ref = this.props;
var format = ref.format;
var prefix = ref.prefix;
var suffix = ref.suffix;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var ref$1 = this.getSeparators();
var decimalSeparator = ref$1.decimalSeparator;
var _findChangedIndex = findChangedIndex(lastValue, value),
start = _findChangedIndex.start,
end = _findChangedIndex.end;
/** Check for any allowed decimal separator is added in the numeric format and replace it with decimal separator */
//check within format pattern
if (typeof format === 'string' && format[caretPos] !== '#') { return true; }
//check in number format
if (!format && (caretPos < prefix.length
|| caretPos >= value.length - suffix.length
|| (decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator))
) {
return true;
}
if (!format && start === end && allowedDecimalSeparators.indexOf(value[selectionStart]) !== -1) {
var separator = decimalScale === 0 ? '' : decimalSeparator;
return value.substr(0, selectionStart) + separator + value.substr(selectionStart + 1, value.length);
}
/* don't do anyhting if something got added,
or if value is empty string (when whole input is cleared)
or whole input is replace with a number
*/
return false;
};
NumberFormat.prototype.checkIfFormatGotDeleted = function checkIfFormatGotDeleted (start , end , value ) {
for (var i = start; i < end; i++) {
if (this.isCharacterAFormat(i, value)) { return true; }
}
return false;
};
var leftBound = !!format ? 0 : prefix.length;
var rightBound = lastValue.length - (!!format ? 0 : suffix.length);
/**
* This will check if any formatting got removed by the delete or backspace and reset the value
* It will also work as fallback if android chome keyDown handler does not work
**/
NumberFormat.prototype.correctInputValue = function correctInputValue (caretPos , lastValue , value ) {
var ref = this.props;
var format = ref.format;
var allowNegative = ref.allowNegative;
var prefix = ref.prefix;
var suffix = ref.suffix;
var decimalScale = ref.decimalScale;
var ref$1 = this.getSeparators();
var allowedDecimalSeparators = ref$1.allowedDecimalSeparators;
var decimalSeparator = ref$1.decimalSeparator;
var lastNumStr = this.state.numAsString || '';
var ref$2 = this.selectionBeforeInput;
var selectionStart = ref$2.selectionStart;
var selectionEnd = ref$2.selectionEnd;
var ref$3 = findChangedIndex(lastValue, value);
var start = ref$3.start;
var end = ref$3.end;
if (value.length > lastValue.length || !value.length || start === end || selectionStart === 0 && selectionEnd === lastValue.length || start === 0 && end === lastValue.length || selectionStart === leftBound && selectionEnd === rightBound) {
return value;
} //if format got deleted reset the value to last value
/** Check for any allowed decimal separator is added in the numeric format and replace it with decimal separator */
if (!format && start === end && allowedDecimalSeparators.indexOf(value[selectionStart]) !== -1 ) {
var separator = decimalScale === 0 ? '' : decimalSeparator;
return value.substr(0, selectionStart) + separator + value.substr(selectionStart + 1, value.length);
}
if (this.checkIfFormatGotDeleted(start, end, lastValue)) {
value = lastValue;
} //for numbers check if beforeDecimal got deleted and there is nothing after decimal,
//clear all numbers in such case while keeping the - sign
var leftBound = !!format ? 0 : prefix.length;
var rightBound = lastValue.length - (!!format ? 0 : suffix.length);
if (
// don't do anything if something got added
value.length > lastValue.length ||
// or if the new value is an empty string
!value.length ||
// or if nothing has changed, in which case start will be same as end
start === end ||
// or in case if whole input is selected and new value is typed
(selectionStart === 0 && selectionEnd === lastValue.length) ||
// or in case if the whole content is replaced by browser, example (autocomplete)
(start === 0 && end === lastValue.length) ||
// or if charcters between prefix and suffix is selected.
// For numeric inputs we apply the format so, prefix and suffix can be ignored
(selectionStart === leftBound && selectionEnd === rightBound)
) {
return value;
}
if (!format) {
var numericString = this.removeFormatting(value);
//if format got deleted reset the value to last value
if (this.checkIfFormatGotDeleted(start, end, lastValue)) {
value = lastValue;
}
var _splitDecimal2 = splitDecimal(numericString, allowNegative),
beforeDecimal = _splitDecimal2.beforeDecimal,
afterDecimal = _splitDecimal2.afterDecimal,
addNegation = _splitDecimal2.addNegation; // eslint-disable-line prefer-const
//clear only if something got deleted
//for numbers check if beforeDecimal got deleted and there is nothing after decimal,
//clear all numbers in such case while keeping the - sign
if (!format) {
var numericString = this.removeFormatting(value);
var ref$4 = splitDecimal(numericString, allowNegative);
var beforeDecimal = ref$4.beforeDecimal;
var afterDecimal = ref$4.afterDecimal;
var addNegation = ref$4.addNegation; // eslint-disable-line prefer-const
//clear only if something got deleted
var isBeforeDecimalPoint = caretPos < value.indexOf(decimalSeparator) + 1;
if (numericString.length < lastNumStr.length && isBeforeDecimalPoint && beforeDecimal === '' && !parseFloat(afterDecimal)) {
return addNegation ? '-' : '';
}
}
var isBeforeDecimalPoint = caretPos < value.indexOf(decimalSeparator) + 1;
return value;
};
if (numericString.length < lastNumStr.length && isBeforeDecimalPoint && beforeDecimal === '' && !parseFloat(afterDecimal)) {
return addNegation ? '-' : '';
}
}
/** Update value and caret position */
NumberFormat.prototype.updateValue = function updateValue (params
) {
var formattedValue = params.formattedValue;
var input = params.input;
var setCaretPosition = params.setCaretPosition; if ( setCaretPosition === void 0 ) setCaretPosition = true;
var numAsString = params.numAsString;
var caretPos = params.caretPos;
var ref = this.props;
var onValueChange = ref.onValueChange;
var ref$1 = this.state;
var lastValue = ref$1.value;
return value;
}
/** Update value and caret position */
if (input) {
//set caret position, and value imperatively when element is provided
if (setCaretPosition) {
}, {
key: "updateValue",
value: function updateValue(params) {
var formattedValue = params.formattedValue,
input = params.input,
_params$setCaretPosit = params.setCaretPosition,
setCaretPosition = _params$setCaretPosit === void 0 ? true : _params$setCaretPosit;
var numAsString = params.numAsString,
caretPos = params.caretPos;
var onValueChange = this.props.onValueChange;
var lastValue = this.state.value;
//calculate caret position if not defined
if (!caretPos) {
var inputValue = params.inputValue || input.value;
if (input) {
//set caret position, and value imperatively when element is provided
if (setCaretPosition) {
//calculate caret position if not defined
if (!caretPos) {
var inputValue = params.inputValue || input.value;
var currentCaretPosition = getCurrentCaretPosition(input);
/**
* set the value imperatively, this is required for IE fix
* This is also required as if new caret position is beyond the previous value.
* Caret position will not be set correctly
*/
var currentCaretPosition = getCurrentCaretPosition(input);
input.value = formattedValue; //get the caret position
/**
* set the value imperatively, this is required for IE fix
* This is also required as if new caret position is beyond the previous value.
* Caret position will not be set correctly
*/
input.value = formattedValue;
caretPos = this.getCaretPosition(inputValue, formattedValue, currentCaretPosition);
} //set caret position
//get the caret position
caretPos = this.getCaretPosition(inputValue, formattedValue, currentCaretPosition);
}
//set caret position
this.setPatchedCaretPosition(input, caretPos, formattedValue);
} else {
/**
* if we are not setting caret position set the value imperatively.
* This is required on onBlur method
*/
input.value = formattedValue;
}
}
this.setPatchedCaretPosition(input, caretPos, formattedValue);
} else {
/**
* if we are not setting caret position set the value imperatively.
* This is required on onBlur method
*/
input.value = formattedValue;
}
} //calculate numeric string if not passed
//calculate numeric string if not passed
if (numAsString === undefined) {
numAsString = this.removeFormatting(formattedValue);
}
if (numAsString === undefined) {
numAsString = this.removeFormatting(formattedValue);
} //update state if value is changed
//update state if value is changed
if (formattedValue !== lastValue) {
this.setState({ value : formattedValue, numAsString: numAsString });
// trigger onValueChange synchronously, so parent is updated along with the number format. Fix for #277, #287
onValueChange(this.getValueObject(formattedValue, numAsString));
}
};
if (formattedValue !== lastValue) {
this.setState({
value: formattedValue,
numAsString: numAsString
}); // trigger onValueChange synchronously, so parent is updated along with the number format. Fix for #277, #287
NumberFormat.prototype.onChange = function onChange (e ) {
var el = e.target;
var inputValue = el.value;
var ref = this;
var state = ref.state;
var props = ref.props;
var isAllowed = props.isAllowed;
var lastValue = state.value || '';
onValueChange(this.getValueObject(formattedValue, numAsString));
}
}
}, {
key: "onChange",
value: function onChange(e) {
var el = e.target;
var inputValue = el.value;
var state = this.state,
props = this.props;
var isAllowed = props.isAllowed;
var lastValue = state.value || '';
var currentCaretPosition = getCurrentCaretPosition(el);
inputValue = this.correctInputValue(currentCaretPosition, lastValue, inputValue);
var formattedValue = this.formatInput(inputValue) || '';
var numAsString = this.removeFormatting(formattedValue);
var valueObj = this.getValueObject(formattedValue, numAsString);
var isChangeAllowed = isAllowed(valueObj);
var currentCaretPosition = getCurrentCaretPosition(el);
if (!isChangeAllowed) {
formattedValue = lastValue;
}
inputValue = this.correctInputValue(currentCaretPosition, lastValue, inputValue);
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
inputValue: inputValue,
input: el
});
var formattedValue = this.formatInput(inputValue) || '';
var numAsString = this.removeFormatting(formattedValue);
if (isChangeAllowed) {
props.onChange(e);
}
}
}, {
key: "onBlur",
value: function onBlur(e) {
var props = this.props,
state = this.state;
var format = props.format,
onBlur = props.onBlur,
allowLeadingZeros = props.allowLeadingZeros;
var numAsString = state.numAsString;
var lastValue = state.value;
this.focusedElm = null;
clearTimeout(this.focusTimeout);
var valueObj = this.getValueObject(formattedValue, numAsString);
var isChangeAllowed = isAllowed(valueObj);
if (!format) {
// if the numAsString is not a valid number reset it to empty
if (isNaN(parseFloat(numAsString))) {
numAsString = '';
}
if (!isChangeAllowed) {
formattedValue = lastValue;
}
if (!allowLeadingZeros) {
numAsString = fixLeadingZero(numAsString);
}
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, inputValue: inputValue, input: el });
var formattedValue = this.formatNumString(numAsString); //change the state
if(isChangeAllowed) {
props.onChange(e);
}
};
if (formattedValue !== lastValue) {
// the event needs to be persisted because its properties can be accessed in an asynchronous way
this.updateValue({
formattedValue: formattedValue,
numAsString: numAsString,
input: e.target,
setCaretPosition: false
});
onBlur(e);
return;
}
}
NumberFormat.prototype.onBlur = function onBlur (e ) {
var ref = this;
var props = ref.props;
var state = ref.state;
var format = props.format;
var onBlur = props.onBlur;
var allowLeadingZeros = props.allowLeadingZeros;
var numAsString = state.numAsString;
var lastValue = state.value;
this.focusedElm = null;
onBlur(e);
}
}, {
key: "onKeyDown",
value: function onKeyDown(e) {
var el = e.target;
var key = e.key;
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value = el.value,
value = _el$value === void 0 ? '' : _el$value;
var expectedCaretPosition;
var _this$props12 = this.props,
decimalScale = _this$props12.decimalScale,
fixedDecimalScale = _this$props12.fixedDecimalScale,
prefix = _this$props12.prefix,
suffix = _this$props12.suffix,
format = _this$props12.format,
onKeyDown = _this$props12.onKeyDown;
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
var negativeRegex = new RegExp('-');
var isPatternFormat = typeof format === 'string';
this.selectionBeforeInput = {
selectionStart: selectionStart,
selectionEnd: selectionEnd
}; //Handle backspace and delete against non numerical/decimal characters or arrow keys
clearTimeout(this.focusTimeout);
if (key === 'ArrowLeft' || key === 'Backspace') {
expectedCaretPosition = selectionStart - 1;
} else if (key === 'ArrowRight') {
expectedCaretPosition = selectionStart + 1;
} else if (key === 'Delete') {
expectedCaretPosition = selectionStart;
} //if expectedCaretPosition is not set it means we don't want to Handle keyDown
//also if multiple characters are selected don't handle
if (!format) {
// if the numAsString is not a valid number reset it to empty
if (isNaN(parseFloat(numAsString))) {
numAsString = '';
}
if (expectedCaretPosition === undefined || selectionStart !== selectionEnd) {
onKeyDown(e);
return;
}
if (!allowLeadingZeros) {
numAsString = fixLeadingZero(numAsString);
}
var newCaretPosition = expectedCaretPosition;
var leftBound = isPatternFormat ? format.indexOf('#') : prefix.length;
var rightBound = isPatternFormat ? format.lastIndexOf('#') + 1 : value.length - suffix.length;
var formattedValue = this.formatNumString(numAsString);
if (key === 'ArrowLeft' || key === 'ArrowRight') {
var direction = key === 'ArrowLeft' ? 'left' : 'right';
newCaretPosition = this.correctCaretPosition(value, expectedCaretPosition, direction);
} else if (key === 'Delete' && !numRegex.test(value[expectedCaretPosition]) && !negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition]) && newCaretPosition < rightBound) {
newCaretPosition++;
}
} else if (key === 'Backspace' && !numRegex.test(value[expectedCaretPosition])) {
/* NOTE: This is special case when backspace is pressed on a
negative value while the cursor position is after prefix. We can't handle it on onChange because
we will not have any information of keyPress
*/
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
var newValue = value.substring(1);
this.updateValue({
formattedValue: newValue,
caretPos: newCaretPosition,
input: el
});
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound) {
newCaretPosition--;
}
//change the state
if (formattedValue !== lastValue) {
// the event needs to be persisted because its properties can be accessed in an asynchronous way
this.updateValue({ formattedValue: formattedValue, numAsString: numAsString, input: e.target, setCaretPosition: false });
onBlur(e);
return;
}
}
onBlur(e);
};
newCaretPosition = this.correctCaretPosition(value, newCaretPosition, 'left');
}
}
NumberFormat.prototype.onKeyDown = function onKeyDown (e ) {
var el = e.target;
var key = e.key;
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
var expectedCaretPosition;
var ref = this.props;
var decimalScale = ref.decimalScale;
var fixedDecimalScale = ref.fixedDecimalScale;
var prefix = ref.prefix;
var suffix = ref.suffix;
var format = ref.format;
var onKeyDown = ref.onKeyDown;
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale;
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator);
var negativeRegex = new RegExp('-');
var isPatternFormat = typeof format === 'string';
if (newCaretPosition !== expectedCaretPosition || expectedCaretPosition < leftBound || expectedCaretPosition > rightBound) {
e.preventDefault();
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
/* NOTE: this is just required for unit test as we need to get the newCaretPosition,
Remove this when you find different solution */
this.selectionBeforeInput = {
selectionStart: selectionStart,
selectionEnd: selectionEnd
};
//Handle backspace and delete against non numerical/decimal characters or arrow keys
if (key === 'ArrowLeft' || key === 'Backspace') {
expectedCaretPosition = selectionStart - 1;
} else if (key === 'ArrowRight') {
expectedCaretPosition = selectionStart + 1;
} else if (key === 'Delete') {
expectedCaretPosition = selectionStart;
}
if (e.isUnitTestRun) {
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
//if expectedCaretPosition is not set it means we don't want to Handle keyDown
//also if multiple characters are selected don't handle
if (expectedCaretPosition === undefined || selectionStart !== selectionEnd) {
onKeyDown(e);
return;
}
onKeyDown(e);
}
/** required to handle the caret position when click anywhere within the input **/
var newCaretPosition = expectedCaretPosition;
var leftBound = isPatternFormat ? format.indexOf('#') : prefix.length;
var rightBound = isPatternFormat ? format.lastIndexOf('#') + 1 : value.length - suffix.length;
}, {
key: "onMouseUp",
value: function onMouseUp(e) {
var el = e.target;
/**
* NOTE: we have to give default value for value as in case when custom input is provided
* value can come as undefined when nothing is provided on value prop.
*/
if (key === 'ArrowLeft' || key === 'ArrowRight') {
var direction = key === 'ArrowLeft' ? 'left' : 'right';
newCaretPosition = this.correctCaretPosition(value, expectedCaretPosition, direction);
} else if (key === 'Delete' && !numRegex.test(value[expectedCaretPosition]) && !negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition]) && newCaretPosition < rightBound) { newCaretPosition++; }
} else if (key === 'Backspace' && !numRegex.test(value[expectedCaretPosition])) {
/* NOTE: This is special case when backspace is pressed on a
negative value while the cursor position is after prefix. We can't handle it on onChange because
we will not have any information of keyPress
*/
if (selectionStart <= leftBound + 1 && value[0] === '-' && typeof format === 'undefined') {
var newValue = value.substring(1);
this.updateValue({formattedValue: newValue, caretPos: newCaretPosition, input: el});
} else if (!negativeRegex.test(value[expectedCaretPosition])) {
while (!numRegex.test(value[newCaretPosition - 1]) && newCaretPosition > leftBound){ newCaretPosition--; }
newCaretPosition = this.correctCaretPosition(value, newCaretPosition, 'left');
}
}
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value2 = el.value,
value = _el$value2 === void 0 ? '' : _el$value2;
if (selectionStart === selectionEnd) {
var caretPosition = this.correctCaretPosition(value, selectionStart);
if (newCaretPosition !== expectedCaretPosition || expectedCaretPosition < leftBound || expectedCaretPosition > rightBound) {
e.preventDefault();
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
if (caretPosition !== selectionStart) {
this.setPatchedCaretPosition(el, caretPosition, value);
}
}
/* NOTE: this is just required for unit test as we need to get the newCaretPosition,
Remove this when you find different solution */
if (e.isUnitTestRun) {
this.setPatchedCaretPosition(el, newCaretPosition, value);
}
this.props.onMouseUp(e);
}
}, {
key: "onFocus",
value: function onFocus(e) {
var _this2 = this;
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
// (onFocus event target selectionStart is always 0 before setTimeout)
e.persist();
this.focusedElm = e.target;
this.focusTimeout = setTimeout(function () {
var el = e.target;
var selectionStart = el.selectionStart,
selectionEnd = el.selectionEnd,
_el$value3 = el.value,
value = _el$value3 === void 0 ? '' : _el$value3;
onKeyDown(e);
var caretPosition = _this2.correctCaretPosition(value, selectionStart); //setPatchedCaretPosition only when everything is not selected on focus (while tabbing into the field)
};
/** required to handle the caret position when click anywhere within the input **/
NumberFormat.prototype.onMouseUp = function onMouseUp (e ) {
var el = e.target;
if (caretPosition !== selectionStart && !(selectionStart === 0 && selectionEnd === value.length)) {
_this2.setPatchedCaretPosition(el, caretPosition, value);
}
/**
* NOTE: we have to give default value for value as in case when custom input is provided
* value can come as undefined when nothing is provided on value prop.
*/
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
_this2.props.onFocus(e);
}, 0);
}
}, {
key: "render",
value: function render() {
var _this$props13 = this.props,
type = _this$props13.type,
displayType = _this$props13.displayType,
customInput = _this$props13.customInput,
renderText = _this$props13.renderText,
getInputRef = _this$props13.getInputRef,
format = _this$props13.format;
var _this$state = this.state,
value = _this$state.value,
mounted = _this$state.mounted;
var otherProps = omit(this.props, propTypes$1); // add input mode on element based on format prop and device once the component is mounted
if (selectionStart === selectionEnd) {
var caretPosition = this.correctCaretPosition(value, selectionStart);
if (caretPosition !== selectionStart) {
this.setPatchedCaretPosition(el, caretPosition, value);
}
}
var inputMode = mounted && addInputMode(format) ? 'numeric' : undefined;
this.props.onMouseUp(e);
};
var inputProps = _extends({
inputMode: inputMode
}, otherProps, {
type: type,
value: value,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
onMouseUp: this.onMouseUp,
onFocus: this.onFocus,
onBlur: this.onBlur
});
NumberFormat.prototype.onFocus = function onFocus (e ) {
var this$1 = this;
if (displayType === 'text') {
return renderText ? renderText(value, otherProps) || null : React.createElement("span", _extends({}, otherProps, {
ref: getInputRef
}), value);
} else if (customInput) {
var CustomInput = customInput;
return React.createElement(CustomInput, _extends({}, inputProps, {
ref: getInputRef
}));
}
// Workaround Chrome and Safari bug https://bugs.chromium.org/p/chromium/issues/detail?id=779328
// (onFocus event target selectionStart is always 0 before setTimeout)
e.persist();
return React.createElement("input", _extends({}, inputProps, {
ref: getInputRef
}));
}
}]);
this.focusedElm = e.target;
this.focusTimeout = setTimeout(function () {
var el = e.target;
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
var value = el.value; if ( value === void 0 ) value = '';
return NumberFormat;
}(React.Component);
var caretPosition = this$1.correctCaretPosition(value, selectionStart);
NumberFormat.propTypes = propTypes$1;
NumberFormat.defaultProps = defaultProps;
//setPatchedCaretPosition only when everything is not selected on focus (while tabbing into the field)
if (caretPosition !== selectionStart && !(selectionStart === 0 && selectionEnd === value.length)) {
this$1.setPatchedCaretPosition(el, caretPosition, value);
}
return NumberFormat;
this$1.props.onFocus(e);
}, 0);
};
NumberFormat.prototype.render = function render () {
var ref = this.props;
var type = ref.type;
var displayType = ref.displayType;
var customInput = ref.customInput;
var renderText = ref.renderText;
var getInputRef = ref.getInputRef;
var format = ref.format;
var ref$1 = this.state;
var value = ref$1.value;
var mounted = ref$1.mounted;
var otherProps = omit(this.props, propTypes$1);
// add input mode on element based on format prop and device once the component is mounted
var inputMode = mounted && addInputMode(format) ? 'numeric' : undefined;
var inputProps = Object.assign({ inputMode: inputMode }, otherProps, {
type: type,
value: value,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
onMouseUp: this.onMouseUp,
onFocus: this.onFocus,
onBlur: this.onBlur
});
if( displayType === 'text'){
return renderText ? (renderText(value, otherProps) || null) : React.createElement( 'span', Object.assign({}, otherProps, { ref: getInputRef }), value);
}
else if (customInput) {
var CustomInput = customInput;
return (
React.createElement( CustomInput, Object.assign({},
inputProps, { ref: getInputRef }))
)
}
return (
React.createElement( 'input', Object.assign({},
inputProps, { ref: getInputRef }))
)
};
return NumberFormat;
}(React.Component));
NumberFormat.propTypes = propTypes$1;
NumberFormat.defaultProps = defaultProps;
return NumberFormat;
}));

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):(e=e||self).NumberFormat=t(e.React)}(this,function(h){"use strict";function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function g(){return(g=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}function o(e){return(o=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function r(e,t){return(r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function i(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}h=h&&h.hasOwnProperty("default")?h.default:h;function a(){}function s(){}s.resetWarningCache=a;var e,t=(function(e){e.exports=function(){function e(e,t,r,n,a,o){if("SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"!==o){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}var r={array:e.isRequired=e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:s,resetWarningCache:a};return r.PropTypes=r}()}(e={exports:{}},e.exports),e.exports);function u(){}function p(e){return!!(e||"").match(/\d/)}function m(e){return null==e}function l(e){return e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&")}function D(e,t){var r=!(1<arguments.length&&void 0!==t)||t,n="-"===e[0],a=n&&r,o=(e=e.replace("-","")).split(".");return{beforeDecimal:o[0],afterDecimal:o[1]||"",hasNagation:n,addNegation:a}}function d(e,t,r){for(var n="",a=r?"0":"",o=0;o<=t-1;o++)n+=e[o]||a;return n}function c(e,t){if(e.value=e.value,null!==e){if(e.createTextRange){var r=e.createTextRange();return r.move("character",t),r.select(),!0}return e.selectionStart||0===e.selectionStart?(e.focus(),e.setSelectionRange(t,t),!0):(e.focus(),!1)}}function v(e,t,r){return Math.min(Math.max(e,t),r)}function f(e){return Math.max(e.selectionStart,e.selectionEnd)}var y={thousandSeparator:t.oneOfType([t.string,t.oneOf([!0])]),decimalSeparator:t.string,allowedDecimalSeparators:t.arrayOf(t.string),thousandsGroupStyle:t.oneOf(["thousand","lakh","wan"]),decimalScale:t.number,fixedDecimalScale:t.bool,displayType:t.oneOf(["input","text"]),prefix:t.string,suffix:t.string,format:t.oneOfType([t.string,t.func]),removeFormatting:t.func,mask:t.oneOfType([t.string,t.arrayOf(t.string)]),value:t.oneOfType([t.number,t.string]),defaultValue:t.oneOfType([t.number,t.string]),isNumericString:t.bool,customInput:t.elementType,allowNegative:t.bool,allowEmptyFormatting:t.bool,allowLeadingZeros:t.bool,onValueChange:t.func,onKeyDown:t.func,onMouseUp:t.func,onChange:t.func,onFocus:t.func,onBlur:t.func,type:t.oneOf(["text","tel","password"]),isAllowed:t.func,renderText:t.func,getInputRef:t.oneOfType([t.func,t.shape({current:t.any})])},S={displayType:"input",decimalSeparator:".",thousandsGroupStyle:"thousand",fixedDecimalScale:!1,prefix:"",suffix:"",allowNegative:!0,allowEmptyFormatting:!1,allowLeadingZeros:!1,isNumericString:!1,type:"text",onValueChange:u,onChange:u,onKeyDown:u,onMouseUp:u,onFocus:u,onBlur:u,isAllowed:function(){return!0}},b=function(){function a(e){var t;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,a),t=function(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?i(e):t}(this,o(a).call(this,e));var r=e.defaultValue;t.validateProps();var n=t.formatValueProp(r);return t.state={value:n,numAsString:t.removeFormatting(n),mounted:!1},t.selectionBeforeInput={selectionStart:0,selectionEnd:0},t.onChange=t.onChange.bind(i(t)),t.onKeyDown=t.onKeyDown.bind(i(t)),t.onMouseUp=t.onMouseUp.bind(i(t)),t.onFocus=t.onFocus.bind(i(t)),t.onBlur=t.onBlur.bind(i(t)),t}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&r(e,t)}(a,h.Component),function(e,t,r){t&&n(e.prototype,t),r&&n(e,r)}(a,[{key:"componentDidMount",value:function(){this.setState({mounted:!0})}},{key:"componentDidUpdate",value:function(e){this.updateValueIfRequired(e)}},{key:"componentWillUnmount",value:function(){clearTimeout(this.focusTimeout)}},{key:"updateValueIfRequired",value:function(e){var t=this.props,r=this.state,n=this.focusedElm,a=r.value,o=r.numAsString,i=void 0===o?"":o;if(e!==t){this.validateProps();var s=this.formatNumString(i),u=m(t.value)?s:this.formatValueProp(),l=this.removeFormatting(u),c=parseFloat(l),f=parseFloat(i);(isNaN(c)&&isNaN(f)||c===f)&&s===a&&(null!==n||u===a)||this.updateValue({formattedValue:u,numAsString:l,input:n})}}},{key:"getFloatString",value:function(e){var t=0<arguments.length&&void 0!==e?e:"",r=this.props.decimalScale,n=this.getSeparators().decimalSeparator,a=this.getNumberRegex(!0),o="-"===t[0];o&&(t=t.replace("-","")),n&&0===r&&(t=t.split(n)[0]);var i=(t=(t.match(a)||[]).join("").replace(n,".")).indexOf(".");return-1!==i&&(t="".concat(t.substring(0,i),".").concat(t.substring(i+1,t.length).replace(new RegExp(l(n),"g"),""))),o&&(t="-"+t),t}},{key:"getNumberRegex",value:function(e,t){var r=this.props,n=r.format,a=r.decimalScale,o=this.getSeparators().decimalSeparator;return new RegExp("\\d"+(!o||0===a||t||n?"":"|"+l(o)),e?"g":void 0)}},{key:"getSeparators",value:function(){var e=this.props.decimalSeparator,t=this.props,r=t.thousandSeparator,n=t.allowedDecimalSeparators;return!0===r&&(r=","),{decimalSeparator:e,thousandSeparator:r,allowedDecimalSeparators:n=n||[e,"."]}}},{key:"getMaskAtIndex",value:function(e){var t=this.props.mask,r=void 0===t?" ":t;return"string"==typeof r?r:r[e]||" "}},{key:"getValueObject",value:function(e,t){var r=parseFloat(t);return{formattedValue:e,value:t,floatValue:isNaN(r)?void 0:r}}},{key:"validateProps",value:function(){var e=this.props.mask,t=this.getSeparators(),r=t.decimalSeparator,n=t.thousandSeparator;if(r===n)throw new Error("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: ".concat(n,' (thousandSeparator = {true} is same as thousandSeparator = ",")\n decimalSeparator: ').concat(r," (default value for decimalSeparator is .)\n "));if(e&&("string"===e?e:e.toString()).match(/\d/g))throw new Error("\n Mask ".concat(e," should not contain numeric character;\n "))}},{key:"setPatchedCaretPosition",value:function(e,t,r){c(e,t),setTimeout(function(){e.value===r&&c(e,t)},0)}},{key:"correctCaretPosition",value:function(e,t,r){var n=this.props,a=n.prefix,o=n.suffix,i=n.format;if(""===e)return 0;if(t=v(t,0,e.length),!i){var s="-"===e[0];return v(t,a.length+(s?1:0),e.length-o.length)}if("function"==typeof i)return t;if("#"===i[t]&&p(e[t]))return t;if("#"===i[t-1]&&p(e[t-1]))return t;var u=i.indexOf("#");t=v(t,u,i.lastIndexOf("#")+1);for(var l=i.substring(t,i.length).indexOf("#"),c=t,f=t+(-1===l?0:l);u<c&&("#"!==i[c]||!p(e[c]));)c-=1;return!p(e[f])||"left"===r&&t!==u||t-c<f-t?p(e[c])?c+1:c:f}},{key:"getCaretPosition",value:function(e,t,r){var n,a,o=this.props.format,i=this.state.value,s=this.getNumberRegex(!0),u=(e.match(s)||[]).join(""),l=(t.match(s)||[]).join("");for(a=n=0;a<r;a++){var c=e[a]||"",f=t[n]||"";if((c.match(s)||c===f)&&("0"!==c||!f.match(s)||"0"===f||u.length===l.length)){for(;c!==t[n]&&n<t.length;)n++;n++}}return"string"!=typeof o||i||(n=t.length),n=this.correctCaretPosition(t,n)}},{key:"removePrefixAndSuffix",value:function(e){var t=this.props,r=t.format,n=t.prefix,a=t.suffix;if(!r&&e){var o="-"===e[0];o&&(e=e.substring(1,e.length));var i=(e=n&&0===e.indexOf(n)?e.substring(n.length,e.length):e).lastIndexOf(a);e=a&&-1!==i&&i===e.length-a.length?e.substring(0,i):e,o&&(e="-"+e)}return e}},{key:"removePatternFormatting",value:function(e){for(var t=this.props.format.split("#").filter(function(e){return""!==e}),r=0,n="",a=0,o=t.length;a<=o;a++){var i=t[a]||"",s=a===o?e.length:e.indexOf(i,r);if(-1===s){n=e;break}n+=e.substring(r,s),r=s+i.length}return(n.match(/\d/g)||[]).join("")}},{key:"removeFormatting",value:function(e){var t=this.props,r=t.format,n=t.removeFormatting;return e?e=r?"string"==typeof r?this.removePatternFormatting(e):"function"==typeof n?n(e):(e.match(/\d/g)||[]).join(""):(e=this.removePrefixAndSuffix(e),this.getFloatString(e)):e}},{key:"formatWithPattern",value:function(e){for(var t=this.props.format,r=0,n=t.split(""),a=0,o=t.length;a<o;a++)"#"===t[a]&&(n[a]=e[r]||this.getMaskAtIndex(r),r+=1);return n.join("")}},{key:"formatAsNumber",value:function(e){var t=this.props,r=t.decimalScale,n=t.fixedDecimalScale,a=t.prefix,o=t.suffix,i=t.allowNegative,s=t.thousandsGroupStyle,u=this.getSeparators(),l=u.thousandSeparator,c=u.decimalSeparator,f=-1!==e.indexOf(".")||r&&n,p=D(e,i),h=p.beforeDecimal,g=p.afterDecimal,m=p.addNegation;return void 0!==r&&(g=d(g,r,n)),l&&(h=function(e,t,r){var n=function(e){switch(e){case"lakh":return/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/g;case"wan":return/(\d)(?=(\d{4})+(?!\d))/g;case"thousand":default:return/(\d)(?=(\d{3})+(?!\d))/g}}(r),a=e.search(/[1-9]/);return a=-1===a?e.length:a,e.substring(0,a)+e.substring(a,e.length).replace(n,"$1"+t)}(h,l,s)),a&&(h=a+h),o&&(g+=o),m&&(h="-"+h),e=h+(f&&c||"")+g}},{key:"formatNumString",value:function(e){var t=0<arguments.length&&void 0!==e?e:"",r=this.props,n=r.format,a=r.allowEmptyFormatting,o=t;return o=""!==t||a?"-"!==t||n?"string"==typeof n?this.formatWithPattern(o):"function"==typeof n?n(o):this.formatAsNumber(o):"-":""}},{key:"formatValueProp",value:function(e){var t=this.props,r=t.format,n=t.decimalScale,a=t.fixedDecimalScale,o=t.allowEmptyFormatting,i=this.props,s=i.value,u=i.isNumericString,l=!(s=m(s)?e:s)&&0!==s;return l&&o&&(s=""),l&&!o?"":("number"==typeof s&&(s=s.toString(),u=!0),"Infinity"===s&&u&&(s=""),u&&!r&&"number"==typeof n&&(s=function(e,t,r){if(-1!==["","-"].indexOf(e))return e;var n=-1!==e.indexOf(".")&&t,a=D(e),o=a.beforeDecimal,i=a.afterDecimal,s=a.hasNagation,u=parseFloat("0.".concat(i||"0")),l=(i.length<=t?u.toString():u.toFixed(t)).split("."),c=o.split("").reverse().reduce(function(e,t,r){return e.length>r?(Number(e[0])+Number(t)).toString()+e.substring(1,e.length):t+e},l[0]),f=d(l[1]||"",Math.min(t,i.length),r),p=n?".":"";return"".concat(s?"-":"").concat(c).concat(p).concat(f)}(s,n,a)),u?this.formatNumString(s):this.formatInput(s))}},{key:"formatNegation",value:function(e){var t=0<arguments.length&&void 0!==e?e:"",r=this.props.allowNegative,n=new RegExp("(-)"),a=new RegExp("(-)(.)*(-)"),o=n.test(t),i=a.test(t);return t=t.replace(/-/g,""),o&&!i&&r&&(t="-"+t),t}},{key:"formatInput",value:function(e){var t=0<arguments.length&&void 0!==e?e:"";return this.props.format||(t=this.removePrefixAndSuffix(t),t=this.formatNegation(t)),t=this.removeFormatting(t),this.formatNumString(t)}},{key:"isCharacterAFormat",value:function(e,t){var r=this.props,n=r.format,a=r.prefix,o=r.suffix,i=r.decimalScale,s=r.fixedDecimalScale,u=this.getSeparators().decimalSeparator;return"string"==typeof n&&"#"!==n[e]||!(n||!(e<a.length||e>=t.length-o.length||i&&s&&t[e]===u))}},{key:"checkIfFormatGotDeleted",value:function(e,t,r){for(var n=e;n<t;n++)if(this.isCharacterAFormat(n,r))return!0;return!1}},{key:"correctInputValue",value:function(e,t,r){var n=this.props,a=n.format,o=n.allowNegative,i=n.prefix,s=n.suffix,u=n.decimalScale,l=this.getSeparators(),c=l.allowedDecimalSeparators,f=l.decimalSeparator,p=this.state.numAsString||"",h=this.selectionBeforeInput,g=h.selectionStart,m=h.selectionEnd,d=function(e,t){for(var r=0,n=0,a=e.length,o=t.length;e[r]===t[r]&&r<a;)r++;for(;e[a-1-n]===t[o-1-n]&&r<o-n&&r<a-n;)n++;return{start:r,end:a-n}}(t,r),v=d.start,y=d.end;if(!a&&v===y&&-1!==c.indexOf(r[g])){var S=0===u?"":f;return r.substr(0,g)+S+r.substr(g+1,r.length)}var b=a?0:i.length,x=t.length-(a?0:s.length);if(r.length>t.length||!r.length||v===y||0===g&&m===t.length||0===v&&y===t.length||g===b&&m===x)return r;if(this.checkIfFormatGotDeleted(v,y,t)&&(r=t),!a){var w=this.removeFormatting(r),O=D(w,o),P=O.beforeDecimal,k=O.afterDecimal,F=O.addNegation,N=e<r.indexOf(f)+1;if(w.length<p.length&&N&&""===P&&!parseFloat(k))return F?"-":""}return r}},{key:"updateValue",value:function(e){var t=e.formattedValue,r=e.input,n=e.setCaretPosition,a=void 0===n||n,o=e.numAsString,i=e.caretPos,s=this.props.onValueChange,u=this.state.value;if(r)if(a){if(!i){var l=e.inputValue||r.value,c=f(r);r.value=t,i=this.getCaretPosition(l,t,c)}this.setPatchedCaretPosition(r,i,t)}else r.value=t;void 0===o&&(o=this.removeFormatting(t)),t!==u&&(this.setState({value:t,numAsString:o}),s(this.getValueObject(t,o)))}},{key:"onChange",value:function(e){var t=e.target,r=t.value,n=this.state,a=this.props,o=a.isAllowed,i=n.value||"",s=f(t);r=this.correctInputValue(s,i,r);var u=this.formatInput(r)||"",l=this.removeFormatting(u),c=o(this.getValueObject(u,l));c||(u=i),this.updateValue({formattedValue:u,numAsString:l,inputValue:r,input:t}),c&&a.onChange(e)}},{key:"onBlur",value:function(e){var t=this.props,r=this.state,n=t.format,a=t.onBlur,o=t.allowLeadingZeros,i=r.numAsString,s=r.value;if(this.focusedElm=null,clearTimeout(this.focusTimeout),!n){isNaN(parseFloat(i))&&(i=""),o||(i=function(e){if(!e)return e;var t="-"===e[0];t&&(e=e.substring(1,e.length));var r=e.split("."),n=r[0].replace(/^0+/,"")||"0",a=r[1]||"";return"".concat(t?"-":"").concat(n).concat(a?".".concat(a):"")}(i));var u=this.formatNumString(i);if(u!==s)return this.updateValue({formattedValue:u,numAsString:i,input:e.target,setCaretPosition:!1}),void a(e)}a(e)}},{key:"onKeyDown",value:function(e){var t,r=e.target,n=e.key,a=r.selectionStart,o=r.selectionEnd,i=r.value,s=void 0===i?"":i,u=this.props,l=u.decimalScale,c=u.fixedDecimalScale,f=u.prefix,p=u.suffix,h=u.format,g=u.onKeyDown,m=void 0!==l&&c,d=this.getNumberRegex(!1,m),v=new RegExp("-"),y="string"==typeof h;if(this.selectionBeforeInput={selectionStart:a,selectionEnd:o},"ArrowLeft"===n||"Backspace"===n?t=a-1:"ArrowRight"===n?t=a+1:"Delete"===n&&(t=a),void 0!==t&&a===o){var S=t,b=y?h.indexOf("#"):f.length,x=y?h.lastIndexOf("#")+1:s.length-p.length;if("ArrowLeft"===n||"ArrowRight"===n){var w="ArrowLeft"===n?"left":"right";S=this.correctCaretPosition(s,t,w)}else if("Delete"!==n||d.test(s[t])||v.test(s[t])){if("Backspace"===n&&!d.test(s[t]))if(a<=b+1&&"-"===s[0]&&void 0===h){var O=s.substring(1);this.updateValue({formattedValue:O,caretPos:S,input:r})}else if(!v.test(s[t])){for(;!d.test(s[S-1])&&b<S;)S--;S=this.correctCaretPosition(s,S,"left")}}else for(;!d.test(s[S])&&S<x;)S++;(S!==t||t<b||x<t)&&(e.preventDefault(),this.setPatchedCaretPosition(r,S,s)),e.isUnitTestRun&&this.setPatchedCaretPosition(r,S,s),g(e)}else g(e)}},{key:"onMouseUp",value:function(e){var t=e.target,r=t.selectionStart,n=t.selectionEnd,a=t.value,o=void 0===a?"":a;if(r===n){var i=this.correctCaretPosition(o,r);i!==r&&this.setPatchedCaretPosition(t,i,o)}this.props.onMouseUp(e)}},{key:"onFocus",value:function(i){var s=this;i.persist(),this.focusedElm=i.target,this.focusTimeout=setTimeout(function(){var e=i.target,t=e.selectionStart,r=e.selectionEnd,n=e.value,a=void 0===n?"":n,o=s.correctCaretPosition(a,t);o===t||0===t&&r===a.length||s.setPatchedCaretPosition(e,o,a),s.props.onFocus(i)},0)}},{key:"render",value:function(){var e=this.props,t=e.type,r=e.displayType,n=e.customInput,a=e.renderText,o=e.getInputRef,i=e.format,s=this.state,u=s.value,l=s.mounted,c=function(t,r){var n={};return Object.keys(t).forEach(function(e){r[e]||(n[e]=t[e])}),n}(this.props,y),f=g({inputMode:l&&function(e){return e||!(navigator.platform&&/iPhone|iPod/.test(navigator.platform))}(i)?"numeric":void 0},c,{type:t,value:u,onChange:this.onChange,onKeyDown:this.onKeyDown,onMouseUp:this.onMouseUp,onFocus:this.onFocus,onBlur:this.onBlur});if("text"===r)return a?a(u,c)||null:h.createElement("span",g({},c,{ref:o}),u);if(n){var p=n;return h.createElement(p,g({},f,{ref:o}))}return h.createElement("input",g({},f,{ref:o}))}}]),a}();return b.propTypes=y,b.defaultProps=S,b});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("react")):"function"==typeof define&&define.amd?define(["react"],e):(t=t||self).NumberFormat=e(t.React)}(this,function(g){"use strict";g=g&&g.hasOwnProperty("default")?g.default:g;function o(){}function n(){}n.resetWarningCache=o;var t,e=(function(t){t.exports=function(){function t(t,e,r,o,n,a){if("SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"!==a){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function e(){return t}var r={array:t.isRequired=t,bool:t,func:t,number:t,object:t,string:t,symbol:t,any:t,arrayOf:e,element:t,elementType:t,instanceOf:e,node:t,objectOf:e,oneOf:e,oneOfType:e,shape:e,exact:e,checkPropTypes:n,resetWarningCache:o};return r.PropTypes=r}()}(t={exports:{}},t.exports),t.exports);function r(){}function c(t){return!!(t||"").match(/\d/)}function f(t){return null==t}function i(t){return t.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&")}function C(t,e){void 0===e&&(e=!0);var r="-"===t[0],o=r&&e,n=(t=t.replace("-","")).split(".");return{beforeDecimal:n[0],afterDecimal:n[1]||"",hasNagation:r,addNegation:o}}function d(t,e,r){for(var o="",n=r?"0":"",a=0;a<=e-1;a++)o+=t[a]||n;return o}function s(t,e){return Array(e+1).join(t)}function p(t){var e="-"===(t+="")[0]?"-":"";e&&(t=t.substring(1));var r=t.split(/[eE]/g),o=r[0],n=r[1];if(!(n=Number(n)))return e+o;var a=1+n,i=(o=o.replace(".","")).length;return a<0?o="0."+s("0",Math.abs(a))+o:i<=a?o+=s("0",a-i):o=(o.substring(0,a)||"0")+"."+o.substring(a),e+o}function a(t,e){if(t.value=t.value,null!==t){if(t.createTextRange){var r=t.createTextRange();return r.move("character",e),r.select(),!0}return t.selectionStart||0===t.selectionStart?(t.focus(),t.setSelectionRange(e,e),!0):(t.focus(),!1)}}function h(t,e,r){return Math.min(Math.max(t,e),r)}function m(t){return Math.max(t.selectionStart,t.selectionEnd)}var v={thousandSeparator:e.oneOfType([e.string,e.oneOf([!0])]),decimalSeparator:e.string,allowedDecimalSeparators:e.arrayOf(e.string),thousandsGroupStyle:e.oneOf(["thousand","lakh","wan"]),decimalScale:e.number,fixedDecimalScale:e.bool,displayType:e.oneOf(["input","text"]),prefix:e.string,suffix:e.string,format:e.oneOfType([e.string,e.func]),removeFormatting:e.func,mask:e.oneOfType([e.string,e.arrayOf(e.string)]),value:e.oneOfType([e.number,e.string]),defaultValue:e.oneOfType([e.number,e.string]),isNumericString:e.bool,customInput:e.elementType,allowNegative:e.bool,allowEmptyFormatting:e.bool,allowLeadingZeros:e.bool,onValueChange:e.func,onKeyDown:e.func,onMouseUp:e.func,onChange:e.func,onFocus:e.func,onBlur:e.func,type:e.oneOf(["text","tel","password"]),isAllowed:e.func,renderText:e.func,getInputRef:e.oneOfType([e.func,e.shape({current:e.any})])},u={displayType:"input",decimalSeparator:".",thousandsGroupStyle:"thousand",fixedDecimalScale:!1,prefix:"",suffix:"",allowNegative:!0,allowEmptyFormatting:!1,allowLeadingZeros:!1,isNumericString:!1,type:"text",onValueChange:r,onChange:r,onKeyDown:r,onMouseUp:r,onFocus:r,onBlur:r,isAllowed:function(){return!0}},l=function(o){function t(t){o.call(this,t);var e=t.defaultValue;this.validateProps();var r=this.formatValueProp(e);this.state={value:r,numAsString:this.removeFormatting(r),mounted:!1},this.selectionBeforeInput={selectionStart:0,selectionEnd:0},this.onChange=this.onChange.bind(this),this.onKeyDown=this.onKeyDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onFocus=this.onFocus.bind(this),this.onBlur=this.onBlur.bind(this)}return o&&(t.__proto__=o),((t.prototype=Object.create(o&&o.prototype)).constructor=t).prototype.componentDidMount=function(){this.setState({mounted:!0})},t.prototype.componentDidUpdate=function(t){this.updateValueIfRequired(t)},t.prototype.componentWillUnmount=function(){clearTimeout(this.focusTimeout)},t.prototype.updateValueIfRequired=function(t){var e=this.props,r=this.state,o=this.focusedElm,n=r.value,a=r.numAsString;if(void 0===a&&(a=""),t!==e){this.validateProps();var i=this.formatNumString(a),s=f(e.value)?i:this.formatValueProp(),u=this.removeFormatting(s),l=parseFloat(u),p=parseFloat(a);(isNaN(l)&&isNaN(p)||l===p)&&i===n&&(null!==o||s===n)||this.updateValue({formattedValue:s,numAsString:u,input:o})}},t.prototype.getFloatString=function(t){void 0===t&&(t="");var e=this.props.decimalScale,r=this.getSeparators().decimalSeparator,o=this.getNumberRegex(!0),n="-"===t[0];n&&(t=t.replace("-","")),r&&0===e&&(t=t.split(r)[0]);var a=(t=(t.match(o)||[]).join("").replace(r,".")).indexOf(".");return-1!==a&&(t=t.substring(0,a)+"."+t.substring(a+1,t.length).replace(new RegExp(i(r),"g"),"")),n&&(t="-"+t),t},t.prototype.getNumberRegex=function(t,e){var r=this.props,o=r.format,n=r.decimalScale,a=this.getSeparators().decimalSeparator;return new RegExp("\\d"+(!a||0===n||e||o?"":"|"+i(a)),t?"g":void 0)},t.prototype.getSeparators=function(){var t=this.props.decimalSeparator,e=this.props,r=e.thousandSeparator,o=e.allowedDecimalSeparators;return!0===r&&(r=","),{decimalSeparator:t,thousandSeparator:r,allowedDecimalSeparators:o=o||[t,"."]}},t.prototype.getMaskAtIndex=function(t){var e=this.props.mask;return void 0===e&&(e=" "),"string"==typeof e?e:e[t]||" "},t.prototype.getValueObject=function(t,e){var r=parseFloat(e);return{formattedValue:t,value:e,floatValue:isNaN(r)?void 0:r}},t.prototype.validateProps=function(){var t=this.props.mask,e=this.getSeparators(),r=e.decimalSeparator,o=e.thousandSeparator;if(r===o)throw new Error("\n Decimal separator can't be same as thousand separator.\n thousandSeparator: "+o+' (thousandSeparator = {true} is same as thousandSeparator = ",")\n decimalSeparator: '+r+" (default value for decimalSeparator is .)\n ");if(t&&("string"===t?t:t.toString()).match(/\d/g))throw new Error("\n Mask "+t+" should not contain numeric character;\n ")},t.prototype.setPatchedCaretPosition=function(t,e,r){a(t,e),setTimeout(function(){t.value===r&&a(t,e)},0)},t.prototype.correctCaretPosition=function(t,e,r){var o=this.props,n=o.prefix,a=o.suffix,i=o.format;if(""===t)return 0;if(e=h(e,0,t.length),!i){var s="-"===t[0];return h(e,n.length+(s?1:0),t.length-a.length)}if("function"==typeof i)return e;if("#"===i[e]&&c(t[e]))return e;if("#"===i[e-1]&&c(t[e-1]))return e;var u=i.indexOf("#");e=h(e,u,i.lastIndexOf("#")+1);for(var l=i.substring(e,i.length).indexOf("#"),p=e,f=e+(-1===l?0:l);u<p&&("#"!==i[p]||!c(t[p]));)p-=1;return!c(t[f])||"left"===r&&e!==u||e-p<f-e?c(t[p])?p+1:p:f},t.prototype.getCaretPosition=function(t,e,r){var o,n,a=this.props.format,i=this.state.value,s=this.getNumberRegex(!0),u=(t.match(s)||[]).join(""),l=(e.match(s)||[]).join("");for(n=o=0;n<r;n++){var p=t[n]||"",f=e[o]||"";if((p.match(s)||p===f)&&("0"!==p||!f.match(s)||"0"===f||u.length===l.length)){for(;p!==e[o]&&o<e.length;)o++;o++}}return"string"!=typeof a||i||(o=e.length),o=this.correctCaretPosition(e,o)},t.prototype.removePrefixAndSuffix=function(t){var e=this.props,r=e.format,o=e.prefix,n=e.suffix;if(!r&&t){var a="-"===t[0];a&&(t=t.substring(1,t.length));var i=(t=o&&0===t.indexOf(o)?t.substring(o.length,t.length):t).lastIndexOf(n);t=n&&-1!==i&&i===t.length-n.length?t.substring(0,i):t,a&&(t="-"+t)}return t},t.prototype.removePatternFormatting=function(t){for(var e=this.props.format.split("#").filter(function(t){return""!==t}),r=0,o="",n=0,a=e.length;n<=a;n++){var i=e[n]||"",s=n===a?t.length:t.indexOf(i,r);if(-1===s){o=t;break}o+=t.substring(r,s),r=s+i.length}return(o.match(/\d/g)||[]).join("")},t.prototype.removeFormatting=function(t){var e=this.props,r=e.format,o=e.removeFormatting;return t?t=r?"string"==typeof r?this.removePatternFormatting(t):"function"==typeof o?o(t):(t.match(/\d/g)||[]).join(""):(t=this.removePrefixAndSuffix(t),this.getFloatString(t)):t},t.prototype.formatWithPattern=function(t){for(var e=this.props.format,r=0,o=e.split(""),n=0,a=e.length;n<a;n++)"#"===e[n]&&(o[n]=t[r]||this.getMaskAtIndex(r),r+=1);return o.join("")},t.prototype.formatAsNumber=function(t){var e=this.props,r=e.decimalScale,o=e.fixedDecimalScale,n=e.prefix,a=e.suffix,i=e.allowNegative,s=e.thousandsGroupStyle,u=this.getSeparators(),l=u.thousandSeparator,p=u.decimalSeparator,f=-1!==t.indexOf(".")||r&&o,c=C(t,i),h=c.beforeDecimal,g=c.afterDecimal,m=c.addNegation;return void 0!==r&&(g=d(g,r,o)),l&&(h=function(t,e,r){var o=function(t){switch(t){case"lakh":return/(\d+?)(?=(\d\d)+(\d)(?!\d))(\.\d+)?/g;case"wan":return/(\d)(?=(\d{4})+(?!\d))/g;case"thousand":default:return/(\d)(?=(\d{3})+(?!\d))/g}}(r),n=t.search(/[1-9]/);return n=-1===n?t.length:n,t.substring(0,n)+t.substring(n,t.length).replace(o,"$1"+e)}(h,l,s)),n&&(h=n+h),a&&(g+=a),m&&(h="-"+h),t=h+(f&&p||"")+g},t.prototype.formatNumString=function(t){void 0===t&&(t="");var e=this.props,r=e.format,o=e.allowEmptyFormatting,n=t;return n=""!==t||o?"-"!==t||r?"string"==typeof r?this.formatWithPattern(n):"function"==typeof r?r(n):this.formatAsNumber(n):"-":""},t.prototype.formatValueProp=function(t){var e=this.props,r=e.format,o=e.decimalScale,n=e.fixedDecimalScale,a=e.allowEmptyFormatting,i=this.props,s=i.value,u=i.isNumericString,l=!(s=f(s)?t:s)&&0!==s;return l&&a&&(s=""),l&&!a?"":("number"==typeof s&&(s=p(s),u=!0),"Infinity"===s&&u&&(s=""),u&&!r&&"number"==typeof o&&(s=function(t,e,r){if(-1!==["","-"].indexOf(t))return t;var o=-1!==t.indexOf(".")&&e,n=C(t),a=n.beforeDecimal,i=n.afterDecimal,s=n.hasNagation,u=parseFloat("0."+(i||"0")),l=(i.length<=e?p(u):u.toFixed(e)).split(".");return(s?"-":"")+a.split("").reverse().reduce(function(t,e,r){return t.length>r?(Number(t[0])+Number(e)).toString()+t.substring(1,t.length):e+t},l[0])+(o?".":"")+d(l[1]||"",Math.min(e,i.length),r)}(s,o,n)),u?this.formatNumString(s):this.formatInput(s))},t.prototype.formatNegation=function(t){void 0===t&&(t="");var e=this.props.allowNegative,r=new RegExp("(-)"),o=new RegExp("(-)(.)*(-)"),n=r.test(t),a=o.test(t);return t=t.replace(/-/g,""),n&&!a&&e&&(t="-"+t),t},t.prototype.formatInput=function(t){return void 0===t&&(t=""),this.props.format||(t=this.removePrefixAndSuffix(t),t=this.formatNegation(t)),t=this.removeFormatting(t),this.formatNumString(t)},t.prototype.isCharacterAFormat=function(t,e){var r=this.props,o=r.format,n=r.prefix,a=r.suffix,i=r.decimalScale,s=r.fixedDecimalScale,u=this.getSeparators().decimalSeparator;return"string"==typeof o&&"#"!==o[t]||!(o||!(t<n.length||t>=e.length-a.length||i&&s&&e[t]===u))},t.prototype.checkIfFormatGotDeleted=function(t,e,r){for(var o=t;o<e;o++)if(this.isCharacterAFormat(o,r))return!0;return!1},t.prototype.correctInputValue=function(t,e,r){var o=this.props,n=o.format,a=o.allowNegative,i=o.prefix,s=o.suffix,u=o.decimalScale,l=this.getSeparators(),p=l.allowedDecimalSeparators,f=l.decimalSeparator,c=this.state.numAsString||"",h=this.selectionBeforeInput,g=h.selectionStart,m=h.selectionEnd,d=function(t,e){for(var r=0,o=0,n=t.length,a=e.length;t[r]===e[r]&&r<n;)r++;for(;t[n-1-o]===e[a-1-o]&&r<a-o&&r<n-o;)o++;return{start:r,end:n-o}}(e,r),v=d.start,y=d.end;if(!n&&v===y&&-1!==p.indexOf(r[g])){var S=0===u?"":f;return r.substr(0,g)+S+r.substr(g+1,r.length)}var x=n?0:i.length,b=e.length-(n?0:s.length);if(r.length>e.length||!r.length||v===y||0===g&&m===e.length||0===v&&y===e.length||g===x&&m===b)return r;if(this.checkIfFormatGotDeleted(v,y,e)&&(r=e),!n){var w=this.removeFormatting(r),P=C(w,a),O=P.beforeDecimal,N=P.afterDecimal,F=P.addNegation,D=t<r.indexOf(f)+1;if(w.length<c.length&&D&&""===O&&!parseFloat(N))return F?"-":""}return r},t.prototype.updateValue=function(t){var e=t.formattedValue,r=t.input,o=t.setCaretPosition;void 0===o&&(o=!0);var n=t.numAsString,a=t.caretPos,i=this.props.onValueChange,s=this.state.value;if(r)if(o){if(!a){var u=t.inputValue||r.value,l=m(r);r.value=e,a=this.getCaretPosition(u,e,l)}this.setPatchedCaretPosition(r,a,e)}else r.value=e;void 0===n&&(n=this.removeFormatting(e)),e!==s&&(this.setState({value:e,numAsString:n}),i(this.getValueObject(e,n)))},t.prototype.onChange=function(t){var e=t.target,r=e.value,o=this.state,n=this.props,a=n.isAllowed,i=o.value||"",s=m(e);r=this.correctInputValue(s,i,r);var u=this.formatInput(r)||"",l=this.removeFormatting(u),p=a(this.getValueObject(u,l));p||(u=i),this.updateValue({formattedValue:u,numAsString:l,inputValue:r,input:e}),p&&n.onChange(t)},t.prototype.onBlur=function(t){var e=this.props,r=this.state,o=e.format,n=e.onBlur,a=e.allowLeadingZeros,i=r.numAsString,s=r.value;if(this.focusedElm=null,clearTimeout(this.focusTimeout),!o){isNaN(parseFloat(i))&&(i=""),a||(i=function(t){if(!t)return t;var e="-"===t[0];e&&(t=t.substring(1,t.length));var r=t.split("."),o=r[0].replace(/^0+/,"")||"0",n=r[1]||"";return(e?"-":"")+o+(n?"."+n:"")}(i));var u=this.formatNumString(i);if(u!==s)return this.updateValue({formattedValue:u,numAsString:i,input:t.target,setCaretPosition:!1}),void n(t)}n(t)},t.prototype.onKeyDown=function(t){var e,r=t.target,o=t.key,n=r.selectionStart,a=r.selectionEnd,i=r.value;void 0===i&&(i="");var s=this.props,u=s.decimalScale,l=s.fixedDecimalScale,p=s.prefix,f=s.suffix,c=s.format,h=s.onKeyDown,g=void 0!==u&&l,m=this.getNumberRegex(!1,g),d=new RegExp("-"),v="string"==typeof c;if(this.selectionBeforeInput={selectionStart:n,selectionEnd:a},"ArrowLeft"===o||"Backspace"===o?e=n-1:"ArrowRight"===o?e=n+1:"Delete"===o&&(e=n),void 0!==e&&n===a){var y=e,S=v?c.indexOf("#"):p.length,x=v?c.lastIndexOf("#")+1:i.length-f.length;if("ArrowLeft"===o||"ArrowRight"===o){var b="ArrowLeft"===o?"left":"right";y=this.correctCaretPosition(i,e,b)}else if("Delete"!==o||m.test(i[e])||d.test(i[e])){if("Backspace"===o&&!m.test(i[e]))if(n<=S+1&&"-"===i[0]&&void 0===c){var w=i.substring(1);this.updateValue({formattedValue:w,caretPos:y,input:r})}else if(!d.test(i[e])){for(;!m.test(i[y-1])&&S<y;)y--;y=this.correctCaretPosition(i,y,"left")}}else for(;!m.test(i[y])&&y<x;)y++;(y!==e||e<S||x<e)&&(t.preventDefault(),this.setPatchedCaretPosition(r,y,i)),t.isUnitTestRun&&this.setPatchedCaretPosition(r,y,i),h(t)}else h(t)},t.prototype.onMouseUp=function(t){var e=t.target,r=e.selectionStart,o=e.selectionEnd,n=e.value;if(void 0===n&&(n=""),r===o){var a=this.correctCaretPosition(n,r);a!==r&&this.setPatchedCaretPosition(e,a,n)}this.props.onMouseUp(t)},t.prototype.onFocus=function(a){var i=this;a.persist(),this.focusedElm=a.target,this.focusTimeout=setTimeout(function(){var t=a.target,e=t.selectionStart,r=t.selectionEnd,o=t.value;void 0===o&&(o="");var n=i.correctCaretPosition(o,e);n===e||0===e&&r===o.length||i.setPatchedCaretPosition(t,n,o),i.props.onFocus(a)},0)},t.prototype.render=function(){var t=this.props,e=t.type,r=t.displayType,o=t.customInput,n=t.renderText,a=t.getInputRef,i=t.format,s=this.state,u=s.value,l=s.mounted,p=function(e,r){var o={};return Object.keys(e).forEach(function(t){r[t]||(o[t]=e[t])}),o}(this.props,v),f=l&&function(t){return t||!(navigator.platform&&/iPhone|iPod/.test(navigator.platform))}(i)?"numeric":void 0,c=Object.assign({inputMode:f},p,{type:e,value:u,onChange:this.onChange,onKeyDown:this.onKeyDown,onMouseUp:this.onMouseUp,onFocus:this.onFocus,onBlur:this.onBlur});if("text"===r)return n?n(u,p)||null:g.createElement("span",Object.assign({},p,{ref:a}),u);if(o){var h=o;return g.createElement(h,Object.assign({},c,{ref:a}))}return g.createElement("input",Object.assign({},c,{ref:a}))},t}(g.Component);return l.propTypes=v,l.defaultProps=u,l});

@@ -582,3 +582,3 @@ "use strict";

if (typeof value === 'number') {
value = value.toString();
value = (0, _utils.toNumericString)(value);
isNumericString = true;

@@ -703,12 +703,14 @@ } //change infinity value to empty string

}
/* don't do anyhting if something got added,
or if value is empty string (when whole input is cleared)
or whole input is replace with a number
*/
var leftBound = !!format ? 0 : prefix.length;
var rightBound = lastValue.length - (!!format ? 0 : suffix.length);
if (value.length > lastValue.length || !value.length || start === end || selectionStart === 0 && selectionEnd === lastValue.length || start === 0 && end === lastValue.length || selectionStart === leftBound && selectionEnd === rightBound) {
if ( // don't do anything if something got added
value.length > lastValue.length || // or if the new value is an empty string
!value.length || // or if nothing has changed, in which case start will be same as end
start === end || // or in case if whole input is selected and new value is typed
selectionStart === 0 && selectionEnd === lastValue.length || // or in case if the whole content is replaced by browser, example (autocomplete)
start === 0 && end === lastValue.length || // or if charcters between prefix and suffix is selected.
// For numeric inputs we apply the format so, prefix and suffix can be ignored
selectionStart === leftBound && selectionEnd === rightBound) {
return value;

@@ -715,0 +717,0 @@ } //if format got deleted reset the value to last value

@@ -16,2 +16,3 @@ "use strict";

exports.limitToScale = limitToScale;
exports.toNumericString = toNumericString;
exports.roundToPrecision = roundToPrecision;

@@ -25,2 +26,10 @@ exports.omit = omit;

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
// basic noop function

@@ -42,3 +51,3 @@ function noop() {}

function escapeRegExp(str) {
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}

@@ -109,2 +118,46 @@

}
function repeat(str, count) {
return Array(count + 1).join(str);
}
function toNumericString(num) {
num += ''; // typecast number to string
// store the sign and remove it from the number.
var sign = num[0] === '-' ? '-' : '';
if (sign) num = num.substring(1); // split the number into cofficient and exponent
var _num$split = num.split(/[eE]/g),
_num$split2 = _slicedToArray(_num$split, 2),
coefficient = _num$split2[0],
exponent = _num$split2[1]; // covert exponent to number;
exponent = Number(exponent); // if there is no exponent part or its 0, return the coffiecient with sign
if (!exponent) return sign + coefficient;
coefficient = coefficient.replace('.', '');
/**
* for scientific notation the current decimal index will be after first number (index 0)
* So effective decimal index will always be 1 + exponent value
*/
var decimalIndex = 1 + exponent;
var coffiecientLn = coefficient.length;
if (decimalIndex < 0) {
// if decimal index is less then 0 add preceding 0s
// add 1 as join will have
coefficient = '0.' + repeat('0', Math.abs(decimalIndex)) + coefficient;
} else if (decimalIndex >= coffiecientLn) {
// if decimal index is less then 0 add leading 0s
coefficient = coefficient + repeat('0', decimalIndex - coffiecientLn);
} else {
// else add decimal point at proper index
coefficient = (coefficient.substring(0, decimalIndex) || '0') + '.' + coefficient.substring(decimalIndex);
}
return sign + coefficient;
}
/**

@@ -127,3 +180,3 @@ * This method is required to round prop value to given scale.

var floatValue = parseFloat("0.".concat(afterDecimal || '0'));
var floatValueStr = afterDecimal.length <= scale ? floatValue.toString() : floatValue.toFixed(scale);
var floatValueStr = afterDecimal.length <= scale ? toNumericString(floatValue) : floatValue.toFixed(scale);
var roundedDecimalParts = floatValueStr.split('.');

@@ -154,3 +207,3 @@ var intPart = beforeDecimal.split('').reverse().reduce(function (roundedStr, current, idx) {

function setCaretPosition(el, caretPos) {
el.value = el.value; // ^ this is used to not only get "focus", but
el.value = el.value; // ^ this is used to not only get 'focus', but
// to make sure we don't have it everything -selected-

@@ -157,0 +210,0 @@ // (it causes an issue in chrome, and having it doesn't hurt any other browser)

{
"name": "react-number-format",
"description": "React component to format number in an input or as a text.",
"version": "4.5.3",
"main": "lib/number_format.js",
"version": "4.5.4",
"main": "dist/react-number-format.cjs.js",
"module": "dist/react-number-format.es.js",

@@ -46,2 +46,3 @@ "author": "Sudhanshu Yadav",

"@babel/register": "^7.6.2",
"@rollup/plugin-buble": "^0.21.3",
"@types/react": "^16.9.4",

@@ -57,2 +58,3 @@ "babel-eslint": "^10.0.3",

"eslint": "^6.5.1",
"eslint-config-prettier": "^8.1.0",
"eslint-loader": "^3.0.2",

@@ -74,2 +76,3 @@ "eslint-plugin-import": "^2.18.2",

"material-ui": "^0.20.2",
"prettier": "^2.2.1",
"react": "^15.4.0 || ^16.0.0",

@@ -83,2 +86,3 @@ "react-dom": "^15.4.0 || ^16.0.0",

"rollup-plugin-filesize": "^6.2.0",
"rollup-plugin-flow": "^1.1.1",
"rollup-plugin-license": "^0.12.1",

@@ -85,0 +89,0 @@ "rollup-plugin-node-resolve": "^5.2.0",

@@ -249,3 +249,9 @@ [![Actions Status](https://github.com/s-yadav/react-number-format/workflows/CI/badge.svg)](https://github.com/s-yadav/react-number-format/actions)

```
Or using React.createRef()
```jsx
const inputRef = React.createRef();
<NumberFormat getInputRef = {inputRef} customInput={TextField} format="#### #### #### ####"/>
```
In case you have provided custom input you can pass there props to get the input reference (getInputRef will not work in that case).

@@ -262,2 +268,3 @@ For ex in material-ui component.

### Live Demo

@@ -264,0 +271,0 @@ [http://codepen.io/s-yadav/pen/bpKNMa](http://codepen.io/s-yadav/pen/bpKNMa)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc