react ~9 KB 0 deps v0.4.0 β†— GitHub β†—

@mshafiqyajid/react-slider

Headless slider hook and styled component. Single and range (dual thumb) mode, tick marks with snap, logarithmic scale, vertical orientation, value tooltip, label / hint / error / invalid / required, keyboard navigation, ARIA-compliant.

Playground #

committed: 40
Props
TSX
import { SliderStyled } from "@mshafiqyajid/react-slider/styled";
import "@mshafiqyajid/react-slider/styles.css";

<SliderStyled
  value={value}
  onChange={setValue}
  tone="primary"
/>

Multi-thumb β€” 3 independent thumbs

snapToMarks
values: 20 Β· 50 Β· 80

Log scale (min=1, max=10 000)

value: 100

Install #

npm install @mshafiqyajid/react-slider

Quick start #

import { SliderStyled } from "@mshafiqyajid/react-slider/styled";
import "@mshafiqyajid/react-slider/styles.css";

const [v, setV] = useState(40);
<SliderStyled value={v} onChange={setV} tone="primary" showValue />

// Range
const [range, setRange] = useState<[number, number]>([20, 80]);
<SliderStyled value={range} onChange={setRange} range />

Marks and snap #

Pass marks={true} to derive ticks from step, an array of numbers, or an array of { value, label? } objects. Add snapToMarks to snap the thumb on release.

// Ticks derived from step
<SliderStyled min={0} max={100} step={25} marks />

// Custom marks with labels
<SliderStyled
  min={0} max={100}
  marks={[{ value: 0, label: "Low" }, { value: 50, label: "Mid" }, { value: 100, label: "High" }]}
  snapToMarks
/>

Logarithmic scale #

<SliderStyled
  min={1} max={1000}
  scale="log"
  scaleBase={10}
  formatValue={(v) => `${v} Hz`}
  showValue
/>

Vertical orientation #

<SliderStyled orientation="vertical" style={{ height: 200 }} />

Form field #

Include label, hint, error, required, and name to use as a proper form field. Range mode emits two hidden inputs: name and name-end.

<SliderStyled
  name="price-range"
  label="Price range"
  hint="Set your budget"
  required
  range
  value={range}
  onChange={setRange}
/>

Headless #

import { useSlider } from "@mshafiqyajid/react-slider";

const { value, trackProps, thumbProps, rangeProps } = useSlider({
  defaultValue: 50,
  min: 0,
  max: 100,
});

return (
  <div className="slider">
    <div {...trackProps} className="track">
      <div {...rangeProps} className="range" />
      {thumbProps.map((thumb, i) => (
        <button key={i} {...thumb} className="thumb" />
      ))}
    </div>
    <span>{Array.isArray(value) ? value.join("–") : value}</span>
  </div>
);

API #

PropTypeDefaultDescription
valuenumber | [number, number]β€”Controlled value
defaultValuenumber | [number, number]min (range: [min, max])Uncontrolled initial value
onChange(v: SliderValue) => voidβ€”Called on every change
onCommit(v: SliderValue) => voidβ€”Fires only on pointer release / keyboard commit, not on every step
minnumber0Minimum value
maxnumber100Maximum value
stepnumber1Step increment
rangebooleanfalseDual thumb range mode
size"sm" | "md" | "lg""md"Track height
tone"neutral" | "primary" | "success" | "danger""neutral"Color
orientation"horizontal" | "vertical""horizontal"Slider orientation
showValuebooleanfalseAlways show value bubble on thumb
showValueOnInteractionbooleanβ€”Show value bubble only while thumb is hovered/active
formatValue(v: number) => ReactNodeβ€”Format the number shown in the value bubble
marksboolean | number[] | SliderMark[]falseTick marks. true derives from step; array sets custom positions with optional labels
snapToMarksbooleanfalseSnap thumb to nearest mark on drag release
scale"linear" | "log""linear"Map the track to a logarithmic scale
scaleBasenumber10Base for the log scale
disabledbooleanfalseDisable interaction
labelReactNodeβ€”Label rendered above the slider
hintReactNodeβ€”Helper text below the slider
errorReactNodeβ€”Error text β€” flips tone to danger, sets aria-invalid
invalidbooleanfalseForce invalid state without inline error text
requiredbooleanβ€”Mark as required (hidden inputs inherit this)
namestringβ€”Form name. Renders hidden input(s); range emits name and name-end
idstringβ€”Override the generated wrapper id
classNamestringβ€”Extra class on the root element
styleCSSPropertiesβ€”Inline style override
Edit this page on GitHub