Skip to content

Allow ranges of length zero#101

Closed
Graham42 wants to merge 1 commit intodavidchin:masterfrom
Graham42:zero_length_range
Closed

Allow ranges of length zero#101
Graham42 wants to merge 1 commit intodavidchin:masterfrom
Graham42:zero_length_range

Conversation

@Graham42
Copy link
Copy Markdown

Sometimes you want a range to have min / max values exactly the same.

This fixes #92, #55, and #85

@Graham42
Copy link
Copy Markdown
Author

@davidchin Thoughts on this?

@davidchin
Copy link
Copy Markdown
Owner

Hey @Graham42, thanks for your contribution. I tested it manually and it works well. However, I'd like to include this as an additive change so that it's backward compatible. Can you introduce a boolean flag, such as equalValues, to turn on this change? Thanks!

@Graham42
Copy link
Copy Markdown
Author

Graham42 commented Jul 29, 2017

I thought about it and decided people actually might want a want to set a minimum length for their range. This will default to 1 for backwards compatibility, but can be set to 0 to achieve my goals.

Also, I added unit tests. (Sorry should have done that the first time round)

Comment thread src/js/input-range/input-range.jsx Outdated
disabled: false,
maxValue: 10,
minValue: 0,
minSize: 1,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a nice idea / suggestion. But I think we might have a problem with minSize set to 1 by default. This is because step value might not be 1. We want minSize to equal to step or exact multiples of step. Do you know how to resolve that problem?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed this to default to null, and use the step size if nothing is passed in. Thoughts?

Copy link
Copy Markdown
Owner

@davidchin davidchin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing the changes! I have few more comments. Let me know if you need any help.

Comment thread src/js/input-range/input-range.jsx Outdated
return new Error('Minimum range size must be a multiple of the step size');
}
}
return PropTypes.number.apply(this, props, propName, args);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think since v15.3, you're not allowed to run the validator directly. You have to call PropTypes.checkPropTypes. i.e.: PropTypes.checkPropTypes({ [propName]: PropTypes.number }, props, propName, componentName);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like checkPropTypes is for checking in production. There's a paragraph just a bit further down on the page you linked that shows how we should handle this.

You might also see this error if you’re calling a PropTypes validator from your own custom PropTypes validator. In this case, the fix is to make sure that you are passing all of the arguments to the inner function. There is a more in-depth explanation of how to fix it on this page.

Comment thread src/js/input-range/input-range.jsx Outdated
import { captialize, distanceTo, isDefined, isObject, length } from '../utils';
import { DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from './key-codes';

function minimumRangeSizeValidator(props, propName, ...args) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for you to move to a separate file, similar to range-prop-type.js?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

Comment thread src/js/input-range/input-range.jsx Outdated
return ['max'];
}

@autobind
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@autobind decorator is probably unnecessary in this case.

Comment thread src/js/input-range/input-range.jsx Outdated
formatLabel: PropTypes.func,
maxValue: rangePropType,
minValue: rangePropType,
minSize: minimumRangeSizeValidator,
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably name the prop differently. Perhaps minRange might be more appropriate?

Comment thread src/js/input-range/input-range.jsx Outdated

@autobind
getMinRangeSize() {
return this.props.minSize !== null ? this.props.minSize : this.props.step;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also need to check undefined

Comment thread src/js/input-range/input-range.jsx Outdated
* @param {Function} [props.formatLabel]
* @param {number|Range} [props.maxValue = 10]
* @param {number|Range} [props.minValue = 0]
* @param {number} [props.minSize = 1] // or defaults to step if step > 1
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update this comment.

@Graham42
Copy link
Copy Markdown
Author

Just realized that requiring the minimum range to be a multiple of step is not a backwards compatible change. Before my original change the logic would allow a minimum range of 1 and (for example) a step of 2. So the range selected could be 1, 3, 5, etc.

I'm thinking it would be best to undo the change the requires the minimum range to be a multiple of step.

@Graham42
Copy link
Copy Markdown
Author

I can rebase and squash all these commits once you're happy with this PR

Copy link
Copy Markdown
Owner

@davidchin davidchin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Graham42, thanks for making all the changes. You're almost there. Can you take a look at my comments? Thanks.

Comment thread src/js/input-range/input-range.jsx Outdated
return values.min >= this.props.minValue &&
values.max <= this.props.maxValue &&
values.min < values.max;
(values.max - values.min) >= this.props.minRange;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current solution (1 as the default minRange value) only works if step value is greater or equal to one. But it doesn't work if the step value is less than one.

I suggest making minRange optional with no default value. If minRange is not provided, use step to check against max/min values here. To ensure minRange is a multiple of step, add a check in minimumRangePropType.

Comment thread src/js/input-range/input-range.jsx Outdated
(values.max - values.min) >= this.props.minRange;
}

return values.max >= this.props.minValue && values.max <= this.props.maxValue;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have to make minRange prop work for single-value sliders.


/**
*
* @param {*} props
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the param type could be a little bit more specific.

Sometimes you want a range to have min / max values exactly the same.
Achieve this by setting a minimum range of zero.
@Graham42
Copy link
Copy Markdown
Author

Felt like it was getting confusing. So I've made the changes and squashed everything down to 1 commit.

@Graham42
Copy link
Copy Markdown
Author

Bump @davidchin

@davidchin
Copy link
Copy Markdown
Owner

Hey @Graham42, sorry I forgot to get back to you. I tested it earlier and found two problems:

  1. It doesn't really work when draggableTrack is set to true.
  2. It doesn't really work when there's only a single value (single slider).

@Graham42
Copy link
Copy Markdown
Author

Thanks, I'll look into it.

@Graham42
Copy link
Copy Markdown
Author

I ended up just using this other package which suits my needs for a range input https://github.com/react-component/slider

@Graham42 Graham42 closed this Oct 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants