RangeSlider
RangeSliders allow users to quickly select a subset range. They should be used when the upper and lower bounds to the range are invariable.
install | yarn add @adobe/react-spectrum |
---|---|
added | 3.7.0 |
usage | import {RangeSlider} from '@adobe/react-spectrum' |
Example#
<RangeSlider label="Range" defaultValue={{ start: 12, end: 36 }} />
<RangeSlider
label="Range"
defaultValue={{ start: 12, end: 36 }}
/>
<RangeSlider
label="Range"
defaultValue={{
start: 12,
end: 36
}}
/>
Value#
RangeSliders are controlled with the value
prop and uncontrolled with the defaultValue
prop.
This value consists of two parts, start
and end
. Both parts must fall between
the RangeSlider's minimum and maximum values, which default to 0 and 100 respectively.
function Example() {
let [value, setValue] = React.useState({start: 25, end: 75});
return (
<Flex gap="size-150" wrap>
<RangeSlider
label="Range (uncontrolled)"
defaultValue={{start: 25, end: 75}} />
<RangeSlider
label="Range (controlled)"
value={value}
onChange={setValue} />
</Flex>
);
}
function Example() {
let [value, setValue] = React.useState({
start: 25,
end: 75
});
return (
<Flex gap="size-150" wrap>
<RangeSlider
label="Range (uncontrolled)"
defaultValue={{ start: 25, end: 75 }}
/>
<RangeSlider
label="Range (controlled)"
value={value}
onChange={setValue}
/>
</Flex>
);
}
function Example() {
let [value, setValue] =
React.useState({
start: 25,
end: 75
});
return (
<Flex
gap="size-150"
wrap
>
<RangeSlider
label="Range (uncontrolled)"
defaultValue={{
start: 25,
end: 75
}}
/>
<RangeSlider
label="Range (controlled)"
value={value}
onChange={setValue}
/>
</Flex>
);
}
Alternatively, a different scale can be used by setting the minValue
and maxValue
props.
<RangeSlider
label="Range"
minValue={50}
maxValue={150}
defaultValue={{start: 75, end: 100}} />
<RangeSlider
label="Range"
minValue={50}
maxValue={150}
defaultValue={{start: 75, end: 100}} />
<RangeSlider
label="Range"
minValue={50}
maxValue={150}
defaultValue={{
start: 75,
end: 100
}}
/>
The slider value can be formatted by using the formatOptions
prop.
formatOptions
is compatible with the option parameter of Intl.NumberFormat and is applied based on the current locale.
<RangeSlider
label="Price range"
formatOptions={{style: 'currency', currency: 'JPY'}}
defaultValue={{start: 75, end: 100}} />
<RangeSlider
label="Price range"
formatOptions={{style: 'currency', currency: 'JPY'}}
defaultValue={{start: 75, end: 100}} />
<RangeSlider
label="Price range"
formatOptions={{
style: 'currency',
currency: 'JPY'
}}
defaultValue={{
start: 75,
end: 100
}}
/>
HTML forms#
RangeSlider supports the startName
and endName
props for integration with HTML forms.
<RangeSlider
label="Range"
defaultValue={{start: 12, end: 36}}
startName="start"
endName="end" />
<RangeSlider
label="Range"
defaultValue={{start: 12, end: 36}}
startName="start"
endName="end" />
<RangeSlider
label="Range"
defaultValue={{
start: 12,
end: 36
}}
startName="start"
endName="end"
/>
Labeling#
Value labels are shown above the Slider by default, but they can also be moved to the side or hidden as needed. The label text should be in sentence case.
<Flex direction="column" maxWidth="size-5000" gap="size-300">
<RangeSlider
label="Jeans price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
defaultValue={{ start: 75, end: 100 }}
/>
<RangeSlider
label="Shoes price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
labelPosition="side"
defaultValue={{ start: 50, end: 100 }}
/>
<RangeSlider
label="Hats price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
showValueLabel={false}
defaultValue={{ start: 15, end: 30 }}
/>
</Flex>
<Flex
direction="column"
maxWidth="size-5000"
gap="size-300"
>
<RangeSlider
label="Jeans price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
defaultValue={{ start: 75, end: 100 }}
/>
<RangeSlider
label="Shoes price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
labelPosition="side"
defaultValue={{ start: 50, end: 100 }}
/>
<RangeSlider
label="Hats price range"
formatOptions={{ style: 'currency', currency: 'USD' }}
showValueLabel={false}
defaultValue={{ start: 15, end: 30 }}
/>
</Flex>
<Flex
direction="column"
maxWidth="size-5000"
gap="size-300"
>
<RangeSlider
label="Jeans price range"
formatOptions={{
style:
'currency',
currency: 'USD'
}}
defaultValue={{
start: 75,
end: 100
}}
/>
<RangeSlider
label="Shoes price range"
formatOptions={{
style:
'currency',
currency: 'USD'
}}
labelPosition="side"
defaultValue={{
start: 50,
end: 100
}}
/>
<RangeSlider
label="Hats price range"
formatOptions={{
style:
'currency',
currency: 'USD'
}}
showValueLabel={false}
defaultValue={{
start: 15,
end: 30
}}
/>
</Flex>
By default, the value label is formatted as a plain number. This can be customized using the following props.
showValueLabel
: Allows you to display or hide the value label.formatOptions
: Allows you to customize the format of the value.getValueLabel
: Allows you to provide a custom function to format the value label.
<Flex direction="column" maxWidth="size-3000" gap="size-300">
<RangeSlider
label="Level range"
showValueLabel={false}
defaultValue={{start: 75, end: 100}} />
<RangeSlider
label="Cacao percentage"
maxValue={1}
step={0.001}
formatOptions={{style: 'percent', minimumFractionDigits: 1}}
defaultValue={{start: .75, end: 1}} />
<RangeSlider
label="Search radius"
maxValue={200}
getValueLabel={meters => ` m to m away`}
defaultValue={{start: 15, end: 60}} />
</Flex>
<Flex
direction="column"
maxWidth="size-3000"
gap="size-300"
>
<RangeSlider
label="Level range"
showValueLabel={false}
defaultValue={{ start: 75, end: 100 }}
/>
<RangeSlider
label="Cacao percentage"
maxValue={1}
step={0.001}
formatOptions={{
style: 'percent',
minimumFractionDigits: 1
}}
defaultValue={{ start: .75, end: 1 }}
/>
<RangeSlider
label="Search radius"
maxValue={200}
getValueLabel={(meters) =>
` m to m away`}
defaultValue={{ start: 15, end: 60 }}
/>
</Flex>
<Flex
direction="column"
maxWidth="size-3000"
gap="size-300"
>
<RangeSlider
label="Level range"
showValueLabel={false}
defaultValue={{
start: 75,
end: 100
}}
/>
<RangeSlider
label="Cacao percentage"
maxValue={1}
step={0.001}
formatOptions={{
style: 'percent',
minimumFractionDigits:
1
}}
defaultValue={{
start: .75,
end: 1
}}
/>
<RangeSlider
label="Search radius"
maxValue={200}
getValueLabel={(meters) =>
` m to m away`}
defaultValue={{
start: 15,
end: 60
}}
/>
</Flex>
Accessibility#
Depending on the visualization being used (i.e. depending on the showValueLabel
prop), a label
, aria-label
, or aria-labelledby
prop is required.
Internationalization#
To internationalize a Slider, a localized string should be passed to the label
prop, aria-label
prop, or value of the associated aria-labelledby
element.
For languages that are read right-to-left (e.g. Hebrew and Arabic), the layout of the slider is automatically flipped. In addition, Slider automatically uses the current locale to format the value label.
Props#
Name | Type | Default | Description |
startName | string | — | The name of the start input element, used when submitting an HTML form. See MDN. |
endName | string | — | The name of the end input element, used when submitting an HTML form. See MDN. |
formatOptions | Intl.NumberFormatOptions | — | The display format of the value label. |
labelPosition | LabelPosition | 'top' | The label's overall position relative to the element it is labeling. |
showValueLabel | boolean | — | Whether the value's label is displayed. True by default if there's a label , false by default if not. |
getValueLabel | (
(value: RangeValue<number>
)) => string | — | A function that returns the content to display as the value's label. Overrides default formatted number. |
contextualHelp | ReactNode | — | A ContextualHelp element to place next to the label. |
orientation | Orientation | 'horizontal' | The orientation of the Slider. |
isDisabled | boolean | — | Whether the whole Slider is disabled. |
minValue | number | 0 | The slider's minimum value. |
maxValue | number | 100 | The slider's maximum value. |
step | number | 1 | The slider's step value. |
value | RangeValue<number> | — | The current value (controlled). |
defaultValue | RangeValue<number> | — | The default value (uncontrolled). |
label | ReactNode | — | The content to display as the label. |
id | string | undefined | — | The element's unique identifier. See MDN. |
Events
Name | Type | Description |
onChangeEnd | (
(value: RangeValue<number>
)) => void | Fired when the slider stops moving, due to being let go. |
onChange | (
(value: T
)) => void | Handler that is called when the value changes. |
Layout
Name | Type | Description |
flex | Responsive<string
| number
| boolean> | When used in a flex layout, specifies how the element will grow or shrink to fit the space available. See MDN. |
flexGrow | Responsive<number> | When used in a flex layout, specifies how the element will grow to fit the space available. See MDN. |
flexShrink | Responsive<number> | When used in a flex layout, specifies how the element will shrink to fit the space available. See MDN. |
flexBasis | Responsive<number | string> | When used in a flex layout, specifies the initial main size of the element. See MDN. |
alignSelf | Responsive<'auto'
| 'normal'
| 'start'
| 'end'
| 'center'
| 'flex-start'
| 'flex-end'
| 'self-start'
| 'self-end'
| 'stretch'> | Overrides the alignItems property of a flex or grid container. See MDN. |
justifySelf | Responsive<'auto'
| 'normal'
| 'start'
| 'end'
| 'flex-start'
| 'flex-end'
| 'self-start'
| 'self-end'
| 'center'
| 'left'
| 'right'
| 'stretch'> | Specifies how the element is justified inside a flex or grid container. See MDN. |
order | Responsive<number> | The layout order for the element within a flex or grid container. See MDN. |
gridArea | Responsive<string> | When used in a grid layout, specifies the named grid area that the element should be placed in within the grid. See MDN. |
gridColumn | Responsive<string> | When used in a grid layout, specifies the column the element should be placed in within the grid. See MDN. |
gridRow | Responsive<string> | When used in a grid layout, specifies the row the element should be placed in within the grid. See MDN. |
gridColumnStart | Responsive<string> | When used in a grid layout, specifies the starting column to span within the grid. See MDN. |
gridColumnEnd | Responsive<string> | When used in a grid layout, specifies the ending column to span within the grid. See MDN. |
gridRowStart | Responsive<string> | When used in a grid layout, specifies the starting row to span within the grid. See MDN. |
gridRowEnd | Responsive<string> | When used in a grid layout, specifies the ending row to span within the grid. See MDN. |
Spacing
Name | Type | Description |
margin | Responsive<DimensionValue> | The margin for all four sides of the element. See MDN. |
marginTop | Responsive<DimensionValue> | The margin for the top side of the element. See MDN. |
marginBottom | Responsive<DimensionValue> | The margin for the bottom side of the element. See MDN. |
marginStart | Responsive<DimensionValue> | The margin for the logical start side of the element, depending on layout direction. See MDN. |
marginEnd | Responsive<DimensionValue> | The margin for the logical end side of an element, depending on layout direction. See MDN. |
marginX | Responsive<DimensionValue> | The margin for both the left and right sides of the element. See MDN. |
marginY | Responsive<DimensionValue> | The margin for both the top and bottom sides of the element. See MDN. |
Sizing
Name | Type | Description |
width | Responsive<DimensionValue> | The width of the element. See MDN. |
minWidth | Responsive<DimensionValue> | The minimum width of the element. See MDN. |
maxWidth | Responsive<DimensionValue> | The maximum width of the element. See MDN. |
height | Responsive<DimensionValue> | The height of the element. See MDN. |
minHeight | Responsive<DimensionValue> | The minimum height of the element. See MDN. |
maxHeight | Responsive<DimensionValue> | The maximum height of the element. See MDN. |
Positioning
Name | Type | Description |
position | Responsive<'static'
| 'relative'
| 'absolute'
| 'fixed'
| 'sticky'> | Specifies how the element is positioned. See MDN. |
top | Responsive<DimensionValue> | The top position for the element. See MDN. |
bottom | Responsive<DimensionValue> | The bottom position for the element. See MDN. |
left | Responsive<DimensionValue> | The left position for the element. See MDN. Consider using start instead for RTL support. |
right | Responsive<DimensionValue> | The right position for the element. See MDN. Consider using start instead for RTL support. |
start | Responsive<DimensionValue> | The logical start position for the element, depending on layout direction. See MDN. |
end | Responsive<DimensionValue> | The logical end position for the element, depending on layout direction. See MDN. |
zIndex | Responsive<number> | The stacking order for the element. See MDN. |
isHidden | Responsive<boolean> | Hides the element. |
Accessibility
Name | Type | Description |
aria-label | string | Defines a string value that labels the current element. |
aria-labelledby | string | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | Identifies the element (or elements) that describes the object. |
aria-details | string | Identifies the element (or elements) that provide a detailed, extended description for the object. |
Advanced
Name | Type | Description |
UNSAFE_className | string | Sets the CSS className for the element. Only use as a last resort. Use style props instead. |
UNSAFE_style | CSSProperties | Sets inline style for the element. Only use as a last resort. Use style props instead. |
Visual options#
Contextual help#
A ContextualHelp element may be placed next to the label to provide additional information or help about a RangeSlider.
import {Content, ContextualHelp, Heading} from '@adobe/react-spectrum';
<RangeSlider
label="Search radius"
formatOptions={{style: 'unit', unit: 'mile'}}
defaultValue={{start: 15, end: 60}}
contextualHelp={
<ContextualHelp variant="info">
<Heading>Ranking</Heading>
<Content>Search results are sorted by distance from city center.</Content>
</ContextualHelp>
} />
import {
Content,
ContextualHelp,
Heading
} from '@adobe/react-spectrum';
<RangeSlider
label="Search radius"
formatOptions={{ style: 'unit', unit: 'mile' }}
defaultValue={{ start: 15, end: 60 }}
contextualHelp={
<ContextualHelp variant="info">
<Heading>Ranking</Heading>
<Content>
Search results are sorted by distance from city
center.
</Content>
</ContextualHelp>
}
/>
import {
Content,
ContextualHelp,
Heading
} from '@adobe/react-spectrum';
<RangeSlider
label="Search radius"
formatOptions={{
style: 'unit',
unit: 'mile'
}}
defaultValue={{
start: 15,
end: 60
}}
contextualHelp={
<ContextualHelp variant="info">
<Heading>
Ranking
</Heading>
<Content>
Search results
are sorted by
distance from
city center.
</Content>
</ContextualHelp>
}
/>
Disabled#
<RangeSlider
label="Price filter"
defaultValue={{ start: 25, end: 50 }}
isDisabled
/>
<RangeSlider
label="Price filter"
defaultValue={{ start: 25, end: 50 }}
isDisabled
/>
<RangeSlider
label="Price filter"
defaultValue={{
start: 25,
end: 50
}}
isDisabled
/>