RangeInput

A styled wrapper around the HTML <input type="range"> element with support for labels, icons, and customization options.

Props

PropTypeDefaultDescription
valuenumberRequiredCurrent slider value
onValueChange(value: number) => voidRequiredCalled when the value changes
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment
labelReactNode-Label text displayed alongside the slider
labelPosition"start" | "end""end"Position of the label
labelSizeSize-Label text size
labelColorTextColor-Label text color
labelBoldboolean-Whether the label is bold
addOnJSX.Element-Icon or element to display
addOnPosition"start" | "end""start"Position of the add-on
gapGap"medium"Space between elements
paddingPadding"none"Container padding
disabledboolean-Disables the input

Basic usage

const [value, setValue] = useState(50);

<RangeInput value={value} onValueChange={setValue} />;

With label

Labels can be positioned at the start or end of the slider:

// Label at end (default)
<RangeInput value={value} onValueChange={setValue} label={`${value}%`} />

// Label at start
<RangeInput
  value={value}
  onValueChange={setValue}
  label={`${value}%`}
  labelPosition="start"
/>

With icon add-on

Add icons to provide context for what the slider controls:

// Icon at start (default)
<RangeInput
  addOn={<Icon icon="volume-2" color="primary" size="medium" />}
  value={volume}
  onValueChange={setVolume}
  label={`${volume}%`}
/>

// Icon at end
<RangeInput
  addOn={<Icon icon="sun" color="warning" size="medium" />}
  addOnPosition="end"
  value={brightness}
  onValueChange={setBrightness}
  label="Brightness"
  labelPosition="start"
/>

Label styling

Customize the label appearance:

<RangeInput
  value={value}
  onValueChange={setValue}
  label={`${value}%`}
  labelSize="large"
  labelColor="highlight"
  labelBold
/>

Custom range

Set min, max, and step values:

// Temperature slider (0-100 in steps of 5)
<RangeInput
  value={temperature}
  onValueChange={setTemperature}
  min={0}
  max={100}
  step={5}
  label={`${temperature}°C`}
/>

// Decimal values (0-1 in steps of 0.1)
<RangeInput
  value={opacity}
  onValueChange={setOpacity}
  min={0}
  max={1}
  step={0.1}
  label={opacity.toFixed(1)}
/>

Volume control example

function VolumeControl() {
  const [volume, setVolume] = useState(50);

  const icon =
    volume === 0 ? "volume-off" : volume < 50 ? "volume-1" : "volume-2";

  return (
    <RangeInput
      addOn={<Icon icon={icon} color="primary" size="medium" />}
      value={volume}
      onValueChange={setVolume}
      label={`${volume}%`}
      labelBold
    />
  );
}

Accessibility

  • The underlying <input type="range"> is fully accessible
  • Labels are properly associated with the input via htmlFor
  • Focus states are visually indicated
  • Use aria-label or visible labels to describe the slider's purpose
<RangeInput aria-label="Volume" value={volume} onValueChange={setVolume} />