Skip to main content
Version: Next 🚧

Slider

Slider picks a number by dragging along a track, drawn the platform's way:

  • iOS: a thin track and a white knob with a soft shadow, like UISlider.
  • Material: Material 3's thick track with a slim handle, a gap either side of it, stop dots at the ends and a value bubble while dragging.
  • Web: a browser's range input, with a dot in the primary colour, a pointer cursor, and a halo around the thumb on hover and focus that grows while you press and drag.

Tap anywhere on the track to jump there, or drag. Pass range for two thumbs.

import { Slider } from '@elik56a/react-native-pickers';
Loading…
<View style={{ gap: 8 }}>
  <Slider
    value={volume}
    onChange={setVolume}
    minimumIcon={<Text>🔈</Text>}
    maximumIcon={<Text>🔊</Text>}
    accessibilityLabel="Volume"
  />
  <Text>Volume: {volume}</Text>
</View>

Try the props​

Platform
step
valueLabel
<Slider value={volume} onChange={setVolume} accessibilityLabel="Volume" />

onChange and onValueChanging​

Like the wheels, the slider has two callbacks:

CallbackWhenUse it for
onChangeOnce, when the finger lifts on a new value, or on each arrow key or screen-reader stepUpdating state, saving
onValueChangingOn every step while draggingHaptics, live previews

The thumb follows the finger on its own while dragging, so a controlled slider doesn't need onValueChanging to move. Use it to preview the value as it changes:

Loading…
<View style={{ gap: 16 }}>
  <View style={{ height: 64, alignItems: 'center', justifyContent: 'center' }}>
    <View style={{ width: preview, height: preview, borderRadius: preview / 2, backgroundColor: '#C8460D' }} />
  </View>
  <Slider
    min={8}
    max={64}
    value={size}
    onValueChanging={setPreview}
    onChange={(next) => {
      setSize(next);
      setPreview(next);
    }}
    accessibilityLabel="Dot size"
  />
</View>

Ranges​

range gives the slider two thumbs, and its value becomes [start, end]. A touch grabs the nearest thumb, and neither can pass the other. Screen readers call them Minimum and Maximum; translate them with thumbLabels.

Loading…
<View style={{ gap: 8 }}>
  <Text>
    ${price[0]} – ${price[1]}
  </Text>
  <Slider
    range
    min={0}
    max={600}
    step={10}
    value={price}
    onChange={setPrice}
    formatValue={(v) => `$${v}`}
    accessibilityLabel="Price"
  />
</View>

Steps and marks​

step sets how far the value moves (default 1); 0 lets it take any value. showSteps puts a dot on the track at each step, left out when they'd be too close to tell apart. The Material design marks the track's inactive ends with stop dots, as Material 3 does.

Loading…
<Slider min={1} max={5} step={1} showSteps value={rating} onChange={setRating} accessibilityLabel="Rating" />

Marks with labels​

marks puts dots on the track at the values you pick; give one a label to write it under the track. Labels inside the filled part of the track read stronger.

Loading…
<Slider marks={marks} value={temperature} onChange={setTemperature} accessibilityLabel="Temperature" />

Only the marks​

snapToMarks restricts the value to the marks: a drag jumps to the nearest one, and arrow keys and screen readers step from mark to mark.

Loading…
<Slider
  marks={marks}
  snapToMarks
  value={temperature}
  onChange={setTemperature}
  formatValue={(v) => `${v}°C`}
  accessibilityLabel="Temperature"
/>

Value bubble​

valueLabel sets when a bubble shows the value over the thumb: 'drag' while dragging (the Material design's default), 'always', or 'never' (the default elsewhere). With 'always' the slider keeps room above the track for it. formatValue sets the bubble's text, which screen readers read too.

Loading…
<Slider
  min={0}
  max={1}
  step={0.05}
  valueLabel="always"
  formatValue={(v) => `${Math.round(v * 100)}%`}
  value={opacity}
  onChange={setOpacity}
  accessibilityLabel="Opacity"
/>

Keyboard and screen readers​

Each thumb is an adjustable control: screen readers step it with swipe up and down (iOS) or the volume keys (Android), and read formatValue's text. On the web, Tab focuses a thumb; arrow keys step it, Page Up and Page Down move a tenth of the range, and Home and End go to the ends.

The track's touch area is 44 pt tall however thin it looks, as iOS asks, and a sheet's swipe to close doesn't take over a drag on it.

Right to left​

In an RTL layout the track fills from the right, and dragging follows.

Styling​

styles takes these slots: container, track (every piece of the track), activeTrack (the filled part), thumb, mark, markLabel, valueLabel and valueLabelText. The filled track and Material's handle use the theme's primary colour.

<Slider value={value} onChange={setValue} styles={{ activeTrack: { backgroundColor: '#34C759' }, thumb: { borderWidth: 1 } }} />

Props​

PropTypeDefaultDescription
valuenumber, or [number, number] with rangeControlled value.
defaultValuenumber, or [number, number] with rangemin, or [min, max]Uncontrolled starting value.
onChange(value) => voidWhen the finger lifts on a new value, or on a key or screen-reader step.
onValueChanging(value) => voidOn every step while dragging.
rangebooleanfalseTwo thumbs; the value is [start, end].
minnumber0
maxnumber100
stepnumber1The value moves in steps this big; 0 for any value.
showStepsbooleanfalseA dot on the track at each step.
marks(number | { value, label? })[]Dots at these values, with labels under the track.
snapToMarksbooleanfalseOnly the marks can be picked.
valueLabel'never' | 'drag' | 'always''drag' in Material, else 'never'When a bubble shows the value over the thumb.
formatValue(value: number) => stringthe number, with the step's decimalsText for the bubble and screen readers.
minimumIconReactNodeBefore the track, like a quiet speaker beside a volume slider.
maximumIconReactNodeAfter the track.
disabledbooleanfalseDims the slider and ignores touches and keys.
accessibilityLabelstringWhat screen readers call the slider.
thumbLabels[string, string]['Minimum', 'Maximum']With range, what screen readers call each thumb.
design'auto' | 'ios' | 'material' | 'web''auto'
themeDeepPartial<PickerTheme>
style / stylesRoot style, and the slots above.
testIDstringOn the root; the track gets ${testID}-track, the thumbs ${testID}-thumb-0 and -1.