iOS slider

A native range input with a quiet track, pill thumb and synchronized stepped values.

Listening level

40%

Use it for

  • A bounded numeric level such as volume, brightness or playback intensity.
  • Provide min, max and step when the range is discrete.

Not for

  • Values that need precise text entry without an accompanying numeric field.
  • Multiple independent values; use separate labeled sliders.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { IOSSlider } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/ios-slider.

2. Vendor the source

npx @noorddev/vlak-cli add ios-slider

The StyleX leaf lands in components/vlak/, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/ios-slider.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { IOSSlider } from "@noorddev/vlak-react";

<IOSSlider name="volume" aria-label="Volume" min={0} max={100} defaultValue={40} onValueChange={value => console.log(value)} />

IOSSlider

Native range keyboard and form behavior beneath the iOS pill thumb.

PropTypeDefaultDescription
valuenumber
defaultValuenumber50
minnumber0
maxnumber100
stepnumber | "any"1
onValueChange(value: number) => void

Also accepts Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "defaultValue" | "min" | "max" | "step" | "children">.

KeysDoes
Tab, Shift+TabMoves focus to or away from the native range input.
Arrows, Home, EndUses the browser’s native range stepping and boundary behavior.
<div class="rs-ios-slider"><span class="rs-ios-slider-track" aria-hidden="true"><span class="rs-ios-slider-fill" style="width:50%"></span><span class="rs-ios-slider-thumb" style="inset-inline-start:50%"></span></span><input class="rs-ios-slider-input" type="range" min="0" max="100" value="50" aria-label="Volume" /></div>
.rs-ios-slider.rs-ios-slider-disabled.rs-ios-slider-track.rs-ios-slider-fill.rs-ios-slider-thumb.rs-ios-slider-input