A slider: one value on a range, or two or more thumbs for a range of values. Each thumb is a
visually hidden native <input type="range">, so the keys (the arrows, Page, Home and End),
assistive technology and forms work as the platform's; the pointer drags a thumb, touch included.
Every name is yours - each thumb's (getAriaLabel, or a FormLabel), and the text of its value
(getAriaValueText) - so the slider carries no language of its own.
import { RangeInput } from '@soroush.tech/design-system/RangeInput'
// One thumb
;<RangeInput
aria-label="Volume"
value={volume}
onChange={(_event, value) => setVolume(value as number)}
/>
// A range - one thumb for each value
;<RangeInput
value={[20, 70]}
onChange={(_event, value) => setRange(value as number[])}
getAriaLabel={(index) => (index === 0 ? 'Least price' : 'Greatest price')}
valueLabel="auto"
/>
Examples
Default
const args: Partial<RangeInputProps> = { defaultValue: 40, 'aria-label': 'Value' } <RangeInput key={JSON.stringify(args.defaultValue)} {...args} />
Range
const args: Partial<RangeInputProps> = { defaultValue: [20, 70], valueLabel: 'auto' } <RangeInput key={JSON.stringify(args.defaultValue)} getAriaLabel={priceLabel} {...args} />
Controlled Value
Value: 30
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <Controlled {...args} />
Marks
const args: Partial<RangeInputProps> = { defaultValue: 30, min: 10, max: 110, step: 10, marks: true, 'aria-label': 'Value', } <RangeInput key={JSON.stringify(args.defaultValue)} {...args} />
Custom Marks
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <RangeInput {...args} defaultValue={20} step={10} marks={labelled} />
Restricted To Marks
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <RangeInput {...args} defaultValue={20} step={null} marks={labelled} />
Value Label Always Shown
const args: Partial<RangeInputProps> = { defaultValue: 40, valueLabel: 'on', 'aria-label': 'Value' } <View paddingTop={4}> <RangeInput key={JSON.stringify(args.defaultValue)} {...args} /> </View>
Vertical
const args: Partial<RangeInputProps> = { defaultValue: 40, step: 20, marks: true, orientation: 'vertical', 'aria-label': 'Value', } <RangeInput key={JSON.stringify(args.defaultValue)} {...args} />
Without Track
const args: Partial<RangeInputProps> = { defaultValue: [20, 37, 50], track: false, 'aria-label': 'Value' } <RangeInput {...args} getAriaLabel={(index) => `Thumb ${index + 1}`} />
Inverted Track
const args: Partial<RangeInputProps> = { defaultValue: [30, 60], track: 'inverted' } <RangeInput {...args} getAriaLabel={priceLabel} />
Minimum Distance Between Thumbs
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <MinimumDistance {...args} />
Non Linear Scale
const args: Partial<RangeInputProps> = { defaultValue: 4, min: 0, max: 10, step: 1, valueLabel: 'auto', 'aria-label': 'Value', } <View paddingTop={4}> <RangeInput key={JSON.stringify(args.defaultValue)} {...args} scale={(value) => 2 ** value} getAriaValueText={(value) => `${value} bytes`} /> </View>
With Aria Value Text
const args: Partial<RangeInputProps> = { defaultValue: 30, min: 0, max: 60, step: 5, shiftStep: 15, valueLabel: 'auto', 'aria-label': 'Timer', } <View paddingTop={4}> <RangeInput key={JSON.stringify(args.defaultValue)} {...args} getAriaValueText={minutes} formatValueLabel={minutes} /> </View>
Range With Aria Value Text
const args: Partial<RangeInputProps> = { defaultValue: [9, 17], min: 0, max: 24, valueLabel: 'auto' } <View paddingTop={4}> <RangeInput {...args} getAriaLabel={(index) => (index === 0 ? 'Opens at' : 'Closes at')} getAriaValueText={(value) => `${value}:00`} formatValueLabel={(value) => `${value}:00`} /> </View>
With An Input Field
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <WithNumberInput {...args} />
Sizes
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <Flex gap={2}> {(['sm', 'md', 'lg'] as const).map((size) => ( <RangeInput key={size} {...args} size={size} aria-label={`Value, ${size}`} /> ))} </Flex>
Colors
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <Flex gap={2}> {(['primary', 'secondary', 'success', 'error'] as const).map((color) => ( <RangeInput key={color} {...args} color={color} aria-label={`Value, ${color}`} /> ))} </Flex>
States
const args: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <Flex gap={2}> <RangeInput {...args} error aria-label="Value, in error" /> <RangeInput {...args} disabled aria-label="Value, disabled" /> </Flex>
In Form Control
Loud or quiet.
const { error, disabled, size, color }: Partial<RangeInputProps> = { 'aria-label': 'Value', defaultValue: 40 } <FormControl error={error} disabled={disabled} size={size} color={color}> <FormLabel>Volume</FormLabel> <RangeInput defaultValue={30} valueLabel="auto" /> <FormHelperText>{error ? 'Too loud.' : 'Loud or quiet.'}</FormHelperText> </FormControl>
Right To Left
const args: Partial<RangeInputProps> = { defaultValue: 30, valueLabel: 'auto', 'aria-label': 'Value' } <View dir="rtl" paddingTop={4}> <RangeInput {...args} /> </View>
Customized
<ThemeProvider theme={customized}> <View paddingTop={4}> <RangeInput aria-label="Value" defaultValue={40} /> </View> </ThemeProvider>