Slider
Sliders allow users to make selections from a range of values.
Sliders reflect a range of values along a bar, from which users may select a single value. They are ideal for adjusting settings such as volume, brightness, or applying image filters.
Quick Start
- Installation
npm install @adaptavant/eds-core
- Import
import { Slider } from '@adaptavant/eds-core';
Usage
The most common usage of the Slider component involves setting a min and max value range. By default, the slider operates in an uncontrolled mode.
const [positiveValue, setPositiveValue] = React.useState(30);
const [rangeValue, setRangeValue] = React.useState(-34);
const [negativeValue, setNegativeValue] = React.useState(-60);
const [largerStepValue, setLargerStepValue] = React.useState(20);
const [decimalValue, setDecimalValue] = React.useState(1.5);
const [largeRangeValue, setLargeRangeValue] = React.useState(500);
const getText = (value) => {
return <Text className="text-body-12 text-secondary mt-1"> Value: {value}</Text>;
};
return (
<Stack className="w-full gap-4 items-stretch">
{/* Standard positive range */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="positive-slider-label">
Slider with positive range
</Label>
<Slider
defaultValue={30}
onValueChange={setPositiveValue}
ariaLabelledBy="positive-slider-label"
/>
{getText(positiveValue)}
</Box>
{/* Negative to positive range */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="neg-pos-slider-label">
Slider with negative to positive range
</Label>
<Slider
defaultValue={-34}
minValue={-50}
maxValue={50}
onValueChange={setRangeValue}
step={5}
ariaLabelledBy="neg-pos-slider-label"
/>
{getText(rangeValue)}
</Box>
{/* Negative range */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="negative-slider-label">
Slider with negative range
</Label>
<Slider
defaultValue={-60}
minValue={-100}
maxValue={-20}
onValueChange={setNegativeValue}
step={10}
ariaLabelledBy="negative-slider-label"
/>
{getText(negativeValue)}
</Box>
{/* Larger step values */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="large-step-slider-label">
Slider with larger step increments
</Label>
<Slider
defaultValue={20}
minValue={0}
maxValue={200}
onValueChange={setLargerStepValue}
step={20}
ariaLabelledBy="large-step-slider-label"
/>
{getText(largerStepValue)}
</Box>
{/* Decimal step values */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="decimal-slider-label">
Slider with decimal steps
</Label>
<Slider
defaultValue={1.5}
minValue={0}
maxValue={5}
onValueChange={setDecimalValue}
step={0.1}
ariaLabelledBy="decimal-slider-label"
/>
{getText(decimalValue)}
</Box>
{/* Large range with small steps */}
<Box className="flex flex-col items-center">
<Label className="sr-only" id="precise-slider-label">
Slider with precise control
</Label>
<Slider
defaultValue={500}
minValue={0}
maxValue={1000}
onValueChange={setLargeRangeValue}
step={0.5}
ariaLabelledBy="precise-slider-label"
/>
{getText(largeRangeValue)}
</Box>
</Stack>
);
Adornments
The Slider component supports adding interactive elements at both ends using the adornmentStart
and adornmentEnd
props.
const [value, setValue] = React.useState(14);
const minValue = 0;
const step = 3;
const maxValue = 100;
const increaseValue = () => {
setValue((prevValue) => Math.min(prevValue + step, maxValue));
};
const decreaseValue = () => {
setValue((prevValue) => Math.max(prevValue - step, minValue));
};
return (
<Slider
value={value}
onValueChange={setValue} // Update state on drag
adornmentStart={
<IconButton
aria-label="Decrease value"
icon={SortDownIcon}
size="small"
onClick={decreaseValue}
variant="neutralTertiary"
/>
}
adornmentEnd={
<IconButton
aria-label="Increase value"
icon={SortUpIcon}
size="small"
onClick={increaseValue}
variant="neutralTertiary"
/>
}
/>
);
Controlled
For more precise control over the slider's value, you can use it in controlled mode by providing a value
prop and handling changes through onValueChange
.
Note: The value
prop will override defaultValue
if both are provided.
const [value, setValue] = React.useState(23);
const handleChange = (newValue) => {
setValue(newValue);
};
return (
<Box className="flex w-full">
<Label className="sr-only" id="slider-label">
Controlled slider
</Label>
<Slider
ariaLabelledBy="slider-label"
onValueChange={handleChange} // Update state on drag
value={value}
/>
</Box>
);
Disabled
The slider can be disabled using the isDisabled
prop.
Style API
Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.
Please refer to the Style API documentation for more insights.
Slider parts
<Box className="w-full">
<Label className="sr-only" id="custom-slider-label">
Slider with Custom Styles
</Label>
<Slider
adornmentEnd={<SortUpIcon />}
adornmentStart={<SortDownIcon />}
ariaLabelledBy="custom-slider-label"
className="gap-4 p-2 rounded-8px" // targets root
classNames={{
adornmentStart: "text-critical", // targets icons inside slots
adornmentEnd: "text-critical",
baseArea: "bg-inverse-tertiary",
container: "h-6",
filledArea: "bg-gradient-to-r from-purple-700 to-blue-700",
thumb: "bg-critical",
}}
defaultValue={23}
/>
</Box>
Stylable Parts | Description |
---|---|
root | The outermost container for the slider, wrapping all inner components. |
baseArea | The background area of the slider, often styled as the rail or track of the slider. |
container | The wrapper around the interactive parts of the slider, used to handle events and positioning. |
filledArea | The portion of the slider track that indicates the selected value range. |
thumb | The draggable element, representing the current value of the slider. |
adornmentStart | The slot content displayed before slider. |
adornmentEnd | The slot content displayed at the end of the slider. |
Usage guidelines
Do
- Provide immediate feedback: Ensure sliders give users instant visual feedback so they can see the effect of their adjustments right away, just like with volume controls on phones.
- Use visual cues like histograms: Include histograms to show the data within the selected range and ensure non-visual alternatives are available for accessibility.
- Set a clear numeric range: Use sliders when users need to choose a number within a specified range, especially if exact precision is not crucial.
- Use sliders for moderate ranges: Sliders work best for moderate ranges; very large or very small ranges can diminish their usefulness.
- Provide clear, descriptive labels: Labels should clearly communicate what’s required, using short, descriptive nouns. This benefits all users, especially those who rely on labels for guidance. Refer to form label patterns for clarity examples.
Don’t
- Don’t use sliders for precise values: When exact accuracy is essential, choose an Input component instead to allow for precision.
- Avoid sliders for arbitrary numeric values: For numbers that aren’t confined to a range or require high precision, use the Input component instead.
- Don’t use sliders for large ranges without steps: If the range is very large, break it into smaller intervals or use larger steps to make adjustments easier.
- Avoid sliders for very small ranges: For small ranges (like 0-3), consider checkboxes or select components for simplicity.
- Don’t skip clear labeling: Labels are essential to communicate expectations clearly. Avoid ambiguous labels; use concise, descriptive phrases that everyone can understand. Use form label patterns for guidance on label clarity.
Best practices
Do
Use inputs, not sliders, for arbitrary or precise numeric values.
Don’t
For high precision (e.g., 5.67), swap the slider with an input for manual adjustment.
Do
Use checkboxes or select components for small ranges (e.g., 0–4) to keep the interface simple and intuitive.
Don’t
Don't use sliders for very small ranges, as they can be unnecessarily complex for such scenarios.
Do
Break large ranges into smaller intervals or use larger steps to make adjustments more manageable.
Don’t
Don't use sliders for very large ranges without steps, as they can be difficult to control and adjust accurately.