react-number-format
Advanced tools
Comparing version 3.0.0-alpha2 to 3.0.0-alpha3
/*! | ||
* react-number-format - 3.0.0-alpha2 | ||
* react-number-format - 3.0.0-alpha3 | ||
* Author : Sudhanshu Yadav | ||
@@ -96,3 +96,4 @@ * Copyright (c) 2016,2017 to Sudhanshu Yadav - ignitersworld.com , released under the MIT license. | ||
decimalSeparator: _propTypes2.default.string, | ||
decimalPrecision: _propTypes2.default.number, | ||
decimalScale: _propTypes2.default.number, | ||
fixedDecimalScale: _propTypes2.default.bool, | ||
displayType: _propTypes2.default.oneOf(['input', 'text']), | ||
@@ -108,2 +109,3 @@ prefix: _propTypes2.default.string, | ||
allowNegative: _propTypes2.default.bool, | ||
onValueChange: _propTypes2.default.func, | ||
onKeyDown: _propTypes2.default.func, | ||
@@ -113,2 +115,3 @@ onMouseUp: _propTypes2.default.func, | ||
onFocus: _propTypes2.default.func, | ||
onBlur: _propTypes2.default.func, | ||
type: _propTypes2.default.oneOf(['text', 'tel']), | ||
@@ -122,2 +125,3 @@ isAllowed: _propTypes2.default.func, | ||
decimalSeparator: '.', | ||
fixedDecimalScale: false, | ||
prefix: '', | ||
@@ -128,2 +132,3 @@ suffix: '', | ||
type: 'text', | ||
onValueChange: _utils.noop, | ||
onChange: _utils.noop, | ||
@@ -133,2 +138,3 @@ onKeyDown: _utils.noop, | ||
onFocus: _utils.noop, | ||
onBlur: _utils.noop, | ||
isAllowed: _utils.returnTrue | ||
@@ -159,2 +165,3 @@ }; | ||
_this.onFocus = _this.onFocus.bind(_this); | ||
_this.onBlur = _this.onBlur.bind(_this); | ||
return _this; | ||
@@ -232,3 +239,3 @@ } | ||
format = _props.format, | ||
decimalPrecision = _props.decimalPrecision; | ||
decimalScale = _props.decimalScale; | ||
@@ -238,3 +245,3 @@ var _getSeparators2 = this.getSeparators(), | ||
return new RegExp('\\d' + (decimalSeparator && decimalPrecision !== 0 && !ignoreDecimalSeparator && !format ? '|' + (0, _utils.escapeRegExp)(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + (0, _utils.escapeRegExp)(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
@@ -518,3 +525,4 @@ }, { | ||
var _props5 = this.props, | ||
decimalPrecision = _props5.decimalPrecision, | ||
decimalScale = _props5.decimalScale, | ||
fixedDecimalScale = _props5.fixedDecimalScale, | ||
allowNegative = _props5.allowNegative, | ||
@@ -535,3 +543,3 @@ prefix = _props5.prefix, | ||
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalPrecision; | ||
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalScale && fixedDecimalScale; | ||
@@ -548,6 +556,6 @@ var parts = numStr.split('.'); | ||
//remove leading zeros from number before decimal | ||
beforeDecimal = (0, _utils.removeLeadingZero)(beforeDecimal); | ||
//beforeDecimal = removeLeadingZero(beforeDecimal); | ||
//apply decimal precision if its defined | ||
if (decimalPrecision !== undefined) afterDecimal = (0, _utils.limitToPrecision)(afterDecimal, decimalPrecision); | ||
if (decimalScale !== undefined) afterDecimal = (0, _utils.limitToScale)(afterDecimal, decimalScale, fixedDecimalScale); | ||
@@ -571,3 +579,4 @@ if (thousandSeparator) { | ||
key: 'formatNumString', | ||
value: function formatNumString(value) { | ||
value: function formatNumString() { | ||
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; | ||
var format = this.props.format; | ||
@@ -600,3 +609,4 @@ | ||
format = _props6.format, | ||
decimalPrecision = _props6.decimalPrecision; | ||
decimalScale = _props6.decimalScale, | ||
fixedDecimalScale = _props6.fixedDecimalScale; | ||
var _props7 = this.props, | ||
@@ -615,6 +625,6 @@ value = _props7.value, | ||
//round the number based on decimalPrecision | ||
//round the number based on decimalScale | ||
//format only if non formatted value is provided | ||
if (isNumericString && !format && typeof decimalPrecision === 'number') { | ||
value = (0, _utils.roundToPrecision)(value, decimalPrecision); | ||
if (isNumericString && !format && typeof decimalScale === 'number') { | ||
value = (0, _utils.roundToPrecision)(value, decimalScale, fixedDecimalScale); | ||
} | ||
@@ -677,3 +687,4 @@ | ||
suffix = _props8.suffix, | ||
decimalPrecision = _props8.decimalPrecision; | ||
decimalScale = _props8.decimalScale, | ||
fixedDecimalScale = _props8.fixedDecimalScale; | ||
@@ -689,3 +700,3 @@ var _getSeparators5 = this.getSeparators(), | ||
//check in number format | ||
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalPrecision && value[caretPos] === decimalSeparator)) { | ||
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator)) { | ||
return true; | ||
@@ -776,4 +787,7 @@ } | ||
this.setState({ value: formattedValue, numAsString: this.removeFormatting(formattedValue) }, function () { | ||
props.onChange(e, valueObj); | ||
props.onValueChange(valueObj); | ||
props.onChange(e); | ||
}); | ||
} else { | ||
props.onChange(e); | ||
} | ||
@@ -784,2 +798,36 @@ | ||
}, { | ||
key: 'onBlur', | ||
value: function onBlur(e) { | ||
var props = this.props, | ||
state = this.state; | ||
var format = props.format, | ||
onBlur = props.onBlur; | ||
var numAsString = state.numAsString; | ||
var lastValue = state.value; | ||
if (!format) { | ||
numAsString = (0, _utils.fixLeadingZero)(numAsString); | ||
var _formatNumString = this.formatNumString(numAsString), | ||
formattedValue = _formatNumString.formattedValue, | ||
_value = _formatNumString.value; | ||
var valueObj = { | ||
formattedValue: formattedValue, | ||
value: _value, | ||
floatValue: parseFloat(_value) | ||
}; | ||
//change the state | ||
if (formattedValue !== lastValue) { | ||
this.setState({ value: formattedValue, numAsString: numAsString }, function () { | ||
props.onValueChange(valueObj); | ||
onBlur(e); | ||
}); | ||
} else { | ||
onBlur(e); | ||
} | ||
} | ||
} | ||
}, { | ||
key: 'onKeyDown', | ||
@@ -795,3 +843,4 @@ value: function onKeyDown(e) { | ||
var _props9 = this.props, | ||
decimalPrecision = _props9.decimalPrecision, | ||
decimalScale = _props9.decimalScale, | ||
fixedDecimalScale = _props9.fixedDecimalScale, | ||
prefix = _props9.prefix, | ||
@@ -802,3 +851,4 @@ suffix = _props9.suffix, | ||
var numRegex = this.getNumberRegex(false, decimalPrecision !== undefined); | ||
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale; | ||
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator); | ||
var negativeRegex = new RegExp('-'); | ||
@@ -909,3 +959,4 @@ var isPatternFormat = typeof format === 'string'; | ||
onMouseUp: this.onMouseUp, | ||
onFocus: this.onFocus | ||
onFocus: this.onFocus, | ||
onBlur: this.onBlur | ||
}); | ||
@@ -1170,5 +1221,5 @@ | ||
exports.escapeRegExp = escapeRegExp; | ||
exports.removeLeadingZero = removeLeadingZero; | ||
exports.fixLeadingZero = fixLeadingZero; | ||
exports.splitString = splitString; | ||
exports.limitToPrecision = limitToPrecision; | ||
exports.limitToScale = limitToScale; | ||
exports.roundToPrecision = roundToPrecision; | ||
@@ -1193,5 +1244,11 @@ exports.omit = omit; | ||
function removeLeadingZero(numStr) { | ||
//remove leading zeros | ||
return numStr.replace(/^0+/, '') || '0'; | ||
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 '' + (isNegative ? '-' : '') + beforeDecimal + (afterDecimal ? '.' + afterDecimal : ''); | ||
} | ||
@@ -1204,9 +1261,10 @@ | ||
/** | ||
* limit decimal numbers to given precision | ||
* limit decimal numbers to given scale | ||
* Not used .fixedTo because that will break with big numbers | ||
*/ | ||
function limitToPrecision(numStr, precision) { | ||
function limitToScale(numStr, scale, fixedDecimalScale) { | ||
var str = ''; | ||
for (var i = 0; i <= precision - 1; i++) { | ||
str += numStr[i] || '0'; | ||
var filler = fixedDecimalScale ? '0' : ''; | ||
for (var i = 0; i <= scale - 1; i++) { | ||
str += numStr[i] || filler; | ||
} | ||
@@ -1217,8 +1275,8 @@ return str; | ||
/** | ||
* This method is required to round prop value to given precision. | ||
* 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, precision) { | ||
function roundToPrecision(numStr, scale, fixedDecimalScale) { | ||
var numberParts = numStr.split('.'); | ||
var roundedDecimalParts = parseFloat('0.' + (numberParts[1] || '0')).toFixed(precision).split('.'); | ||
var roundedDecimalParts = parseFloat('0.' + (numberParts[1] || '0')).toFixed(scale).split('.'); | ||
var intPart = numberParts[0].split('').reverse().reduce(function (roundedStr, current, idx) { | ||
@@ -1231,3 +1289,3 @@ if (roundedStr.length > idx) { | ||
var decimalPart = roundedDecimalParts[1]; | ||
var decimalPart = limitToScale(roundedDecimalParts[1] || '', (numberParts[1] || '').length, fixedDecimalScale); | ||
@@ -1234,0 +1292,0 @@ return intPart + (decimalPart ? '.' + decimalPart : ''); |
/*! | ||
* react-number-format - 3.0.0-alpha2 | ||
* react-number-format - 3.0.0-alpha3 | ||
* Author : Sudhanshu Yadav | ||
* Copyright (c) 2016,2017 to Sudhanshu Yadav - ignitersworld.com , released under the MIT license. | ||
*/ | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.NumberFormat=t(require("react")):e.NumberFormat=t(e.React)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u=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},s=function(){function e(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)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),f=r(2),l=n(f),c=r(7),p=n(c),h=r(8),d={thousandSeparator:l.default.oneOfType([l.default.string,l.default.oneOf([!0])]),decimalSeparator:l.default.string,decimalPrecision:l.default.number,displayType:l.default.oneOf(["input","text"]),prefix:l.default.string,suffix:l.default.string,format:l.default.oneOfType([l.default.string,l.default.func]),removeFormatting:l.default.func,mask:l.default.oneOfType([l.default.string,l.default.arrayOf(l.default.string)]),value:l.default.oneOfType([l.default.number,l.default.string]),isNumericString:l.default.bool,customInput:l.default.func,allowNegative:l.default.bool,onKeyDown:l.default.func,onMouseUp:l.default.func,onChange:l.default.func,onFocus:l.default.func,type:l.default.oneOf(["text","tel"]),isAllowed:l.default.func,renderText:l.default.func},m={displayType:"input",decimalSeparator:".",prefix:"",suffix:"",allowNegative:!0,isNumericString:!1,type:"text",onChange:h.noop,onKeyDown:h.noop,onMouseUp:h.noop,onFocus:h.noop,isAllowed:h.returnTrue},g=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));r.validateProps();var n=r.formatValueProp();return r.state={value:n,numAsString:r.removeFormatting(n)},r.onChange=r.onChange.bind(r),r.onKeyDown=r.onKeyDown.bind(r),r.onMouseUp=r.onMouseUp.bind(r),r.onFocus=r.onFocus.bind(r),r}return i(t,e),s(t,[{key:"componentDidUpdate",value:function(e){this.updateValueIfRequired(e)}},{key:"updateValueIfRequired",value:function(e){var t=this.props,r=this.state;if(e!==t){this.validateProps();var n=r.value,o=r.numAsString||"",a=void 0===t.value?this.formatNumString(o).formattedValue:this.formatValueProp();a!==n&&this.setState({value:a,numAsString:this.removeFormatting(a)})}}},{key:"getFloatString",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.getSeparators(),r=t.decimalSeparator,n=this.getNumberRegex(!0),o="-"===e[0];o&&(e=e.replace("-","")),e=(e.match(n)||[]).join("").replace(r,".");var a=e.indexOf(".");return a!==-1&&(e=e.substring(0,a)+"."+e.substring(a+1,e.length).replace(new RegExp((0,h.escapeRegExp)(r),"g"),"")),o&&(e="-"+e),e}},{key:"getNumberRegex",value:function(e,t){var r=this.props,n=r.format,o=r.decimalPrecision,a=this.getSeparators(),i=a.decimalSeparator;return new RegExp("\\d"+(!i||0===o||t||n?"":"|"+(0,h.escapeRegExp)(i)),e?"g":void 0)}},{key:"getSeparators",value:function(){var e=this.props.decimalSeparator,t=this.props.thousandSeparator;return t===!0&&(t=","),{decimalSeparator:e,thousandSeparator:t}}},{key:"getMaskAtIndex",value:function(e){var t=this.props.mask,r=void 0===t?" ":t;return"string"==typeof r?r:r[e]||" "}},{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\n thousandSeparator: "+n+' (thousandSeparator = {true} is same as thousandSeparator = ",")\n decimalSeparator: '+r+" (default value for decimalSeparator is .)\n ");if(e){var o="string"===e?e:e.toString();if(o.match(/\d/g))throw new Error("\n Mask "+e+" should not contain numeric character;\n ")}}},{key:"setPatchedCaretPosition",value:function(e,t,r){(0,h.setCaretPosition)(e,t),setTimeout(function(){e.value===r&&(0,h.setCaretPosition)(e,t)},0)}},{key:"correctCaretPosition",value:function(e,t,r){var n=this.props,o=n.prefix,a=n.suffix,i=n.format;if(!i){var u="-"===e[0];return Math.min(Math.max(t,o.length+(u?1:0)),e.length-a.length)}if("function"==typeof i)return t;if("#"===i[t]&&(0,h.charIsNumber)(e[t]))return t;if("#"===i[t-1]&&(0,h.charIsNumber)(e[t-1]))return t;var s=i.indexOf("#"),f=i.lastIndexOf("#");t=Math.min(Math.max(t,s),f+1);for(var l=i.substring(t,i.length).indexOf("#"),c=t,p=t+(l===-1?0:l);c>s&&("#"!==i[c]||!(0,h.charIsNumber)(e[c]));)c-=1;var d=!(0,h.charIsNumber)(e[p])||"left"===r&&t!==s||t-c<p-t;return d?c+1:p}},{key:"getCaretPosition",value:function(e,t,r){var n=this.props.format,o=this.state.value,a=this.getNumberRegex(!0),i=(e.match(a)||[]).join(""),u=(t.match(a)||[]).join(""),s=void 0,f=void 0;for(s=0,f=0;f<r;f++){var l=e[f],c=t[s]||"";if((l.match(a)||l===c)&&("0"!==l||!c.match(a)||"0"===c||i.length===u.length)){for(;l!==t[s]&&s<t.length;)s++;s++}}return"string"!=typeof n||o||(s=t.length),s=this.correctCaretPosition(t,s)}},{key:"removePrefixAndSuffix",value:function(e){var t=this.props,r=t.format,n=t.prefix,o=t.suffix;if(!r&&e){var a="-"===e[0];a&&(e=e.substring(1,e.length)),e=n&&0===e.indexOf(n)?e.substring(n.length,e.length):e;var i=e.lastIndexOf(o);e=o&&i!==-1&&i===e.length-o.length?e.substring(0,i):e,a&&(e="-"+e)}return e}},{key:"removePatternFormatting",value:function(e){for(var t=this.props.format,r=t.split("#").filter(function(e){return""!==e}),n=0,o="",a=0,i=r.length;a<=i;a++){var u=r[a]||"",s=a===i?e.length:e.indexOf(u,n);if(s===-1){o=e;break}o+=e.substring(n,s),n=s+u.length}return(o.match(/\d/g)||[]).join("")}},{key:"removeFormatting",value:function e(t){var r=this.props,n=r.format,e=r.removeFormatting;return t?(n?t="string"==typeof n?this.removePatternFormatting(t):"function"==typeof e?e(t):(t.match(/\d/g)||[]).join(""):(t=this.removePrefixAndSuffix(t),t=this.getFloatString(t)),t):t}},{key:"formatWithPattern",value:function(e){for(var t=this.props.format,r=0,n=t.split(""),o=0,a=t.length;o<a;o++)"#"===t[o]&&(n[o]=e[r]||this.getMaskAtIndex(r),r+=1);return n.join("")}},{key:"formatAsNumber",value:function(e){var t=this.props,r=t.decimalPrecision,n=t.allowNegative,o=t.prefix,a=t.suffix,i=this.getSeparators(),u=i.thousandSeparator,s=i.decimalSeparator,f="-"===e[0],l=f&&n;e=e.replace("-","");var c=e.indexOf(".")!==-1||r,p=e.split("."),d=p[0],m=p[1]||"";return""!==d||parseFloat(m)?(d=(0,h.removeLeadingZero)(d),void 0!==r&&(m=(0,h.limitToPrecision)(m,r)),u&&(d=d.replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+u)),o&&(d=o+d),a&&(m+=a),l&&(d="-"+d),e=d+(c&&s||"")+m):l?"-":""}},{key:"formatNumString",value:function(e){var t=this.props.format,r=e;return""===e?r="":"-"!==e||t?r="string"==typeof t?this.formatWithPattern(r):"function"==typeof t?t(r):this.formatAsNumber(r):(r="-",e=""),{value:e,formattedValue:r}}},{key:"formatValueProp",value:function(){var e=this.props,t=e.format,r=e.decimalPrecision,n=this.props,o=n.value,a=n.isNumericString;if(void 0===o)return"";"number"==typeof o&&(o=o.toString(),a=!0),a&&!t&&"number"==typeof r&&(o=(0,h.roundToPrecision)(o,r));var i=a?this.formatNumString(o):this.formatInput(o);return i.formattedValue}},{key:"formatNegation",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.props.allowNegative,r=new RegExp("(-)"),n=new RegExp("(-)(.)*(-)"),o=r.test(e),a=n.test(e);return e=e.replace(/-/g,""),o&&!a&&t&&(e="-"+e),e}},{key:"formatInput",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.props.format;return t||(e=this.formatNegation(e)),e=this.removeFormatting(e),this.formatNumString(e)}},{key:"isCharacterAFormat",value:function(e,t){var r=this.props,n=r.format,o=r.prefix,a=r.suffix,i=r.decimalPrecision,u=this.getSeparators(),s=u.decimalSeparator;return"string"==typeof n&&"#"!==n[e]||!(n||!(e<o.length||e>=t.length-a.length||i&&t[e]===s))}},{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){if(r.length>=t.length||!r.length)return r;var n=e,o=(0,h.splitString)(t,e),a=(0,h.splitString)(r,e),i=o[1].lastIndexOf(a[1]),u=i!==-1?o[1].substring(0,i):"",s=n+u.length;return this.checkIfFormatGotDeleted(n,s,t)&&(r=t),r}},{key:"onChange",value:function(e){e.persist();var t=e.target,r=t.value,n=this.state,o=this.props,a=o.isAllowed,i=n.value||"",u=Math.max(t.selectionStart,t.selectionEnd);r=this.correctInputValue(u,i,r);var s=this.formatInput(r),f=s.formattedValue,l=void 0===f?"":f,c=s.value,p={formattedValue:l,value:c,floatValue:parseFloat(c)};a(p)||(l=i),t.value=l;var h=this.getCaretPosition(r,l,u);return this.setPatchedCaretPosition(t,h,l),l!==i&&this.setState({value:l,numAsString:this.removeFormatting(l)},function(){o.onChange(e,p)}),c}},{key:"onKeyDown",value:function e(t){var r=t.target,n=t.key,o=r.selectionEnd,a=r.value,i=r.selectionStart,u=void 0,s=this.props,f=s.decimalPrecision,l=s.prefix,c=s.suffix,p=s.format,e=s.onKeyDown,h=this.getNumberRegex(!1,void 0!==f),d=new RegExp("-"),m="string"==typeof p;if("ArrowLeft"===n||"Backspace"===n?u=i-1:"ArrowRight"===n?u=i+1:"Delete"===n&&(u=i),void 0===u||i!==o)return void e(t);var g=u,v=m?p.indexOf("#"):l.length,y=m?p.lastIndexOf("#")+1:a.length-c.length;if("ArrowLeft"===n||"ArrowRight"===n){var x="ArrowLeft"===n?"left":"right";g=this.correctCaretPosition(a,u,x)}else if("Delete"!==n||h.test(a[u])||d.test(a[u])){if("Backspace"===n&&!h.test(a[u])&&!d.test(a[u])){for(;!h.test(a[g-1])&&g>v;)g--;g=this.correctCaretPosition(a,g,"left")}}else for(;!h.test(a[g])&&g<y;)g++;(g!==u||u<v||u>y)&&(t.preventDefault(),this.setPatchedCaretPosition(r,g,a)),t.isUnitTestRun&&this.setPatchedCaretPosition(r,g,a),this.props.onKeyDown(t)}},{key:"onMouseUp",value:function(e){var t=e.target,r=t.selectionStart,n=t.selectionEnd,o=t.value;if(r===n){var a=this.correctCaretPosition(o,r);a!==r&&this.setPatchedCaretPosition(t,a,o)}this.props.onMouseUp(e)}},{key:"onFocus",value:function(e){var t=e.target,r=t.selectionStart,n=t.value,o=this.correctCaretPosition(n,r);o!==r&&this.setPatchedCaretPosition(t,o,n),this.props.onFocus(e)}},{key:"render",value:function(){var e=this.props,t=e.type,r=e.displayType,n=e.customInput,o=e.renderText,a=this.state.value,i=(0,h.omit)(this.props,d),s=u({},i,{type:t,value:a,onChange:this.onChange,onKeyDown:this.onKeyDown,onMouseUp:this.onMouseUp,onFocus:this.onFocus});if("text"===r)return o?o(a)||null:p.default.createElement("span",i,a);if(n){var f=n;return p.default.createElement(f,s)}return p.default.createElement("input",s)}}]),t}(p.default.Component);g.propTypes=d,g.defaultProps=m,e.exports=g},function(e,t,r){e.exports=r(3)()},function(e,t,r){"use strict";var n=r(4),o=r(5),a=r(6);e.exports=function(){function e(e,t,r,n,i,u){u!==a&&o(!1,"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")}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t){"use strict";function r(e){return function(){return e}}var n=function(){};n.thatReturns=r,n.thatReturnsFalse=r(!1),n.thatReturnsTrue=r(!0),n.thatReturnsNull=r(null),n.thatReturnsThis=function(){return this},n.thatReturnsArgument=function(e){return e},e.exports=n},function(e,t,r){"use strict";function n(e,t,r,n,a,i,u,s){if(o(t),!e){var f;if(void 0===t)f=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[r,n,a,i,u,s],c=0;f=new Error(t.replace(/%s/g,function(){return l[c++]})),f.name="Invariant Violation"}throw f.framesToPop=1,f}}var o=function(e){};e.exports=n},function(e,t){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(t,r){t.exports=e},function(e,t){"use strict";function r(){}function n(){return!0}function o(e){return!!(e||"").match(/\d/)}function a(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function i(e){return e.replace(/^0+/,"")||"0"}function u(e,t){return[e.substring(0,t),e.substring(t)]}function s(e,t){for(var r="",n=0;n<=t-1;n++)r+=e[n]||"0";return r}function f(e,t){var r=e.split("."),n=parseFloat("0."+(r[1]||"0")).toFixed(t).split("."),o=r[0].split("").reverse().reduce(function(e,t,r){return e.length>r?(Number(e[0])+Number(t)).toString()+e.substring(1,e.length):t+e},n[0]),a=n[1];return o+(a?"."+a:"")}function l(e,t){var r={};return Object.keys(e).forEach(function(n){t[n]||(r[n]=e[n])}),r}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)}}Object.defineProperty(t,"__esModule",{value:!0}),t.noop=r,t.returnTrue=n,t.charIsNumber=o,t.escapeRegExp=a,t.removeLeadingZero=i,t.splitString=u,t.limitToPrecision=s,t.roundToPrecision=f,t.omit=l,t.setCaretPosition=c}])}); | ||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):"object"==typeof exports?exports.NumberFormat=t(require("react")):e.NumberFormat=t(e.React)}(this,function(e){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){e.exports=r(1)},function(e,t,r){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var u=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},s=function(){function e(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)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),l=r(2),f=n(l),c=r(7),p=n(c),h=r(8),d={thousandSeparator:f.default.oneOfType([f.default.string,f.default.oneOf([!0])]),decimalSeparator:f.default.string,decimalScale:f.default.number,fixedDecimalScale:f.default.bool,displayType:f.default.oneOf(["input","text"]),prefix:f.default.string,suffix:f.default.string,format:f.default.oneOfType([f.default.string,f.default.func]),removeFormatting:f.default.func,mask:f.default.oneOfType([f.default.string,f.default.arrayOf(f.default.string)]),value:f.default.oneOfType([f.default.number,f.default.string]),isNumericString:f.default.bool,customInput:f.default.func,allowNegative:f.default.bool,onValueChange:f.default.func,onKeyDown:f.default.func,onMouseUp:f.default.func,onChange:f.default.func,onFocus:f.default.func,onBlur:f.default.func,type:f.default.oneOf(["text","tel"]),isAllowed:f.default.func,renderText:f.default.func},g={displayType:"input",decimalSeparator:".",fixedDecimalScale:!1,prefix:"",suffix:"",allowNegative:!0,isNumericString:!1,type:"text",onValueChange:h.noop,onChange:h.noop,onKeyDown:h.noop,onMouseUp:h.noop,onFocus:h.noop,onBlur:h.noop,isAllowed:h.returnTrue},m=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));r.validateProps();var n=r.formatValueProp();return r.state={value:n,numAsString:r.removeFormatting(n)},r.onChange=r.onChange.bind(r),r.onKeyDown=r.onKeyDown.bind(r),r.onMouseUp=r.onMouseUp.bind(r),r.onFocus=r.onFocus.bind(r),r.onBlur=r.onBlur.bind(r),r}return i(t,e),s(t,[{key:"componentDidUpdate",value:function(e){this.updateValueIfRequired(e)}},{key:"updateValueIfRequired",value:function(e){var t=this.props,r=this.state;if(e!==t){this.validateProps();var n=r.value,o=r.numAsString||"",a=void 0===t.value?this.formatNumString(o).formattedValue:this.formatValueProp();a!==n&&this.setState({value:a,numAsString:this.removeFormatting(a)})}}},{key:"getFloatString",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.getSeparators(),r=t.decimalSeparator,n=this.getNumberRegex(!0),o="-"===e[0];o&&(e=e.replace("-","")),e=(e.match(n)||[]).join("").replace(r,".");var a=e.indexOf(".");return a!==-1&&(e=e.substring(0,a)+"."+e.substring(a+1,e.length).replace(new RegExp((0,h.escapeRegExp)(r),"g"),"")),o&&(e="-"+e),e}},{key:"getNumberRegex",value:function(e,t){var r=this.props,n=r.format,o=r.decimalScale,a=this.getSeparators(),i=a.decimalSeparator;return new RegExp("\\d"+(!i||0===o||t||n?"":"|"+(0,h.escapeRegExp)(i)),e?"g":void 0)}},{key:"getSeparators",value:function(){var e=this.props.decimalSeparator,t=this.props.thousandSeparator;return t===!0&&(t=","),{decimalSeparator:e,thousandSeparator:t}}},{key:"getMaskAtIndex",value:function(e){var t=this.props.mask,r=void 0===t?" ":t;return"string"==typeof r?r:r[e]||" "}},{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\n thousandSeparator: "+n+' (thousandSeparator = {true} is same as thousandSeparator = ",")\n decimalSeparator: '+r+" (default value for decimalSeparator is .)\n ");if(e){var o="string"===e?e:e.toString();if(o.match(/\d/g))throw new Error("\n Mask "+e+" should not contain numeric character;\n ")}}},{key:"setPatchedCaretPosition",value:function(e,t,r){(0,h.setCaretPosition)(e,t),setTimeout(function(){e.value===r&&(0,h.setCaretPosition)(e,t)},0)}},{key:"correctCaretPosition",value:function(e,t,r){var n=this.props,o=n.prefix,a=n.suffix,i=n.format;if(!i){var u="-"===e[0];return Math.min(Math.max(t,o.length+(u?1:0)),e.length-a.length)}if("function"==typeof i)return t;if("#"===i[t]&&(0,h.charIsNumber)(e[t]))return t;if("#"===i[t-1]&&(0,h.charIsNumber)(e[t-1]))return t;var s=i.indexOf("#"),l=i.lastIndexOf("#");t=Math.min(Math.max(t,s),l+1);for(var f=i.substring(t,i.length).indexOf("#"),c=t,p=t+(f===-1?0:f);c>s&&("#"!==i[c]||!(0,h.charIsNumber)(e[c]));)c-=1;var d=!(0,h.charIsNumber)(e[p])||"left"===r&&t!==s||t-c<p-t;return d?c+1:p}},{key:"getCaretPosition",value:function(e,t,r){var n=this.props.format,o=this.state.value,a=this.getNumberRegex(!0),i=(e.match(a)||[]).join(""),u=(t.match(a)||[]).join(""),s=void 0,l=void 0;for(s=0,l=0;l<r;l++){var f=e[l],c=t[s]||"";if((f.match(a)||f===c)&&("0"!==f||!c.match(a)||"0"===c||i.length===u.length)){for(;f!==t[s]&&s<t.length;)s++;s++}}return"string"!=typeof n||o||(s=t.length),s=this.correctCaretPosition(t,s)}},{key:"removePrefixAndSuffix",value:function(e){var t=this.props,r=t.format,n=t.prefix,o=t.suffix;if(!r&&e){var a="-"===e[0];a&&(e=e.substring(1,e.length)),e=n&&0===e.indexOf(n)?e.substring(n.length,e.length):e;var i=e.lastIndexOf(o);e=o&&i!==-1&&i===e.length-o.length?e.substring(0,i):e,a&&(e="-"+e)}return e}},{key:"removePatternFormatting",value:function(e){for(var t=this.props.format,r=t.split("#").filter(function(e){return""!==e}),n=0,o="",a=0,i=r.length;a<=i;a++){var u=r[a]||"",s=a===i?e.length:e.indexOf(u,n);if(s===-1){o=e;break}o+=e.substring(n,s),n=s+u.length}return(o.match(/\d/g)||[]).join("")}},{key:"removeFormatting",value:function e(t){var r=this.props,n=r.format,e=r.removeFormatting;return t?(n?t="string"==typeof n?this.removePatternFormatting(t):"function"==typeof e?e(t):(t.match(/\d/g)||[]).join(""):(t=this.removePrefixAndSuffix(t),t=this.getFloatString(t)),t):t}},{key:"formatWithPattern",value:function(e){for(var t=this.props.format,r=0,n=t.split(""),o=0,a=t.length;o<a;o++)"#"===t[o]&&(n[o]=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,o=t.allowNegative,a=t.prefix,i=t.suffix,u=this.getSeparators(),s=u.thousandSeparator,l=u.decimalSeparator,f="-"===e[0],c=f&&o;e=e.replace("-","");var p=e.indexOf(".")!==-1||r&&n,d=e.split("."),g=d[0],m=d[1]||"";return""!==g||parseFloat(m)?(void 0!==r&&(m=(0,h.limitToScale)(m,r,n)),s&&(g=g.replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+s)),a&&(g=a+g),i&&(m+=i),c&&(g="-"+g),e=g+(p&&l||"")+m):c?"-":""}},{key:"formatNumString",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.props.format,r=e;return""===e?r="":"-"!==e||t?r="string"==typeof t?this.formatWithPattern(r):"function"==typeof t?t(r):this.formatAsNumber(r):(r="-",e=""),{value:e,formattedValue:r}}},{key:"formatValueProp",value:function(){var e=this.props,t=e.format,r=e.decimalScale,n=e.fixedDecimalScale,o=this.props,a=o.value,i=o.isNumericString;if(void 0===a)return"";"number"==typeof a&&(a=a.toString(),i=!0),i&&!t&&"number"==typeof r&&(a=(0,h.roundToPrecision)(a,r,n));var u=i?this.formatNumString(a):this.formatInput(a);return u.formattedValue}},{key:"formatNegation",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.props.allowNegative,r=new RegExp("(-)"),n=new RegExp("(-)(.)*(-)"),o=r.test(e),a=n.test(e);return e=e.replace(/-/g,""),o&&!a&&t&&(e="-"+e),e}},{key:"formatInput",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=this.props.format;return t||(e=this.formatNegation(e)),e=this.removeFormatting(e),this.formatNumString(e)}},{key:"isCharacterAFormat",value:function(e,t){var r=this.props,n=r.format,o=r.prefix,a=r.suffix,i=r.decimalScale,u=r.fixedDecimalScale,s=this.getSeparators(),l=s.decimalSeparator;return"string"==typeof n&&"#"!==n[e]||!(n||!(e<o.length||e>=t.length-a.length||i&&u&&t[e]===l))}},{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){if(r.length>=t.length||!r.length)return r;var n=e,o=(0,h.splitString)(t,e),a=(0,h.splitString)(r,e),i=o[1].lastIndexOf(a[1]),u=i!==-1?o[1].substring(0,i):"",s=n+u.length;return this.checkIfFormatGotDeleted(n,s,t)&&(r=t),r}},{key:"onChange",value:function(e){e.persist();var t=e.target,r=t.value,n=this.state,o=this.props,a=o.isAllowed,i=n.value||"",u=Math.max(t.selectionStart,t.selectionEnd);r=this.correctInputValue(u,i,r);var s=this.formatInput(r),l=s.formattedValue,f=void 0===l?"":l,c=s.value,p={formattedValue:f,value:c,floatValue:parseFloat(c)};a(p)||(f=i),t.value=f;var h=this.getCaretPosition(r,f,u);return this.setPatchedCaretPosition(t,h,f),f!==i?this.setState({value:f,numAsString:this.removeFormatting(f)},function(){o.onValueChange(p),o.onChange(e)}):o.onChange(e),c}},{key:"onBlur",value:function e(t){var r=this.props,n=this.state,o=r.format,e=r.onBlur,a=n.numAsString,i=n.value;if(!o){a=(0,h.fixLeadingZero)(a);var u=this.formatNumString(a),s=u.formattedValue,l=u.value,f={formattedValue:s,value:l,floatValue:parseFloat(l)};s!==i?this.setState({value:s,numAsString:a},function(){r.onValueChange(f),e(t)}):e(t)}}},{key:"onKeyDown",value:function e(t){var r=t.target,n=t.key,o=r.selectionEnd,a=r.value,i=r.selectionStart,u=void 0,s=this.props,l=s.decimalScale,f=s.fixedDecimalScale,c=s.prefix,p=s.suffix,h=s.format,e=s.onKeyDown,d=void 0!==l&&f,g=this.getNumberRegex(!1,d),m=new RegExp("-"),v="string"==typeof h;if("ArrowLeft"===n||"Backspace"===n?u=i-1:"ArrowRight"===n?u=i+1:"Delete"===n&&(u=i),void 0===u||i!==o)return void e(t);var y=u,x=v?h.indexOf("#"):c.length,S=v?h.lastIndexOf("#")+1:a.length-p.length;if("ArrowLeft"===n||"ArrowRight"===n){var b="ArrowLeft"===n?"left":"right";y=this.correctCaretPosition(a,u,b)}else if("Delete"!==n||g.test(a[u])||m.test(a[u])){if("Backspace"===n&&!g.test(a[u])&&!m.test(a[u])){for(;!g.test(a[y-1])&&y>x;)y--;y=this.correctCaretPosition(a,y,"left")}}else for(;!g.test(a[y])&&y<S;)y++;(y!==u||u<x||u>S)&&(t.preventDefault(),this.setPatchedCaretPosition(r,y,a)),t.isUnitTestRun&&this.setPatchedCaretPosition(r,y,a),this.props.onKeyDown(t)}},{key:"onMouseUp",value:function(e){var t=e.target,r=t.selectionStart,n=t.selectionEnd,o=t.value;if(r===n){var a=this.correctCaretPosition(o,r);a!==r&&this.setPatchedCaretPosition(t,a,o)}this.props.onMouseUp(e)}},{key:"onFocus",value:function(e){var t=e.target,r=t.selectionStart,n=t.value,o=this.correctCaretPosition(n,r);o!==r&&this.setPatchedCaretPosition(t,o,n),this.props.onFocus(e)}},{key:"render",value:function(){var e=this.props,t=e.type,r=e.displayType,n=e.customInput,o=e.renderText,a=this.state.value,i=(0,h.omit)(this.props,d),s=u({},i,{type:t,value:a,onChange:this.onChange,onKeyDown:this.onKeyDown,onMouseUp:this.onMouseUp,onFocus:this.onFocus,onBlur:this.onBlur});if("text"===r)return o?o(a)||null:p.default.createElement("span",i,a);if(n){var l=n;return p.default.createElement(l,s)}return p.default.createElement("input",s)}}]),t}(p.default.Component);m.propTypes=d,m.defaultProps=g,e.exports=m},function(e,t,r){e.exports=r(3)()},function(e,t,r){"use strict";var n=r(4),o=r(5),a=r(6);e.exports=function(){function e(e,t,r,n,i,u){u!==a&&o(!1,"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")}function t(){return e}e.isRequired=e;var r={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return r.checkPropTypes=n,r.PropTypes=r,r}},function(e,t){"use strict";function r(e){return function(){return e}}var n=function(){};n.thatReturns=r,n.thatReturnsFalse=r(!1),n.thatReturnsTrue=r(!0),n.thatReturnsNull=r(null),n.thatReturnsThis=function(){return this},n.thatReturnsArgument=function(e){return e},e.exports=n},function(e,t,r){"use strict";function n(e,t,r,n,a,i,u,s){if(o(t),!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var f=[r,n,a,i,u,s],c=0;l=new Error(t.replace(/%s/g,function(){return f[c++]})),l.name="Invariant Violation"}throw l.framesToPop=1,l}}var o=function(e){};e.exports=n},function(e,t){"use strict";var r="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=r},function(t,r){t.exports=e},function(e,t){"use strict";function r(){}function n(){return!0}function o(e){return!!(e||"").match(/\d/)}function a(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}function i(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",o=r[1]||"";return""+(t?"-":"")+n+(o?"."+o:"")}function u(e,t){return[e.substring(0,t),e.substring(t)]}function s(e,t,r){for(var n="",o=r?"0":"",a=0;a<=t-1;a++)n+=e[a]||o;return n}function l(e,t,r){var n=e.split("."),o=parseFloat("0."+(n[1]||"0")).toFixed(t).split("."),a=n[0].split("").reverse().reduce(function(e,t,r){return e.length>r?(Number(e[0])+Number(t)).toString()+e.substring(1,e.length):t+e},o[0]),i=s(o[1]||"",(n[1]||"").length,r);return a+(i?"."+i:"")}function f(e,t){var r={};return Object.keys(e).forEach(function(n){t[n]||(r[n]=e[n])}),r}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)}}Object.defineProperty(t,"__esModule",{value:!0}),t.noop=r,t.returnTrue=n,t.charIsNumber=o,t.escapeRegExp=a,t.fixLeadingZero=i,t.splitString=u,t.limitToScale=s,t.roundToPrecision=l,t.omit=f,t.setCaretPosition=c}])}); |
@@ -55,5 +55,5 @@ import React from 'react'; | ||
<h3> | ||
Decimal precision : Format currency in input with decimal precision | ||
Decimal scale : Format currency in input with decimal scale | ||
</h3> | ||
<NumberFormat thousandSeparator={true} decimalPrecision={3} prefix="$" /> | ||
<NumberFormat thousandSeparator={true} decimalScale={3} fixedDecimalScale={true} prefix="$" /> | ||
</div> | ||
@@ -86,13 +86,13 @@ | ||
<div> | ||
ThousandSeperator: ',', decimalSeparator='.', decimalPrecision:2 | ||
ThousandSeperator: ',', decimalSeparator='.', decimalScale:2 | ||
</div> | ||
<div> | ||
<NumberFormat thousandSeparator="," decimalSeparator="." decimalPrecision={2} /> | ||
<NumberFormat thousandSeparator="," decimalSeparator="." decimalScale={2} /> | ||
</div> | ||
<br/> | ||
<div> | ||
ThousandSeperator: '.', decimalSeparator=',', decimalPrecision:2 | ||
ThousandSeperator: '.', decimalSeparator=',', decimalScale:2 | ||
</div> | ||
<div> | ||
<NumberFormat thousandSeparator="." decimalSeparator="," decimalPrecision={2} /> | ||
<NumberFormat thousandSeparator="." decimalSeparator="," decimalScale={2} /> | ||
</div> | ||
@@ -99,0 +99,0 @@ </div> |
@@ -28,3 +28,4 @@ 'use strict'; | ||
decimalSeparator: _propTypes2.default.string, | ||
decimalPrecision: _propTypes2.default.number, | ||
decimalScale: _propTypes2.default.number, | ||
fixedDecimalScale: _propTypes2.default.bool, | ||
displayType: _propTypes2.default.oneOf(['input', 'text']), | ||
@@ -40,2 +41,3 @@ prefix: _propTypes2.default.string, | ||
allowNegative: _propTypes2.default.bool, | ||
onValueChange: _propTypes2.default.func, | ||
onKeyDown: _propTypes2.default.func, | ||
@@ -45,2 +47,3 @@ onMouseUp: _propTypes2.default.func, | ||
onFocus: _propTypes2.default.func, | ||
onBlur: _propTypes2.default.func, | ||
type: _propTypes2.default.oneOf(['text', 'tel']), | ||
@@ -54,2 +57,3 @@ isAllowed: _propTypes2.default.func, | ||
decimalSeparator: '.', | ||
fixedDecimalScale: false, | ||
prefix: '', | ||
@@ -60,2 +64,3 @@ suffix: '', | ||
type: 'text', | ||
onValueChange: _utils.noop, | ||
onChange: _utils.noop, | ||
@@ -65,2 +70,3 @@ onKeyDown: _utils.noop, | ||
onFocus: _utils.noop, | ||
onBlur: _utils.noop, | ||
isAllowed: _utils.returnTrue | ||
@@ -91,2 +97,3 @@ }; | ||
_this.onFocus = _this.onFocus.bind(_this); | ||
_this.onBlur = _this.onBlur.bind(_this); | ||
return _this; | ||
@@ -164,3 +171,3 @@ } | ||
format = _props.format, | ||
decimalPrecision = _props.decimalPrecision; | ||
decimalScale = _props.decimalScale; | ||
@@ -170,3 +177,3 @@ var _getSeparators2 = this.getSeparators(), | ||
return new RegExp('\\d' + (decimalSeparator && decimalPrecision !== 0 && !ignoreDecimalSeparator && !format ? '|' + (0, _utils.escapeRegExp)(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + (0, _utils.escapeRegExp)(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
@@ -450,3 +457,4 @@ }, { | ||
var _props5 = this.props, | ||
decimalPrecision = _props5.decimalPrecision, | ||
decimalScale = _props5.decimalScale, | ||
fixedDecimalScale = _props5.fixedDecimalScale, | ||
allowNegative = _props5.allowNegative, | ||
@@ -467,3 +475,3 @@ prefix = _props5.prefix, | ||
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalPrecision; | ||
var hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalScale && fixedDecimalScale; | ||
@@ -480,6 +488,6 @@ var parts = numStr.split('.'); | ||
//remove leading zeros from number before decimal | ||
beforeDecimal = (0, _utils.removeLeadingZero)(beforeDecimal); | ||
//beforeDecimal = removeLeadingZero(beforeDecimal); | ||
//apply decimal precision if its defined | ||
if (decimalPrecision !== undefined) afterDecimal = (0, _utils.limitToPrecision)(afterDecimal, decimalPrecision); | ||
if (decimalScale !== undefined) afterDecimal = (0, _utils.limitToScale)(afterDecimal, decimalScale, fixedDecimalScale); | ||
@@ -503,3 +511,4 @@ if (thousandSeparator) { | ||
key: 'formatNumString', | ||
value: function formatNumString(value) { | ||
value: function formatNumString() { | ||
var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; | ||
var format = this.props.format; | ||
@@ -532,3 +541,4 @@ | ||
format = _props6.format, | ||
decimalPrecision = _props6.decimalPrecision; | ||
decimalScale = _props6.decimalScale, | ||
fixedDecimalScale = _props6.fixedDecimalScale; | ||
var _props7 = this.props, | ||
@@ -547,6 +557,6 @@ value = _props7.value, | ||
//round the number based on decimalPrecision | ||
//round the number based on decimalScale | ||
//format only if non formatted value is provided | ||
if (isNumericString && !format && typeof decimalPrecision === 'number') { | ||
value = (0, _utils.roundToPrecision)(value, decimalPrecision); | ||
if (isNumericString && !format && typeof decimalScale === 'number') { | ||
value = (0, _utils.roundToPrecision)(value, decimalScale, fixedDecimalScale); | ||
} | ||
@@ -609,3 +619,4 @@ | ||
suffix = _props8.suffix, | ||
decimalPrecision = _props8.decimalPrecision; | ||
decimalScale = _props8.decimalScale, | ||
fixedDecimalScale = _props8.fixedDecimalScale; | ||
@@ -621,3 +632,3 @@ var _getSeparators5 = this.getSeparators(), | ||
//check in number format | ||
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalPrecision && value[caretPos] === decimalSeparator)) { | ||
if (!format && (caretPos < prefix.length || caretPos >= value.length - suffix.length || decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator)) { | ||
return true; | ||
@@ -708,4 +719,7 @@ } | ||
this.setState({ value: formattedValue, numAsString: this.removeFormatting(formattedValue) }, function () { | ||
props.onChange(e, valueObj); | ||
props.onValueChange(valueObj); | ||
props.onChange(e); | ||
}); | ||
} else { | ||
props.onChange(e); | ||
} | ||
@@ -716,2 +730,36 @@ | ||
}, { | ||
key: 'onBlur', | ||
value: function onBlur(e) { | ||
var props = this.props, | ||
state = this.state; | ||
var format = props.format, | ||
onBlur = props.onBlur; | ||
var numAsString = state.numAsString; | ||
var lastValue = state.value; | ||
if (!format) { | ||
numAsString = (0, _utils.fixLeadingZero)(numAsString); | ||
var _formatNumString = this.formatNumString(numAsString), | ||
formattedValue = _formatNumString.formattedValue, | ||
_value = _formatNumString.value; | ||
var valueObj = { | ||
formattedValue: formattedValue, | ||
value: _value, | ||
floatValue: parseFloat(_value) | ||
}; | ||
//change the state | ||
if (formattedValue !== lastValue) { | ||
this.setState({ value: formattedValue, numAsString: numAsString }, function () { | ||
props.onValueChange(valueObj); | ||
onBlur(e); | ||
}); | ||
} else { | ||
onBlur(e); | ||
} | ||
} | ||
} | ||
}, { | ||
key: 'onKeyDown', | ||
@@ -727,3 +775,4 @@ value: function onKeyDown(e) { | ||
var _props9 = this.props, | ||
decimalPrecision = _props9.decimalPrecision, | ||
decimalScale = _props9.decimalScale, | ||
fixedDecimalScale = _props9.fixedDecimalScale, | ||
prefix = _props9.prefix, | ||
@@ -734,3 +783,4 @@ suffix = _props9.suffix, | ||
var numRegex = this.getNumberRegex(false, decimalPrecision !== undefined); | ||
var ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale; | ||
var numRegex = this.getNumberRegex(false, ignoreDecimalSeparator); | ||
var negativeRegex = new RegExp('-'); | ||
@@ -841,3 +891,4 @@ var isPatternFormat = typeof format === 'string'; | ||
onMouseUp: this.onMouseUp, | ||
onFocus: this.onFocus | ||
onFocus: this.onFocus, | ||
onBlur: this.onBlur | ||
}); | ||
@@ -844,0 +895,0 @@ |
@@ -10,5 +10,5 @@ 'use strict'; | ||
exports.escapeRegExp = escapeRegExp; | ||
exports.removeLeadingZero = removeLeadingZero; | ||
exports.fixLeadingZero = fixLeadingZero; | ||
exports.splitString = splitString; | ||
exports.limitToPrecision = limitToPrecision; | ||
exports.limitToScale = limitToScale; | ||
exports.roundToPrecision = roundToPrecision; | ||
@@ -33,5 +33,11 @@ exports.omit = omit; | ||
function removeLeadingZero(numStr) { | ||
//remove leading zeros | ||
return numStr.replace(/^0+/, '') || '0'; | ||
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 '' + (isNegative ? '-' : '') + beforeDecimal + (afterDecimal ? '.' + afterDecimal : ''); | ||
} | ||
@@ -44,9 +50,10 @@ | ||
/** | ||
* limit decimal numbers to given precision | ||
* limit decimal numbers to given scale | ||
* Not used .fixedTo because that will break with big numbers | ||
*/ | ||
function limitToPrecision(numStr, precision) { | ||
function limitToScale(numStr, scale, fixedDecimalScale) { | ||
var str = ''; | ||
for (var i = 0; i <= precision - 1; i++) { | ||
str += numStr[i] || '0'; | ||
var filler = fixedDecimalScale ? '0' : ''; | ||
for (var i = 0; i <= scale - 1; i++) { | ||
str += numStr[i] || filler; | ||
} | ||
@@ -57,8 +64,8 @@ return str; | ||
/** | ||
* This method is required to round prop value to given precision. | ||
* 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, precision) { | ||
function roundToPrecision(numStr, scale, fixedDecimalScale) { | ||
var numberParts = numStr.split('.'); | ||
var roundedDecimalParts = parseFloat('0.' + (numberParts[1] || '0')).toFixed(precision).split('.'); | ||
var roundedDecimalParts = parseFloat('0.' + (numberParts[1] || '0')).toFixed(scale).split('.'); | ||
var intPart = numberParts[0].split('').reverse().reduce(function (roundedStr, current, idx) { | ||
@@ -71,3 +78,3 @@ if (roundedStr.length > idx) { | ||
var decimalPart = roundedDecimalParts[1]; | ||
var decimalPart = limitToScale(roundedDecimalParts[1] || '', (numberParts[1] || '').length, fixedDecimalScale); | ||
@@ -74,0 +81,0 @@ return intPart + (decimalPart ? '.' + decimalPart : ''); |
{ | ||
"name": "react-number-format", | ||
"description": "React component to format number in an input or as a text.", | ||
"version": "3.0.0-alpha2", | ||
"version": "3.0.0-alpha3", | ||
"main": "lib/number_format.js", | ||
@@ -6,0 +6,0 @@ "author": "Sudhanshu Yadav", |
@@ -24,3 +24,4 @@ # react-number-format | ||
| decimalSeparator | single character string| . | Support decimal point on a number | | ||
| decimalPrecision | number| none| If defined it limits to given decimal precision | | ||
| decimalScale | number| none| If defined it limits to given decimal scale | | ||
| fixedDecimalScale | boolean| false| If true it add 0s to match given decimalScale| | ||
| allowNegative | boolean | true | allow negative numbers (Only when format option is not provided) | | ||
@@ -37,3 +38,3 @@ | prefix | String (ex : $) | none | Add a prefix before the number | | ||
| customInput | Component Reference | input | This allow supporting custom inputs with number format. | | ||
| onChange | (e, values) => {} | none | onChange handler accepts event object and [values object](#values-object) | | ||
| onValueChange | (values) => {} | none | onValueChange handler accepts [values object](#values-object) | | ||
| isAllowed | ([values](#values-object)) => true or false | none | A checker function to check if input value is valid or not | | ||
@@ -57,8 +58,10 @@ | renderText | (formattedValue) => React Element | null | A renderText method useful if you want to render formattedValue in different element other than span. | | ||
2. Value as prop will be rounded to given precision if format option is not provided. | ||
2. Value as prop will be rounded to given decimal scale if format option is not provided. | ||
3. If you want to block floating number set decimalPrecision to 0. | ||
3. If you want to block floating number set decimalScale to 0. | ||
4. Use type as tel when you are providing format prop. This will change the mobile keyboard layout to have only numbers. In other case use type as text, so user can type decimal separator. | ||
5. onChange no longer gets values object. You need to use onValueChange instead. onChange/onFocus/onBlur and other input events will be directly passed to the input. | ||
### Examples | ||
@@ -185,3 +188,5 @@ #### Prefix and thousand separator : Format currency as text | ||
### v3.0.0-alpha | ||
- Added renderText prop to render formatted value differently. | ||
- onChange no longer gets values object. You need to use onValueChange instead. This is done because formatted value may change on onBlur event. calling onChange on onBlur doesn't feel right. | ||
- decimalPrecision is changed to decimalScale. Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. | ||
- decimalScale by default will not add 0s to match provided decimalScale value like decimalPrecision. You have to set fixedDecimalScale to true. | ||
- onChange api been changed. Now it receives [values object](#values-object) as second parameter. | ||
@@ -199,3 +204,3 @@ - mask can be now array of string in which case mask at specific index will be mapped with the # of the pattern. | ||
- thousandSeparator accepts only true as boolean (which defaults to ,) or thousandSeparator string | ||
- decimalPrecision only accepts number Now | ||
- decimalPrecision only accepts number now | ||
- Value can be passed as string or number but if it is passed as string you should maintain the same decimal separator on the string what you provided as decimalSeparator prop. | ||
@@ -202,0 +207,0 @@ - Added back the type prop for the input type attribute (Only text or tel is supported) |
@@ -10,5 +10,5 @@ //@flow | ||
escapeRegExp, | ||
removeLeadingZero, | ||
fixLeadingZero, | ||
splitString, | ||
limitToPrecision, | ||
limitToScale, | ||
roundToPrecision, | ||
@@ -23,3 +23,4 @@ omit, | ||
decimalSeparator: PropTypes.string, | ||
decimalPrecision: PropTypes.number, | ||
decimalScale: PropTypes.number, | ||
fixedDecimalScale: PropTypes.bool, | ||
displayType: PropTypes.oneOf(['input', 'text']), | ||
@@ -41,2 +42,3 @@ prefix: PropTypes.string, | ||
allowNegative: PropTypes.bool, | ||
onValueChange: PropTypes.func, | ||
onKeyDown: PropTypes.func, | ||
@@ -46,2 +48,3 @@ onMouseUp: PropTypes.func, | ||
onFocus: PropTypes.func, | ||
onBlur: PropTypes.func, | ||
type: PropTypes.oneOf(['text', 'tel']), | ||
@@ -55,2 +58,3 @@ isAllowed: PropTypes.func, | ||
decimalSeparator: '.', | ||
fixedDecimalScale: false, | ||
prefix: '', | ||
@@ -61,2 +65,3 @@ suffix: '', | ||
type: 'text', | ||
onValueChange: noop, | ||
onChange: noop, | ||
@@ -66,3 +71,4 @@ onKeyDown: noop, | ||
onFocus: noop, | ||
isAllowed: returnTrue, | ||
onBlur: noop, | ||
isAllowed: returnTrue | ||
}; | ||
@@ -79,2 +85,3 @@ | ||
onFocus: Function | ||
onBlur: Function | ||
static defaultProps: Object | ||
@@ -98,2 +105,3 @@ constructor(props: Object) { | ||
this.onFocus = this.onFocus.bind(this); | ||
this.onBlur = this.onBlur.bind(this); | ||
} | ||
@@ -153,5 +161,5 @@ | ||
getNumberRegex(g: boolean, ignoreDecimalSeparator?: boolean) { | ||
const {format, decimalPrecision} = this.props; | ||
const {format, decimalScale} = this.props; | ||
const {decimalSeparator} = this.getSeparators(); | ||
return new RegExp('\\d' + (decimalSeparator && decimalPrecision !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && decimalScale !== 0 && !ignoreDecimalSeparator && !format ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
@@ -401,3 +409,3 @@ | ||
formatAsNumber(numStr: string) { | ||
const {decimalPrecision, allowNegative, prefix, suffix} = this.props; | ||
const {decimalScale, fixedDecimalScale, allowNegative, prefix, suffix} = this.props; | ||
const {thousandSeparator, decimalSeparator} = this.getSeparators(); | ||
@@ -410,3 +418,3 @@ | ||
const hasDecimalSeparator = numStr.indexOf('.') !== -1 || decimalPrecision; | ||
const hasDecimalSeparator = numStr.indexOf('.') !== -1 || (decimalScale && fixedDecimalScale); | ||
@@ -423,6 +431,6 @@ const parts = numStr.split('.'); | ||
//remove leading zeros from number before decimal | ||
beforeDecimal = removeLeadingZero(beforeDecimal); | ||
//beforeDecimal = removeLeadingZero(beforeDecimal); | ||
//apply decimal precision if its defined | ||
if (decimalPrecision !== undefined) afterDecimal = limitToPrecision(afterDecimal, decimalPrecision); | ||
if (decimalScale !== undefined) afterDecimal = limitToScale(afterDecimal, decimalScale, fixedDecimalScale); | ||
@@ -445,3 +453,3 @@ if(thousandSeparator) { | ||
formatNumString(value: string) { | ||
formatNumString(value: string = '') { | ||
const {format} = this.props; | ||
@@ -471,3 +479,3 @@ let formattedValue = value; | ||
formatValueProp() { | ||
const {format, decimalPrecision} = this.props; | ||
const {format, decimalScale, fixedDecimalScale} = this.props; | ||
let {value, isNumericString} = this.props; | ||
@@ -483,6 +491,6 @@ | ||
//round the number based on decimalPrecision | ||
//round the number based on decimalScale | ||
//format only if non formatted value is provided | ||
if (isNumericString && !format && typeof decimalPrecision === 'number') { | ||
value = roundToPrecision(value, decimalPrecision) | ||
if (isNumericString && !format && typeof decimalScale === 'number') { | ||
value = roundToPrecision(value, decimalScale, fixedDecimalScale) | ||
} | ||
@@ -532,3 +540,3 @@ | ||
isCharacterAFormat(caretPos: number, value: string) { | ||
const {format, prefix, suffix, decimalPrecision} = this.props; | ||
const {format, prefix, suffix, decimalScale, fixedDecimalScale} = this.props; | ||
const {decimalSeparator} = this.getSeparators(); | ||
@@ -542,3 +550,3 @@ | ||
|| caretPos >= value.length - suffix.length | ||
|| (decimalPrecision && value[caretPos] === decimalSeparator)) | ||
|| (decimalScale && fixedDecimalScale && value[caretPos] === decimalSeparator)) | ||
) { | ||
@@ -620,4 +628,7 @@ return true; | ||
this.setState({value : formattedValue, numAsString: this.removeFormatting(formattedValue)}, () => { | ||
props.onChange(e, valueObj); | ||
props.onValueChange(valueObj); | ||
props.onChange(e); | ||
}); | ||
} else { | ||
props.onChange(e); | ||
} | ||
@@ -628,2 +639,28 @@ | ||
onBlur(e: SyntheticInputEvent) { | ||
const {props, state} = this; | ||
const {format, onBlur} = props; | ||
let {numAsString} = state; | ||
const lastValue = state.value; | ||
if (!format) { | ||
numAsString = fixLeadingZero(numAsString); | ||
const {formattedValue, value} = this.formatNumString(numAsString); | ||
const valueObj = { | ||
formattedValue, | ||
value, | ||
floatValue: parseFloat(value) | ||
}; | ||
//change the state | ||
if (formattedValue !== lastValue) { | ||
this.setState({value : formattedValue, numAsString}, () => { | ||
props.onValueChange(valueObj); | ||
onBlur(e); | ||
}); | ||
} else { | ||
onBlur(e); | ||
} | ||
} | ||
} | ||
onKeyDown(e: SyntheticKeyboardInputEvent) { | ||
@@ -635,4 +672,5 @@ const el = e.target; | ||
let expectedCaretPosition; | ||
const {decimalPrecision, prefix, suffix, format, onKeyDown} = this.props; | ||
const numRegex = this.getNumberRegex(false, decimalPrecision !== undefined); | ||
const {decimalScale, fixedDecimalScale, prefix, suffix, format, onKeyDown} = this.props; | ||
const ignoreDecimalSeparator = decimalScale !== undefined && fixedDecimalScale; | ||
const numRegex = this.getNumberRegex(false, ignoreDecimalSeparator); | ||
const negativeRegex = new RegExp('-'); | ||
@@ -727,3 +765,4 @@ const isPatternFormat = typeof format === 'string'; | ||
onMouseUp: this.onMouseUp, | ||
onFocus: this.onFocus | ||
onFocus: this.onFocus, | ||
onBlur: this.onBlur | ||
}) | ||
@@ -730,0 +769,0 @@ |
@@ -15,5 +15,11 @@ //@flow | ||
export function removeLeadingZero(numStr: string) { | ||
//remove leading zeros | ||
return numStr.replace(/^0+/,'') || '0'; | ||
export function fixLeadingZero(numStr?: string) { | ||
if (!numStr) return numStr; | ||
const isNegative = numStr[0] === '-'; | ||
if (isNegative) numStr = numStr.substring(1, numStr.length); | ||
const parts = numStr.split('.'); | ||
const beforeDecimal = parts[0].replace(/^0+/,'') || '0'; | ||
const afterDecimal = parts[1] || ''; | ||
return `${isNegative ? '-': ''}${beforeDecimal}${afterDecimal ? `.${afterDecimal}` : ''}`; | ||
} | ||
@@ -26,9 +32,10 @@ | ||
/** | ||
* limit decimal numbers to given precision | ||
* limit decimal numbers to given scale | ||
* Not used .fixedTo because that will break with big numbers | ||
*/ | ||
export function limitToPrecision(numStr: string, precision: number) { | ||
export function limitToScale(numStr: string, scale: number, fixedDecimalScale: boolean) { | ||
let str = '' | ||
for (let i=0; i<=precision - 1; i++) { | ||
str += numStr[i] || '0' | ||
const filler = fixedDecimalScale ? '0' : ''; | ||
for (let i=0; i<=scale - 1; i++) { | ||
str += numStr[i] || filler; | ||
} | ||
@@ -39,8 +46,8 @@ return str; | ||
/** | ||
* This method is required to round prop value to given precision. | ||
* This method is required to round prop value to given scale. | ||
* Not used .round or .fixedTo because that will break with big numbers | ||
*/ | ||
export function roundToPrecision(numStr: string, precision: number) { | ||
export function roundToPrecision(numStr: string, scale: number, fixedDecimalScale: boolean) { | ||
const numberParts = numStr.split('.'); | ||
const roundedDecimalParts = parseFloat(`0.${numberParts[1] || '0'}`).toFixed(precision).split('.'); | ||
const roundedDecimalParts = parseFloat(`0.${numberParts[1] || '0'}`).toFixed(scale).split('.'); | ||
const intPart = numberParts[0].split('').reverse().reduce((roundedStr, current, idx) => { | ||
@@ -51,5 +58,5 @@ if (roundedStr.length > idx) { | ||
return current + roundedStr; | ||
}, roundedDecimalParts[0]) | ||
}, roundedDecimalParts[0]); | ||
const decimalPart = roundedDecimalParts[1]; | ||
const decimalPart = limitToScale(roundedDecimalParts[1] || '', (numberParts[1] || '').length, fixedDecimalScale); | ||
@@ -56,0 +63,0 @@ return intPart + (decimalPart ? '.' + decimalPart : ''); |
@@ -33,22 +33,31 @@ import React from 'react'; | ||
it('should not round decimals by defualt', () => { | ||
const wrapper = shallow(<NumberFormat value="4111" displayType={'text'} />); | ||
expect(wrapper.find('span').text()).toEqual('4111'); | ||
}); | ||
it('should limit decimal scale to given value', () => { | ||
const wrapper = shallow(<NumberFormat value={4111.344} displayType={'text'} decimalScale={2}/>); | ||
expect(wrapper.find('span').text()).toEqual('4111.34'); | ||
it('should round to 2 decimals if passed true', () => { | ||
const wrapper = shallow(<NumberFormat value="4111" displayType={'text'} decimalPrecision={2} />); | ||
expect(wrapper.find('span').text()).toEqual('4111.00'); | ||
wrapper.setProps({ | ||
value: 4111.358 | ||
}); | ||
wrapper.update(); | ||
expect(wrapper.find('span').text()).toEqual('4111.36'); | ||
}); | ||
it('should round to 4 decimals if passed 4', () => { | ||
const wrapper = shallow(<NumberFormat value="4111.11" displayType={'text'} decimalPrecision={4} />); | ||
it('it should add zeros if fixedDecimalScale is provided', () => { | ||
const wrapper = shallow(<NumberFormat value="4111.11" displayType={'text'} decimalScale={4} fixedDecimalScale={true}/>); | ||
expect(wrapper.find('span').text()).toEqual('4111.1100'); | ||
wrapper.setProps({ | ||
decimalScale: 1 | ||
}); | ||
wrapper.update(); | ||
expect(wrapper.find('span').text()).toEqual('4111.1'); | ||
}); | ||
it('should accept custom renderText method', () => { | ||
const wrapper = shallow(<NumberFormat value="4111.11" thousandSeparator="," renderText={value => <div>{value}</div>} displayType={'text'} decimalPrecision={4} />); | ||
expect(wrapper.find('div').text()).toEqual('4,111.1100'); | ||
const wrapper = shallow(<NumberFormat value="4111.11" thousandSeparator="," renderText={value => <div>{value}</div>} displayType={'text'} />); | ||
expect(wrapper.find('div').text()).toEqual('4,111.11'); | ||
}) | ||
}); |
import React from 'react'; | ||
import NumberFormat from '../../src/number_format'; | ||
import {getCustomEvent, simulateKeyInput, shallow, mount} from '../test_util'; | ||
import {getCustomEvent, simulateKeyInput, simulateBlurEvent, shallow, mount} from '../test_util'; | ||
@@ -15,3 +15,3 @@ | ||
describe('Test NumberFormat as input with numeric format options', () => { | ||
it('show the initial value as $0 when number 0 is passed', () => { | ||
it('should show the initial value as $0 when number 0 is passed', () => { | ||
const wrapper = shallow(<NumberFormat value={0} thousandSeparator={true} prefix={'$'} />); | ||
@@ -21,8 +21,8 @@ expect(wrapper.state().value).toEqual('$0'); | ||
it('show the initial value as empty string when empty string is passed and decimalPrecision is set', () => { | ||
const wrapper = mount(<NumberFormat value="" thousandSeparator={true} decimalPrecision={2} />); | ||
it('should show the initial value as empty string when empty string is passed and decimalScale is set', () => { | ||
const wrapper = mount(<NumberFormat value="" thousandSeparator={true} decimalScale={2} />); | ||
expect(wrapper.state().value).toEqual(''); | ||
}); | ||
it('show the initial value as empty string when empty string is passed and decimalPrecision is not set', () => { | ||
it('should show the initial value as empty string when empty string is passed and decimalScale is not set', () => { | ||
const wrapper = mount(<NumberFormat value="" thousandSeparator={true} />); | ||
@@ -116,3 +116,3 @@ expect(wrapper.state().value).toEqual(''); | ||
it('should allow floating/integer numbers as values and do proper formatting', () => { | ||
const wrapper = shallow(<NumberFormat value={12345.67} />, { lifecycleExperimental: true }); | ||
const wrapper = shallow(<NumberFormat value={12345.67} />); | ||
expect(wrapper.state().value).toEqual('12345.67'); | ||
@@ -127,3 +127,3 @@ | ||
wrapper.setProps({thousandSeparator: '.', decimalSeparator: ',', decimalPrecision: 0}); | ||
wrapper.setProps({thousandSeparator: '.', decimalSeparator: ',', decimalScale: 0}); | ||
expect(wrapper.state().value).toEqual('12.346'); | ||
@@ -133,3 +133,3 @@ }); | ||
it('should update formatted value if any of the props changes', () => { | ||
const wrapper = shallow(<NumberFormat value={12345.67} />, { lifecycleExperimental: true }); | ||
const wrapper = shallow(<NumberFormat value={12345.67} />); | ||
expect(wrapper.state().value).toEqual('12345.67'); | ||
@@ -143,3 +143,3 @@ | ||
wrapper.setProps({thousandSeparator: '.', decimalSeparator: ',', decimalPrecision: 0}); | ||
wrapper.setProps({thousandSeparator: '.', decimalSeparator: ',', decimalScale: 0}); | ||
expect(wrapper.state().value).toEqual('12.346'); | ||
@@ -159,4 +159,4 @@ }); | ||
it('should support decimal precision with custom decimal separator', () => { | ||
const wrapper = shallow(<NumberFormat thousandSeparator={'.'} decimalSeparator={','} decimalPrecision={2} />); | ||
it('should support decimal scale with custom decimal separator', () => { | ||
const wrapper = shallow(<NumberFormat thousandSeparator={'.'} decimalSeparator={','} decimalScale={2} />); | ||
const input = wrapper.find('input'); | ||
@@ -168,11 +168,11 @@ | ||
it('should limit to passed decimal precision', () => { | ||
const wrapper = shallow(<NumberFormat decimalPrecision={4}/>); | ||
it('should limit to passed decimal scale', () => { | ||
const wrapper = shallow(<NumberFormat decimalScale={4} fixedDecimalScale={true}/>); | ||
const input = wrapper.find('input'); | ||
//case 1st - already exactly precision 4 should stay that way | ||
//case 1st - already exactly scale 4 should stay that way | ||
input.simulate('change', getCustomEvent('4111.1111')); | ||
expect(wrapper.state().value).toEqual('4111.1111'); | ||
//case 2nd - longer precision should round | ||
//case 2nd - longer scale should round | ||
input.simulate('change', getCustomEvent('4111.11111')); | ||
@@ -186,3 +186,3 @@ expect(wrapper.state().value).toEqual('4111.1111'); | ||
//case 3rd - shorter precision adds 0 | ||
//case 3rd - shorter scale adds 0 | ||
input.simulate('change', getCustomEvent('4111.111')); | ||
@@ -196,4 +196,4 @@ expect(wrapper.state().value).toEqual('4111.1110'); | ||
//case 5 - round with two decimal precision | ||
wrapper.setProps({decimalPrecision: 2}); | ||
//case 5 - round with two decimal scale | ||
wrapper.setProps({decimalScale: 2}); | ||
input.simulate('change', getCustomEvent('4111.111')); | ||
@@ -203,4 +203,15 @@ expect(wrapper.state().value).toEqual('4111.11'); | ||
it('should not round the initial if decimalPrecision is not provided', () => { | ||
const wrapper = shallow(<NumberFormat value={123213.7535}/>, {lifecycleExperimental: true}); | ||
it('should not add zeros to fixedDecimalScale is not set', () => { | ||
const wrapper = shallow(<NumberFormat decimalScale={4} value={24.45}/>); | ||
expect(wrapper.state().value).toEqual('24.45'); | ||
wrapper.setProps({ | ||
value: 24.45678 | ||
}); | ||
wrapper.update(); | ||
expect(wrapper.state().value).toEqual('24.4568'); | ||
}); | ||
it('should not round the initial if decimalScale is not provided', () => { | ||
const wrapper = shallow(<NumberFormat value={123213.7535}/>); | ||
expect(wrapper.state().value).toEqual('123213.7535'); | ||
@@ -232,4 +243,4 @@ | ||
it('should round the initial value to given decimalPrecision', () => { | ||
const wrapper = shallow(<NumberFormat value={123213.7536} isNumericString={true} decimalPrecision={1}/>, {lifecycleExperimental: true}); | ||
it('should round the initial value to given decimalScale', () => { | ||
const wrapper = shallow(<NumberFormat value={123213.7536} isNumericString={true} decimalScale={1}/>); | ||
expect(wrapper.state().value).toEqual('123213.8'); | ||
@@ -246,3 +257,3 @@ | ||
decimalSeparator: ',', | ||
decimalPrecision: 3 | ||
decimalScale: 3 | ||
}); | ||
@@ -254,3 +265,3 @@ | ||
value: 36790.876, | ||
decimalPrecision: 0 | ||
decimalScale: 0 | ||
}) | ||
@@ -260,3 +271,3 @@ | ||
wrapper.setProps({ | ||
decimalPrecision: 2 | ||
decimalScale: 2 | ||
}) | ||
@@ -280,4 +291,4 @@ | ||
it('should allow deleting all numbers when decimalPrecision is defined', () => { | ||
const wrapper = shallow(<NumberFormat prefix="$" decimalPrecision={3} value="$1.000"/>); | ||
it('should allow deleting all numbers when decimalScale and fixedDecimalScale is defined', () => { | ||
const wrapper = shallow(<NumberFormat prefix="$" decimalScale={3} value="$1.000" fixedDecimalScale={true}/>); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 2); | ||
@@ -287,8 +298,8 @@ expect(wrapper.state().value).toEqual('') | ||
it('should not allow to remove decimalSeparator if decimalPrecision is defined', () => { | ||
const wrapper = shallow(<NumberFormat prefix="$" thousandSeparator={true} decimalPrecision={3} value="$1,234.000"/>); | ||
it('should not allow to remove decimalSeparator if decimalScale and fixedDecimalScale is defined', () => { | ||
const wrapper = shallow(<NumberFormat prefix="$" thousandSeparator={true} decimalScale={3} fixedDecimalScale={true} value="$1,234.000"/>); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 7); | ||
expect(wrapper.state().value).toEqual('$1,234.000'); | ||
wrapper.setProps({decimalPrecision: undefined}) | ||
wrapper.setProps({decimalScale: undefined}) | ||
wrapper.update(); | ||
@@ -316,7 +327,7 @@ simulateKeyInput(wrapper.find('input'), 'Backspace', 7); | ||
it('sould not allow decimal numbers if decimal precision is set to 0', () => { | ||
const wrapper = shallow(<NumberFormat thousandSeparator={true} decimalPrecision={0}/>, {lifecycleExperimental: true}); | ||
it('sould not allow decimal numbers if decimal scale is set to 0', () => { | ||
const wrapper = shallow(<NumberFormat thousandSeparator={true} decimalScale={0}/>); | ||
const input = wrapper.find('input'); | ||
//case 1 - decimal precision set to 0 | ||
//case 1 - decimal scale set to 0 | ||
input.simulate('change', getCustomEvent('4111.')); | ||
@@ -327,2 +338,3 @@ expect(wrapper.state().value).toEqual('4,111'); | ||
wrapper.setProps({value: 1234.78}); | ||
wrapper.update(); | ||
expect(wrapper.state().value).toEqual('1,235'); | ||
@@ -332,9 +344,64 @@ }); | ||
it('should allow decimal seperator and thousand separator on suffix prefix', () => { | ||
const wrapper = shallow(<NumberFormat value={1231237.56} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'} suffix={' per sq. ft.'}/> , {lifecycleExperimental: true}); | ||
const wrapper = shallow(<NumberFormat value={1231237.56} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'} suffix={' per sq. ft.'}/> ); | ||
expect(wrapper.state().value).toEqual('$1,231,237.56 per sq. ft.'); | ||
wrapper.setProps({suffix: '', prefix: '$ per, sq. ft. '}); | ||
wrapper.update(); | ||
expect(wrapper.state().value).toEqual('$ per, sq. ft. 1,231,237.56'); | ||
}); | ||
it('should not remove leading 0s while user is in focus', () => { | ||
const wrapper = shallow(<NumberFormat value={23456.78} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'}/> ); | ||
simulateKeyInput(wrapper.find('input'), '0', 1); | ||
expect(wrapper.state().value).toEqual('$023,456.78'); | ||
wrapper.setProps({value: 10000.25}); | ||
wrapper.update(); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 2); | ||
expect(wrapper.state().value).toEqual('$0,000.25'); | ||
simulateKeyInput(wrapper.find('input'), '2', 1); | ||
expect(wrapper.state().value).toEqual('$20,000.25'); | ||
}); | ||
it('should remove leading 0s while user go out of focus', () => { | ||
const wrapper = shallow(<NumberFormat value={23456.78} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'}/> ); | ||
simulateKeyInput(wrapper.find('input'), '0', 1); | ||
simulateBlurEvent(wrapper.find('input')); | ||
expect(wrapper.state().value).toEqual('$23,456.78'); | ||
wrapper.setProps({value: 10000.25}); | ||
wrapper.update(); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 2); | ||
simulateBlurEvent(wrapper.find('input')); | ||
expect(wrapper.state().value).toEqual('$0.25'); | ||
}); | ||
it('should add 0 before decimal if user is in focus', () => { | ||
const wrapper = shallow(<NumberFormat value={0.78} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'}/> ); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 2); | ||
expect(wrapper.state().value).toEqual('$.78'); | ||
simulateKeyInput(wrapper.find('input'), '2', 1); | ||
expect(wrapper.state().value).toEqual('$2.78'); | ||
}); | ||
it('should not add 0 before decimal if user go out of focus', () => { | ||
const wrapper = shallow(<NumberFormat value={0.78} thousandSeparator={','} decimalSeparator={'.'} prefix={'$'}/> ); | ||
simulateKeyInput(wrapper.find('input'), 'Backspace', 2); | ||
expect(wrapper.state().value).toEqual('$.78'); | ||
simulateBlurEvent(wrapper.find('input')); | ||
expect(wrapper.state().value).toEqual('$0.78'); | ||
}); | ||
}); |
@@ -73,3 +73,3 @@ import React from 'react'; | ||
return floatValue <= 10000; | ||
}} value={9999}/>, {lifecycleExperimental: true}); | ||
}} value={9999}/>); | ||
@@ -76,0 +76,0 @@ const input = wrapper.find('input'); |
@@ -133,2 +133,13 @@ import Enzyme, {shallow, mount} from 'enzyme'; | ||
export function simulateBlurEvent(input) { | ||
const currentValue = input.prop('value'); | ||
const blurEvent = getEvent({}, { | ||
value: currentValue, | ||
}); | ||
input.simulate('blur', blurEvent); | ||
} | ||
export {Enzyme, shallow, mount}; |
351032
3997
218