From ea39abdacd41e6c3f2af1112822833b5669275d7 Mon Sep 17 00:00:00 2001 From: davidchin Date: Sun, 22 Nov 2015 11:16:55 +1100 Subject: [PATCH] Add disabled prop --- README.md | 1 + example/js/App.js | 7 ++++ scss/_InputRangeSlider.scss | 11 +++++- scss/_InputRangeTrack.scss | 4 ++ scss/_InputRangeVariables.scss | 8 +++- src/InputRange/InputRange.js | 24 +++++++++++- test/InputRange.spec.js | 70 ++++++++++++++++++++++++++-------- 7 files changed, 104 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index bbff32f..dc4819e 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ ariaLabelledby |string |`aria-labelledby` attribute classNames |Object.<string> |CSS class names defaultValue |number |Default value defaultValues |Object |Default values +disabled |boolean |Disabled or not maxValue |number |Maximum value it can accept minValue |number |Minimum value it can accept name |string |Name of `form` input diff --git a/example/js/App.js b/example/js/App.js index 415a568..568f175 100644 --- a/example/js/App.js +++ b/example/js/App.js @@ -64,6 +64,13 @@ class App extends React.Component { minValue={0} defaultValue={defaultValue} /> + + ); } diff --git a/scss/_InputRangeSlider.scss b/scss/_InputRangeSlider.scss index 16bcaa8..fefc15d 100644 --- a/scss/_InputRangeSlider.scss +++ b/scss/_InputRangeSlider.scss @@ -15,11 +15,18 @@ width: $InputRange-slider-width; &:active { - transform: $InputRange-slider-transform--active; + transform: $InputRange-slider--active-transform; } &:focus { - box-shadow: 0 0 0 5px transparentize($InputRange-primaryColor, 0.8); + box-shadow: 0 0 0 5px transparentize($InputRange-slider-background, 0.8); + } + + .InputRange.is-disabled & { + background: $InputRange-slider--is-disabled-background; + border: $InputRange-slider--is-disabled-border; + box-shadow: none; + transform: none; } } diff --git a/scss/_InputRangeTrack.scss b/scss/_InputRangeTrack.scss index a6c601f..568ccd1 100644 --- a/scss/_InputRangeTrack.scss +++ b/scss/_InputRangeTrack.scss @@ -5,6 +5,10 @@ height: $InputRange-track-height; position: relative; transition: $inputRange-track-transition; + + .InputRange.is-disabled & { + background: $InputRange-track--is-disabled-background; + } } .InputRange-track--container { diff --git a/scss/_InputRangeVariables.scss b/scss/_InputRangeVariables.scss index 43eb42c..bd4f04c 100644 --- a/scss/_InputRangeVariables.scss +++ b/scss/_InputRangeVariables.scss @@ -2,6 +2,7 @@ $InputRange-fontFamily: 'Helvetica Neue', san-serif; $InputRange-primaryColor: #3f51b5; $InputRange-neutralColor: #aaaaaa; $InputRange-neutralLightColor: #eeeeee; +$InputRange-disabledColor: #cccccc; // InputRange-slider $InputRange-slider-background: $InputRange-primaryColor !default; @@ -9,14 +10,17 @@ $InputRange-slider-border: 1px solid $InputRange-primaryColor !default; $InputRange-slider-height: 1rem !default; $InputRange-slider-width: 1rem !default; $InputRange-slider-transition: transform 0.3s ease-out, box-shadow 0.3s ease-out; -$InputRange-slider-transform--active: scale(1.3) !default; $InputRange-sliderContainer-transition: left 0.3s ease-out; +$InputRange-slider--active-transform: scale(1.3) !default; +$InputRange-slider--is-disabled-background: $InputRange-disabledColor !default; +$InputRange-slider--is-disabled-border: 1px solid $InputRange-disabledColor !default; // InputRange-label $InputRange-label-color: $InputRange-neutralColor !default; // InputRange-track -$InputRange-track--active-background: $InputRange-primaryColor !default; $InputRange-track-background: $InputRange-neutralLightColor !default; $InputRange-track-height: 0.3rem !default; $inputRange-track-transition: left 0.3s ease-out, width 0.3s ease-out; +$InputRange-track--active-background: $InputRange-primaryColor !default; +$InputRange-track--is-disabled-background: $InputRange-neutralLightColor !default; diff --git a/src/InputRange/InputRange.js b/src/InputRange/InputRange.js index d876cac..8b9eee3 100644 --- a/src/InputRange/InputRange.js +++ b/src/InputRange/InputRange.js @@ -233,12 +233,20 @@ class InputRange extends React.Component { // Handlers handleSliderMouseMove(slider, event) { + if (this.props.disabled) { + return; + } + const position = this.valueTransformer.positionFromEvent(event); this.setPosition(slider, position); } handleSliderKeyDown(slider, event) { + if (this.props.disabled) { + return; + } + switch (event.keyCode) { case KeyCode.LEFT_ARROW: this.decrementValue(slider); @@ -254,6 +262,10 @@ class InputRange extends React.Component { } handleTrackMouseDown(track, position) { + if (this.props.disabled) { + return; + } + this.setPosition(null, position); } @@ -313,9 +325,17 @@ class InputRange extends React.Component { render() { const classNames = this.props.classNames; + let componentClassName = classNames.component; + + if (this.props.disabled) { + componentClassName = `${componentClassName} is-disabled`; + } return ( -
+
{ this.props.minValue } @@ -348,6 +368,7 @@ InputRange.propTypes = { classNames: React.PropTypes.objectOf(React.PropTypes.string), defaultValue: maxMinValuePropType, defaultValues: maxMinValuePropType, + disabled: React.PropTypes.bool, maxValue: maxMinValuePropType, minValue: maxMinValuePropType, name: React.PropTypes.string, @@ -359,6 +380,7 @@ InputRange.propTypes = { InputRange.defaultProps = { classNames: defaultClassNames, + disabled: false, minValue: 0, maxValue: 10, step: 1, diff --git a/test/InputRange.spec.js b/test/InputRange.spec.js index 35d3848..d0086f6 100644 --- a/test/InputRange.spec.js +++ b/test/InputRange.spec.js @@ -45,6 +45,7 @@ describe('InputRange', () => { it('should set the initial position for slider', () => { const props = { classNames: jasmine.any(Object), + disabled: false, maxValue: 20, minValue: 0, values: { @@ -551,74 +552,111 @@ describe('InputRange', () => { }); describe('handleSliderMouseMove', () => { + let slider; + let event; + beforeEach(() => { spyOn(inputRange, 'setPosition'); - }); - it('should set the position of a slider according to mouse event', () => { - const slider = inputRange.refs.sliderMax; - const event = { + slider = inputRange.refs.sliderMax; + event = { clientX: 100, clientY: 200, }; + }); + it('should set the position of a slider according to mouse event', () => { inputRange.handleSliderMouseMove(slider, event); expect(inputRange.setPosition).toHaveBeenCalledWith(slider, { x: 92, y: 0 }); }); + + it('should not set the position of a slider if disabled', () => { + inputRange.props.disabled = true; + inputRange.handleSliderMouseMove(slider, event); + + expect(inputRange.setPosition).not.toHaveBeenCalled(); + }); }); describe('handleSliderKeyDown', () => { + let slider; + let event; + describe('when pressing left arrow key', () => { beforeEach(() => { spyOn(inputRange, 'decrementValue'); - }); - it('should decrement value', () => { - const slider = inputRange.refs.sliderMax; - const event = { + slider = inputRange.refs.sliderMax; + event = { keyCode: 37, }; + }); + it('should decrement value', () => { inputRange.handleSliderKeyDown(slider, event); expect(inputRange.decrementValue).toHaveBeenCalledWith(slider); }); + + it('should not decrement value if disabled', () => { + inputRange.props.disabled = true; + inputRange.handleSliderKeyDown(slider, event); + + expect(inputRange.decrementValue).not.toHaveBeenCalled(); + }); }); describe('when pressing right arrow key', () => { beforeEach(() => { spyOn(inputRange, 'incrementValue'); - }); - it('should increment value', () => { - const slider = inputRange.refs.sliderMax; - const event = { + slider = inputRange.refs.sliderMax; + event = { keyCode: 39, }; + }); + it('should increment value', () => { inputRange.handleSliderKeyDown(slider, event); expect(inputRange.incrementValue).toHaveBeenCalledWith(slider); }); + + it('should not increment value if disabled', () => { + inputRange.props.disabled = true; + inputRange.handleSliderKeyDown(slider, event); + + expect(inputRange.incrementValue).not.toHaveBeenCalled(); + }); }); }); describe('handleTrackMouseDown', () => { + let track; + let position; + beforeEach(() => { spyOn(inputRange, 'setPosition'); - }); - it('should set a new position based on the position of mouse click', () => { - const track = {}; - const position = { + track = {}; + position = { x: 100, y: 0, }; + }); + it('should set a new position based on the position of mouse click', () => { inputRange.handleTrackMouseDown(track, position); expect(inputRange.setPosition).toHaveBeenCalledWith(null, position); }); + + it('should not set a new position if disabled', () => { + inputRange.props.disabled = true; + inputRange.handleTrackMouseDown(track, position); + + expect(inputRange.setPosition).not.toHaveBeenCalled(); + }); }); });