Skip to content

Commit

Permalink
Add defaultValue prop
Browse files Browse the repository at this point in the history
  • Loading branch information
davidchin committed Nov 21, 2015
1 parent 333e4c7 commit 0df907a
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 50 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ Property | Type | Description
:-----------------------|:------------------------|:----------------------------------
ariaLabelledby |string |`aria-labelledby` attribute
classNames |Object.<string> |CSS class names
defaultValue |number |Default value
defaultValues |Object |Default values
maxValue |number |Maximum value it can accept
minValue |number |Minimum value it can accept
name |string |Name of `form` input
onChange |Function |`onChange` callback
step |number |Increment/decrement value
value |number |Default value
values |Array.<number> |Default range of values
value |number |Current value
values |Object |Current range of values

## Development

Expand Down
25 changes: 24 additions & 1 deletion example/js/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,35 @@ class App extends React.Component {
this.state = {
value: 5,
values: {
min: 2,
min: 5,
max: 10,
},
};
}

handleValuesChange(component, values) {
console.log(values);

this.setState({
values: values,
});
}

handleValueChange(component, value) {
console.log(value);

this.setState({
value: value,
});
}

render() {
const defaultValue = 2;
const defaultValues = {
min: 2,
max: 8,
};

return (
<form className="form">
<InputRange
Expand All @@ -35,12 +45,25 @@ class App extends React.Component {
values={this.state.values}
onChange={this.handleValuesChange.bind(this)}
/>

<InputRange
maxValue={20}
minValue={0}
defaultValues={defaultValues}
/>

<InputRange
maxValue={20}
minValue={0}
value={this.state.value}
onChange={this.handleValueChange.bind(this)}
/>

<InputRange
maxValue={20}
minValue={0}
defaultValue={defaultValue}
/>
</form>
);
}
Expand Down
1 change: 1 addition & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = function(config) {

files: [
'node_modules/react/dist/react.js',
'node_modules/lodash/index.js',
'node_modules/babelify/polyfill.js',
'src/**/*.js',
'test/**/*.js'
Expand Down
40 changes: 31 additions & 9 deletions src/InputRange/InputRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import Slider from './Slider';
import Track from './Track';
import ValueTransformer from './ValueTransformer';
import { autobind, captialize, clamp, distanceTo, extend } from './util';
import { autobind, captialize, clamp, distanceTo, extend, isEmpty, isNumber, omit } from './util';
import { maxMinValuePropType } from './propTypes';
import defaultClassNames from './defaultClassNames';

Expand Down Expand Up @@ -53,6 +53,7 @@ class InputRange extends React.Component {

// Initial state
const state = {
didChange: false,
percentages: {
min: 0,
max: 0,
Expand All @@ -69,7 +70,8 @@ class InputRange extends React.Component {

this.state = state;
this.valueTransformer = new ValueTransformer(this);
this.isMultiValue = this.props.hasOwnProperty('values');
this.isMultiValue = this.props.hasOwnProperty('defaultValues') ||
this.props.hasOwnProperty('values');

// Auto-bind
autobind([
Expand All @@ -85,24 +87,27 @@ class InputRange extends React.Component {
}

componentWillReceiveProps(nextProps) {
this.setPositionsByProps(nextProps);
const props = omit(nextProps, ['defaultValue', 'defaultValues']);

this.setPositionsByProps(props);
}

shouldComponentUpdate(nextProps, nextState) {
const currentProps = this.props;
const currentState = this.state;

return (
const shouldUpdate = (
currentState.values.min !== nextState.values.min ||
currentState.values.max !== nextState.values.max ||
currentState.value !== nextState.value ||
currentProps.minValue !== nextProps.minValue ||
currentProps.maxValue !== nextProps.maxValue
);

return shouldUpdate;
}

componentDidUpdate() {
if (this.props.onChange) {
if (this.props.onChange && this.state.didChange) {
let results = this.state.values.max;

if (this.isMultiValue) {
Expand All @@ -111,6 +116,10 @@ class InputRange extends React.Component {

this.props.onChange(this, results);
}

this.setState({
didChange: true,
});
}

// Getters / Setters
Expand Down Expand Up @@ -168,13 +177,21 @@ class InputRange extends React.Component {
}

setPositionByValue(slider, value) {
if (!isNumber(value)) {
return;
}

const validValue = clamp(value, this.props.minValue, this.props.maxValue);
const position = this.valueTransformer.positionFromValue(validValue);

this.setPosition(slider, position);
}

setPositionsByValues(values) {
if (!values || !isNumber(values.min) || !isNumber(values.max)) {
return;
}

const validValues = {
min: clamp(values.min, this.props.minValue, this.props.maxValue),
max: clamp(values.max, this.props.minValue, this.props.maxValue),
Expand All @@ -190,9 +207,13 @@ class InputRange extends React.Component {

setPositionsByProps(props) {
if (this.isMultiValue) {
this.setPositionsByValues(props.values);
const values = !isEmpty(props.values) ? props.values : props.defaultValues;

this.setPositionsByValues(values);
} else {
this.setPositionByValue(this.refs.sliderMax, props.value);
const value = isNumber(props.value) ? props.value : props.defaultValue;

this.setPositionByValue(this.refs.sliderMax, value);
}
}

Expand Down Expand Up @@ -325,6 +346,8 @@ class InputRange extends React.Component {
InputRange.propTypes = {
ariaLabelledby: React.PropTypes.string,
classNames: React.PropTypes.objectOf(React.PropTypes.string),
defaultValue: maxMinValuePropType,
defaultValues: maxMinValuePropType,
maxValue: maxMinValuePropType,
minValue: maxMinValuePropType,
name: React.PropTypes.string,
Expand All @@ -338,7 +361,6 @@ InputRange.defaultProps = {
classNames: defaultClassNames,
minValue: 0,
maxValue: 10,
value: 0,
step: 1,
};

Expand Down
16 changes: 12 additions & 4 deletions src/InputRange/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ export function maxMinValuePropType(props) {
const minValue = props.minValue;
const value = props.value;
const values = props.values;
const defaultValue = props.defaultValue;
const defaultValues = props.defaultValues;

if (!numberPredicate(value)) {
return new Error('`value` must be a number');
if (!values &&
!defaultValues &&
!numberPredicate(value) &&
!numberPredicate(defaultValue)) {
return new Error('`value` or `defaultValue` must be a number');
}

if (!value && !objectOf(values, numberPredicate)) {
return new Error('`values` must be an object of numbers');
if (!value &&
!defaultValue &&
!objectOf(values, numberPredicate) &&
!objectOf(defaultValues, numberPredicate)) {
return new Error('`values` or `defaultValues` must be an object of numbers');
}

if (minValue >= maxValue) {
Expand Down
31 changes: 31 additions & 0 deletions src/InputRange/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ function extend() {
return Object.assign.apply(Object, arguments);
}

function includes(array, value) {
return array.indexOf(value) > -1;
}

function omit(obj, omitKeys) {
const keys = Object.keys(obj);
const outputObj = {};

keys.forEach((key) => {
if (!includes(omitKeys, key)) {
outputObj[key] = obj[key];
}
});

return outputObj;
}

function captialize(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
Expand All @@ -18,6 +35,18 @@ function isNumber(number) {
return typeof number === 'number';
}

function isEmpty(obj) {
if (!obj) {
return true;
}

if (Array.isArray(obj)) {
return obj.length === 0;
}

return Object.keys(obj).length === 0;
}

function arrayOf(array, predicate) {
if (!Array.isArray(array)) {
return false;
Expand Down Expand Up @@ -63,8 +92,10 @@ const util = {
clamp,
distanceTo,
extend,
isEmpty,
isNumber,
objectOf,
omit,
};

export default util;
Loading

0 comments on commit 0df907a

Please sign in to comment.