diff --git a/bower.json b/bower.json index 78d7212..cd7ca33 100644 --- a/bower.json +++ b/bower.json @@ -4,7 +4,7 @@ "dist/react-input-range.js", "dist/react-input-range.css" ], - "version": "0.5.1", + "version": "0.6.0", "description": "React component for inputting numeric values within a range", "homepage": "https://github.com/davidchin/react-input-range", "authors": [ diff --git a/dist/react-input-range.js b/dist/react-input-range.js index f9c4e7f..6d807ea 100644 --- a/dist/react-input-range.js +++ b/dist/react-input-range.js @@ -44,6 +44,8 @@ var _util = require('./util'); var _propTypes = require('./propTypes'); +var internals = new WeakMap(); + var KeyCode = { LEFT_ARROW: 37, RIGHT_ARROW: 39 @@ -71,6 +73,12 @@ function shouldUpdate(inputRange, values) { return isWithinRange(inputRange, values) && hasStepDifference(inputRange, values); } +function getDocument(inputRange) { + var ownerDocument = inputRange.refs.inputRange.ownerDocument; + + return ownerDocument; +} + function getComponentClassName(inputRange) { var props = inputRange.props; @@ -217,7 +225,9 @@ var InputRange = (function (_React$Component) { _get(Object.getPrototypeOf(InputRange.prototype), 'constructor', this).call(this, props); - (0, _util.autobind)(['handleSliderMouseMove', 'handleSliderKeyDown', 'handleTrackMouseDown'], this); + internals.set(this, {}); + + (0, _util.autobind)(['handleInteractionEnd', 'handleInteractionStart', 'handleKeyDown', 'handleKeyUp', 'handleMouseDown', 'handleMouseUp', 'handleSliderKeyDown', 'handleSliderMouseMove', 'handleTouchStart', 'handleTouchEnd', 'handleTrackMouseDown'], this); } _createClass(InputRange, [{ @@ -285,7 +295,7 @@ var InputRange = (function (_React$Component) { } }, { key: 'handleSliderMouseMove', - value: function handleSliderMouseMove(slider, event) { + value: function handleSliderMouseMove(event, slider) { if (this.props.disabled) { return; } @@ -297,7 +307,7 @@ var InputRange = (function (_React$Component) { } }, { key: 'handleSliderKeyDown', - value: function handleSliderKeyDown(slider, event) { + value: function handleSliderKeyDown(event, slider) { if (this.props.disabled) { return; } @@ -319,7 +329,7 @@ var InputRange = (function (_React$Component) { } }, { key: 'handleTrackMouseDown', - value: function handleTrackMouseDown(track, position) { + value: function handleTrackMouseDown(event, track, position) { if (this.props.disabled) { return; } @@ -328,6 +338,78 @@ var InputRange = (function (_React$Component) { this.updatePosition(key, position); } + }, { + key: 'handleInteractionStart', + value: function handleInteractionStart() { + var _this = internals.get(this); + + if (!this.props.onChangeComplete || (0, _util.isDefined)(_this.startValue)) { + return; + } + + _this.startValue = this.props.value; + } + }, { + key: 'handleInteractionEnd', + value: function handleInteractionEnd() { + var _this = internals.get(this); + + if (!this.props.onChangeComplete || !(0, _util.isDefined)(_this.startValue)) { + return; + } + + if (_this.startValue !== this.props.value) { + this.props.onChangeComplete(this, this.props.value); + } + + _this.startValue = null; + } + }, { + key: 'handleKeyDown', + value: function handleKeyDown(event) { + this.handleInteractionStart(event); + } + }, { + key: 'handleKeyUp', + value: function handleKeyUp(event) { + this.handleInteractionEnd(event); + } + }, { + key: 'handleMouseDown', + value: function handleMouseDown(event) { + var document = getDocument(this); + + this.handleInteractionStart(event); + + document.addEventListener('mouseup', this.handleMouseUp); + } + }, { + key: 'handleMouseUp', + value: function handleMouseUp(event) { + var document = getDocument(this); + + this.handleInteractionEnd(event); + + document.removeEventListener('mouseup', this.handleMouseUp); + } + }, { + key: 'handleTouchStart', + value: function handleTouchStart(event) { + var document = getDocument(this); + + this.handleInteractionStart(event); + + document.addEventListener('touchend', this.handleTouchEnd); + } + }, { + key: 'handleTouchEnd', + value: function handleTouchEnd(event) { + var document = getDocument(this); + + this.handleInteractionEnd(event); + + document.removeEventListener('touchend', this.handleTouchEnd); + } }, { key: 'render', value: function render() { @@ -342,7 +424,11 @@ var InputRange = (function (_React$Component) { { 'aria-disabled': this.props.disabled, ref: 'inputRange', - className: componentClassName }, + className: componentClassName, + onKeyDown: this.handleKeyDown, + onKeyUp: this.handleKeyUp, + onMouseDown: this.handleMouseDown, + onTouchStart: this.handleTouchStart }, _react2['default'].createElement( _Label2['default'], { @@ -404,6 +490,7 @@ InputRange.propTypes = { minValue: _propTypes.maxMinValuePropType, name: _react2['default'].PropTypes.string, onChange: _react2['default'].PropTypes.func.isRequired, + onChangeComplete: _react2['default'].PropTypes.func, step: _react2['default'].PropTypes.number, value: _propTypes.maxMinValuePropType }; @@ -564,7 +651,7 @@ var Slider = (function (_React$Component) { }, { key: 'handleMouseMove', value: function handleMouseMove(event) { - this.props.onSliderMouseMove(this, event); + this.props.onSliderMouseMove(event, this); } }, { key: 'handleTouchStart', @@ -579,7 +666,7 @@ var Slider = (function (_React$Component) { }, { key: 'handleTouchMove', value: function handleTouchMove(event) { - this.props.onSliderMouseMove(this, event); + this.props.onSliderMouseMove(event, this); } }, { key: 'handleTouchEnd', @@ -594,7 +681,7 @@ var Slider = (function (_React$Component) { }, { key: 'handleKeyDown', value: function handleKeyDown(event) { - this.props.onSliderKeyDown(this, event); + this.props.onSliderKeyDown(event, this); } }, { key: 'render', @@ -714,7 +801,7 @@ var Track = (function (_React$Component) { y: 0 }; - this.props.onTrackMouseDown(this, position); + this.props.onTrackMouseDown(event, this, position); } }, { key: 'handleTouchStart', @@ -883,6 +970,10 @@ function isObject(object) { return object !== null && typeof object === 'object'; } +function isDefined(value) { + return value !== undefined && value !== null; +} + function isEmpty(obj) { if (!obj) { return true; @@ -940,6 +1031,7 @@ var util = { clamp: clamp, distanceTo: distanceTo, extend: extend, + isDefined: isDefined, isEmpty: isEmpty, isNumber: isNumber, isObject: isObject, diff --git a/dist/react-input-range.min.js b/dist/react-input-range.min.js index f280e96..60349ee 100644 --- a/dist/react-input-range.min.js +++ b/dist/react-input-range.min.js @@ -1 +1 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.InputRange=e()}}(function(){return function e(t,n,r){function a(u,i){if(!n[u]){if(!t[u]){var l="function"==typeof require&&require;if(!i&&l)return l(u,!0);if(o)return o(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var f=n[u]={exports:{}};t[u][0].call(f.exports,function(e){var n=t[u][1][e];return a(n?n:e)},f,f.exports,e,t,n,r)}return n[u].exports}for(var o="function"==typeof require&&require,u=0;u=n.minValue&&t.max<=n.maxValue&&t.min=n.minValue&&t.max<=n.maxValue}function l(e,t){var n=e.props,r=R["default"].valuesFromProps(e);return(0,_.length)(t.min,r.min)>=n.step||(0,_.length)(t.max,r.max)>=n.step}function s(e,t){return i(e,t)&&l(e,t)}function f(e){var t=e.props;return t.disabled?t.classNames.component+" is-disabled":t.classNames.component}function p(e,t){return t===e.refs.sliderMin?"min":"max"}function c(e){return e.isMultiValue?["min","max"]:["max"]}function d(e,t){var n=R["default"].valuesFromProps(e),r=R["default"].positionsFromValues(e,n);if(e.isMultiValue){var a=(0,_.distanceTo)(t,r.min),o=(0,_.distanceTo)(t,r.max);if(o>a)return"min"}return"max"}function m(e){var t=e.props.classNames,n=[],r=c(e),a=R["default"].valuesFromProps(e),o=R["default"].percentagesFromValues(e,a),u=!0,i=!1,l=void 0;try{for(var s,f=r[Symbol.iterator]();!(u=(s=f.next()).done);u=!0){var p=s.value,d=a[p],m=o[p],h="slider"+(0,_.captialize)(p),v=e.props,y=v.maxValue,b=v.minValue;"min"===p?y=a.max:b=a.min;var g=w["default"].createElement(M["default"],{classNames:t,key:p,maxValue:y,minValue:b,onSliderKeyDown:e.handleSliderKeyDown,onSliderMouseMove:e.handleSliderMouseMove,percentage:m,ref:h,type:p,value:d});n.push(g)}}catch(O){i=!0,l=O}finally{try{!u&&f["return"]&&f["return"]()}finally{if(i)throw l}}return n}function h(e){var t=[],n=c(e),r=!0,a=!1,o=void 0;try{for(var u,i=n[Symbol.iterator]();!(r=(u=i.next()).done);r=!0){var l=u.value,s=e.isMultiValue?""+e.props.name+(0,_.captialize)(l):e.props.name;w["default"].createElement("input",{type:"hidden",name:s})}}catch(f){a=!0,o=f}finally{try{!r&&i["return"]&&i["return"]()}finally{if(a)throw o}}return t}Object.defineProperty(n,"__esModule",{value:!0});var v=function(){function e(e,t){for(var n=0;n=t?new Error("`minValue` must be smaller than `maxValue`"):n>=t?new Error("`maxValue` must be larger than `minValue`"):n>r||r>t?new Error("`value` must be within `minValue` and `maxValue`"):void 0:new Error("`value` or `defaultValue` must be a number or an array")}Object.defineProperty(n,"__esModule",{value:!0});var a=e("./util");n.maxMinValuePropType=r},{"./util":7}],7:[function(e,t,n){"use strict";function r(e,t,n){return Math.min(Math.max(e,t),n)}function a(){return Object.assign.apply(Object,arguments)}function o(e,t){return e.indexOf(t)>-1}function u(e,t){var n=Object.keys(e),r={};return n.forEach(function(n){o(t,n)||(r[n]=e[n])}),r}function i(e){return e.charAt(0).toUpperCase()+e.slice(1)}function l(e,t){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}function s(e,t){return Math.abs(e-t)}function f(e){return"number"==typeof e}function p(e){return null!==e&&"object"==typeof e}function c(e){return e?Array.isArray(e)?0===e.length:0===Object.keys(e).length:!0}function d(e,t){if(!Array.isArray(e))return!1;for(var n=0,r=e.length;r>n;n++)if(!t(e[n]))return!1;return!0}function m(e,t,n){if(!p(e))return!1;for(var r=n||Object.keys(e),a=0,o=r.length;o>a;a++){var u=r[a];if(!t(e[u]))return!1}return!0}function h(e,t){e.forEach(function(e){t[e]=t[e].bind(t)})}Object.defineProperty(n,"__esModule",{value:!0});var v={arrayOf:d,autobind:h,captialize:i,clamp:r,distanceTo:l,extend:a,isEmpty:c,isNumber:f,isObject:p,length:s,objectOf:m,omit:u};n["default"]=v,t.exports=n["default"]},{}],8:[function(e,t,n){"use strict";function r(e,t){var n=e.trackClientRect.width,r=t.x/n;return r||0}function a(e,t){var n=r(e,t),a=e.props.maxValue-e.props.minValue,o=e.props.minValue+a*n;return o}function o(e){var t=arguments.length<=1||void 0===arguments[1]?e:arguments[1],n=t.props;return function(){if(e.isMultiValue){var t=n.value;return((0,c.isEmpty)(t)||!(0,c.objectOf)(t,c.isNumber))&&(t=n.defaultValue),Object.create(t)}var r=(0,c.isNumber)(n.value)?n.value:n.defaultValue;return{min:n.minValue,max:r}}()}function u(e,t){var n=(0,c.clamp)(t,e.props.minValue,e.props.maxValue),r=e.props.maxValue-e.props.minValue,a=(n-e.props.minValue)/r;return a||0}function i(e,t){var n={min:u(e,t.min),max:u(e,t.max)};return n}function l(e,t){var n=e.trackClientRect.width,r=u(e,t),a=r*n;return{x:a,y:0}}function s(e,t){var n={min:l(e,t.min),max:l(e,t.max)};return n}function f(e,t){var n=e.trackClientRect,r=n.width,a=t.touches?t.touches[0]:t,o=a.clientX,u={x:(0,c.clamp)(o-n.left,0,r),y:0};return u}function p(e,t){return Math.round(t/e.props.step)*e.props.step}Object.defineProperty(n,"__esModule",{value:!0});var c=e("./util"),d={percentageFromPosition:r,percentageFromValue:u,percentagesFromValues:i,positionFromEvent:f,positionFromValue:l,positionsFromValues:s,stepValueFromValue:p,valueFromPosition:a,valuesFromProps:o};n["default"]=d,t.exports=n["default"]},{"./util":7}],9:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(n,"__esModule",{value:!0});var a=e("./InputRange"),o=r(a);n["default"]=o["default"],t.exports=n["default"]},{"./InputRange":1}]},{},[9])(9)}); \ No newline at end of file +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.InputRange=e()}}(function(){return function e(t,n,a){function r(u,i){if(!n[u]){if(!t[u]){var l="function"==typeof require&&require;if(!i&&l)return l(u,!0);if(o)return o(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var p=n[u]={exports:{}};t[u][0].call(p.exports,function(e){var n=t[u][1][e];return r(n?n:e)},p,p.exports,e,t,n,a)}return n[u].exports}for(var o="function"==typeof require&&require,u=0;u=n.minValue&&t.max<=n.maxValue&&t.min=n.minValue&&t.max<=n.maxValue}function l(e,t){var n=e.props,a=R["default"].valuesFromProps(e);return(0,_.length)(t.min,a.min)>=n.step||(0,_.length)(t.max,a.max)>=n.step}function s(e,t){return i(e,t)&&l(e,t)}function p(e){var t=e.refs.inputRange.ownerDocument;return t}function f(e){var t=e.props;return t.disabled?t.classNames.component+" is-disabled":t.classNames.component}function c(e,t){return t===e.refs.sliderMin?"min":"max"}function d(e){return e.isMultiValue?["min","max"]:["max"]}function h(e,t){var n=R["default"].valuesFromProps(e),a=R["default"].positionsFromValues(e,n);if(e.isMultiValue){var r=(0,_.distanceTo)(t,a.min),o=(0,_.distanceTo)(t,a.max);if(o>r)return"min"}return"max"}function v(e){var t=e.props.classNames,n=[],a=d(e),r=R["default"].valuesFromProps(e),o=R["default"].percentagesFromValues(e,r),u=!0,i=!1,l=void 0;try{for(var s,p=a[Symbol.iterator]();!(u=(s=p.next()).done);u=!0){var f=s.value,c=r[f],h=o[f],v="slider"+(0,_.captialize)(f),m=e.props,y=m.maxValue,b=m.minValue;"min"===f?y=r.max:b=r.min;var w=g["default"].createElement(T["default"],{classNames:t,key:f,maxValue:y,minValue:b,onSliderKeyDown:e.handleSliderKeyDown,onSliderMouseMove:e.handleSliderMouseMove,percentage:h,ref:v,type:f,value:c});n.push(w)}}catch(M){i=!0,l=M}finally{try{!u&&p["return"]&&p["return"]()}finally{if(i)throw l}}return n}function m(e){var t=[],n=d(e),a=!0,r=!1,o=void 0;try{for(var u,i=n[Symbol.iterator]();!(a=(u=i.next()).done);a=!0){var l=u.value,s=e.isMultiValue?""+e.props.name+(0,_.captialize)(l):e.props.name;g["default"].createElement("input",{type:"hidden",name:s})}}catch(p){r=!0,o=p}finally{try{!a&&i["return"]&&i["return"]()}finally{if(r)throw o}}return t}Object.defineProperty(n,"__esModule",{value:!0});var y=function(){function e(e,t){for(var n=0;n=t?new Error("`minValue` must be smaller than `maxValue`"):n>=t?new Error("`maxValue` must be larger than `minValue`"):n>a||a>t?new Error("`value` must be within `minValue` and `maxValue`"):void 0:new Error("`value` or `defaultValue` must be a number or an array")}Object.defineProperty(n,"__esModule",{value:!0});var r=e("./util");n.maxMinValuePropType=a},{"./util":7}],7:[function(e,t,n){"use strict";function a(e,t,n){return Math.min(Math.max(e,t),n)}function r(){return Object.assign.apply(Object,arguments)}function o(e,t){return e.indexOf(t)>-1}function u(e,t){var n=Object.keys(e),a={};return n.forEach(function(n){o(t,n)||(a[n]=e[n])}),a}function i(e){return e.charAt(0).toUpperCase()+e.slice(1)}function l(e,t){return Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2))}function s(e,t){return Math.abs(e-t)}function p(e){return"number"==typeof e}function f(e){return null!==e&&"object"==typeof e}function c(e){return void 0!==e&&null!==e}function d(e){return e?Array.isArray(e)?0===e.length:0===Object.keys(e).length:!0}function h(e,t){if(!Array.isArray(e))return!1;for(var n=0,a=e.length;a>n;n++)if(!t(e[n]))return!1;return!0}function v(e,t,n){if(!f(e))return!1;for(var a=n||Object.keys(e),r=0,o=a.length;o>r;r++){var u=a[r];if(!t(e[u]))return!1}return!0}function m(e,t){e.forEach(function(e){t[e]=t[e].bind(t)})}Object.defineProperty(n,"__esModule",{value:!0});var y={arrayOf:h,autobind:m,captialize:i,clamp:a,distanceTo:l,extend:r,isDefined:c,isEmpty:d,isNumber:p,isObject:f,length:s,objectOf:v,omit:u};n["default"]=y,t.exports=n["default"]},{}],8:[function(e,t,n){"use strict";function a(e,t){var n=e.trackClientRect.width,a=t.x/n;return a||0}function r(e,t){var n=a(e,t),r=e.props.maxValue-e.props.minValue,o=e.props.minValue+r*n;return o}function o(e){var t=arguments.length<=1||void 0===arguments[1]?e:arguments[1],n=t.props;return function(){if(e.isMultiValue){var t=n.value;return((0,c.isEmpty)(t)||!(0,c.objectOf)(t,c.isNumber))&&(t=n.defaultValue),Object.create(t)}var a=(0,c.isNumber)(n.value)?n.value:n.defaultValue;return{min:n.minValue,max:a}}()}function u(e,t){var n=(0,c.clamp)(t,e.props.minValue,e.props.maxValue),a=e.props.maxValue-e.props.minValue,r=(n-e.props.minValue)/a;return r||0}function i(e,t){var n={min:u(e,t.min),max:u(e,t.max)};return n}function l(e,t){var n=e.trackClientRect.width,a=u(e,t),r=a*n;return{x:r,y:0}}function s(e,t){var n={min:l(e,t.min),max:l(e,t.max)};return n}function p(e,t){var n=e.trackClientRect,a=n.width,r=t.touches?t.touches[0]:t,o=r.clientX,u={x:(0,c.clamp)(o-n.left,0,a),y:0};return u}function f(e,t){return Math.round(t/e.props.step)*e.props.step}Object.defineProperty(n,"__esModule",{value:!0});var c=e("./util"),d={percentageFromPosition:a,percentageFromValue:u,percentagesFromValues:i,positionFromEvent:p,positionFromValue:l,positionsFromValues:s,stepValueFromValue:f,valueFromPosition:r,valuesFromProps:o};n["default"]=d,t.exports=n["default"]},{"./util":7}],9:[function(e,t,n){"use strict";function a(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(n,"__esModule",{value:!0});var r=e("./InputRange"),o=a(r);n["default"]=o["default"],t.exports=n["default"]},{"./InputRange":1}]},{},[9])(9)}); \ No newline at end of file diff --git a/package.json b/package.json index 2618f56..371993f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-input-range", - "version": "0.5.1", + "version": "0.6.0", "description": "React component for inputting numeric values within a range", "keywords": [ "react",