react ~7 KB 0 deps v0.1.0 β†— GitHub β†—

@mshafiqyajid/react-range

Headless range hook and styled component. Single-thumb and dual-thumb mode, snap-point tick marks, drag/always/never tooltip, inverted fill, label / hint / error / required, full keyboard navigation, ARIA-compliant.

Playground #

committed: 20–70
Props
TSX
import { RangeStyled } from "@mshafiqyajid/react-range/styled";
import "@mshafiqyajid/react-range/styles.css";

<RangeStyled
  value={value}
  onChange={setValue}
/>

Tone variants β€” single slider

primary
success
warning
danger
neutral

Marks showcase

Step marks (step=25)
Labelled marks

Install #

npm install @mshafiqyajid/react-range

Quick start #

import { RangeStyled } from "@mshafiqyajid/react-range/styled";
import "@mshafiqyajid/react-range/styles.css";

// Single slider
const [volume, setVolume] = useState(40);
<RangeStyled mode="single" value={volume} onChange={setVolume} tone="primary" label="Volume" />

// Range slider
const [range, setRange] = useState<[number, number]>([20, 80]);
<RangeStyled mode="range" value={range} onChange={setRange} tone="primary" label="Price range" />

Marks #

Pass marks={true} to derive ticks from step, or an array of { value, label? } objects for custom positions and labels.

// Auto-marks from step
<RangeStyled mode="single" min={0} max={100} step={25} marks />

// Custom labelled marks
<RangeStyled
  mode="range"
  marks={[
    { value: 0, label: "Low" },
    { value: 50, label: "Mid" },
    { value: 100, label: "High" },
  ]}
/>

Tooltip #

Control tooltip visibility with showTooltip. Use tooltipFormat to customise the displayed value.

// Show only while dragging (default)
<RangeStyled mode="single" showTooltip="drag" />

// Always visible
<RangeStyled mode="single" showTooltip="always" tooltipFormat={(v) => `$${v}`} />

// Never show
<RangeStyled mode="range" showTooltip="never" />

Form field #

Combine label, hint, error, required, and onChangeEnd for a proper form control.

<RangeStyled
  mode="range"
  label="Budget"
  hint="Set your minimum and maximum"
  required
  value={range}
  onChange={setRange}
  onChangeEnd={handleSubmit}
/>

// Error state
<RangeStyled
  mode="range"
  label="Price"
  error="Range must be at least $10 apart"
  value={range}
  onChange={setRange}
/>

Inverted #

Set inverted to reverse the fill direction β€” useful for "remaining capacity" or reversed value semantics.

<RangeStyled mode="single" inverted value={value} onChange={setValue} />

Headless #

import { useRange } from "@mshafiqyajid/react-range";

const { value, rootProps, trackProps, getThumbProps, getTrackFillProps } = useRange({
  defaultValue: [20, 80],
  min: 0,
  max: 100,
  mode: "range",
  onChange: (v) => console.log(v),
  onChangeEnd: (v) => console.log("committed:", v),
});

return (
  <div {...rootProps} className="my-range">
    <div {...trackProps} className="track">
      <div className="rail" />
      <div {...getTrackFillProps()} className="fill" />
      {[0, 1].map((i) => (
        <div key={i} {...getThumbProps(i)} className="thumb" />
      ))}
    </div>
  </div>
);

API #

PropTypeDefaultDescription
valuenumber | [number, number]β€”Controlled value
defaultValuenumber | [number, number]min / [min, max]Uncontrolled initial value
onChange(v) => voidβ€”Fires on every change
onChangeEnd(v) => voidβ€”Fires on pointer release or keyboard commit
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment
mode"single" | "range""range"Single or dual thumb
disabledbooleanfalseDisable interaction
invertedbooleanfalseInvert fill direction
showTooltip"always" | "drag" | "never""drag"Tooltip visibility
tooltipFormat(v: number) => stringβ€”Format tooltip value
marksboolean | { value, label? }[]falseTick marks; true derives from step
size"sm" | "md" | "lg""md"Track and thumb size
tone"neutral" | "primary" | "success" | "warning" | "danger""primary"Fill color
labelstringβ€”Label above the slider
hintstringβ€”Helper text below
errorstringβ€”Error text β€” sets data-invalid and danger tone
requiredbooleanβ€”Mark as required
invalidbooleanβ€”Force invalid state without error text
classNamestringβ€”Extra class on root div
styleCSSPropertiesβ€”Inline style on root div

Keyboard #

KeyAction
ArrowRight / ArrowUp+1 step
ArrowLeft / ArrowDown-1 step
Shift + ArrowΒ±10% of range
HomeJump to minimum
EndJump to maximum
Edit this page on GitHub