Skip to contentSkip to navigationSkip to topbar
Figma
Star

Slider

A Slider is a draggable input that allows a user to select an imprecise numerical value within a range.

Version 2.0.2
Github

Component preview theme
const DefaultSliderExample = () => {
const [value, setValue] = React.useState(0.75);
const id = useUID();
const numberFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US');
}, []);
return (
<Form>
<FormControl>
<Label htmlFor={id}>Brightness</Label>
<Slider
id={id}
numberFormatter={numberFormatter}
value={value}
onChange={(newValue) => setValue(newValue)}
/>
</FormControl>
</Form>
);
};
render(
<DefaultSliderExample />
)

Guidelines

Guidelines page anchor

About Slider

About Slider page anchor

A Slider allows a user to select a numerical value when:

  • Immediate feedback is important.
  • The value doesn’t need to be precise, especially when the act of choosing a bigger or smaller value is more important than the value itself.
  • The value is in a defined range.

Slider uses Adobe's Spectrum React-Aria useSlider(link takes you to an external page) under the hood.

Both Sliders and number Inputs are form fields that take numerical values. Because the mouse and touch interaction on a Slider is less precise, use a Slider when the exact number value isn’t important, for example, when selecting image opacity or audio volume.

If the user needs to select an exact value, use a number Input instead. If you want to let users select between consecutive values, you can also use a Radio Button Group.

Slider is a form element and follows the same accessibility guidelines as other form fields:

  • Include a label on all form fields. Use one of 3 ways to label a form field:
    • Visible label with Label (preferred)
    • Visible label that's associated to the input with aria-labelledby
    • Label directly using aria-label
  • Each label must use the htmlFor prop that equals the id of the associated Input.
  • Provide clear identification of required fields in the label or at the start of a form. Use the required prop to programmatically indicate they are required to browsers.
  • Include inline error Help Text on any field that errors to make it visually clear that the field changed.
  • If the input has associated help text, include the aria-describedby prop on the input. This should match the id of the help text.

Use a Slider when a user should select an imprecise value from a midsized and defined numerical range, such as 1–100.

Component preview theme
const DefaultSliderExample = () => {
const [value, setValue] = React.useState(0.75);
const id = useUID();
const numberFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US');
}, []);
return (
<Form>
<FormControl>
<Label htmlFor={id}>Brightness</Label>
<Slider
id={id}
numberFormatter={numberFormatter}
value={value}
onChange={(newValue) => setValue(newValue)}
/>
</FormControl>
</Form>
);
};
render(
<DefaultSliderExample />
)

Avoid errors on Sliders by changing the defined range so no errors can occur.

If a user is still able to choose an invalid option, change the Slider to its error state and use Help Text to add an inline error. For additional guidance on how to compose error messages, refer to the error state pattern.

Component preview theme
const ErrorSliderExample = () => {
const [value, setValue] = React.useState(0.2);
const id = useUID();
const helpTextId = useUID();
const numberFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US', { style: 'percent' });
}, []);
const hasError = value < 0.3;
return (
<Form>
<FormControl>
<Label required htmlFor={id}>Delivery alerts</Label>
<Slider
hasError={hasError}
id={id}
aria-describedby={helpTextId}
value={value}
minValue={0}
maxValue={1}
step={0.01}
onChange={(newValue) => setValue(newValue)}
numberFormatter={numberFormatter}
/>
<HelpText id={helpTextId} variant={hasError ? "error" : "default"}>
The delivery rate's threshold must be greater than 30%.
</HelpText>
</FormControl>
</Form>
);
};
render(
<ErrorSliderExample />
)

Use a disabled Slider to show users that they can't interact with the Slider.

Component preview theme
const DisabledSliderExample = () => {
const [value, setValue] = React.useState(0.5);
const id = useUID();
const numberFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US', { style: 'percent' });
}, []);
return (
<Form>
<FormControl>
<Label disabled htmlFor={id}>Volume</Label>
<Slider
disabled
id={id}
value={value}
minValue={0}
maxValue={1}
step={0.01}
onChange={(newValue) => setValue(newValue)}
numberFormatter={numberFormatter}
/>
</FormControl>
</Form>
);
};
render(
<DisabledSliderExample />
)

Use a custom range Slider when the default range doesn't fit your use case.

Component preview theme
const CustomRangeSliderExample = () => {
const [value, setValue] = React.useState(0.55);
const id = useUID();
const PercentFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US', { style: 'percent' });
}, []);
return (
<Form>
<FormControl>
<Label htmlFor={id}>Partition size</Label>
<Slider
id={id}
value={value}
minValue={0.5}
maxValue={0.8}
step={0.01}
onChange={(newValue) => setValue(newValue)}
numberFormatter={PercentFormatter}
/>
</FormControl>
</Form>
);
};
render(
<CustomRangeSliderExample />
)

Use a Slider with hidden range labels when the range is obvious or the labels are not needed.

Component preview theme
const HiddenRangeLabelsSlider = () => {
const [value, setValue] = React.useState(32);
const id = useUID();
const NumberFormatter = React.useMemo(() => {
return new Intl.NumberFormat('en-US');
}, []);
return (
<Form>
<FormControl>
<Label htmlFor={id}>Scale</Label>
<Slider
id={id}
value={value}
onChange={(newValue) => setValue(newValue)}
numberFormatter={NumberFormatter}
hideRangeLabels
/>
</FormControl>
</Form>
);
};
render(
<HiddenRangeLabelsSlider />
)
Minimum value:0%
Maximum value:100%
Do

Use a Slider for mid-sized, defined ranges, usually 1–100.

Minimum value:0
Maximum value:3
Don't

Don’t use a Slider for very large or very small ranges.

¥
Do

Use a number Input when an exact number value matters.

Minimum value:¥0
Maximum value:¥10,000
Don't

Don’t use a Slider when an exact number value matters.

Current balance
Do

Use a Meter when you need to visually show the size of a numerical value, but don’t want the bar to be interactive.

Minimum value:¥0
Maximum value:¥10,000
Don't

Don’t use a disabled Slider when the value of the Slider is important to show. Disabled form fields aren’t high-contrast enough to be visible.

Maximum messages per month
Protection level
Do

Use a Radio Group or Radio Button Group to allow users to select a list of consecutive options with precision, whether they’re numerical or not.

Minimum value:0
Maximum value:50,000
Don't

Don’t use a Slider to allow selection of non-numerical values or when there isn’t a definable range.

Installation

Installation page anchor
yarn add @twilio-paste/core - or - yarn add @twilio-paste/slider
import {Slider} from '@twilio-paste/core/slider';

const Component = () => {
  const [value, setValue] = React.useState(10);
  const sliderId = useUID();
  const helpTextId = useUID(); // optional

  const numberFormatter = React.useMemo(() => {
    return new Intl.NumberFormat('en-US', {style: 'percent'});
  }, []);

  return (
    <Slider
      id={sliderId}
      aria-describedby={helpTextId}
      value={value}
      minValue={0}
      maxValue={100}
      step={1}
      onChange={(newValue) => setValue(newValue)}
      numberFormatter={numberFormatter}
    />
  );
};
PropTypeDescriptionDefault
idstringMust provide an id to match with a labelundefined
numberFormatterIntl.NumberFormatter(link takes you to an external page)Used to format the value into i18n formats. Can return localized currencies and percentages
aria-describedby?stringOptional id to pair the input to its help textundefined
aria-labelledby?stringOptional id to pair the input to its label text (if not using a regular label with htmlFor)undefined
disabled?booleanDisables the sliderfalse
hasError?booleanShows error styling on the Sliderfalse
hideRangeLabels?booleanHides the min and max values that appear over the sliderfalse
minValue?numberThe smallest number in the slider range1
maxValue?numberThe largest number in the slider range100
step?numberThe incremented value as you drag along the range1
value?numberThe current selected value1
onChange?(value: number) => voidFired on every change as the thumb is dragged along the track
onChangeEnd?(value: number) => voidFired at the end of the dragging event once
element?stringOverrides the default element name to apply unique styles with the Customization Provider'SLIDER'