From 643d20e8e351dd988aca12f46c006cc88b5dc095 Mon Sep 17 00:00:00 2001 From: vlad-ignatov Date: Sat, 29 Jul 2017 11:39:01 -0400 Subject: [PATCH] Prepare for 2.1.0 release --- CHANGELOG.md | 8 ++++++++ __tests__/misc.test.jsx | 9 ++++++--- dist/react-numeric-input.js | 2 +- dist/react-numeric-input.min.js | 2 +- examples/Demo.jsx | 7 +++++-- examples/examples.js | 6 ++++-- index.js | 2 +- package.json | 2 +- src/NumericInput.jsx | 2 +- 9 files changed, 28 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1292045..85c7563 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +2.1.0 +-------------------------------------------------------------------------------- +* Added `snap` prop to make the value snap to the closest step when using buttons or up/down keys to change it. +* Pass a reference to the input element to the onChange callbacks +* Fixed an issue preventing the input from being editable when it's entire value is selected +* Fixed an issue that might cause the component to loose its value if re-rendered without value prop + + 2.0.9 -------------------------------------------------------------------------------- * Field now accepts `"-."`, `"+.`", `"."`, `"-"`, and `"+"` at beginning of input value. diff --git a/__tests__/misc.test.jsx b/__tests__/misc.test.jsx index c35a249..751462c 100644 --- a/__tests__/misc.test.jsx +++ b/__tests__/misc.test.jsx @@ -56,7 +56,10 @@ describe ('NumericInput/misc', function() { TestUtils.Simulate.focus(input) input.value = 1 TestUtils.Simulate.change(input) - expect(log.toString()).toEqual('1,1') + expect(log.length).toEqual(3) + expect(log[0]).toEqual(1) + expect(log[1]).toEqual('1') + expect(log[2]).toEqual(input) done() }) @@ -116,10 +119,10 @@ describe ('NumericInput/misc', function() { TestUtils.Simulate.focus(input) input.value = 2 TestUtils.Simulate.change(input) - expect(log).toEqual([2,'2']) + expect(log).toEqual([2, '2', input]) input.value = "" TestUtils.Simulate.change(input) - expect(log).toEqual([2,'2',null,""]) + expect(log).toEqual([2, '2', input, null, "", input]) done() }) diff --git a/dist/react-numeric-input.js b/dist/react-numeric-input.js index 73cc552..d9be5f8 100644 --- a/dist/react-numeric-input.js +++ b/dist/react-numeric-input.js @@ -237,7 +237,7 @@ return /******/ (function(modules) { // webpackBootstrap // 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) || this.state.value === null)) { - this._invokeEventCallback("onChange", this.state.value, this.refs.input.value); + this._invokeEventCallback("onChange", this.state.value, this.refs.input.value, this.refs.input); } // focus the input is needed (for example up/down buttons set diff --git a/dist/react-numeric-input.min.js b/dist/react-numeric-input.min.js index c0ed7a5..e0f326e 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"),require("prop-types")):"function"==typeof define&&define.amd?define(["React","prop-types"],e):"object"==typeof exports?exports.NumericInput=e(require("React"),require("prop-types")):t.NumericInput=e(t.React,t["prop-types"])}(this,function(t,e){return function(t){function e(o){if(n[o])return n[o].exports;var a=n[o]={exports:{},id:o,loaded:!1};return t[o].call(a.exports,a,a.exports,e),a.loaded=!0,a.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 a(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 i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(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 r(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 l(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 p=Object.assign||function(t){for(var e=1;ea;a++)o[a]=arguments[a];var r=s(this,(t=Object.getPrototypeOf(e)).call.apply(t,[this].concat(o)));return r.state={selectionStart:null,selectionEnd:null,value:"value"in r.props?r.props.value:r.props.defaultValue,btnDownHover:!1,btnDownActive:!1,btnUpHover:!1,btnUpActive:!1,inputFocus:!1},r.stop=r.stop.bind(r),r}return r(e,t),c(e,[{key:"componentWillReceiveProps",value:function(t){if(t.hasOwnProperty("value")){var e=String(t.value||0===t.value?t.value:"").replace(/^\s*|\s*$/,"");this.setState({value:"value"in t&&""!==e?this._parse(e):null,stringValue:e})}}},{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),stringValue:e})},!this.state.inputFocus&&y&&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 a=this._valid!==e;this._valid=e,e?(u(this.refs.wrapper,"has-error"),a&&this._invokeEventCallback("onInvalid",e,this.state.value,this.refs.input.value)):(l(this.refs.wrapper,"has-error"),a&&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 this.props.snap&&(n=Math.round(n/this.props.step)*this.props.step),n!==this.state.value?(this.setState({value:n,stringValue:n},e),!0):!1}},{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];if(!o.isDefaultPrevented())if(o.keyCode===b)o.preventDefault(),this._step(o.ctrlKey||o.metaKey?.1:o.shiftKey?10:1);else if(o.keyCode===m)o.preventDefault(),this._step(o.ctrlKey||o.metaKey?-.1:o.shiftKey?-10:-1);else{var a=this.refs.input.value,i=a.length;8===o.keyCode?this.refs.input.selectionStart==this.refs.input.selectionEnd&&this.refs.input.selectionEnd>0&&a.length&&"."===a.charAt(this.refs.input.selectionEnd-1)&&(o.preventDefault(),this.refs.input.selectionStart=this.refs.input.selectionEnd=this.refs.input.selectionEnd-1):46===o.keyCode&&this.refs.input.selectionStart==this.refs.input.selectionEnd&&this.refs.input.selectionEndthis.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),a=1;n>a;a++)o[a-1]=arguments[a];(e=this.props[t]).call.apply(e,[null].concat(o))}}},{key:"render",value:function(){var t=this,n=this.props,o=this.state,i={},s=this.props,r=(s.step,s.min,s.max,s.precision,s.parse,s.format,s.mobile),u=(s.snap,s.value,s.type,s.style),l=(s.defaultValue,s.onInvalid,s.onValid,a(s,["step","min","max","precision","parse","format","mobile","snap","value","type","style","defaultValue","onInvalid","onValid"]));for(var c in e.style)i[c]=p({},e.style[c],u?u[c]||{}:{});var f=n.className&&/\bform-control\b/.test(n.className);"auto"==r&&(r=y&&"ontouchstart"in document),"function"==typeof r&&(r=r.call(this)),r=!!r;var h={wrap:{style:u===!1?null:i.wrap,className:"react-numeric-input",ref:"wrapper",onMouseUp:void 0,onMouseLeave:void 0},input:p({ref:"input",type:"text",style:u===!1?null:p({},i.input,f?{}:i["input:not(.form-control)"],o.inputFocus?i["input:focus"]:{})},l),btnUp:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:p({},i.btn,i.btnUp,n.disabled?i["btn:disabled"]:o.btnUpActive?i["btn:active"]:o.btnUpHover?i["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:p({},i.btn,i.btnDown,n.disabled?i["btn:disabled"]:o.btnDownActive?i["btn:active"]:o.btnDownHover?i["btn:hover"]:{})}};return/^[+-.]{1,2}$/.test(o.stringValue)?h.input.value=o.stringValue:o.value||0===o.value?h.input.value=this._format(o.value):h.input.value="",f&&u!==!1&&p(h.wrap.style,i["wrap.hasFormControl"]),r&&u!==!1&&(p(h.input.style,i["input.mobile"]),p(h.btnUp.style,i["btnUp.mobile"]),p(h.btnDown.style,i["btnDown.mobile"])),n.disabled?u!==!1&&p(h.input.style,i["input:disabled"]):(p(h.wrap,{onMouseUp:this.stop,onMouseLeave:this.stop}),p(h.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")}}),p(h.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")}}),p(h.input,{onChange:function(e){var n=e.target.value,o=t._parse(n);isNaN(o)&&(o=null),t.setState({value:o,stringValue: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(){var e=t._parse(n[0].target.value);t.setState({value:e,stringValue:e},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(){var e=t._parse(n[0].target.value);t.setState({value:e},function(){t._invokeEventCallback.apply(t,["onBlur"].concat(n))})})}})),r?d["default"].createElement("span",h.wrap,d["default"].createElement("input",h.input),d["default"].createElement("b",h.btnUp,d["default"].createElement("i",{style:u===!1?null:i.minus}),d["default"].createElement("i",{style:u===!1?null:i.plus})),d["default"].createElement("b",h.btnDown,d["default"].createElement("i",{style:u===!1?null:i.minus}))):d["default"].createElement("span",h.wrap,d["default"].createElement("input",h.input),d["default"].createElement("b",h.btnUp,d["default"].createElement("i",{style:u===!1?null:i.arrowUp})),d["default"].createElement("b",h.btnDown,d["default"].createElement("i",{style:u===!1?null:i.arrowDown})))}}]),e}(f.Component);g.propTypes={step:v["default"].number,min:v["default"].number,max:v["default"].number,precision:v["default"].number,maxLength:v["default"].number,parse:v["default"].func,format:v["default"].func,className:v["default"].string,disabled:v["default"].bool,readOnly:v["default"].bool,required:v["default"].bool,snap:v["default"].bool,noValidate:v["default"].oneOfType([v["default"].bool,v["default"].string]),style:v["default"].oneOfType([v["default"].object,v["default"].bool]),type:v["default"].string,pattern:v["default"].string,onFocus:v["default"].func,onBlur:v["default"].func,onKeyDown:v["default"].func,onChange:v["default"].func,onInvalid:v["default"].func,onValid:v["default"].func,onInput:v["default"].func,onSelect:v["default"].func,size:v["default"].oneOfType([v["default"].number,v["default"].string]),value:v["default"].oneOfType([v["default"].number,v["default"].string]),defaultValue:v["default"].oneOfType([v["default"].number,v["default"].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}},g.defaultProps={step:1,min:Number.MIN_SAFE_INTEGER||-9007199254740991,max:Number.MAX_SAFE_INTEGER||9007199254740991,precision:0,parse:null,format:null,mobile:"auto",style:{}},g.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,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,-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)"}},g.SPEED=50,g.DELAY=500,t.exports=g},function(e,n){e.exports=t},function(t,n){t.exports=e}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("React"),require("prop-types")):"function"==typeof define&&define.amd?define(["React","prop-types"],e):"object"==typeof exports?exports.NumericInput=e(require("React"),require("prop-types")):t.NumericInput=e(t.React,t["prop-types"])}(this,function(t,e){return function(t){function e(o){if(n[o])return n[o].exports;var a=n[o]={exports:{},id:o,loaded:!1};return t[o].call(a.exports,a,a.exports,e),a.loaded=!0,a.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 a(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 i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(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 r(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 l(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 p=Object.assign||function(t){for(var e=1;ea;a++)o[a]=arguments[a];var r=s(this,(t=Object.getPrototypeOf(e)).call.apply(t,[this].concat(o)));return r.state={selectionStart:null,selectionEnd:null,value:"value"in r.props?r.props.value:r.props.defaultValue,btnDownHover:!1,btnDownActive:!1,btnUpHover:!1,btnUpActive:!1,inputFocus:!1},r.stop=r.stop.bind(r),r}return r(e,t),c(e,[{key:"componentWillReceiveProps",value:function(t){if(t.hasOwnProperty("value")){var e=String(t.value||0===t.value?t.value:"").replace(/^\s*|\s*$/,"");this.setState({value:"value"in t&&""!==e?this._parse(e):null,stringValue:e})}}},{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.refs.input),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),stringValue:e})},!this.state.inputFocus&&y&&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 a=this._valid!==e;this._valid=e,e?(u(this.refs.wrapper,"has-error"),a&&this._invokeEventCallback("onInvalid",e,this.state.value,this.refs.input.value)):(l(this.refs.wrapper,"has-error"),a&&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 this.props.snap&&(n=Math.round(n/this.props.step)*this.props.step),n!==this.state.value?(this.setState({value:n,stringValue:n},e),!0):!1}},{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];if(!o.isDefaultPrevented())if(o.keyCode===b)o.preventDefault(),this._step(o.ctrlKey||o.metaKey?.1:o.shiftKey?10:1);else if(o.keyCode===m)o.preventDefault(),this._step(o.ctrlKey||o.metaKey?-.1:o.shiftKey?-10:-1);else{var a=this.refs.input.value,i=a.length;8===o.keyCode?this.refs.input.selectionStart==this.refs.input.selectionEnd&&this.refs.input.selectionEnd>0&&a.length&&"."===a.charAt(this.refs.input.selectionEnd-1)&&(o.preventDefault(),this.refs.input.selectionStart=this.refs.input.selectionEnd=this.refs.input.selectionEnd-1):46===o.keyCode&&this.refs.input.selectionStart==this.refs.input.selectionEnd&&this.refs.input.selectionEndthis.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),a=1;n>a;a++)o[a-1]=arguments[a];(e=this.props[t]).call.apply(e,[null].concat(o))}}},{key:"render",value:function(){var t=this,n=this.props,o=this.state,i={},s=this.props,r=(s.step,s.min,s.max,s.precision,s.parse,s.format,s.mobile),u=(s.snap,s.value,s.type,s.style),l=(s.defaultValue,s.onInvalid,s.onValid,a(s,["step","min","max","precision","parse","format","mobile","snap","value","type","style","defaultValue","onInvalid","onValid"]));for(var c in e.style)i[c]=p({},e.style[c],u?u[c]||{}:{});var f=n.className&&/\bform-control\b/.test(n.className);"auto"==r&&(r=y&&"ontouchstart"in document),"function"==typeof r&&(r=r.call(this)),r=!!r;var h={wrap:{style:u===!1?null:i.wrap,className:"react-numeric-input",ref:"wrapper",onMouseUp:void 0,onMouseLeave:void 0},input:p({ref:"input",type:"text",style:u===!1?null:p({},i.input,f?{}:i["input:not(.form-control)"],o.inputFocus?i["input:focus"]:{})},l),btnUp:{onMouseEnter:void 0,onMouseDown:void 0,onMouseUp:void 0,onMouseLeave:void 0,onTouchStart:void 0,onTouchEnd:void 0,style:u===!1?null:p({},i.btn,i.btnUp,n.disabled?i["btn:disabled"]:o.btnUpActive?i["btn:active"]:o.btnUpHover?i["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:p({},i.btn,i.btnDown,n.disabled?i["btn:disabled"]:o.btnDownActive?i["btn:active"]:o.btnDownHover?i["btn:hover"]:{})}};return/^[+-.]{1,2}$/.test(o.stringValue)?h.input.value=o.stringValue:o.value||0===o.value?h.input.value=this._format(o.value):h.input.value="",f&&u!==!1&&p(h.wrap.style,i["wrap.hasFormControl"]),r&&u!==!1&&(p(h.input.style,i["input.mobile"]),p(h.btnUp.style,i["btnUp.mobile"]),p(h.btnDown.style,i["btnDown.mobile"])),n.disabled?u!==!1&&p(h.input.style,i["input:disabled"]):(p(h.wrap,{onMouseUp:this.stop,onMouseLeave:this.stop}),p(h.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")}}),p(h.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")}}),p(h.input,{onChange:function(e){var n=e.target.value,o=t._parse(n);isNaN(o)&&(o=null),t.setState({value:o,stringValue: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(){var e=t._parse(n[0].target.value);t.setState({value:e,stringValue:e},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(){var e=t._parse(n[0].target.value);t.setState({value:e},function(){t._invokeEventCallback.apply(t,["onBlur"].concat(n))})})}})),r?d["default"].createElement("span",h.wrap,d["default"].createElement("input",h.input),d["default"].createElement("b",h.btnUp,d["default"].createElement("i",{style:u===!1?null:i.minus}),d["default"].createElement("i",{style:u===!1?null:i.plus})),d["default"].createElement("b",h.btnDown,d["default"].createElement("i",{style:u===!1?null:i.minus}))):d["default"].createElement("span",h.wrap,d["default"].createElement("input",h.input),d["default"].createElement("b",h.btnUp,d["default"].createElement("i",{style:u===!1?null:i.arrowUp})),d["default"].createElement("b",h.btnDown,d["default"].createElement("i",{style:u===!1?null:i.arrowDown})))}}]),e}(f.Component);g.propTypes={step:v["default"].number,min:v["default"].number,max:v["default"].number,precision:v["default"].number,maxLength:v["default"].number,parse:v["default"].func,format:v["default"].func,className:v["default"].string,disabled:v["default"].bool,readOnly:v["default"].bool,required:v["default"].bool,snap:v["default"].bool,noValidate:v["default"].oneOfType([v["default"].bool,v["default"].string]),style:v["default"].oneOfType([v["default"].object,v["default"].bool]),type:v["default"].string,pattern:v["default"].string,onFocus:v["default"].func,onBlur:v["default"].func,onKeyDown:v["default"].func,onChange:v["default"].func,onInvalid:v["default"].func,onValid:v["default"].func,onInput:v["default"].func,onSelect:v["default"].func,size:v["default"].oneOfType([v["default"].number,v["default"].string]),value:v["default"].oneOfType([v["default"].number,v["default"].string]),defaultValue:v["default"].oneOfType([v["default"].number,v["default"].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}},g.defaultProps={step:1,min:Number.MIN_SAFE_INTEGER||-9007199254740991,max:Number.MAX_SAFE_INTEGER||9007199254740991,precision:0,parse:null,format:null,mobile:"auto",style:{}},g.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,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,-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)"}},g.SPEED=50,g.DELAY=500,t.exports=g},function(e,n){e.exports=t},function(t,n){t.exports=e}])}); \ No newline at end of file diff --git a/examples/Demo.jsx b/examples/Demo.jsx index 640ab8b..fa4a75d 100644 --- a/examples/Demo.jsx +++ b/examples/Demo.jsx @@ -21,7 +21,9 @@ export default class Demo extends React.Component required : { value: true, on: false }, noValidate: { value: true, on: false }, pattern : { value: "[0-9].[0-9][0-9]", on: false }, - title : { value: "The title attr", on: false }//, + title : { value: "The title attr", on: false }, + snap : { value: true, on: false }, + inputmode : { value: "numeric", on: false } // library } } @@ -186,7 +188,8 @@ export default class Demo extends React.Component { name: "title" , type: "text" }, { name: "required" , type: "bool" }, { name: "noValidate", type: "bool" }, - { name: "inputmode" , type: "text" } + { name: "inputmode" , type: "text" }, + { name: "snap" , type: "bool" } ])} {/* parse function parseFloat diff --git a/examples/examples.js b/examples/examples.js index 7e55c14..61d5109 100644 --- a/examples/examples.js +++ b/examples/examples.js @@ -158,7 +158,9 @@ return /******/ (function(modules) { // webpackBootstrap required: { value: true, on: false }, noValidate: { value: true, on: false }, pattern: { value: "[0-9].[0-9][0-9]", on: false }, - title: { value: "The title attr", on: false } //, + title: { value: "The title attr", on: false }, + snap: { value: true, on: false }, + inputmode: { value: "numeric", on: false } // library } }; @@ -358,7 +360,7 @@ return /******/ (function(modules) { // webpackBootstrap React.createElement( "tbody", null, - this.renderPropEditors([{ name: "name", type: "text" }, { name: "className", type: "text" }, { name: "value", type: "text" }, { name: "min", type: "number" }, { name: "max", type: "number" }, { name: "step", type: "number", min: 0.001, step: 0.1, precision: 3 }, { name: "precision", type: "number", min: 0, max: 20 }, { name: "size", type: "number", min: 0, max: 60 }, { name: "maxLength", type: "number", min: 0, max: 20 }, { name: "disabled", type: "bool" }, { name: "readOnly", type: "bool" }, { name: "mobile", type: "bool" }, { name: "pattern", type: "text" }, { name: "title", type: "text" }, { name: "required", type: "bool" }, { name: "noValidate", type: "bool" }, { name: "inputmode", type: "text" }]) + this.renderPropEditors([{ name: "name", type: "text" }, { name: "className", type: "text" }, { name: "value", type: "text" }, { name: "min", type: "number" }, { name: "max", type: "number" }, { name: "step", type: "number", min: 0.001, step: 0.1, precision: 3 }, { name: "precision", type: "number", min: 0, max: 20 }, { name: "size", type: "number", min: 0, max: 60 }, { name: "maxLength", type: "number", min: 0, max: 20 }, { name: "disabled", type: "bool" }, { name: "readOnly", type: "bool" }, { name: "mobile", type: "bool" }, { name: "pattern", type: "text" }, { name: "title", type: "text" }, { name: "required", type: "bool" }, { name: "noValidate", type: "bool" }, { name: "inputmode", type: "text" }, { name: "snap", type: "bool" }]) ) ) ) diff --git a/index.js b/index.js index 16a4616..9eb5ceb 100644 --- a/index.js +++ b/index.js @@ -142,7 +142,7 @@ module.exports = key: 'componentDidUpdate', value: function componentDidUpdate(prevProps, prevState) { if (prevState.value !== this.state.value && (!isNaN(this.state.value) || this.state.value === null)) { - this._invokeEventCallback("onChange", this.state.value, this.refs.input.value); + this._invokeEventCallback("onChange", this.state.value, this.refs.input.value, this.refs.input); } if (this.state.inputFocus) { diff --git a/package.json b/package.json index 7226ba6..6b552bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-numeric-input", - "version": "2.0.9", + "version": "2.1.0", "description": "Number input component that can replace the native number input which is not yet very well supported and where it is, it does not have the same appearance across the browsers. Additionally this component offers more flexible options and can be used for any values (differently formatted representations of the internal numeric value).", "main": "index.js", "scripts": { diff --git a/src/NumericInput.jsx b/src/NumericInput.jsx index ad34a17..0f45dab 100644 --- a/src/NumericInput.jsx +++ b/src/NumericInput.jsx @@ -363,7 +363,7 @@ class NumericInput extends Component // 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) || this.state.value === null)) { - this._invokeEventCallback("onChange", this.state.value, this.refs.input.value) + this._invokeEventCallback("onChange", this.state.value, this.refs.input.value, this.refs.input) } // focus the input is needed (for example up/down buttons set