# Slider

> Single and range sliders whose thumbs follow the finger 1:1 and settle onto the nearest step on release, with a value bubble that grows out of the thumb while dragging and optional step ticks that tick.

- Type: Component (inputs)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/slider
- Markdown: https://goodui.dev/native/components/slider.md
- Registry item: https://goodui.dev/native/r/slider.json
- Dependencies: react-native-gesture-handler, react-native-reanimated
- Keywords: react native slider, range slider, price range filter, dual thumb slider, slider with value label, stepped slider haptics, reanimated slider

## When to use

- Picking a value where the position matters more than the exact digit: volume, brightness, budget, distance.
- A range: price filter, age range, time window (RangeSlider).
- A small set of evenly spaced values with feedback: rating 1 to 5, tip percentage (step with showTicks).

## When not to use

- An exact number the person types: use text-field.
- Small counts changed by one (guests, quantity): use quantity-stepper.
- Two to five named options: use segmented-control.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add https://goodui.dev/native/r/slider.json
npx expo install --fix
```

The component lands in `components/goodui-native/slider/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs locale.

### Setup

- Wrap the app in GestureHandlerRootView and ThemeProvider.

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
import { useState } from "react";
import { RangeSlider, Slider } from "@/components/goodui-native/slider/slider";

export function Filters() {
  const [distance, setDistance] = useState(10);
  const [price, setPrice] = useState<[number, number]>([40, 180]);
  return (
    <>
      <Slider accessibilityLabel="Distance" value={distance} onValueChange={setDistance} min={1} max={50} formatValue={(v) => `${v} km`} />
      <RangeSlider
        accessibilityLabel="Price"
        value={price}
        onValueChange={setPrice}
        onSlidingComplete={(range) => refetch(range)}
        min={0}
        max={300}
        step={10}
        formatValue={(v) => `$${v}`}
      />
    </>
  );
}
```

## Examples

### Stepped with ticks and an always-visible value

```tsx
<Slider accessibilityLabel="Tip" defaultValue={15} min={0} max={30} step={5} showTicks showValue="always" formatValue={(v) => `${v}%`} />
```

### Continuous, small, status tone

```tsx
<Slider size="sm" tone="warning" step={0} showValue="never" accessibilityLabel="Brightness" />
```

## API reference

### Slider

`import { Slider } from "@/components/goodui-native/slider/slider";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `min` | `number` | – | Lowest value. Default 0. |
| `max` | `number` | – | Highest value. Default 100. |
| `step` | `number` | – | Values snap to multiples of this. Default 1. `0` is continuous. |
| `showTicks` | `boolean` | – | Dots at every step, and a select haptic each time the value crosses one. Shown only when there are 40 steps or fewer. |
| `showValue` | `"drag" \| "always" \| "never"` | – | Value bubble above the thumb: `drag` appears while dragging, `always` stays and grows while dragging, `never`. |
| `formatValue` | `(value: number) => string` | – | Text for a value in the bubble and for screen readers, for example `(v) => \`$${v}\``. |
| `tone` | `"success" \| "warning" \| "danger" \| "accent"` | – | Fill color. `accent` by default; status tones only when the value means a status. |
| `size` | `"sm" \| "md"` | – | Thumb 22 (`sm`) or 28 pt (`md`). The touch area stays at least 44 pt tall. |
| `disabled` | `boolean` | – | Dims the control and ignores presses. |
| `haptic` | `boolean` | – | `false` silences the tick and edge haptics. |
| `onSlidingStart` | `() => void` | – | Called when a drag or tap starts changing the value. |
| `accessibilityLabel` | `string` | – | Screen reader label, for example "Volume". |
| `labels` | `Partial<SliderLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |
| `value` | `number` | – | The value (controlled). Pair it with `onValueChange`. |
| `defaultValue` | `number` | – | Initial value when uncontrolled. Defaults to `min`. |
| `onValueChange` | `(value: number) => void` | – | Called while dragging, each time the snapped value changes. |
| `onSlidingComplete` | `(value: number) => void` | – | Called once when the finger lifts, with the final value. Save or fetch here. |

### RangeSlider

`import { RangeSlider } from "@/components/goodui-native/slider/slider";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `min` | `number` | – | Lowest value. Default 0. |
| `max` | `number` | – | Highest value. Default 100. |
| `step` | `number` | – | Values snap to multiples of this. Default 1. `0` is continuous. |
| `showTicks` | `boolean` | – | Dots at every step, and a select haptic each time the value crosses one. Shown only when there are 40 steps or fewer. |
| `showValue` | `"drag" \| "always" \| "never"` | – | Value bubble above the thumb: `drag` appears while dragging, `always` stays and grows while dragging, `never`. |
| `formatValue` | `(value: number) => string` | – | Text for a value in the bubble and for screen readers, for example `(v) => \`$${v}\``. |
| `tone` | `"success" \| "warning" \| "danger" \| "accent"` | – | Fill color. `accent` by default; status tones only when the value means a status. |
| `size` | `"sm" \| "md"` | – | Thumb 22 (`sm`) or 28 pt (`md`). The touch area stays at least 44 pt tall. |
| `disabled` | `boolean` | – | Dims the control and ignores presses. |
| `haptic` | `boolean` | – | `false` silences the tick and edge haptics. |
| `onSlidingStart` | `() => void` | – | Called when a drag or tap starts changing the value. |
| `accessibilityLabel` | `string` | – | Screen reader label, for example "Volume". |
| `labels` | `Partial<SliderLabels>` | – | Overrides for the built-in strings; a GooduiLocaleProvider pack sets them app-wide. |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |
| `value` | `[number, number]` | – | The low and high values (controlled). |
| `defaultValue` | `[number, number]` | – | Initial values when uncontrolled. Defaults to `[min, max]`. |
| `onValueChange` | `(value: [number, number]) => void` | – | Called while dragging, each time either snapped value changes. |
| `onSlidingComplete` | `(value: [number, number]) => void` | – | Called once when the finger lifts, with the final pair. |
| `minDistance` | `number` | – | Smallest gap between the two values. Default one step. |
| `thumbLabels` | `[string, string]` | – | Screen reader labels of the two thumbs. Same as `labels.minimum` and `labels.maximum`. |

## Accessibility

- Each thumb is an adjustable element (a slider on the web) with min, max, now and the formatted text as its value.
- Screen readers use the increment and decrement actions; one action moves one step (or 5 % of the range when continuous).
- Range thumbs are labelled '<label>, Minimum' and '<label>, Maximum' (thumbLabels to localize).
- On the web each thumb is focusable; arrow keys step it and show the value bubble while focused.
- The touch area is 44 pt tall regardless of the visual size.

## Motion

- Dragging: the thumb tracks the finger 1:1 (grabbing it keeps the finger's offset, grabbing the track brings the nearest thumb to the finger) and scales to 1.08.
- Release: the thumb settles onto the step the value already shows on the snappy spring.
- Tapping the track moves the nearest thumb there on the smooth spring.
- The value bubble grows out of the top of the thumb while dragging (showValue 'drag' appears from nothing, 'always' grows from 84 %).
- Outside value changes move the thumbs on the smooth spring.
- Reduced motion: no thumb or bubble scaling (the bubble simply appears), release and outside changes jump to the value; dragging still follows the finger.

## Haptics

- select each time the value crosses a tick (with showTicks)
- select when the value reaches min or max

## Performance

- The gesture and all thumb, fill and bubble motion run on the UI thread.
- React updates only when the snapped value changes, not per frame. Use onSlidingComplete for expensive work.

## Notes for AI

- Use Slider for one value and RangeSlider for a [low, high] pair. Both work controlled or uncontrolled.
- onValueChange fires during the drag; put requests and saves in onSlidingComplete.
- step={0} is continuous. showTicks only draws when there are 40 steps or fewer.
- Always pass accessibilityLabel and a formatValue that adds the unit.
- Leave room above the slider when showValue is 'drag': the bubble floats over the content above. 'always' reserves its own space.
- Requires GestureHandlerRootView at the app root.

## Related

- [Quantity stepper](https://goodui.dev/native/components/quantity-stepper.md): A − value + stepper whose value rolls in the direction of change. Hold a button to repeat with acceleration; the ends push back with a rubber-band bounce and a warning haptic. In a cart the − turns into a trash button at the minimum.
- [Segmented control](https://goodui.dev/native/components/segmented-control.md): Two to five views of the same thing with an elastic highlight that stretches toward the new segment, can be dragged, and ticks at every boundary. Includes a billing toggle.

## Guidance for AI tools

Slider: Single and range sliders whose thumbs follow the finger 1:1 and settle onto the nearest step on release, with a value bubble that grows out of the thumb while dragging and optional step ticks that tick. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
