Skip to content

Commit 540aa13

Browse files
committed
Notify delegate when interaction is complete
1 parent dfef1df commit 540aa13

File tree

10 files changed

+188
-26
lines changed

10 files changed

+188
-26
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ maxValue |number |Maximum value it c
7878
minValue |number |Minimum value it can accept
7979
name |string |Name of `form` input
8080
onChange |Function |`onChange` callback (required)
81+
onChangeComplete |Function |`onChangeComplete` callback
8182
step |number |Increment/decrement value
8283
value |number | Object.<number> |Current value(s) (required)
8384

example/js/App.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class App extends React.Component {
5050
});
5151
}
5252

53+
handleChangeComplete(component, value) {
54+
console.log(value);
55+
}
56+
5357
render() {
5458
const defaultValue = 2;
5559
const defaultValue2 = {
@@ -64,13 +68,15 @@ class App extends React.Component {
6468
minValue={0}
6569
value={this.state.value}
6670
onChange={this.handleValueChange.bind(this)}
71+
onChangeComplete={this.handleChangeComplete.bind(this)}
6772
/>
6873

6974
<InputRange
7075
maxValue={20}
7176
minValue={0}
7277
value={this.state.value4}
7378
onChange={this.handleValue4Change.bind(this)}
79+
onChangeComplete={this.handleChangeComplete.bind(this)}
7480
/>
7581

7682
<InputRange

karma.conf.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ module.exports = function(config) {
3737
]
3838
},
3939

40+
customLaunchers: {
41+
ChromeCustom: {
42+
base: 'Chrome',
43+
flags: [
44+
'--window-size=300,300'
45+
]
46+
}
47+
},
48+
4049
reporters: ['progress'],
4150

4251
port: 9876,
@@ -47,7 +56,7 @@ module.exports = function(config) {
4756

4857
autoWatch: true,
4958

50-
browsers: ['PhantomJS2'],
59+
browsers: ['ChromeCustom'],
5160

5261
singleRun: false
5362
})

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@
5050
"karma": "^0.13.8",
5151
"karma-babel-preprocessor": "^5.2.1",
5252
"karma-browserify": "^4.3.0",
53-
"karma-es6-shim": "^0.1.3",
53+
"karma-chrome-launcher": "^0.2.2",
5454
"karma-jasmine": "^0.3.6",
55-
"karma-phantomjs2-launcher": "^0.3.2",
5655
"lodash": "^3.10.0",
5756
"phantomjs": "^1.9.17",
5857
"react": "^0.14.0",

src/InputRange/InputRange.js

Lines changed: 94 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import Track from './Track';
44
import Label from './Label';
55
import defaultClassNames from './defaultClassNames';
66
import valueTransformer from './valueTransformer';
7-
import { autobind, captialize, distanceTo, isObject, length } from './util';
7+
import { autobind, captialize, distanceTo, isDefined, isObject, length } from './util';
88
import { maxMinValuePropType } from './propTypes';
99

1010
// Constants
11+
const internals = new WeakMap();
12+
1113
const KeyCode = {
1214
LEFT_ARROW: 37,
1315
RIGHT_ARROW: 39,
@@ -40,6 +42,12 @@ function shouldUpdate(inputRange, values) {
4042
hasStepDifference(inputRange, values);
4143
}
4244

45+
function getDocument(inputRange) {
46+
const { inputRange: { ownerDocument } } = inputRange.refs;
47+
48+
return ownerDocument;
49+
}
50+
4351
function getComponentClassName(inputRange) {
4452
const { props } = inputRange;
4553

@@ -142,10 +150,21 @@ class InputRange extends React.Component {
142150
constructor(props) {
143151
super(props);
144152

153+
// Private
154+
internals.set(this, {});
155+
145156
// Auto-bind
146157
autobind([
147-
'handleSliderMouseMove',
158+
'handleInteractionEnd',
159+
'handleInteractionStart',
160+
'handleKeyDown',
161+
'handleKeyUp',
162+
'handleMouseDown',
163+
'handleMouseUp',
148164
'handleSliderKeyDown',
165+
'handleSliderMouseMove',
166+
'handleTouchStart',
167+
'handleTouchEnd',
149168
'handleTrackMouseDown',
150169
], this);
151170
}
@@ -230,7 +249,7 @@ class InputRange extends React.Component {
230249
}
231250

232251
// Handlers
233-
handleSliderMouseMove(slider, event) {
252+
handleSliderMouseMove(event, slider) {
234253
if (this.props.disabled) {
235254
return;
236255
}
@@ -241,7 +260,7 @@ class InputRange extends React.Component {
241260
this.updatePosition(key, position);
242261
}
243262

244-
handleSliderKeyDown(slider, event) {
263+
handleSliderKeyDown(event, slider) {
245264
if (this.props.disabled) {
246265
return;
247266
}
@@ -262,7 +281,7 @@ class InputRange extends React.Component {
262281
}
263282
}
264283

265-
handleTrackMouseDown(track, position) {
284+
handleTrackMouseDown(event, track, position) {
266285
if (this.props.disabled) {
267286
return;
268287
}
@@ -272,6 +291,70 @@ class InputRange extends React.Component {
272291
this.updatePosition(key, position);
273292
}
274293

294+
handleInteractionStart() {
295+
const _this = internals.get(this);
296+
297+
if (!this.props.onChangeComplete || isDefined(_this.startValue)) {
298+
return;
299+
}
300+
301+
_this.startValue = this.props.value;
302+
}
303+
304+
handleInteractionEnd() {
305+
const _this = internals.get(this);
306+
307+
if (!this.props.onChangeComplete || !isDefined(_this.startValue)) {
308+
return;
309+
}
310+
311+
if (_this.startValue !== this.props.value) {
312+
this.props.onChangeComplete(this, this.props.value);
313+
}
314+
315+
_this.startValue = null;
316+
}
317+
318+
handleKeyDown(event) {
319+
this.handleInteractionStart(event);
320+
}
321+
322+
handleKeyUp(event) {
323+
this.handleInteractionEnd(event);
324+
}
325+
326+
handleMouseDown(event) {
327+
const document = getDocument(this);
328+
329+
this.handleInteractionStart(event);
330+
331+
document.addEventListener('mouseup', this.handleMouseUp);
332+
}
333+
334+
handleMouseUp(event) {
335+
const document = getDocument(this);
336+
337+
this.handleInteractionEnd(event);
338+
339+
document.removeEventListener('mouseup', this.handleMouseUp);
340+
}
341+
342+
handleTouchStart(event) {
343+
const document = getDocument(this);
344+
345+
this.handleInteractionStart(event);
346+
347+
document.addEventListener('touchend', this.handleTouchEnd);
348+
}
349+
350+
handleTouchEnd(event) {
351+
const document = getDocument(this);
352+
353+
this.handleInteractionEnd(event);
354+
355+
document.removeEventListener('touchend', this.handleTouchEnd);
356+
}
357+
275358
// Render
276359
render() {
277360
const { classNames } = this.props;
@@ -283,7 +366,11 @@ class InputRange extends React.Component {
283366
<div
284367
aria-disabled={ this.props.disabled }
285368
ref="inputRange"
286-
className={ componentClassName }>
369+
className={ componentClassName }
370+
onKeyDown={ this.handleKeyDown }
371+
onKeyUp={ this.handleKeyUp }
372+
onMouseDown={ this.handleMouseDown }
373+
onTouchStart={ this.handleTouchStart }>
287374
<Label
288375
className={ classNames.labelMin }
289376
containerClassName={ classNames.labelContainer }>
@@ -320,6 +407,7 @@ InputRange.propTypes = {
320407
minValue: maxMinValuePropType,
321408
name: React.PropTypes.string,
322409
onChange: React.PropTypes.func.isRequired,
410+
onChangeComplete: React.PropTypes.func,
323411
step: React.PropTypes.number,
324412
value: maxMinValuePropType,
325413
};

src/InputRange/Slider.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Slider extends React.Component {
5959
}
6060

6161
handleMouseMove(event) {
62-
this.props.onSliderMouseMove(this, event);
62+
this.props.onSliderMouseMove(event, this);
6363
}
6464

6565
handleTouchStart(event) {
@@ -72,7 +72,7 @@ class Slider extends React.Component {
7272
}
7373

7474
handleTouchMove(event) {
75-
this.props.onSliderMouseMove(this, event);
75+
this.props.onSliderMouseMove(event, this);
7676
}
7777

7878
handleTouchEnd() {
@@ -85,7 +85,7 @@ class Slider extends React.Component {
8585
}
8686

8787
handleKeyDown(event) {
88-
this.props.onSliderKeyDown(this, event);
88+
this.props.onSliderKeyDown(event, this);
8989
}
9090

9191
// Render

src/InputRange/Track.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ class Track extends React.Component {
3535
return clientRect;
3636
}
3737

38-
// Methods
39-
4038
// Handlers
4139
handleMouseDown(event) {
4240
const trackClientRect = this.clientRect;
@@ -46,7 +44,7 @@ class Track extends React.Component {
4644
y: 0,
4745
};
4846

49-
this.props.onTrackMouseDown(this, position);
47+
this.props.onTrackMouseDown(event, this, position);
5048
}
5149

5250
handleTouchStart(event) {

src/InputRange/util.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ function isObject(object) {
4444
return object !== null && typeof object === 'object';
4545
}
4646

47+
function isDefined(value) {
48+
return value !== undefined && value !== null;
49+
}
50+
4751
function isEmpty(obj) {
4852
if (!obj) {
4953
return true;
@@ -102,6 +106,7 @@ const util = {
102106
clamp,
103107
distanceTo,
104108
extend,
109+
isDefined,
105110
isEmpty,
106111
isNumber,
107112
isObject,

0 commit comments

Comments
 (0)