Skip to content
Notra logoNotra UI
Esc
↑↓navigate↵open⌘Jpreview

Step Slider

A slider that snaps to a fixed set of values, from the Notra pricing page.

"use client";

import { useState } from "react";

import { StepSlider } from "../components/step-slider";

const PROMPT_STEPS = [5, 10, 25, 50, 100, 150, 250, 500, 1000] as const;
const THOUSAND = 1000;

const formatPrompts = (value: number) =>
  value >= THOUSAND ? `${value / THOUSAND}K` : value;

export default function StepSliderExample() {
  const [prompts, setPrompts] = useState(10);

  return (
    <div className="flex w-full max-w-3xl flex-col gap-5 p-6">
      <div className="flex items-baseline justify-between gap-6">
        <span className="text-lg font-medium">Prompts</span>
        <span className="text-4xl tabular-nums">{prompts}</span>
      </div>
      <StepSlider
        aria-label="Prompts"
        formatLabel={formatPrompts}
        getValueText={(value) => `${value} prompts`}
        majorSteps={[5, 25, 100, 250, 1000]}
        onValueChange={setPrompts}
        steps={PROMPT_STEPS}
        value={prompts}
      />
    </div>
  );
}
$ bunx --bun shadcn@latest add @notra/step-slider

StepSlider is built on Base UI’s Slider, like the shadcn Slider, so it keeps keyboard, pointer and screen reader support. The values don’t have to be evenly spaced: every stop takes the same room on the track. The purple fill carries a dot texture, and a brighter band of dots sweeps through it on every step, while dragging too. Reduced motion turns the sweep off.

<StepSlider
  aria-label="Prompts"
  onValueChange={setPrompts}
  steps={[5, 10, 25, 50, 100]}
  value={prompts}
/>
Prop Default Description
steps The values the slider snaps to, in ascending order.
value The selected value. A value between stops shows as the nearest stop.
defaultValue first step The starting value when value is not set.
onValueChange Called with the new value on every step.
onValueCommitted Called when a drag, key press or label click ends.
formatLabel the number Label under each stop. Clicking a label selects it.
majorSteps all steps Steps whose label stays visible when the slider is narrower than 32rem.
hideLabels false Hides the labels under the track.
getValueText the number Screen reader text for a value, e.g. "10 prompts".
positionOf nearest step Fractional step index for a value, to place typed values between stops, e.g. 2.5.
name Submits the selected value, not the step index, with a form.

Every other Base UI Slider.Root prop, such as disabled, is passed through. For right-to-left layouts, wrap the slider in Base UI’s DirectionProvider with direction="rtl" so the thumb flips along with the stops.