Code Monkey home page Code Monkey logo

react-input-range's Introduction

react-input-range

InputRange is a React component allowing users to input numeric values within a specific range. It can accept a single value, or a range of values (min/max). By default, basic styles are applied, but can be overridden depending on your design requirements.

Build Status

Demo

A CodePen demo is available here.

Installation

  1. Install react-input-range using npm (or yarn). npm install react-input-range
  2. Import react-input-range to use InputRange component.
  3. Optionally, import react-input-range/lib/css/index.css if you want to apply the default styling.

Usage

To accept min/max value:

import React from 'react';
import ReactDOM from 'react-dom';
import InputRange from 'react-input-range';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: { min: 2, max: 10 },
    };
  }

  render() {
    return (
      <InputRange
        maxValue={20}
        minValue={0}
        value={this.state.value}
        onChange={value => this.setState({ value })} />
    );
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);

To accept a single value:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = { value: 10 };
  }

  render() {
    return (
      <InputRange
        maxValue={20}
        minValue={0}
        value={this.state.value}
        onChange={value => this.setState({ value })} />
    );
  }
}

To format labels:

<InputRange
  formatLabel={value => `${value}cm`}
  value={this.state.value}
  onChange={value => this.setState({ value })} />

To specify the amount of increment/decrement

<InputRange
  step={2}
  value={this.state.value}
  onChange={value => this.setState({ value })} />

API

InputRange#props

allowSameValues: boolean

Set to true to allow minValue and maxValue to be the same.

ariaLabelledby: string

Set aria-labelledby attribute to your component.

ariaControls: string

Set aria-controls attribute to your component.

classNames: InputRangeClassNames

Override the default CSS classes applied to your component and its sub-components.

disabled: boolean

If this property is set to true, your component is disabled. This means you'll not able to interact with it.

draggableTrack: boolean

If this property is set to true, you can drag the entire track.

formatLabel: (value: number, type: string): string

By default, value labels are displayed as plain numbers. If you want to change the display, you can do so by passing in a function. The function can return something different, i.e.: append a unit, reduce the precision of a number.

maxValue: number

Set a maximum value for your component. You cannot drag your slider beyond this value.

minValue: number

Set a minimum value for your component. You cannot drag your slider under this value.

name: string

Set a name for your form component.

onChange: (value: number | Range): void

Whenever your user interacts with your component (i.e.: dragging a slider), this function gets called. Inside the function, you should assign the new value to your component.

onChangeStart: (value: number | Range): void

Whenever your user starts interacting with your component (i.e.: onMouseDown, or onTouchStart), this function gets called.

onChangeComplete: (value: number | Range): void

Every mouse / touch event can trigger multiple updates, therefore causing onChange callback to fire multiple times. On the other hand, onChangeComplete callback only gets called when the user stops dragging.

step: number

The default increment/decrement of your component is 1. You can change that by setting a different number to this property.

value: number | Range

Set the current value for your component. If only a single number is provided, only a single slider will get rendered. If a range object (min/max) is provided, two sliders will get rendered

Types

InputRangeClassNames

  • activeTrack: string
  • disabledInputRange: string
  • inputRange: string
  • labelContainer: string
  • maxLabel: string
  • minLabel: string
  • slider: string
  • sliderContainer: string
  • track: string
  • valueLabel: string

Range

  • max: number
  • min: number

Development

If you want to work on this project locally, you need to grab all of its dependencies, for which we recommend using yarn. You can find the instructions to setup yarn here.

yarn install

After that, you should be able run to preview

yarn dev

To test

yarn test

Contributions are welcome. :)

react-input-range's People

Contributors

chrisdale44 avatar davidchin avatar emolr avatar esseb avatar frontenddeveloping avatar jcgertig avatar jhblacklock avatar leobauza avatar mallorybulkley avatar mmaday avatar moritzuehling avatar oyeanuj avatar patrik-piskay avatar rejschaap avatar sheepfromheaven avatar wdolo avatar wesleyklop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-input-range's Issues

add a way to remove animation

Hi,
the animation is nice and all.
But what if I'd like to remove/disable the animation ?

Is there a way to do it atm ?

Regards

Step size forces value to be multiple of that number

Say I have a slider where the minValue = 17 and the maxValue = 100. If I set the step size at 10, I expect the lower range slider to go 17 -> 27 -> 37 and the upper range slider to go from 100 -> 90 -> 80.

Instead, the lower range slider goes 17 -> 20 -> 30. Because of this, it can't return to its initial value of 17.

Binding timing

I was wondering if the initializeTouchEvents and autobind should happen in componentDidMount rather than the constructor? Seems to work anyway under normal circumstances but I ran it with the hot loader and it exploded with:

Invariant Violation: Component (with keys: getDOMNode,_handleChange,props,context,state,refs,_reactInternalInstance) contains render method but is not mounted in the DOM

Flexible change on classNames

It should be possible to change a className in some components of the InputRange without resetting all the default classes.

For example, given the InputRange classNames set below:

...
classNames={ { component: 'custom-input-range__component' } }
...

That will remove all the default classes and setup the component only. It should be possible to keep the default behaviour for other classes of components (like labelMax, labelMin, slider) and change only other desired ones.

Another possibility would be export all default class names and extend them.

Hidden inputs never worked

Hey, I don't actually need this feature but it looks like the hidden inputs feature never worked since renderHiddenInputs just returns an empty array. You could fix it by doing something like:

function renderHiddenInputs(rangeSlider) {
  const keys = getKeys(rangeSlider);

  return keys.map((key) => {
    const name = rangeSlider.isMultiValue ?
      `${rangeSlider.props.name}${captialize(key)}` : rangeSlider.props.name;
    return <input key={key} type="hidden" name={name} />;
  });
}

And perhaps only render if name is passed:

{this.props.name && renderHiddenInputs(this)}

Otherwise you would get undefinedMax and undefinedMin

Not working for project using react 0.14

npm install react-input-range --save
npm WARN peerDependencies The peer dependency react@^0.13.3 included from react-input-range will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm ERR! Darwin 14.3.0
npm ERR! argv "node" "/usr/local/bin/npm" "install" "react-input-range" "--save"
npm ERR! node v0.12.4
npm ERR! npm v2.10.1
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package react does not satisfy its siblings' peerDependencies requirements!

How to use with a owner component?

I want to use this component within another React component. onChange I would like to print the current value of the slider within the owner component. To do this, I call setState on every onChange to make the value available for my components render. This causes InputRange to freeze.

This shows the issue: http://codepen.io/anon/pen/zvzodN

Here I'm calling setState directly on the component itself, but it's the same if I call it on an owner.

Could you tell me what the problem is?

TypeError: Cannot read property 'ownerDocument' of undefined when using with redux-form

In a basic create-redux-app setup, I have the following code:

import 'react-input-range/dist/react-input-range.css'
import React from 'react';
import ReactDOM from 'react-dom';
import InputRange from 'react-input-range';
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import { reducer as formReducer, reduxForm, Field } from 'redux-form';

const rootReducer = combineReducers({
  form: formReducer
});

const store = createStore(rootReducer);

const App = (props) => {
  return (
    <form onSubmit={props.handleSubmit}>
      <Field
        name="foo"
        maxValue={20}
        minValue={0}
        component={({input: {onChange, ...inputParams}, ...params})=>(
    <InputRange
      {...inputParams}
      {...params}
      onChange={(control, values) => onChange(values)}
      />
          )}
      />
    </form>
  );
};

const AppForm = reduxForm({
  form: 'test',
  initialValues: {
    foo: {
      min: 2,
      max: 10
    }
  },
  onSubmit: (values) => console.log("SUBMIT!", values)
})(App);

ReactDOM.render(
  <Provider store={store}><AppForm /></Provider>,
  document.getElementById('root')
);

The initial rendering is ok, but if you drag the InputRange a bit, it throws the following error:

Uncaught TypeError: Cannot read property 'ownerDocument' of undefined
at getDocument (Slider.js:38)
at Slider.handleMouseUp (Slider.js:126)
Uncaught TypeError: Cannot read property 'ownerDocument' of undefined
at getDocument (InputRange.js:117)
at InputRange.handleMouseUp (InputRange.js:613)

Here's a GitHub repo where the error happens: https://github.com/stralsi/react-input-range-error

Decimal steps and floats can make it impossible to select the max value

Steps to reproduce:

  1. Open http://codepen.io/Esseb/pen/zqZVma
  2. Try to move the slider all the way to the right

Result:
The slider stops at 3.9000000000000004
screen shot 2016-03-22 at 12 40 48

Further information:
Tested in Firefox on Mac.

I worked around the issue in my app by simply multiplying the min, max, value, and step I send in by 100 and rounding down to prevent react-input-range from having to deal with floats. The values I needed were min 0%, max 4%, and step 0.1%, so multiplying by 100 worked fine for my case.

preventDefault inside passive event listener

Hello. using this component in latest Chrome causes following warning:

Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

Stack trace:

preventDefault	@	SyntheticEvent.js:32
handleTrackMouseDown	@	input-range.js:560
handleMouseDown	@	track.js:146
handleTouchStart	@	track.js:159
ReactErrorUtils.invokeGuardedCallback	@	ReactErrorUtils.js:27
executeDispatch	@	EventPluginUtils.js:20
executeDispatchesInOrder	@	EventPluginUtils.js:23
executeDispatchesAndRelease	@	EventPluginHub.js:20
executeDispatchesAndReleaseTopLevel	@	EventPluginHub.js:20
forEachAccumulated	@	forEachAccumulated.js:16
processEventQueue	@	EventPluginHub.js:91
runEventQueueInBatch	@	ReactEventEmitterMixin.js:9
handleTopLevel	@	ReactEventEmitterMixin.js:12
handleTopLevelImpl	@	ReactEventListener.js:21
perform	@	Transaction.js:99
batchedUpdates	@	ReactDefaultBatchingStrategy.js:13
batchedUpdates	@	ReactUpdates.js:16
dispatchEvent	@	ReactEventListener.js:41

UPD: one of possible solutions is to add approptiate CSS rule to .input-range__slider

UPD2: Perhaps, touch-action: pan-x; is suitable in this case, since vertical positioning is not supported

onChange should not be required when input range is disabled

Hi @davidchin! I have a use-case where I am using this to either show progress or some stat but in both cases, it is not changeable by the user.

For that, I can use the disabled option though then react-input-range prompts me for a onChange function which in this case doesn't make semantic sense. For now, I am using a noop but the appropriate fix I imagine would be checking against the disabled condition to see if onChange is needed or not.

Failed prop type: The prop `onChange` is marked as required in `InputRange`, but its value is `undefined`.

Just wanted to bring it up for future enhancements!

Testing - How to simulate value change

I'm trying to write a test which checks that when I change the values, certain strings in the DOM change.

I'm trying to simulate a click on the track container or the slider, but it does not seem to register the click event. Or a mousedown event. Is this possible?

Is it mobile optimized?

Hi, first thank you for great component. I would like to use it in HTML5 SPA. The only issue on mobile (Chrome, Safari) is that sometimes component is not responsive sliding. Not sure if it's because the drag handlers are too small for fingers or any problem. Is the component mobile ready?

Improve animation performance

I've noticed that a change in value results into a change in width for the active track and a change of left for the slider container. Changing these properties causes unnecessary reflows and repaints (see here: width and left).

Would it make sense to change both of these to transform so only composite is triggered when the value is changed?

This would result into an improved animation performance and in general a more smooth feel as the elements can animate through "sub CSS pixels" on screens with a higher pixel density.

props.value is not obvious enought

When using props.value as an object, it should be more clear what the expected field are.
We've got an example, but the table down the readme is not clear enought

Starting the drag of the slider handle needs to be normalized to the starting value, value change should not happen without movement

When you start to drag the slider handle, it will instantly jump to the horizontal position that the drag was initiated on.

This can lead to some frustration with fine adjustments on larger input ranges.

To see an example, go here:
http://codepen.io/anon/pen/OWYWOz

Try beginning a drag on the RIGHT side of the circle, and then on the LEFT side of the circle, without actually dragging it.

Notice how the value instantly jumps by some increment?

If you click down on the handle without moving it should not change the value, the value should remain what the value was at the start.

Value changes should only occur once movement has occurred.

Labels on hover

Hi @davidchin! Firstly, thank for you building this useful component and putting out there!

It seems to be a common use-case for sliders to have some sort of a tooltip. I was wondering if adding a tooltip (css-only, so no new dependencies) is on your radar, or if you had any thoughts on about it?

Thank you!

Doesn't work with webpack

Thanks a lot for the great component! Looks like the best of the available range sliders!

However, I'm having troubles to use this with webpack.

It throws the following error on line 480:

Uncaught TypeError: Cannot read property 'initializeTouchEvents' of undefined

Looks like React couldn't be imported.

Am I doing something wrong?

Necessary polyfills?

Could you tell me which polyfills this component depends on?

I'm using it in a environment, where I can't afford including the complete Babel polyfill. I'd like to include only the polyfills that are necessary.

When I use require('core-js/fn/symbol');, I get the following error in IE11:

Object doesn't support property or method 'Symbol(Symbol.iterator)_6.dcz7vm7xaw5'

I also tried another Symbol polyfill with require('es6-symbol/implement');. IE11 says:

Object expected

Are there other polyfill dependencies apart from Symbol?

I'd need to get the component working in IE10 and IE11. I'm using version 0.3.2 of the component, as I still have to use React 0.13.3. I've also uploaded a repo demonstrating the issue here.

I am not allowed to npm install [email protected] with react 15.0.1

Running

npm install [email protected]

I get the following error:

npm WARN peerDependencies The peer dependency react@^0.14.0 included from react-input-range will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm ERR! Windows_NT 10.0.10586
npm ERR! argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js" "install" "[email protected]"
npm ERR! node v4.4.2
npm ERR! npm v2.15.0
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package [email protected] does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react@^0.14.0

npm ERR! Please include the following file with any support request:
npm ERR! C:\Users\Eric\meteorProj\test\npm-debug.log

Thanks

Performance input range

Hello, I use electron+react and react-input-range.
I have a problem with frequent updates value.
If I frequently update the value, the CPU usage immediately picks up 30%.
Any ideas how to increase performance.

<InputRange
          maxValue={1}
          minValue={0}
          step={0.10}
          value={this.props.time}
/>

Ref undefined

Hello there,

Nice library you have here, thank you for your time.

I'm having a problem with the refs not sticking for whatever reason. when the component tries to obtain the owner document I get this error:

Cannot read property 'ownerDocument' of undefined

This occurs in both the InputRange.js and Slider.js files in the function getDocument.

Basically, the refs key of the passed component instance is an empty object.

Any ideas?

Thanks again

Region drag

Would be great if its possible to drag the region, so min and max are updated while the width stays the same.

Issue in Firefox on Android

The range sliders are acting quite sluggish and unpredictable in Firefox (46.0.1) on Android (v. 5.1.1, Nexus 7). In our app we are experience delays, about 2-3 seconds, on updating the handle position when touching and dragging either one of the handles (range value).
Another issue is that when once you have updated one of the handles, and released it, it is very hard to get hold of the other handle. Seems like the touchend event is not properly being handled, or something along those lines.

eslint config

Are you willing to accept dropping this eslint rule ?

  quotes:
    - 2
    - single

I'am developing on window and git automatically checkout with crlf .

Issue on Android Native/Stock Browser

Can't seem to load my web app on android (Samsung/Lenovo) native/stock browser because i was importing react-input-range. Once i commented out the import, my web app can be loaded on the browser.

alternative to step number

When using very distant minValue and maxValue it would be super cool to be able to specify a custom function/range to specify something else than a linear repartition.

The example that i think of is a selector for the price of a house.
Let's say we start at 80 000 and end at 10 000 000.

It's pretty clear that we don't want to make constant jumps.

Input-Range not working after version update

Hello!

The react-input-range component stopped working after updating to version 1.1.3. Here are the before and after pictures of what's happening.

There seem to be no errors in the console related to this component. Any pointers on what the issue might be?

Thank you!
screen shot 2017-05-16 at 11 51 26 am
screen shot 2017-05-16 at 11 51 54 am

Decimal values

Oh and support for decimal values would also be great :). Sorry for so many issues!

Feature Request: Adding support for a graph range slider

Hey there! I really like this project. I'd like to talk about extending the input range to be compatible with how I'd integrate it into a d3 timeseries graph.

Say I had a timeseries of data from 2000 to 2018, but I want to zoom in to a specific date range. To do this I'd drag each dot in to a specific start and end date and notice the graph update to that new date range.

Now say I'd like to look back a year or two at the same zoom level. To do this I could click and drag the line between the dots and effectively pan to the range I'd like to see.

The maximum and minimum of the range slider is related to the max and min of my timeseries data.

rangeslider mock up

Is this something this project is interested in supporting? What areas of the code do you think need to be changed to support this? I'd love to know what you think!

Set up for development

I'd like to set the project up for development, so I can send some pull requests regarding the issues I've opened, so I don't have to bother you too much :).

However, I'm having some troubles with running npm run start after npm install:

❯ npm run start

> [email protected] start /Users/Jan/Projects/OpenSource/react-input-range
> gulp run

[11:44:34] Requiring external module babel-core/register
module.js:338
    throw err;
          ^
Error: Cannot find module '/Users/Jan/Projects/OpenSource/react-input-range/build/react-input-range'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.require.resolve (module.js:388:19)
    at Object.<anonymous> (/Users/Jan/Projects/OpenSource/react-input-range/tasks/config.js:48:15)
    at Module._compile (module.js:460:26)
    at normalLoader (/Users/Jan/Projects/OpenSource/react-input-range/node_modules/babel-core/lib/api/register/node.js:199:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/Jan/Projects/OpenSource/react-input-range/node_modules/babel-core/lib/api/register/node.js:216:7)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)

npm ERR! Darwin 15.0.0
npm ERR! argv "node" "/usr/local/bin/npm" "run" "start"
npm ERR! node v0.12.7
npm ERR! npm  v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `gulp run`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script 'gulp run'.
npm ERR! This is most likely a problem with the react-input-range package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp run
npm ERR! You can get their info via:
npm ERR!     npm owner ls react-input-range
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/Jan/Projects/OpenSource/react-input-range/npm-debug.log

Also npm run build brings up the same error.

And one more question: Could you be so kind to tell me how to install scss_lint locally in the project folder? I've installed it through sudo gem install scss-lint, but npm run test tells me that I don't have scss_lint installed?

Thank you very much!

browserify-shim as a dependency?

When installing through npm, importing the module and building I received the error Error: Cannot find module 'browserify-shim' from...

I'm not sure why this would be required but perhaps it needs to be moved from devDependencies to dependencies? I installed browserify-shim myself and It started building fine.

Maybe something on my end is messed up but I thought I'd add it here just in case. Thoughts?

Formating label

Is there a way to custom format the way currently selected value is shown?

Interval selection to single value

If I have for example a double selection in this interval [1, 5], can I select only one value, for example only the value 3? (the min and the max to overlap on the same value)

Hours and minutes for values?

Hi, thanks for this module.

I need to create a range input with hours and minutes. Is it possible with this module?
range-time

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.