nili/ui
All components

Slider

Overview
9 exports3 variant axes23 props4 files
import { Slider, SliderValue } from '@nili/ui';

This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.

Single thumb and range

The shape of the value is the type: a number renders one thumb, a [number, number] renders a range. A range slider cannot be handed a single number by accident.

Volume40
Price range20 – 70
import { Slider } from "@nili/ui"

export function Example() {
  const [value, setValue] = useState(40)
  const [range, setRange] = useState([20, 70])

  return (
    <>
      <Slider
        label="Volume"
        value={value}
        onValueChange={setValue}
        showValue
      />

      <Slider
        label="Price"
        value={range}
        onValueChange={setRange}
        showValue
      />
    </>
  )
}

Label, sublabel and value

label names the thumbs as well as showing above the track. showValue puts the current number beside it; sublabel adds a muted second line.

Brightness
BrightnessScreen only60
import { Slider } from "@nili/ui"

export function Example() {
  return (
    <>
      <Slider label={t('brightness')} defaultValue={60} />
      <Slider label="Brightness" sublabel="Screen only" defaultValue={60} showValue />

      {/* no visible label — name the thumbs instead */}
      <Slider defaultValue={60} thumbLabels={["Brightness"]} />
    </>
  )
}

Tooltip

tooltip shows the value in a bubble above the thumb while dragging — useful when there is no room for a permanent readout.

Opacity
import { Slider } from "@nili/ui"

export function Example() {
  return <Slider label={t('opacity')} defaultValue={75} tooltip />
}

Steps and bounds

min, max and step behave as you would expect. minStepsBetweenThumbs keeps the two ends of a range from crossing.

Rating3
Temperature20
Budget200 – 600
import { Slider } from "@nili/ui"

export function Example() {
  return (
    <>
      <Slider label="Rating" min={1} max={5} step={1} defaultValue={3} showValue />
      <Slider label="Temperature" min={-20} max={50} step={5} defaultValue={20} showValue />
      <Slider
        label="Budget"
        min={0}
        max={1000}
        step={50}
        defaultValue={[200, 600]}
        minStepsBetweenThumbs={2}
        showValue
      />
    </>
  )
}

Formatting

formatValue changes every number the user sees or hears, not only the visible one. Digits follow the ambient locale by default, so a Persian UI gets Persian numerals for free.

Storage120 GB
Discount25%
import { Slider } from "@nili/ui"

export function Example() {
  return (
    <>
      <Slider
        label="Storage"
        max={500}
        defaultValue={120}
        showValue
        formatValue={(value) => `${value} GB`}
      />

      <Slider
        label="Discount"
        defaultValue={25}
        showValue
        formatValue={(value) => `${value}%`}
      />
    </>
  )
}

Commit and disabled

onValueChange fires on every step while dragging; onValueCommit fires once, when the pointer or key is released. Use the second for anything expensive — a request per pixel of drag is the usual way a slider takes a server down.

Results per page20
Disabled40
Disabled range
import { Slider } from "@nili/ui"

export function Example() {
  return (
    <>
      <Slider
        label="Results per page"
        defaultValue={20}
        max={100}
        step={10}
        showValue
        onValueCommit={(value) => refetch(value)}
      />

      <Slider label="Disabled" defaultValue={40} disabled />
    </>
  )
}