API Reference / React InstantSearch Widgets / RangeSlider
Apr. 24, 2019

RangeSlider

About this widget

Since a lot of sliders already exist, we didn’t include one by default. However, you can easily connect React InstantSearch to an existing one using the connectRange connector.

Customize the UI - connectRange

If you want to create your own UI of the RangeSlider widget or use another UI library, you can use connectors.

Connectors are higher-order components. They encapsulate the logic for a specific kind of widget and they provide a way to interact with the InstantSearch context.

They have an outer component API that we call exposed props, and they provide some other props to the wrapped components which are called the provided props.

This connector is also used to build other widgets: RangeInput RatingMenu

It’s a 3-step process:

// 1. Create a React component
const RangeSlider = () => {
  // return the DOM output
};

// 2. Connect the component using the connector
const CustomRangeSlider = connectRange(RangeSlider);

// 3. Use your connected widget
<CustomRangeSlider />

Create a React component

const RangeSlider = ({
  object currentRefinement,
  number min,
  number max,
  function refine,
}) => {
  // return the DOM output
};

Provided Props

The examples built with the connector uses Rheostat (version 2.x.x) to render the slider. Make sure to have the library correctly setup before trying the demo. We chose Rheostat for the example but you can use any library.

currentRefinement
type: object

The currently applied refinement or the minimum/maximum value.

1
2
3
4
5
6
7
8
9
const RangeSlider = ({ currentRefinement }) => (
  <Rheostat
    // ...
    values={[
      currentRefinement.min,
      currentRefinement.max
    ]}
  />
);
min
type: number

The minimum available value.

1
2
3
4
5
6
const RangeSlider = ({ min }) => (
  <Rheostat
    // ...
    min={min}
  />
);
max
type: number

The maximum available value.

1
2
3
4
5
6
const RangeSlider = ({ max }) => (
  <Rheostat
    // ...
    max={max}
  />
);
refine
type: function

Selects a range.

1
2
3
4
5
6
7
8
const RangeSlider = ({ refine }) => (
  <Rheostat
    // ...
    onChange={({ values: [min, max] }) => {
      refine({ min, max });
    }}
  />
);

Create and instantiate your connected widget

const CustomRangeSlider = connectRange(RangeSlider);

<CustomRangeSlider
  attribute={string}
  // Optional parameters
  defaultRefinement={object}
  min={number}
  max={number}
/>

Exposed Props

attribute
type: string
Required

The name of the attribute in the record.

1
<CustomRangeSlider attribute="price" />
defaultRefinement
type: object
Optional

The default state of the widget containing the min and/or the max of the range.

1
2
3
4
5
6
7
<CustomRangeSlider
  // ...
  defaultRefinement={{
    min: 10,
    max: 500,
  }}
/>
min
type: number
Optional

The minimum value for the input. When not provided, the minimum value is automatically computed by Algolia from the data in the index.

1
2
3
4
<CustomRangeSlider
  // ...
  min={10}
/>
max
type: number
Optional

The maximum value for the input. When not provided, the maximum value is automatically computed by Algolia from the data in the index.

1
2
3
4
<CustomRangeSlider
  // ...
  max={500}
/>

Full example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ⚠️ This example only works with the version 2.x of Rheostat

import Rheostat from 'rheostat';
import { connectRange } from 'react-instantsearch-dom';

class RangeSlider extends Component {
  state = {
    min: this.props.min,
    max: this.props.max,
  }

  componentDidUpdate(prevProps) {
    const { currentRefinement } = prevProps;
    if (
      this.props.canRefine &&
      (currentRefinement.min !== this.props.currentRefinement.min ||
        currentRefinement.max !== this.props.currentRefinement.max)
    ) {
      this.setState({
        ...currentRefinement,
      });
    }
  }

  onChange = ({ values: [min, max] }) => {
    const { currentRefinement, refine } = this.props;
    if (currentRefinement.min !== min || currentRefinement.max !== max) {
      refine({
        min,
        max,
      });
    }
  }

  onValuesUpdated = ({ values: [min, max] }) => {
    this.setState({
      min,
      max,
    });
  }

  render() {
    const { min, max, currentRefinement } = this.props;
    if (min === max) {
      return null;
    }

    return (
      <Rheostat
        className="ais-RangeSlider"
        min={min}
        max={max}
        values={[currentRefinement.min, currentRefinement.max]}
        onChange={this.onChange}
        onValuesUpdated={this.onValuesUpdated}
      >
        <div
          className="rheostat-marker rheostat-marker--large"
          style={{ left: 0 }}
        >
          <div className="rheostat-value">{this.state.min}</div>
        </div>
        <div
          className="rheostat-marker rheostat-marker--large"
          style={{ right: 0 }}
        >
          <div className="rheostat-value">{this.state.max}</div>
        </div>
      </Rheostat>
    );
  }
}

const CustomRangeSlider = connectRange(RangeSlider);

Did you find this page helpful?