> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ais-range-slider

> Lets users refine search results by a numeric range using a slider.

```vue Signature theme={"system"}
<ais-range-input
  attribute="string"
  // Optional parameters
  :min="number"
  :max="number"
  :precision="number"
/>
```

## Import

<Tabs>
  <Tab title="Component">
    To ensure optimal bundle sizes,
    see [Optimize build size](/doc/guides/building-search-ui/going-further/improve-performance/vue#optimize-build-size).

    ```js Vue icon=code theme={"system"}
    import { AisRangeInput } from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    export default {
      components: {
        AisRangeInput
      },
      // ...
    };
    ```
  </Tab>

  <Tab title="Plugin">
    This imports all widgets, even the ones you don't use.
    For more information, see [Get started with Vue InstantSearch](/doc/guides/building-search-ui/getting-started/vue).

    ```js JavaScript icon="code" theme={"system"}
    import Vue from "vue";
    import InstantSearch from "vue-instantsearch";
    // Use "vue-instantsearch/vue3/es" for Vue 3

    Vue.use(InstantSearch);
    ```
  </Tab>
</Tabs>

<Card title="See this widget in action" icon="monitor-play" href="https://instantsearchjs.netlify.app/stories/vue/?path=/story/ais-range-input--with-vuetify-slider" horizontal>
  Preview this widget and its behavior.
</Card>

## About this widget

Since there are many third-party range sliders for Vue, none is included by default.
However, you can use the default slot in [`ais-range-input`](/doc/api-reference/widgets/range-input/vue) to make a slider.
The example here uses [Vuetify](https://vuetifyjs.com)'s `v-range-slider`.
Make sure you've installed the library for your Vue version and are familiar with the API of `v-range-slider`.

For Vue 2:

* [Install Vuetify 2](https://v2.vuetifyjs.com/en/getting-started/installation)
* [API reference](https://v2.vuetifyjs.com/en/components/range-sliders) for `v-range-slider`

For Vue 3:

* [Install Vuetify 3+](https://vuetifyjs.com/en/getting-started/installation/#existing-projects)
* [API reference](https://vuetifyjs.com/en/components/range-sliders) for `v-range-slider`

### Requirements

The [`attribute`](#param-attribute) provided to the widget must be in attributes for faceting,
either on the [dashboard](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting-with-dashboard) or using the [`attributesForFaceting`](/doc/api-reference/api-parameters/attributesForFaceting) parameter with the API.

The values of the attribute must be numbers, not strings.

## Examples

<CodeGroup>
  ```vue Vue 2 theme={"system"}
  <template>
    <ais-range-input attribute="price">
      <template v-slot="{ currentRefinement, range, refine }">
        <v-app>
          <v-range-slider
            :min="range.min"
            :max="range.max"
            :value="toValue(currentRefinement, range)"
            @end="refine({ min: $event[0], max: $event[1] })"
            step="1"
            thumb-label
          />
        </v-app>
      </template>
    </ais-range-input>
  </template>

  <script>
  export default {
    methods: {
      toValue(value, range) {
        return [
          typeof value.min === "number" ? value.min : range.min,
          typeof value.max === "number" ? value.max : range.max,
        ];
      },
    },
  };
  </script>
  ```

  ```vue Vue 3 theme={"system"}
  <template>
    <ais-range-input attribute="price">
      <template v-slot="{ currentRefinement, range, refine }">
        <v-range-slider
          :min="range.min"
          :max="range.max"
          :model-value="toValue(currentRefinement, range)"
          @end="refine({ min: $event[0], max: $event[1] })"
          step="1"
          thumb-label
        />
      </template>
    </ais-range-input>
  </template>

  <script>
  export default {
    methods: {
      toValue(value, range) {
        return [
          typeof value.min === "number" ? value.min : range.min,
          typeof value.max === "number" ? value.max : range.max,
        ];
      },
    },
  };
  </script>
  ```
</CodeGroup>

## Props

<ParamField body="attribute" type="string" required>
  The name of the attribute in the record.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input attribute="price" />
  ```
</ParamField>

<ParamField body="min" type="number">
  The minimum value for the input.
  When not provided, the minimum value is automatically computed by Algolia from the data in the index.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :min="10"
  />
  ```
</ParamField>

<ParamField body="max" type="number">
  The maximum value for the input.
  When not provided, the maximum value is automatically computed by Algolia from the data in the index.

  ```vue Vue icon=code theme={"system"}
  <ais-range-input
    [...]
    :max="500"
  />
  ```
</ParamField>

<ParamField body="precision" type="number" default={0}>
  The number of digits after the decimal point to use.

  Use a negative value to round values to powers of 10.

  For example, a precision of -2 would round a number to the nearest hundred,
  while a precision of -3 would round it to the nearest thousand.

  ```vue Vue icon=code theme={"system"}
  <!-- Round values to 2 digits after the decimal point -->
  <ais-range-input
    [...]
    :precision="2"
  />

  <!-- Round values to the nearest hundred -->

  <ais-range-input
  [...]
  :precision="-2"
  />

  ```
</ParamField>

## Customize the UI

<ParamField body="default">
  The slot to override the complete DOM output of the widget.

  when you implement this slot, none of the other slots will change the output, as the default slot surrounds them.

  **Scope**

  * `currentRefinement: { min: number, max: number }`. The currently applied refinement.
  * `range: { min: number, max: number }`. The minimum and maximum available value.
  * `refine: ({ min: number, max: number }) => void`. A function to select the refinement.

  <CodeGroup>
    ```vue Vue 2 theme={"system"}
    <template>
      <!-- ... -->
      <ais-range-input attribute="price">
        <template v-slot="{ currentRefinement, range, refine }">
          <v-app>
            <v-range-slider
              :min="range.min"
              :max="range.max"
              :value="toValue(currentRefinement, range)"
              @end="refine({ min: $event[0], max: $event[1] })"
              step="1"
              thumb-label
            />
          </v-app>
        </template>
      </ais-range-input>
      <!-- ... -->
    </template>

    <script>
    export default {
      // ...
      methods: {
        toValue(value, range) {
          return [
            typeof value.min === "number" ? value.min : range.min,
            typeof value.max === "number" ? value.max : range.max,
          ];
        },
      },
    };
    </script>
    ```

    ```vue Vue 3 theme={"system"}
    <template>
      <!-- ... -->
      <ais-range-input attribute="price">
        <template v-slot="{ currentRefinement, range, refine }">
          <v-range-slider
            :min="range.min"
            :max="range.max"
            :model-value="toValue(currentRefinement, range)"
            @end="refine({ min: $event[0], max: $event[1] })"
            step="1"
            thumb-label
          />
        </template>
      </ais-range-input>
      <!-- ... -->
    </template>

    <script>
    export default {
      // ...
      methods: {
        toValue(value, range) {
          return [
            typeof value.min === "number" ? value.min : range.min,
            typeof value.max === "number" ? value.max : range.max,
          ];
        },
      },
    };
    </script>
    ```
  </CodeGroup>
</ParamField>

## HTML output

```html HTML icon=code-xml theme={"system"}
<div class="ais-RangeInput">
  <!-- HTML output of the custom component -->
</div>
```
