react-number-format
Advanced tools
Comparing version 1.0.2 to 1.1.0-alpha2
/*! | ||
* react-number-format - 1.0.2 | ||
* react-number-format - 1.1.0-alpha2 | ||
* Author : Sudhanshu Yadav | ||
@@ -93,4 +93,5 @@ * Copyright (c) 2016,2017 to Sudhanshu Yadav - ignitersworld.com , released under the MIT license. | ||
var propTypes = { | ||
thousandSeparator: _react.PropTypes.oneOf([',', '.', true, false]), | ||
decimalSeparator: _react.PropTypes.oneOf([',', '.', true, false]), | ||
thousandSeparator: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]), | ||
decimalSeparator: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]), | ||
decimalPrecision: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.bool]), | ||
displayType: _react.PropTypes.oneOf(['input', 'text']), | ||
@@ -101,3 +102,4 @@ prefix: _react.PropTypes.string, | ||
mask: _react.PropTypes.string, | ||
value: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]) | ||
value: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), | ||
customInput: _react.PropTypes.func | ||
}; | ||
@@ -107,3 +109,4 @@ | ||
displayType: 'input', | ||
decimalSeparator: '.' | ||
decimalSeparator: '.', | ||
decimalPrecision: false | ||
}; | ||
@@ -124,2 +127,3 @@ | ||
_this.onInput = _this.onInput.bind(_this); | ||
_this.onKeyDown = _this.onKeyDown.bind(_this); | ||
return _this; | ||
@@ -140,5 +144,5 @@ } | ||
value: function getSeparators() { | ||
var _props = this.props; | ||
var thousandSeparator = _props.thousandSeparator; | ||
var decimalSeparator = _props.decimalSeparator; | ||
var _props = this.props, | ||
thousandSeparator = _props.thousandSeparator, | ||
decimalSeparator = _props.decimalSeparator; | ||
@@ -149,4 +153,4 @@ if (thousandSeparator === true) { | ||
if (decimalSeparator && thousandSeparator) { | ||
decimalSeparator = thousandSeparator === ',' ? '.' : ','; | ||
if (decimalSeparator && thousandSeparator && typeof decimalSeparator !== 'string') { | ||
decimalSeparator = thousandSeparator === '.' ? ',' : '.'; | ||
} | ||
@@ -165,13 +169,11 @@ | ||
key: 'getNumberRegex', | ||
value: function getNumberRegex(g) { | ||
var _getSeparators = this.getSeparators(); | ||
value: function getNumberRegex(g, ignoreDecimalSeperator) { | ||
var _getSeparators = this.getSeparators(), | ||
decimalSeparator = _getSeparators.decimalSeparator; | ||
var decimalSeparator = _getSeparators.decimalSeparator; | ||
return new RegExp('\\d' + (decimalSeparator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && !ignoreDecimalSeperator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
}, { | ||
key: 'setCaretPosition', | ||
value: function setCaretPosition(caretPos) { | ||
var el = this.refs.input; | ||
value: function setCaretPosition(el, caretPos) { | ||
el.value = el.value; | ||
@@ -203,5 +205,5 @@ // ^ this is used to not only get "focus", but | ||
value: function formatWithPattern(str) { | ||
var _props2 = this.props; | ||
var format = _props2.format; | ||
var mask = _props2.mask; | ||
var _props2 = this.props, | ||
format = _props2.format, | ||
mask = _props2.mask; | ||
@@ -230,12 +232,13 @@ if (!format) return str; | ||
value: function formatInput(val) { | ||
var _props3 = this.props; | ||
var prefix = _props3.prefix; | ||
var suffix = _props3.suffix; | ||
var mask = _props3.mask; | ||
var format = _props3.format; | ||
var _props3 = this.props, | ||
prefix = _props3.prefix, | ||
suffix = _props3.suffix, | ||
mask = _props3.mask, | ||
format = _props3.format; | ||
var _getSeparators2 = this.getSeparators(); | ||
var _getSeparators2 = this.getSeparators(), | ||
thousandSeparator = _getSeparators2.thousandSeparator, | ||
decimalSeparator = _getSeparators2.decimalSeparator; | ||
var thousandSeparator = _getSeparators2.thousandSeparator; | ||
var decimalSeparator = _getSeparators2.decimalSeparator; | ||
var decimalPrecision = this.props.decimalPrecision; | ||
@@ -263,5 +266,11 @@ var maskPattern = format && typeof format == 'string' && !!mask; | ||
afterDecimal = ''; | ||
var hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1; | ||
var hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1 || decimalPrecision !== false; | ||
if (decimalSeparator && hasDecimals) { | ||
var parts = formattedValue.split(decimalSeparator); | ||
var parts = void 0; | ||
if (decimalPrecision !== false) { | ||
var precision = decimalPrecision === true ? 2 : decimalPrecision; | ||
parts = parseFloat(formattedValue).toFixed(precision).split(decimalSeparator); | ||
} else { | ||
parts = formattedValue.split(decimalSeparator); | ||
} | ||
beforeDecimal = parts[0]; | ||
@@ -298,6 +307,2 @@ afterDecimal = parts[1]; | ||
//check if there is no number before caret position | ||
while (j > 0 && formattedValue[j]) { | ||
if (!formattedValue[j - 1].match(numRegex)) j--;else break; | ||
} | ||
return j; | ||
@@ -311,15 +316,21 @@ } | ||
e.persist(); | ||
var inputValue = e.target.value; | ||
var el = e.target; | ||
var inputValue = el.value; | ||
var _formatInput = this.formatInput(inputValue); | ||
var _formatInput = this.formatInput(inputValue), | ||
formattedValue = _formatInput.formattedValue, | ||
value = _formatInput.value; | ||
var formattedValue = _formatInput.formattedValue; | ||
var value = _formatInput.value; | ||
var cursorPos = el.selectionStart; | ||
var cursorPos = this.refs.input.selectionStart; | ||
//change the state | ||
this.setState({ value: formattedValue }, function () { | ||
cursorPos = _this2.getCursorPosition(inputValue, formattedValue, cursorPos); | ||
_this2.setCaretPosition(cursorPos); | ||
/* | ||
setting caret position within timeout of 0ms is required for mobile chrome, | ||
otherwise browser resets the caret position after we set it | ||
*/ | ||
setTimeout(function () { | ||
return _this2.setCaretPosition(el, cursorPos); | ||
}, 0); | ||
if (callback) callback(e, value); | ||
@@ -341,2 +352,32 @@ }); | ||
}, { | ||
key: 'onKeyDown', | ||
value: function onKeyDown(e) { | ||
var el = e.target; | ||
var selectionStart = el.selectionStart, | ||
selectionEnd = el.selectionEnd, | ||
value = el.value; | ||
var decimalPrecision = this.props.decimalPrecision; | ||
var key = e.key; | ||
var numRegex = this.getNumberRegex(false, decimalPrecision !== false); | ||
//Handle backspace and delete against non numerical/decimal characters | ||
if (selectionEnd - selectionStart === 0) { | ||
if (key === 'Delete' && !numRegex.test(value[selectionStart])) { | ||
e.preventDefault(); | ||
var nextCursorPosition = selectionStart; | ||
while (!numRegex.test(value[nextCursorPosition]) && nextCursorPosition < value.length) { | ||
nextCursorPosition++; | ||
}this.setCaretPosition(el, nextCursorPosition); | ||
} else if (key === 'Backspace' && !numRegex.test(value[selectionStart - 1])) { | ||
e.preventDefault(); | ||
var prevCursorPosition = selectionStart; | ||
while (!numRegex.test(value[prevCursorPosition - 1]) && prevCursorPosition > 0) { | ||
prevCursorPosition--; | ||
}this.setCaretPosition(el, prevCursorPosition); | ||
} | ||
} | ||
if (this.props.onKeyDown) this.props.onKeyDown(e); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -350,2 +391,10 @@ value: function render() { | ||
var inputProps = _extends({}, props, { | ||
type: 'tel', | ||
value: this.state.value, | ||
onInput: this.onChange, | ||
onChange: this.onChange, | ||
onKeyDown: this.onKeyDown | ||
}); | ||
if (this.props.displayType === 'text') { | ||
@@ -357,10 +406,8 @@ return _react2.default.createElement( | ||
); | ||
} else if (this.props.customInput) { | ||
var CustomInput = this.props.customInput; | ||
return _react2.default.createElement(CustomInput, inputProps); | ||
} | ||
return _react2.default.createElement('input', _extends({}, props, { | ||
type: 'tel', | ||
value: this.state.value, | ||
ref: 'input', | ||
onInput: this.onChange, | ||
onChange: this.onChange | ||
})); | ||
return _react2.default.createElement('input', inputProps); | ||
} | ||
@@ -367,0 +414,0 @@ }]); |
/*! | ||
* react-number-format - 1.0.2 | ||
* react-number-format - 1.1.0-alpha2 | ||
* 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)}function u(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var s=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},p=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={thousandSeparator:f.PropTypes.oneOf([",",".",!0,!1]),decimalSeparator:f.PropTypes.oneOf([",",".",!0,!1]),displayType:f.PropTypes.oneOf(["input","text"]),prefix:f.PropTypes.string,suffix:f.PropTypes.string,format:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.func]),mask:f.PropTypes.string,value:f.PropTypes.oneOfType([f.PropTypes.number,f.PropTypes.string])},h={displayType:"input",decimalSeparator:"."},v=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.state={value:r.formatInput(e.value).formattedValue},r.onChange=r.onChange.bind(r),r.onInput=r.onInput.bind(r),r}return i(t,e),p(t,[{key:"componentWillReceiveProps",value:function(e){e.value!==this.props.value&&this.setState({value:this.formatInput(e.value).formattedValue})}},{key:"getSeparators",value:function(){var e=this.props,t=e.thousandSeparator,r=e.decimalSeparator;return t===!0&&(t=","),r&&t&&(r=","===t?".":","),r===!0&&(r="."),{decimalSeparator:r,thousandSeparator:t}}},{key:"getNumberRegex",value:function(e){var t=this.getSeparators(),r=t.decimalSeparator;return new RegExp("\\d"+(r?"|"+u(r):""),e?"g":void 0)}},{key:"setCaretPosition",value:function(e){var t=this.refs.input;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)}}},{key:"formatWithPattern",value:function(e){var t=this.props,r=t.format,n=t.mask;if(!r)return e;for(var o=r.split("#").length-1,a=0,i=r,u=0,s=e.length;u<s;u++)u<o&&(a=i.indexOf("#"),i=i.replace("#",e[u]));var p=i.lastIndexOf("#");return n?i.replace(/#/g,n):i.substring(0,a+1)+(p!==-1?i.substring(p+1,i.length):"")}},{key:"formatInput",value:function(e){var t=this.props,r=t.prefix,n=t.suffix,o=(t.mask,t.format),a=this.getSeparators(),i=a.thousandSeparator,u=a.decimalSeparator,s=this.getNumberRegex(!0);if("number"==typeof e&&(e+=""),!e||!e.match(s))return{value:"",formattedValue:""};var p=e.match(s).join(""),f=p;if(o)"string"==typeof o?f=this.formatWithPattern(f):"function"==typeof o&&(f=o(f));else{var l=f,c="",h=f.indexOf(u)!==-1;if(u&&h){var v=f.split(u);l=v[0],c=v[1]}i&&(l=l.replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+i)),r&&(l=r+l),n&&(c+=n),f=l+(h&&u||"")+c}return{value:f.match(s).join(""),formattedValue:f}}},{key:"getCursorPosition",value:function(e,t,r){for(var n=this.getNumberRegex(),o=0,a=0;a<r;a++)if(e[a].match(n)||e[a]===t[o]){for(;e[a]!==t[o]&&o<t.length;)o++;o++}for(;o>0&&t[o]&&!t[o-1].match(n);)o--;return o}},{key:"onChangeHandler",value:function(e,t){var r=this;e.persist();var n=e.target.value,o=this.formatInput(n),a=o.formattedValue,i=o.value,u=this.refs.input.selectionStart;return this.setState({value:a},function(){u=r.getCursorPosition(n,a,u),r.setCaretPosition(u),t&&t(e,i)}),i}},{key:"onChange",value:function(e){this.onChangeHandler(e,this.props.onChange)}},{key:"onInput",value:function(e){this.onChangeHandler(e,this.props.onInput)}},{key:"render",value:function(){var e=s({},this.props);return Object.keys(c).forEach(function(t){delete e[t]}),"text"===this.props.displayType?l["default"].createElement("span",e,this.state.value):l["default"].createElement("input",s({},e,{type:"tel",value:this.state.value,ref:"input",onInput:this.onChange,onChange:this.onChange}))}}]),t}(l["default"].Component);v.propTypes=c,v.defaultProps=h,e.exports=v},function(t,r){t.exports=e}])}); | ||
!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)}function s(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var p=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},u=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={thousandSeparator:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool]),decimalSeparator:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool]),decimalPrecision:f.PropTypes.oneOfType([f.PropTypes.number,f.PropTypes.bool]),displayType:f.PropTypes.oneOf(["input","text"]),prefix:f.PropTypes.string,suffix:f.PropTypes.string,format:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.func]),mask:f.PropTypes.string,value:f.PropTypes.oneOfType([f.PropTypes.number,f.PropTypes.string]),customInput:f.PropTypes.func},y={displayType:"input",decimalSeparator:".",decimalPrecision:!1},h=function(e){function t(e){o(this,t);var r=a(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e));return r.state={value:r.formatInput(e.value).formattedValue},r.onChange=r.onChange.bind(r),r.onInput=r.onInput.bind(r),r.onKeyDown=r.onKeyDown.bind(r),r}return i(t,e),u(t,[{key:"componentWillReceiveProps",value:function(e){e.value!==this.props.value&&this.setState({value:this.formatInput(e.value).formattedValue})}},{key:"getSeparators",value:function(){var e=this.props,t=e.thousandSeparator,r=e.decimalSeparator;return t===!0&&(t=","),r&&t&&"string"!=typeof r&&(r="."===t?",":"."),r===!0&&(r="."),{decimalSeparator:r,thousandSeparator:t}}},{key:"getNumberRegex",value:function(e,t){var r=this.getSeparators(),n=r.decimalSeparator;return new RegExp("\\d"+(n&&!t?"|"+s(n):""),e?"g":void 0)}},{key:"setCaretPosition",value:function(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)}}},{key:"formatWithPattern",value:function(e){var t=this.props,r=t.format,n=t.mask;if(!r)return e;for(var o=r.split("#").length-1,a=0,i=r,s=0,p=e.length;s<p;s++)s<o&&(a=i.indexOf("#"),i=i.replace("#",e[s]));var u=i.lastIndexOf("#");return n?i.replace(/#/g,n):i.substring(0,a+1)+(u!==-1?i.substring(u+1,i.length):"")}},{key:"formatInput",value:function(e){var t=this.props,r=t.prefix,n=t.suffix,o=(t.mask,t.format),a=this.getSeparators(),i=a.thousandSeparator,s=a.decimalSeparator,p=this.props.decimalPrecision,u=this.getNumberRegex(!0);if("number"==typeof e&&(e+=""),!e||!e.match(u))return{value:"",formattedValue:""};var f=e.match(u).join(""),l=f;if(o)"string"==typeof o?l=this.formatWithPattern(l):"function"==typeof o&&(l=o(l));else{var c=l,y="",h=l.indexOf(s)!==-1||p!==!1;if(s&&h){var v=void 0;if(p!==!1){var d=p===!0?2:p;v=parseFloat(l).toFixed(d).split(s)}else v=l.split(s);c=v[0],y=v[1]}i&&(c=c.replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+i)),r&&(c=r+c),n&&(y+=n),l=c+(h&&s||"")+y}return{value:l.match(u).join(""),formattedValue:l}}},{key:"getCursorPosition",value:function(e,t,r){for(var n=this.getNumberRegex(),o=0,a=0;a<r;a++)if(e[a].match(n)||e[a]===t[o]){for(;e[a]!==t[o]&&o<t.length;)o++;o++}return o}},{key:"onChangeHandler",value:function(e,t){var r=this;e.persist();var n=e.target,o=n.value,a=this.formatInput(o),i=a.formattedValue,s=a.value,p=n.selectionStart;return this.setState({value:i},function(){p=r.getCursorPosition(o,i,p),setTimeout(function(){return r.setCaretPosition(n,p)},0),t&&t(e,s)}),s}},{key:"onChange",value:function(e){this.onChangeHandler(e,this.props.onChange)}},{key:"onInput",value:function(e){this.onChangeHandler(e,this.props.onInput)}},{key:"onKeyDown",value:function(e){var t=e.target,r=t.selectionStart,n=t.selectionEnd,o=t.value,a=this.props.decimalPrecision,i=e.key,s=this.getNumberRegex(!1,a!==!1);if(n-r===0)if("Delete"!==i||s.test(o[r])){if("Backspace"===i&&!s.test(o[r-1])){e.preventDefault();for(var p=r;!s.test(o[p-1])&&p>0;)p--;this.setCaretPosition(t,p)}}else{e.preventDefault();for(var u=r;!s.test(o[u])&&u<o.length;)u++;this.setCaretPosition(t,u)}this.props.onKeyDown&&this.props.onKeyDown(e)}},{key:"render",value:function(){var e=p({},this.props);Object.keys(c).forEach(function(t){delete e[t]});var t=p({},e,{type:"tel",value:this.state.value,onInput:this.onChange,onChange:this.onChange,onKeyDown:this.onKeyDown});if("text"===this.props.displayType)return l.default.createElement("span",e,this.state.value);if(this.props.customInput){var r=this.props.customInput;return l.default.createElement(r,t)}return l.default.createElement("input",t)}}]),t}(l.default.Component);h.propTypes=c,h.defaultProps=y,e.exports=h},function(t,r){t.exports=e}])}); |
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; | ||
import NumberFormat from '../../src/number_format'; | ||
import TextField from 'material-ui/TextField'; | ||
@@ -49,5 +51,25 @@ class App extends React.Component { | ||
<h3> | ||
Decimal precision : Format currency in input with decimal precision | ||
</h3> | ||
<NumberFormat thousandSeparator={true} decimalPrecision={true} prefix={'$'}/> | ||
</div> | ||
<div className="example"> | ||
<h3> | ||
Custom thousand seperator : Format currency in input | ||
</h3> | ||
<NumberFormat thousandSeparator={'.'} decimalSeparator={','} prefix={'$'} /> | ||
<div> | ||
ThousandSeperator: '.', decimalSeparator=',' | ||
</div> | ||
<div> | ||
<NumberFormat thousandSeparator={"."} decimalSeparator={','} prefix={'$'} /> | ||
</div> | ||
<br/> | ||
<div> | ||
ThousandSeperator: ' ', decimalSeparator='.' | ||
</div> | ||
<div> | ||
<NumberFormat thousandSeparator={" "} decimalSeparator={'.'} prefix={'$'} /> | ||
</div> | ||
</div> | ||
@@ -75,2 +97,10 @@ | ||
</div> | ||
<div className="example"> | ||
<h3> | ||
Custom input : Format credit card number | ||
</h3> | ||
<NumberFormat customInput={TextField} format="#### #### #### ####"/> | ||
</div> | ||
</div> | ||
@@ -81,3 +111,8 @@ ) | ||
const ThemedApp = () => { | ||
return (<MuiThemeProvider> | ||
<App /> | ||
</MuiThemeProvider>); | ||
}; | ||
ReactDOM.render(<App />, document.getElementById('app')); | ||
ReactDOM.render(<ThemedApp />, document.getElementById('app')); |
@@ -25,4 +25,5 @@ 'use strict'; | ||
var propTypes = { | ||
thousandSeparator: _react.PropTypes.oneOf([',', '.', true, false]), | ||
decimalSeparator: _react.PropTypes.oneOf([',', '.', true, false]), | ||
thousandSeparator: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]), | ||
decimalSeparator: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.bool]), | ||
decimalPrecision: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.bool]), | ||
displayType: _react.PropTypes.oneOf(['input', 'text']), | ||
@@ -33,3 +34,4 @@ prefix: _react.PropTypes.string, | ||
mask: _react.PropTypes.string, | ||
value: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]) | ||
value: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), | ||
customInput: _react.PropTypes.func | ||
}; | ||
@@ -39,3 +41,4 @@ | ||
displayType: 'input', | ||
decimalSeparator: '.' | ||
decimalSeparator: '.', | ||
decimalPrecision: false | ||
}; | ||
@@ -56,2 +59,3 @@ | ||
_this.onInput = _this.onInput.bind(_this); | ||
_this.onKeyDown = _this.onKeyDown.bind(_this); | ||
return _this; | ||
@@ -72,5 +76,5 @@ } | ||
value: function getSeparators() { | ||
var _props = this.props; | ||
var thousandSeparator = _props.thousandSeparator; | ||
var decimalSeparator = _props.decimalSeparator; | ||
var _props = this.props, | ||
thousandSeparator = _props.thousandSeparator, | ||
decimalSeparator = _props.decimalSeparator; | ||
@@ -81,4 +85,4 @@ if (thousandSeparator === true) { | ||
if (decimalSeparator && thousandSeparator) { | ||
decimalSeparator = thousandSeparator === ',' ? '.' : ','; | ||
if (decimalSeparator && thousandSeparator && typeof decimalSeparator !== 'string') { | ||
decimalSeparator = thousandSeparator === '.' ? ',' : '.'; | ||
} | ||
@@ -97,13 +101,11 @@ | ||
key: 'getNumberRegex', | ||
value: function getNumberRegex(g) { | ||
var _getSeparators = this.getSeparators(); | ||
value: function getNumberRegex(g, ignoreDecimalSeperator) { | ||
var _getSeparators = this.getSeparators(), | ||
decimalSeparator = _getSeparators.decimalSeparator; | ||
var decimalSeparator = _getSeparators.decimalSeparator; | ||
return new RegExp('\\d' + (decimalSeparator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && !ignoreDecimalSeperator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
}, { | ||
key: 'setCaretPosition', | ||
value: function setCaretPosition(caretPos) { | ||
var el = this.refs.input; | ||
value: function setCaretPosition(el, caretPos) { | ||
el.value = el.value; | ||
@@ -135,5 +137,5 @@ // ^ this is used to not only get "focus", but | ||
value: function formatWithPattern(str) { | ||
var _props2 = this.props; | ||
var format = _props2.format; | ||
var mask = _props2.mask; | ||
var _props2 = this.props, | ||
format = _props2.format, | ||
mask = _props2.mask; | ||
@@ -162,12 +164,13 @@ if (!format) return str; | ||
value: function formatInput(val) { | ||
var _props3 = this.props; | ||
var prefix = _props3.prefix; | ||
var suffix = _props3.suffix; | ||
var mask = _props3.mask; | ||
var format = _props3.format; | ||
var _props3 = this.props, | ||
prefix = _props3.prefix, | ||
suffix = _props3.suffix, | ||
mask = _props3.mask, | ||
format = _props3.format; | ||
var _getSeparators2 = this.getSeparators(); | ||
var _getSeparators2 = this.getSeparators(), | ||
thousandSeparator = _getSeparators2.thousandSeparator, | ||
decimalSeparator = _getSeparators2.decimalSeparator; | ||
var thousandSeparator = _getSeparators2.thousandSeparator; | ||
var decimalSeparator = _getSeparators2.decimalSeparator; | ||
var decimalPrecision = this.props.decimalPrecision; | ||
@@ -195,5 +198,11 @@ var maskPattern = format && typeof format == 'string' && !!mask; | ||
afterDecimal = ''; | ||
var hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1; | ||
var hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1 || decimalPrecision !== false; | ||
if (decimalSeparator && hasDecimals) { | ||
var parts = formattedValue.split(decimalSeparator); | ||
var parts = void 0; | ||
if (decimalPrecision !== false) { | ||
var precision = decimalPrecision === true ? 2 : decimalPrecision; | ||
parts = parseFloat(formattedValue).toFixed(precision).split(decimalSeparator); | ||
} else { | ||
parts = formattedValue.split(decimalSeparator); | ||
} | ||
beforeDecimal = parts[0]; | ||
@@ -230,6 +239,2 @@ afterDecimal = parts[1]; | ||
//check if there is no number before caret position | ||
while (j > 0 && formattedValue[j]) { | ||
if (!formattedValue[j - 1].match(numRegex)) j--;else break; | ||
} | ||
return j; | ||
@@ -243,15 +248,21 @@ } | ||
e.persist(); | ||
var inputValue = e.target.value; | ||
var el = e.target; | ||
var inputValue = el.value; | ||
var _formatInput = this.formatInput(inputValue); | ||
var _formatInput = this.formatInput(inputValue), | ||
formattedValue = _formatInput.formattedValue, | ||
value = _formatInput.value; | ||
var formattedValue = _formatInput.formattedValue; | ||
var value = _formatInput.value; | ||
var cursorPos = el.selectionStart; | ||
var cursorPos = this.refs.input.selectionStart; | ||
//change the state | ||
this.setState({ value: formattedValue }, function () { | ||
cursorPos = _this2.getCursorPosition(inputValue, formattedValue, cursorPos); | ||
_this2.setCaretPosition(cursorPos); | ||
/* | ||
setting caret position within timeout of 0ms is required for mobile chrome, | ||
otherwise browser resets the caret position after we set it | ||
*/ | ||
setTimeout(function () { | ||
return _this2.setCaretPosition(el, cursorPos); | ||
}, 0); | ||
if (callback) callback(e, value); | ||
@@ -273,2 +284,32 @@ }); | ||
}, { | ||
key: 'onKeyDown', | ||
value: function onKeyDown(e) { | ||
var el = e.target; | ||
var selectionStart = el.selectionStart, | ||
selectionEnd = el.selectionEnd, | ||
value = el.value; | ||
var decimalPrecision = this.props.decimalPrecision; | ||
var key = e.key; | ||
var numRegex = this.getNumberRegex(false, decimalPrecision !== false); | ||
//Handle backspace and delete against non numerical/decimal characters | ||
if (selectionEnd - selectionStart === 0) { | ||
if (key === 'Delete' && !numRegex.test(value[selectionStart])) { | ||
e.preventDefault(); | ||
var nextCursorPosition = selectionStart; | ||
while (!numRegex.test(value[nextCursorPosition]) && nextCursorPosition < value.length) { | ||
nextCursorPosition++; | ||
}this.setCaretPosition(el, nextCursorPosition); | ||
} else if (key === 'Backspace' && !numRegex.test(value[selectionStart - 1])) { | ||
e.preventDefault(); | ||
var prevCursorPosition = selectionStart; | ||
while (!numRegex.test(value[prevCursorPosition - 1]) && prevCursorPosition > 0) { | ||
prevCursorPosition--; | ||
}this.setCaretPosition(el, prevCursorPosition); | ||
} | ||
} | ||
if (this.props.onKeyDown) this.props.onKeyDown(e); | ||
} | ||
}, { | ||
key: 'render', | ||
@@ -282,2 +323,10 @@ value: function render() { | ||
var inputProps = _extends({}, props, { | ||
type: 'tel', | ||
value: this.state.value, | ||
onInput: this.onChange, | ||
onChange: this.onChange, | ||
onKeyDown: this.onKeyDown | ||
}); | ||
if (this.props.displayType === 'text') { | ||
@@ -289,10 +338,8 @@ return _react2.default.createElement( | ||
); | ||
} else if (this.props.customInput) { | ||
var CustomInput = this.props.customInput; | ||
return _react2.default.createElement(CustomInput, inputProps); | ||
} | ||
return _react2.default.createElement('input', _extends({}, props, { | ||
type: 'tel', | ||
value: this.state.value, | ||
ref: 'input', | ||
onInput: this.onChange, | ||
onChange: this.onChange | ||
})); | ||
return _react2.default.createElement('input', inputProps); | ||
} | ||
@@ -299,0 +346,0 @@ }]); |
{ | ||
"name": "react-number-format", | ||
"description": "React component to format number in an input or as a text.", | ||
"version": "1.0.2", | ||
"version": "1.1.0-alpha2", | ||
"main": "lib/number_format.js", | ||
@@ -42,2 +42,3 @@ "author": "Sudhanshu Yadav", | ||
"classnames": "^2.2.3", | ||
"cross-env": "^3.1.4", | ||
"eslint": "^2.5.3", | ||
@@ -61,2 +62,3 @@ "eslint-config-standard": "^5.1.0", | ||
"karma-webpack": "^1.7.0", | ||
"material-ui": "^0.16.7", | ||
"react": "^15.0.1", | ||
@@ -63,0 +65,0 @@ "react-addons-test-utils": "^15.0.1", |
@@ -20,4 +20,5 @@ # react-number-format | ||
| ------------- |-------------| -----| -------- | | ||
| thousandSeparator | mixed: true/false (boolean) or ,/. (string) | false | Add thousand separators on number | | ||
| decimalSeparator | mixed: ./, (string) or true/false (boolean)| . | Support decimal point on a number | | ||
| thousandSeparator | mixed: single character string or true/false (boolean) | false | Add thousand separators on number | | ||
| decimalSeparator | mixed: single character string or true/false (boolean)| . | Support decimal point on a number | | ||
| decimalPrecision | mixed: number or boolean | false (2 if true)| If false it does not limit decimal place, if true default precision is 2 or else limits to provided decimal place | | ||
| prefix | String (ex : $) | none | Add a prefix before the number | | ||
@@ -29,5 +30,6 @@ | suffix | String (ex : /-) | none | Add a prefix after the number | | ||
| mask | String (ex : _) | none | If mask defined, component will show non entered placed with masked value. | ||
| customInput | Component Reference | input | This allow supporting custom inputs with number format. See details | ||
| onChange | (e, value) => {} | none | onChange handler accepts event object through which you can get formattedValue (e.targe.value # $2,223) and second parameter non formatted value (ie: 2223) | ||
Other than this it accepts all the props which can be given to a input or span based on displayType you selected. | ||
**Other than this it accepts all the props which can be given to a input or span based on displayType you selected.** | ||
@@ -93,2 +95,19 @@ ### Examples | ||
### Custom Inputs | ||
You can easily extend your custom input with number format. But custom input should have all input props. | ||
```jsx | ||
import TextField from 'material-ui/TextField'; | ||
``` | ||
```jsx | ||
<NumberFormat customInput={TextField} format="#### #### #### ####"/> | ||
``` | ||
**Passing custom input props** | ||
All custom input props and number input props are passed together. | ||
```jsx | ||
<NumberFormat hintText="Some placeholder" value={this.state.card} customInput={TextField} format="#### #### #### ####"/> | ||
``` | ||
### Live Demo | ||
@@ -95,0 +114,0 @@ [http://codepen.io/s-yadav/pen/bpKNMa](http://codepen.io/s-yadav/pen/bpKNMa) |
@@ -9,4 +9,5 @@ //const React = require('react'); | ||
const propTypes = { | ||
thousandSeparator: PropTypes.oneOf([',', '.', true, false]), | ||
decimalSeparator: PropTypes.oneOf([',', '.', true, false]), | ||
thousandSeparator: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), | ||
decimalSeparator: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), | ||
decimalPrecision: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]), | ||
displayType: PropTypes.oneOf(['input', 'text']), | ||
@@ -23,3 +24,4 @@ prefix: PropTypes.string, | ||
PropTypes.string | ||
]) | ||
]), | ||
customInput: PropTypes.func | ||
}; | ||
@@ -29,3 +31,4 @@ | ||
displayType: 'input', | ||
decimalSeparator: '.' | ||
decimalSeparator: '.', | ||
decimalPrecision: false | ||
}; | ||
@@ -41,2 +44,3 @@ | ||
this.onInput = this.onInput.bind(this); | ||
this.onKeyDown = this.onKeyDown.bind(this); | ||
} | ||
@@ -58,4 +62,4 @@ | ||
if (decimalSeparator && thousandSeparator) { | ||
decimalSeparator = thousandSeparator === ',' ? '.' : ','; | ||
if (decimalSeparator && thousandSeparator && typeof decimalSeparator !== 'string') { | ||
decimalSeparator = thousandSeparator === '.' ? ',' : '.'; | ||
} | ||
@@ -73,32 +77,30 @@ | ||
getNumberRegex(g) { | ||
getNumberRegex(g, ignoreDecimalSeperator) { | ||
const {decimalSeparator} = this.getSeparators(); | ||
return new RegExp('\\d' + (decimalSeparator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
return new RegExp('\\d' + (decimalSeparator && !ignoreDecimalSeperator ? '|' + escapeRegExp(decimalSeparator) : ''), g ? 'g' : undefined); | ||
} | ||
setCaretPosition(caretPos) { | ||
const el = this.refs.input; | ||
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) { | ||
const 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; | ||
} | ||
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) { | ||
const 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; | ||
} | ||
// fail city, fortunately this never happens (as far as I've tested) :) | ||
el.focus(); | ||
return false; | ||
} | ||
} | ||
@@ -130,3 +132,4 @@ | ||
const {prefix, suffix, mask, format} = this.props; | ||
const {thousandSeparator, decimalSeparator} = this.getSeparators() | ||
const {thousandSeparator, decimalSeparator} = this.getSeparators(); | ||
const {decimalPrecision} = this.props; | ||
const maskPattern = format && typeof format == 'string' && !!mask; | ||
@@ -154,5 +157,11 @@ | ||
let beforeDecimal = formattedValue, afterDecimal = ''; | ||
const hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1; | ||
const hasDecimals = formattedValue.indexOf(decimalSeparator) !== -1 || decimalPrecision !== false; | ||
if(decimalSeparator && hasDecimals) { | ||
const parts = formattedValue.split(decimalSeparator) | ||
let parts; | ||
if (decimalPrecision !== false) { | ||
const precision = decimalPrecision === true ? 2 : decimalPrecision; | ||
parts = parseFloat(formattedValue).toFixed(precision).split(decimalSeparator); | ||
} else { | ||
parts = formattedValue.split(decimalSeparator); | ||
} | ||
beforeDecimal = parts[0]; | ||
@@ -168,3 +177,3 @@ afterDecimal = parts[1]; | ||
formattedValue = beforeDecimal + (hasDecimals && decimalSeparator || '') + afterDecimal; | ||
formattedValue = beforeDecimal + (hasDecimals && decimalSeparator || '') + afterDecimal; | ||
} | ||
@@ -188,7 +197,2 @@ | ||
//check if there is no number before caret position | ||
while(j > 0 && formattedValue[j]){ | ||
if(!formattedValue[j-1].match(numRegex)) j--; | ||
else break; | ||
} | ||
return j; | ||
@@ -199,5 +203,6 @@ } | ||
e.persist(); | ||
const inputValue = e.target.value; | ||
const el = e.target; | ||
const inputValue = el.value; | ||
const {formattedValue,value} = this.formatInput(inputValue); | ||
let cursorPos = this.refs.input.selectionStart; | ||
let cursorPos = el.selectionStart; | ||
@@ -207,3 +212,7 @@ //change the state | ||
cursorPos = this.getCursorPosition(inputValue, formattedValue, cursorPos ); | ||
this.setCaretPosition(cursorPos); | ||
/* | ||
setting caret position within timeout of 0ms is required for mobile chrome, | ||
otherwise browser resets the caret position after we set it | ||
*/ | ||
setTimeout(() => this.setCaretPosition(el, cursorPos), 0); | ||
if(callback) callback(e,value); | ||
@@ -221,2 +230,25 @@ }); | ||
} | ||
onKeyDown(e) { | ||
const el = e.target; | ||
const {selectionStart, selectionEnd, value} = el; | ||
const {decimalPrecision} = this.props; | ||
const {key} = e; | ||
const numRegex = this.getNumberRegex(false, decimalPrecision !== false); | ||
//Handle backspace and delete against non numerical/decimal characters | ||
if(selectionEnd - selectionStart === 0) { | ||
if (key === 'Delete' && !numRegex.test(value[selectionStart])) { | ||
e.preventDefault(); | ||
let nextCursorPosition = selectionStart; | ||
while (!numRegex.test(value[nextCursorPosition]) && nextCursorPosition < value.length) nextCursorPosition++; | ||
this.setCaretPosition(el, nextCursorPosition); | ||
} else if (key === 'Backspace' && !numRegex.test(value[selectionStart - 1])) { | ||
e.preventDefault(); | ||
let prevCursorPosition = selectionStart; | ||
while (!numRegex.test(value[prevCursorPosition - 1]) && prevCursorPosition > 0) prevCursorPosition--; | ||
this.setCaretPosition(el, prevCursorPosition); | ||
} | ||
} | ||
if (this.props.onKeyDown) this.props.onKeyDown(e); | ||
} | ||
render() { | ||
@@ -229,14 +261,26 @@ const props = Object.assign({}, this.props); | ||
const inputProps = Object.assign({}, props, { | ||
type:'tel', | ||
value:this.state.value, | ||
onInput:this.onChange, | ||
onChange:this.onChange, | ||
onKeyDown:this.onKeyDown, | ||
}) | ||
if(this.props.displayType === 'text'){ | ||
if( this.props.displayType === 'text'){ | ||
return (<span {...props}>{this.state.value}</span>); | ||
} | ||
else if (this.props.customInput) { | ||
const CustomInput = this.props.customInput; | ||
return ( | ||
<CustomInput | ||
{...inputProps} | ||
/> | ||
) | ||
} | ||
return ( | ||
<input | ||
{...props} | ||
type="tel" | ||
value={this.state.value} | ||
ref="input" | ||
onInput={this.onChange} | ||
onChange={this.onChange} | ||
{...inputProps} | ||
/> | ||
@@ -243,0 +287,0 @@ ) |
@@ -182,2 +182,70 @@ import React from 'react'; | ||
}); | ||
it('should round to passed decimal precision', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput decimalPrecision={4}/>); | ||
const input = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'input' | ||
); | ||
//case 1st - already exactly precision 4 should stay that way | ||
input.value = "4111.1111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.1111"); | ||
//case 2nd - longer precision should round | ||
input.value = "4111.11111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.1111"); | ||
//case 3rd - shorter precision adds 0 | ||
input.value = "4111.111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.1110"); | ||
//case 4th - no decimal should round with 4 zeros | ||
input.value = "4111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.0000"); | ||
}); | ||
it('should not round by default', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput />); | ||
const input = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'input' | ||
); | ||
//case 1st - no rounding with long decimal | ||
input.value = "4111.111111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.111111"); | ||
//case 2nd - no rounding with whole numbers | ||
input.value = "4111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111"); | ||
//case 3rd - no rounding on single place decimals | ||
input.value = "4111.1"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.1"); | ||
}); | ||
it('should round default 2 places', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput decimalPrecision={true} />); | ||
const input = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'input' | ||
); | ||
//case 1st - auto round to 2 places | ||
input.value = "4111.1111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.11"); | ||
//case 2nd - auto round whole integers | ||
input.value = "4111"; | ||
ReactTestUtils.Simulate.change(input); | ||
expect(input.value).toEqual("4111.00"); | ||
}); | ||
}); | ||
@@ -226,2 +294,26 @@ | ||
}); | ||
it('should not round decimals by defualt', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput value="4111" displayType={'text'} />); | ||
const span = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'span' | ||
); | ||
expect(span.textContent).toEqual("4111"); | ||
}); | ||
it('should round to 2 decimals if passed true', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput value="4111" displayType={'text'} decimalPrecision={true} />); | ||
const span = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'span' | ||
); | ||
expect(span.textContent).toEqual("4111.00"); | ||
}); | ||
it('should round to 4 decimals if passed 4', () => { | ||
const component = ReactTestUtils.renderIntoDocument(<FormatNumberInput value="4111.11" displayType={'text'} decimalPrecision={4} />); | ||
const span = ReactTestUtils.findRenderedDOMComponentWithTag( | ||
component, 'span' | ||
); | ||
expect(span.textContent).toEqual("4111.1100"); | ||
}); | ||
}); |
@@ -10,3 +10,3 @@ module.exports = { | ||
output: { | ||
publicPath: "http://localhost:8080/", | ||
publicPath: "http://localhost:9000/", | ||
// path: path.join(__dirname, "public","js"), | ||
@@ -13,0 +13,0 @@ filename: '[name].js' |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
88543
1703
132
36
3