diff --git a/__tests__/misc.test.jsx b/__tests__/misc.test.jsx index 66ac010..afe8ded 100644 --- a/__tests__/misc.test.jsx +++ b/__tests__/misc.test.jsx @@ -44,7 +44,7 @@ describe ('NumericInput/misc', function() { * * @see https://github.com/vlad-ignatov/react-numeric-input/issues/19 */ - it ('onChange get called properly with `min`', done => { + it ('onChange gets called properly with `min`', done => { let log = [] let widget = TestUtils.renderIntoDocument( @@ -99,4 +99,25 @@ describe ('NumericInput/misc', function() { done() }) } + + /** + * onChange gets called when input content is deleted + * @see https://github.com/vlad-ignatov/react-numeric-input/issues/27 + */ + it ('onChange gets called when input content is deleted', done => { + let log = [] + let widget = TestUtils.renderIntoDocument( + log.push(...args)}/> + ) + let input = widget.refs.input + + TestUtils.Simulate.focus(input) + input.value = 2 + TestUtils.Simulate.change(input) + expect(log).toEqual([2,'2']) + input.value = "" + TestUtils.Simulate.change(input) + expect(log).toEqual([2,'2',null,""]) + done() + }) }) diff --git a/dist/react-numeric-input.js b/dist/react-numeric-input.js index fa2eec5..4811998 100644 --- a/dist/react-numeric-input.js +++ b/dist/react-numeric-input.js @@ -229,7 +229,7 @@ return /******/ (function(modules) { // webpackBootstrap // Call the onChange if needed. This is placed here because there are // many reasons for changing the value and this is the common place // that can capture them all - if (prevState.value !== this.state.value && !isNaN(this.state.value)) { + if (prevState.value !== this.state.value && (!isNaN(this.state.value) || this.state.value === null)) { this._invokeEventCallback("onChange", this.state.value, this.refs.input.value); } @@ -804,7 +804,11 @@ return /******/ (function(modules) { // webpackBootstrap _extends(attrs.input, { onChange: function onChange(e) { - _this5.setState({ value: _this5._parse(e.target.value) }); + var val = _this5._parse(e.target.value); + if (isNaN(val)) { + val = null; + } + _this5.setState({ value: val }); }, onKeyDown: this._onKeyDown.bind(this), onInput: function onInput() { diff --git a/dist/react-numeric-input.min.js b/dist/react-numeric-input.min.js index 0b4a964..434be19 100644 --- a/dist/react-numeric-input.min.js +++ b/dist/react-numeric-input.min.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("React")):"function"==typeof define&&define.amd?define(["React"],e):"object"==typeof exports?exports.NumericInput=e(require("React")):t.NumericInput=e(t.React)}(this,function(t){return function(t){function e(o){if(n[o])return n[o].exports;var s=n[o]={exports:{},id:o,loaded:!1};return t[o].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function o(t){return t&&t.__esModule?t:{"default":t}}function s(t,e){var n={};for(var o in t)e.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(t,o)&&(n[o]=t[o]);return n}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function i(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t,e){return t.classList?t.classList.add(e):void(t.className.search(new RegExp("\\b"+e+"\\b"))||(t.className=" "+e))}function p(t,e){if(t.className){if(t.classList)return t.classList.remove(e);t.className=t.className.replace(new RegExp("\\b"+e+"\\b","g"),"")}}var l=Object.assign||function(t){for(var e=1;es;s++)o[s]=arguments[s];var i=a(this,(t=Object.getPrototypeOf(e)).call.apply(t,[this].concat(o)));return i.state={selectionStart:null,selectionEnd:null,value:"value"in i.props?i.props.value:i.props.defaultValue,btnDownHover:!1,btnDownActive:!1,btnUpHover:!1,btnUpActive:!1,inputFocus:!1},i.stop=i.stop.bind(i),i}return i(e,t),c(e,[{key:"componentWillReceiveProps",value:function(t){var e=String(t.value||0===t.value?t.value:"").replace(/^\s*|\s*$/,"");this.setState({value:"value"in t&&""!==e?this._parse(e):null})}},{key:"componentWillUpdate",value:function(){this.saveSelection()}},{key:"componentDidUpdate",value:function(t,e){e.value===this.state.value||isNaN(this.state.value)||this._invokeEventCallback("onChange",this.state.value,this.refs.input.value),this.state.inputFocus&&(this.refs.input.focus(),(this.state.selectionStart||0===this.state.selectionStart)&&(this.refs.input.selectionStart=this.state.selectionStart),(this.state.selectionEnd||0===this.state.selectionEnd)&&(this.refs.input.selectionEnd=this.state.selectionEnd)),this.checkValidity()}},{key:"componentWillUnmount",value:function(){this.stop()}},{key:"componentDidMount",value:function(){var t=this;this.refs.input.getValueAsNumber=function(){return t.state.value||0},this.refs.input.setValue=function(e){t.setState({value:t._parse(e)})},!this.state.inputFocus&&b&&document.activeElement===this.refs.input&&(this.state.inputFocus=!0,this.refs.input.focus(),this._invokeEventCallback("onFocus",{target:this.refs.input,type:"focus"})),this.checkValidity()}},{key:"saveSelection",value:function(){this.state.selectionStart=this.refs.input.selectionStart,this.state.selectionEnd=this.refs.input.selectionEnd}},{key:"checkValidity",value:function(){var t=void 0,e="",n=!!this.refs.input.checkValidity,o=!(!this.props.noValidate||"false"==this.props.noValidate);this.refs.input.noValidate=o,t=o||!n,t?e="":(""===this.refs.input.pattern&&(this.refs.input.pattern=this.props.required?".+":".*"),n&&(this.refs.input.checkValidity(),t=this.refs.input.validity.valid,t||(e=this.refs.input.validationMessage)),t&&n&&this.props.maxLength&&this.refs.input.value.length>this.props.maxLength&&(e="This value is too long")),e=e||(t?"":this.refs.input.validationMessage||"Unknown Error");var s=this._valid!==e;this._valid=e,e?(u(this.refs.wrapper,"has-error"),s&&this._invokeEventCallback("onInvalid",e,this.state.value,this.refs.input.value)):(p(this.refs.wrapper,"has-error"),s&&this._invokeEventCallback("onValid",this.state.value,this.refs.input.value))}},{key:"_toNumber",value:function(t,e){e=void 0===e?this.state.inputFocus&&!(this.state.btnDownActive||this.state.btnUpActive):!!e;var n=parseFloat(t),o=Math.pow(10,this.props.precision);return(isNaN(n)||!isFinite(n))&&(n=0),e?n:(n=Math.min(Math.max(n,this.props.min),this.props.max),n=Math.round(n*o)/o)}},{key:"_parse",value:function(t){return"function"==typeof this.props.parse?parseFloat(this.props.parse(t)):parseFloat(t)}},{key:"_format",value:function(t){var e=this._toNumber(t).toFixed(this.props.precision);return this.props.format?this.props.format(e):e}},{key:"_step",value:function(t,e){var n=this._toNumber((this.state.value||0)+this.props.step*t,!1);return n!==this.state.value?(this.setState({value:n},e),!0):!1}},{key:"_onChange",value:function(t){this.setState({value:this._parse(t.target.value)})}},{key:"_onKeyDown",value:function(){for(var t=arguments.length,e=Array(t),n=0;t>n;n++)e[n]=arguments[n];e[0].persist(),this._invokeEventCallback.apply(this,["onKeyDown"].concat(e));var o=e[0];o.isDefaultPrevented()||(o.keyCode===v?(o.preventDefault(),this._step(o.ctrlKey||o.metaKey?.1:o.shiftKey?10:1)):o.keyCode===d&&(o.preventDefault(),this._step(o.ctrlKey||o.metaKey?-.1:o.shiftKey?-10:-1)))}},{key:"stop",value:function(){this._timer&&clearTimeout(this._timer)}},{key:"increase",value:function(){var t=this,n=arguments.length<=0||void 0===arguments[0]?!1:arguments[0],o=arguments[1];this.stop(),this._step(1,o),(isNaN(this.state.value)||this.state.valuethis.props.min)&&(this._timer=setTimeout(function(){t.decrease(!0)},n?e.SPEED:e.DELAY))}},{key:"onMouseDown",value:function(t,e){"down"==t?this.decrease(!1,e):"up"==t&&this.increase(!1,e)}},{key:"onTouchStart",value:function(t,e){e.preventDefault(),"down"==t?this.decrease():"up"==t&&this.increase()}},{key:"_invokeEventCallback",value:function(t){if("function"==typeof this.props[t]){for(var e,n=arguments.length,o=Array(n>1?n-1:0),s=1;n>s;s++)o[s-1]=arguments[s];(e=this.props[t]).call.apply(e,[null].concat(o))}}},{key:"render",value:function(){var t=this,n=this.props,o=this.state,r={},a=this.props,i=(a.step,a.min,a.max,a.precision,a.parse,a.format,a.mobile),u=(a.value,a.type,a.style),p=(a.defaultValue,a.onInvalid,a.onValid,s(a,["step","min","max","precision","parse","format","mobile","value","type","style","defaultValue","onInvalid","onValid"]));for(var c in e.style)r[c]=l({},e.style[c],u?u[c]||{}:{});var h=n.className&&/\bform-control\b/.test(n.className);"auto"==i&&(i=b&&"ontouchstart"in document),"function"==typeof i&&(i=i.call(this)),i=!!i;var v={wrap:{style:u===!1?null:r.wrap,className:"react-numeric-input",ref:"wrapper",onMouseUp:void 0,onMouseLeave:void 0},input:l({ref:"input",type:"text",style:u===!1?null:l({},r.input,h?{}:r["input:not(.form-control)"],o.inputFocus?r["input:focus"]:{})},p),btnUp:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:l({},r.btn,r.btnUp,n.disabled?r["btn:disabled"]:o.btnUpActive?r["btn:active"]:o.btnUpHover?r["btn:hover"]:{})},btnDown:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:l({},r.btn,r.btnDown,n.disabled?r["btn:disabled"]:o.btnDownActive?r["btn:active"]:o.btnDownHover?r["btn:hover"]:{})}};return o.value||0===o.value?v.input.value=this._format(o.value):v.input.value="",h&&u!==!1&&l(v.wrap.style,r["wrap.hasFormControl"]),i&&u!==!1&&(l(v.input.style,r["input.mobile"]),l(v.btnUp.style,r["btnUp.mobile"]),l(v.btnDown.style,r["btnDown.mobile"])),n.disabled?u!==!1&&l(v.input.style,r["input:disabled"]):(l(v.wrap,{onMouseUp:this.stop,onMouseLeave:this.stop}),l(v.btnUp,{onTouchStart:this.onTouchStart.bind(this,"up"),onTouchEnd:this.stop,onMouseEnter:function(){t.setState({btnUpHover:!0})},onMouseLeave:function(){t.stop(),t.setState({btnUpHover:!1,btnUpActive:!1})},onMouseUp:function(){t.setState({btnUpHover:!0,btnUpActive:!1})},onMouseDown:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].preventDefault(),n[0].persist(),t.setState({btnUpHover:!0,btnUpActive:!0,inputFocus:!0},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))}),t.onMouseDown("up")}}),l(v.btnDown,{onTouchStart:this.onTouchStart.bind(this,"down"),onTouchEnd:this.stop,onMouseEnter:function(){t.setState({btnDownHover:!0})},onMouseLeave:function(){t.stop(),t.setState({btnDownHover:!1,btnDownActive:!1})},onMouseUp:function(){t.setState({btnDownHover:!0,btnDownActive:!1})},onMouseDown:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].preventDefault(),n[0].persist(),t.setState({btnDownHover:!0,btnDownActive:!0,inputFocus:!0},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))}),t.onMouseDown("down")}}),l(v.input,{onChange:function(e){t.setState({value:t._parse(e.target.value)})},onKeyDown:this._onKeyDown.bind(this),onInput:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];t.saveSelection(),t._invokeEventCallback.apply(t,["onInput"].concat(n))},onSelect:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];t.saveSelection(),t._invokeEventCallback.apply(t,["onSelect"].concat(n))},onFocus:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].persist(),t.setState({inputFocus:!0},function(){t.setState({value:t._parse(n[0].target.value)},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))})})},onBlur:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].persist(),t.setState({inputFocus:!1},function(){t.setState({value:t._parse(n[0].target.value)},function(){t._invokeEventCallback.apply(t,["onBlur"].concat(n))})})}})),i?f["default"].createElement("span",v.wrap,f["default"].createElement("input",v.input),f["default"].createElement("b",v.btnUp,f["default"].createElement("i",{style:u===!1?null:r.minus}),f["default"].createElement("i",{style:u===!1?null:r.plus})),f["default"].createElement("b",v.btnDown,f["default"].createElement("i",{style:u===!1?null:r.minus}))):f["default"].createElement("span",v.wrap,f["default"].createElement("input",v.input),f["default"].createElement("b",v.btnUp,f["default"].createElement("i",{style:u===!1?null:r.arrowUp})),f["default"].createElement("b",v.btnDown,f["default"].createElement("i",{style:u===!1?null:r.arrowDown})))}}]),e}(h.Component);y.propTypes={step:h.PropTypes.number,min:h.PropTypes.number,max:h.PropTypes.number,precision:h.PropTypes.number,maxLength:h.PropTypes.number,parse:h.PropTypes.func,format:h.PropTypes.func,className:h.PropTypes.string,disabled:h.PropTypes.bool,readOnly:h.PropTypes.bool,required:h.PropTypes.bool,noValidate:h.PropTypes.oneOfType([h.PropTypes.bool,h.PropTypes.string]),style:h.PropTypes.oneOfType([h.PropTypes.object,h.PropTypes.bool]),type:h.PropTypes.string,pattern:h.PropTypes.string,onFocus:h.PropTypes.func,onBlur:h.PropTypes.func,onKeyDown:h.PropTypes.func,onChange:h.PropTypes.func,onInvalid:h.PropTypes.func,onValid:h.PropTypes.func,onInput:h.PropTypes.func,onSelect:h.PropTypes.func,size:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),value:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),defaultValue:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),mobile:function(t,e){var n=t[e];return n!==!0&&n!==!1&&"auto"!==n&&"function"!=typeof n?new Error('The "mobile" prop must be true, false, "auto" or a function'):void 0}},y.defaultProps={step:1,min:Number.MIN_SAFE_INTEGER||-9007199254740991,max:Number.MAX_SAFE_INTEGER||9007199254740991,precision:0,parse:null,format:null,mobile:"auto",style:{}},y.style={wrap:{position:"relative",display:"inline-block"},"wrap.hasFormControl":{display:"block"},arrowUp:{position:"absolute",top:"50%",left:"50%",width:0,height:0,borderWidth:"0 0.6ex 0.6ex 0.6ex",borderColor:"transparent transparent rgba(0, 0, 0, 0.7)",borderStyle:"solid",margin:"-0.3ex 0 0 -0.56ex"},arrowDown:{position:"absolute",top:"50%",left:"50%",width:0,height:0,borderWidth:"0.6ex 0.6ex 0 0.6ex",borderColor:"rgba(0, 0, 0, 0.7) transparent transparent",borderStyle:"solid",margin:"-0.3ex 0 0 -0.56ex"},plus:{position:"absolute",top:"50%",left:"50%",width:2,height:10,background:"rgba(0,0,0,.7)",margin:"-5px 0 0 -1px"},minus:{position:"absolute",top:"50%",left:"50%",width:10,height:2,background:"rgba(0,0,0,.7)",margin:"-1px 0 0 -5px"},btn:{position:"absolute",right:2,width:"2.26ex",borderColor:"rgba(0,0,0,.1)",borderStyle:"solid",textAlign:"center",cursor:"default",transition:"all 0.1s",background:"rgba(0,0,0,.1)",boxShadow:"-1px -1px 3px rgba(0,0,0,.1) inset,\n 1px 1px 3px rgba(255,255,255,.7) inset"},btnUp:{top:2,bottom:"50%",borderRadius:"2px 2px 0 0",borderWidth:"1px 1px 0 1px"},"btnUp.mobile":{width:"3.3ex",bottom:2,boxShadow:"none",borderRadius:2,borderWidth:1},btnDown:{top:"50%",bottom:2,borderRadius:"0 0 2px 2px",borderWidth:"0 1px 1px 1px"},"btnDown.mobile":{width:"3.3ex",bottom:2,left:2,top:2,right:"auto",boxShadow:"none",borderRadius:2,borderWidth:1},"btn:hover":{background:"rgba(0,0,0,.2)"},"btn:active":{background:"rgba(0,0,0,.3)",boxShadow:"0 1px 3px rgba(0,0,0,.2) inset,\n -1px -1px 4px rgba(255,255,255,.5) inset"},"btn:disabled":{opacity:.5,boxShadow:"none",cursor:"not-allowed"},input:{paddingRight:"3ex",boxSizing:"border-box"},"input:not(.form-control)":{border:"1px solid #ccc",borderRadius:2,paddingLeft:4,display:"block",WebkitAppearance:"none",lineHeight:"normal"},"input.mobile":{paddingLeft:" 3.4ex",paddingRight:"3.4ex",textAlign:"center"},"input:focus":{},"input:disabled":{color:"rgba(0, 0, 0, 0.3)",textShadow:"0 1px 0 rgba(255, 255, 255, 0.8)"}},y.SPEED=50,y.DELAY=500,t.exports=y},function(e,n){e.exports=t}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("React")):"function"==typeof define&&define.amd?define(["React"],e):"object"==typeof exports?exports.NumericInput=e(require("React")):t.NumericInput=e(t.React)}(this,function(t){return function(t){function e(o){if(n[o])return n[o].exports;var s=n[o]={exports:{},id:o,loaded:!1};return t[o].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function o(t){return t&&t.__esModule?t:{"default":t}}function s(t,e){var n={};for(var o in t)e.indexOf(o)>=0||Object.prototype.hasOwnProperty.call(t,o)&&(n[o]=t[o]);return n}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function i(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t,e){return t.classList?t.classList.add(e):void(t.className.search(new RegExp("\\b"+e+"\\b"))||(t.className=" "+e))}function p(t,e){if(t.className){if(t.classList)return t.classList.remove(e);t.className=t.className.replace(new RegExp("\\b"+e+"\\b","g"),"")}}var l=Object.assign||function(t){for(var e=1;es;s++)o[s]=arguments[s];var i=a(this,(t=Object.getPrototypeOf(e)).call.apply(t,[this].concat(o)));return i.state={selectionStart:null,selectionEnd:null,value:"value"in i.props?i.props.value:i.props.defaultValue,btnDownHover:!1,btnDownActive:!1,btnUpHover:!1,btnUpActive:!1,inputFocus:!1},i.stop=i.stop.bind(i),i}return i(e,t),c(e,[{key:"componentWillReceiveProps",value:function(t){var e=String(t.value||0===t.value?t.value:"").replace(/^\s*|\s*$/,"");this.setState({value:"value"in t&&""!==e?this._parse(e):null})}},{key:"componentWillUpdate",value:function(){this.saveSelection()}},{key:"componentDidUpdate",value:function(t,e){e.value===this.state.value||isNaN(this.state.value)&&null!==this.state.value||this._invokeEventCallback("onChange",this.state.value,this.refs.input.value),this.state.inputFocus&&(this.refs.input.focus(),(this.state.selectionStart||0===this.state.selectionStart)&&(this.refs.input.selectionStart=this.state.selectionStart),(this.state.selectionEnd||0===this.state.selectionEnd)&&(this.refs.input.selectionEnd=this.state.selectionEnd)),this.checkValidity()}},{key:"componentWillUnmount",value:function(){this.stop()}},{key:"componentDidMount",value:function(){var t=this;this.refs.input.getValueAsNumber=function(){return t.state.value||0},this.refs.input.setValue=function(e){t.setState({value:t._parse(e)})},!this.state.inputFocus&&b&&document.activeElement===this.refs.input&&(this.state.inputFocus=!0,this.refs.input.focus(),this._invokeEventCallback("onFocus",{target:this.refs.input,type:"focus"})),this.checkValidity()}},{key:"saveSelection",value:function(){this.state.selectionStart=this.refs.input.selectionStart,this.state.selectionEnd=this.refs.input.selectionEnd}},{key:"checkValidity",value:function(){var t=void 0,e="",n=!!this.refs.input.checkValidity,o=!(!this.props.noValidate||"false"==this.props.noValidate);this.refs.input.noValidate=o,t=o||!n,t?e="":(""===this.refs.input.pattern&&(this.refs.input.pattern=this.props.required?".+":".*"),n&&(this.refs.input.checkValidity(),t=this.refs.input.validity.valid,t||(e=this.refs.input.validationMessage)),t&&n&&this.props.maxLength&&this.refs.input.value.length>this.props.maxLength&&(e="This value is too long")),e=e||(t?"":this.refs.input.validationMessage||"Unknown Error");var s=this._valid!==e;this._valid=e,e?(u(this.refs.wrapper,"has-error"),s&&this._invokeEventCallback("onInvalid",e,this.state.value,this.refs.input.value)):(p(this.refs.wrapper,"has-error"),s&&this._invokeEventCallback("onValid",this.state.value,this.refs.input.value))}},{key:"_toNumber",value:function(t,e){e=void 0===e?this.state.inputFocus&&!(this.state.btnDownActive||this.state.btnUpActive):!!e;var n=parseFloat(t),o=Math.pow(10,this.props.precision);return(isNaN(n)||!isFinite(n))&&(n=0),e?n:(n=Math.min(Math.max(n,this.props.min),this.props.max),n=Math.round(n*o)/o)}},{key:"_parse",value:function(t){return"function"==typeof this.props.parse?parseFloat(this.props.parse(t)):parseFloat(t)}},{key:"_format",value:function(t){var e=this._toNumber(t).toFixed(this.props.precision);return this.props.format?this.props.format(e):e}},{key:"_step",value:function(t,e){var n=this._toNumber((this.state.value||0)+this.props.step*t,!1);return n!==this.state.value?(this.setState({value:n},e),!0):!1}},{key:"_onChange",value:function(t){this.setState({value:this._parse(t.target.value)})}},{key:"_onKeyDown",value:function(){for(var t=arguments.length,e=Array(t),n=0;t>n;n++)e[n]=arguments[n];e[0].persist(),this._invokeEventCallback.apply(this,["onKeyDown"].concat(e));var o=e[0];o.isDefaultPrevented()||(o.keyCode===v?(o.preventDefault(),this._step(o.ctrlKey||o.metaKey?.1:o.shiftKey?10:1)):o.keyCode===d&&(o.preventDefault(),this._step(o.ctrlKey||o.metaKey?-.1:o.shiftKey?-10:-1)))}},{key:"stop",value:function(){this._timer&&clearTimeout(this._timer)}},{key:"increase",value:function(){var t=this,n=arguments.length<=0||void 0===arguments[0]?!1:arguments[0],o=arguments[1];this.stop(),this._step(1,o),(isNaN(this.state.value)||this.state.valuethis.props.min)&&(this._timer=setTimeout(function(){t.decrease(!0)},n?e.SPEED:e.DELAY))}},{key:"onMouseDown",value:function(t,e){"down"==t?this.decrease(!1,e):"up"==t&&this.increase(!1,e)}},{key:"onTouchStart",value:function(t,e){e.preventDefault(),"down"==t?this.decrease():"up"==t&&this.increase()}},{key:"_invokeEventCallback",value:function(t){if("function"==typeof this.props[t]){for(var e,n=arguments.length,o=Array(n>1?n-1:0),s=1;n>s;s++)o[s-1]=arguments[s];(e=this.props[t]).call.apply(e,[null].concat(o))}}},{key:"render",value:function(){var t=this,n=this.props,o=this.state,r={},a=this.props,i=(a.step,a.min,a.max,a.precision,a.parse,a.format,a.mobile),u=(a.value,a.type,a.style),p=(a.defaultValue,a.onInvalid,a.onValid,s(a,["step","min","max","precision","parse","format","mobile","value","type","style","defaultValue","onInvalid","onValid"]));for(var c in e.style)r[c]=l({},e.style[c],u?u[c]||{}:{});var h=n.className&&/\bform-control\b/.test(n.className);"auto"==i&&(i=b&&"ontouchstart"in document),"function"==typeof i&&(i=i.call(this)),i=!!i;var v={wrap:{style:u===!1?null:r.wrap,className:"react-numeric-input",ref:"wrapper",onMouseUp:void 0,onMouseLeave:void 0},input:l({ref:"input",type:"text",style:u===!1?null:l({},r.input,h?{}:r["input:not(.form-control)"],o.inputFocus?r["input:focus"]:{})},p),btnUp:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:l({},r.btn,r.btnUp,n.disabled?r["btn:disabled"]:o.btnUpActive?r["btn:active"]:o.btnUpHover?r["btn:hover"]:{})},btnDown:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:l({},r.btn,r.btnDown,n.disabled?r["btn:disabled"]:o.btnDownActive?r["btn:active"]:o.btnDownHover?r["btn:hover"]:{})}};return o.value||0===o.value?v.input.value=this._format(o.value):v.input.value="",h&&u!==!1&&l(v.wrap.style,r["wrap.hasFormControl"]),i&&u!==!1&&(l(v.input.style,r["input.mobile"]),l(v.btnUp.style,r["btnUp.mobile"]),l(v.btnDown.style,r["btnDown.mobile"])),n.disabled?u!==!1&&l(v.input.style,r["input:disabled"]):(l(v.wrap,{onMouseUp:this.stop,onMouseLeave:this.stop}),l(v.btnUp,{onTouchStart:this.onTouchStart.bind(this,"up"),onTouchEnd:this.stop,onMouseEnter:function(){t.setState({btnUpHover:!0})},onMouseLeave:function(){t.stop(),t.setState({btnUpHover:!1,btnUpActive:!1})},onMouseUp:function(){t.setState({btnUpHover:!0,btnUpActive:!1})},onMouseDown:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].preventDefault(),n[0].persist(),t.setState({btnUpHover:!0,btnUpActive:!0,inputFocus:!0},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))}),t.onMouseDown("up")}}),l(v.btnDown,{onTouchStart:this.onTouchStart.bind(this,"down"),onTouchEnd:this.stop,onMouseEnter:function(){t.setState({btnDownHover:!0})},onMouseLeave:function(){t.stop(),t.setState({btnDownHover:!1,btnDownActive:!1})},onMouseUp:function(){t.setState({btnDownHover:!0,btnDownActive:!1})},onMouseDown:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].preventDefault(),n[0].persist(),t.setState({btnDownHover:!0,btnDownActive:!0,inputFocus:!0},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))}),t.onMouseDown("down")}}),l(v.input,{onChange:function(e){var n=t._parse(e.target.value);isNaN(n)&&(n=null),t.setState({value:n})},onKeyDown:this._onKeyDown.bind(this),onInput:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];t.saveSelection(),t._invokeEventCallback.apply(t,["onInput"].concat(n))},onSelect:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];t.saveSelection(),t._invokeEventCallback.apply(t,["onSelect"].concat(n))},onFocus:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].persist(),t.setState({inputFocus:!0},function(){t.setState({value:t._parse(n[0].target.value)},function(){t._invokeEventCallback.apply(t,["onFocus"].concat(n))})})},onBlur:function(){for(var e=arguments.length,n=Array(e),o=0;e>o;o++)n[o]=arguments[o];n[0].persist(),t.setState({inputFocus:!1},function(){t.setState({value:t._parse(n[0].target.value)},function(){t._invokeEventCallback.apply(t,["onBlur"].concat(n))})})}})),i?f["default"].createElement("span",v.wrap,f["default"].createElement("input",v.input),f["default"].createElement("b",v.btnUp,f["default"].createElement("i",{style:u===!1?null:r.minus}),f["default"].createElement("i",{style:u===!1?null:r.plus})),f["default"].createElement("b",v.btnDown,f["default"].createElement("i",{style:u===!1?null:r.minus}))):f["default"].createElement("span",v.wrap,f["default"].createElement("input",v.input),f["default"].createElement("b",v.btnUp,f["default"].createElement("i",{style:u===!1?null:r.arrowUp})),f["default"].createElement("b",v.btnDown,f["default"].createElement("i",{style:u===!1?null:r.arrowDown})))}}]),e}(h.Component);y.propTypes={step:h.PropTypes.number,min:h.PropTypes.number,max:h.PropTypes.number,precision:h.PropTypes.number,maxLength:h.PropTypes.number,parse:h.PropTypes.func,format:h.PropTypes.func,className:h.PropTypes.string,disabled:h.PropTypes.bool,readOnly:h.PropTypes.bool,required:h.PropTypes.bool,noValidate:h.PropTypes.oneOfType([h.PropTypes.bool,h.PropTypes.string]),style:h.PropTypes.oneOfType([h.PropTypes.object,h.PropTypes.bool]),type:h.PropTypes.string,pattern:h.PropTypes.string,onFocus:h.PropTypes.func,onBlur:h.PropTypes.func,onKeyDown:h.PropTypes.func,onChange:h.PropTypes.func,onInvalid:h.PropTypes.func,onValid:h.PropTypes.func,onInput:h.PropTypes.func,onSelect:h.PropTypes.func,size:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),value:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),defaultValue:h.PropTypes.oneOfType([h.PropTypes.number,h.PropTypes.string]),mobile:function(t,e){var n=t[e];return n!==!0&&n!==!1&&"auto"!==n&&"function"!=typeof n?new Error('The "mobile" prop must be true, false, "auto" or a function'):void 0}},y.defaultProps={step:1,min:Number.MIN_SAFE_INTEGER||-9007199254740991,max:Number.MAX_SAFE_INTEGER||9007199254740991,precision:0,parse:null,format:null,mobile:"auto",style:{}},y.style={wrap:{position:"relative",display:"inline-block"},"wrap.hasFormControl":{display:"block"},arrowUp:{position:"absolute",top:"50%",left:"50%",width:0,height:0,borderWidth:"0 0.6ex 0.6ex 0.6ex",borderColor:"transparent transparent rgba(0, 0, 0, 0.7)",borderStyle:"solid",margin:"-0.3ex 0 0 -0.56ex"},arrowDown:{position:"absolute",top:"50%",left:"50%",width:0,height:0,borderWidth:"0.6ex 0.6ex 0 0.6ex",borderColor:"rgba(0, 0, 0, 0.7) transparent transparent",borderStyle:"solid",margin:"-0.3ex 0 0 -0.56ex"},plus:{position:"absolute",top:"50%",left:"50%",width:2,height:10,background:"rgba(0,0,0,.7)",margin:"-5px 0 0 -1px"},minus:{position:"absolute",top:"50%",left:"50%",width:10,height:2,background:"rgba(0,0,0,.7)",margin:"-1px 0 0 -5px"},btn:{position:"absolute",right:2,width:"2.26ex",borderColor:"rgba(0,0,0,.1)",borderStyle:"solid",textAlign:"center",cursor:"default",transition:"all 0.1s",background:"rgba(0,0,0,.1)",boxShadow:"-1px -1px 3px rgba(0,0,0,.1) inset,\n 1px 1px 3px rgba(255,255,255,.7) inset"},btnUp:{top:2,bottom:"50%",borderRadius:"2px 2px 0 0",borderWidth:"1px 1px 0 1px"},"btnUp.mobile":{width:"3.3ex",bottom:2,boxShadow:"none",borderRadius:2,borderWidth:1},btnDown:{top:"50%",bottom:2,borderRadius:"0 0 2px 2px",borderWidth:"0 1px 1px 1px"},"btnDown.mobile":{width:"3.3ex",bottom:2,left:2,top:2,right:"auto",boxShadow:"none",borderRadius:2,borderWidth:1},"btn:hover":{background:"rgba(0,0,0,.2)"},"btn:active":{background:"rgba(0,0,0,.3)",boxShadow:"0 1px 3px rgba(0,0,0,.2) inset,\n -1px -1px 4px rgba(255,255,255,.5) inset"},"btn:disabled":{opacity:.5,boxShadow:"none",cursor:"not-allowed"},input:{paddingRight:"3ex",boxSizing:"border-box"},"input:not(.form-control)":{border:"1px solid #ccc",borderRadius:2,paddingLeft:4,display:"block",WebkitAppearance:"none",lineHeight:"normal"},"input.mobile":{paddingLeft:" 3.4ex",paddingRight:"3.4ex",textAlign:"center"},"input:focus":{},"input:disabled":{color:"rgba(0, 0, 0, 0.3)",textShadow:"0 1px 0 rgba(255, 255, 255, 0.8)"}},y.SPEED=50,y.DELAY=500,t.exports=y},function(e,n){e.exports=t}])}); \ No newline at end of file diff --git a/index.js b/index.js index 8f8abd7..25bb9ec 100644 --- a/index.js +++ b/index.js @@ -134,7 +134,7 @@ module.exports = }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { - if (prevState.value !== this.state.value && !isNaN(this.state.value)) { + if (prevState.value !== this.state.value && (!isNaN(this.state.value) || this.state.value === null)) { this._invokeEventCallback("onChange", this.state.value, this.refs.input.value); } @@ -568,7 +568,11 @@ module.exports = _extends(attrs.input, { onChange: function onChange(e) { - _this5.setState({ value: _this5._parse(e.target.value) }); + var val = _this5._parse(e.target.value); + if (isNaN(val)) { + val = null; + } + _this5.setState({ value: val }); }, onKeyDown: this._onKeyDown.bind(this), onInput: function onInput() { diff --git a/src/NumericInput.jsx b/src/NumericInput.jsx index 37f10a1..93d4e7c 100644 --- a/src/NumericInput.jsx +++ b/src/NumericInput.jsx @@ -357,7 +357,7 @@ class NumericInput extends Component // Call the onChange if needed. This is placed here because there are // many reasons for changing the value and this is the common place // that can capture them all - if (prevState.value !== this.state.value && !isNaN(this.state.value)) { + if (prevState.value !== this.state.value && (!isNaN(this.state.value) || this.state.value === null)) { this._invokeEventCallback("onChange", this.state.value, this.refs.input.value) } @@ -909,7 +909,11 @@ class NumericInput extends Component Object.assign(attrs.input, { onChange : e => { - this.setState({ value: this._parse(e.target.value) }) + let val = this._parse(e.target.value) + if (isNaN(val)) { + val = null + } + this.setState({ value: val }) }, onKeyDown: this._onKeyDown.bind(this), onInput: (...args) => {