Slider

Free

Range slider with single-value and dual-handle range mode, tick marks and step control.

</>sv-slider sliderrangeinput
import { SvSliderComponent } from '@styloviz/forms';

Demo & usage

Basic usage

Usage example — open the gallery for the full interactive demo.

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Dual-handle range

Enable range to select a min/max band.

example.htmlAngular
<sv-slider [range]="true" [min]="0" [max]="1000" [(rangeStart)]="lo" [(rangeEnd)]="hi" suffix="$" />

Ticks & value label

example.htmlAngular
<sv-slider [min]="0" [max]="10" [step]="1" [showTicks]="true" [showValue]="true" [(ngModel)]="rating" />

When to use

  • Choosing an approximate numeric value within a known range (volume, price, opacity).
  • You need a price/value band — use `range` for dual handles.
  • When the exact number matters, pair with or prefer a Number Input.

Async states

None — this component has nothing to load, so it has no loading, empty or error state to drive.

Inputs

NameTypeDefaultDescription
valuenumber (two-way)50Single slider value. Use `[(value)]` for two-way binding.
rangeStartnumber (two-way)20Range slider lower bound. Use with `range=true`.
rangeEndnumber (two-way)80Range slider upper bound. Use with `range=true`.
rangebooleanfalseEnable range (two-handle) mode.
minGapnumber | nullnullSmallest allowed distance between the two handles. `null` uses one `step`.
showInputsbooleanfalseRender a number field bound to each handle.
minnumber0Minimum value.
maxnumber100Maximum value.
stepnumber1Step increment.
labelstring''Optional label above the slider.
inputIdstring''Explicit id forwarded to the (single) native input. Auto-generated when omitted.
ariaLabelstring''`aria-label` for the slider when there is no visible `label`.
showValuebooleantrueShow the current value. THIS USED TO BE IGNORED IN RANGE MODE. The single slider honoured it; the two-handle one drew its value bubbles unconditionally, so a host that had already rendered a formatted range above the track — the normal thing to do for money, where `4000000` is not a label anybody wants — got the raw numbers printed on top of it anyway, with no way to turn them off. One input, one meaning, both modes.
valueFormat((value: number) => string) | nullnullTurn a raw value into the text on the bubbles and the min/max labels. A price range slider is the case this exists for. Without it the scale under the track reads `200000 … 4000000`, which is a number a computer wrote; with `formatMoneyShort` it reads `$200k … $4M`. `prefix`/`suffix` cannot do this — they concatenate, they do not format, so no combination of them produces a grouped or abbreviated figure. Pass a STABLE reference (a class field or a bound method), not an arrow written in the template: a new function identity on every change detection pass defeats the memoisation on the computed signals below.
prefixstring''Text prefix for value display (e.g. '$').
suffixstring''Text suffix for value display (e.g. '%').
showTicksbooleanfalseShow tick marks below the track (single mode only).
tickCountnumber5Number of visible tick marks (evenly spaced).
disabledbooleanfalseDisable interaction.
variantSliderVariant'primary'Color variant.
sizeSliderSize'md'Size — controls track height and thumb size.
errorMessagestring''Client-side validation message.
serverErrorSvServerErrornullA rejection reported by the server about this value. Self-expiring.

Outputs

EventPayload typeDescription
rangeChange[number, number]Emits updated range as [start, end].
valueChangenumberEmits the new `value` whenever it changes — the output half of `[(value)]`.
rangeStartChangenumberEmits the new `rangeStart` whenever it changes — the output half of `[(rangeStart)]`.
rangeEndChangenumberEmits the new `rangeEnd` whenever it changes — the output half of `[(rangeEnd)]`.

Customization & theming

  • Single value (`[(value)]`) or dual-handle range (`[(rangeStart)]` / `[(rangeEnd)]`, `range="true"`).
  • Configure `min`, `max`, `step`, optional `showTicks` / `tickCount`, and a `prefix` / `suffix` value readout (`showValue`).
  • Pick a `variant` and `size`; name the control with `label` or `ariaLabel`.

Best practices

  • Do: Show the current value (`showValue`) or a bound readout so the choice is legible.
  • Do: Choose a `step` that matches the precision users actually need.
  • Don't: Don't use a slider for precise or wide-range entry (e.g. 1–1,000,000) — type it instead.

Accessibility

  • Built on the native `<input type="range">`, so it has implicit `role="slider"` and full keyboard support — arrows nudge by `step`, Home/End jump to bounds, PageUp/PageDown step larger.
  • The single slider associates its `label` via `for`/`id` (or set `ariaLabel`); `prefix`/`suffix` are announced through `aria-valuetext` (e.g. "70%").
  • Range handles expose `aria-valuetext` and dynamic `aria-valuemin`/`aria-valuemax` (each handle bounded by the other); the thumb shows a clear focus ring.
  • Implements ControlValueAccessor for the single value — works with `[(ngModel)]` and reactive forms; `formControl.disable()` disables the slider.
  • Right-to-left is handled by the platform for the keyboard and by CSS for the layout: the native input flips Left/Right and the thumb itself, and the fill, bubbles and insets use `inset-inline-*` so they resolve from the same `direction` rather than a second guess at it. The component adds no key handler of its own — that would have to re-derive the platform's behaviour and would disagree with it somewhere.
  • `aria-valuenow`, `aria-valuemin` and `aria-valuemax` are numbers and do not flip: a screen reader announces 40 of 100 whichever way the track is drawn.

Feedback on Slider

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.