RangeSlider
Select an interval by dragging the handles, clicking the track, using the keyboard, or entering values directly.
Currency range
0 commits
Decimal steps
Percentage formatting
Arrow keys move 1%. Shift + arrow or Page Up / Down moves 10%.
Logarithmic pressure
Each arrow moves one decade (×10 or ÷10). Values and callbacks stay in bar.
Overlapping handles
Right-to-left layout
Right-to-left layouts mirror the track and horizontal arrow keys.
Usage
<script>
import { RangeSlider } from 'svelte-widgets'
let value = $state([120, 360])
</script>
<RangeSlider
label="Nightly budget"
min={0}
max={500}
step={10}
bind:value
format_value={(value) => '$' + value}
on_commit={(value) => console.log('Apply filter', value)}
/>
Interaction details
- Drag or tap: the nearest handle moves. Handles stop at one another. At the same value, drag in either direction to separate them.
- Keyboard: Tab reaches each handle in a fixed order. Arrows move one step; Shift + arrow and Page Up / Down move ten. Home / End reach that handle’s allowed bounds.
- Type: edits apply on Enter or blur, snap to the nearest step, and stay within the allowed interval. Escape discards a draft. Empty or invalid drafts restore the current value.
- Events: binding and
on_inputupdate while dragging.on_commitruns at the end of a changed gesture, on each keyboard adjustment, or after a changed numeric edit. Pointer cancellation keeps and commits the last value. External prop updates emit neither callback. - Logarithmic scale:
scale="log"spaces positions and ticks geometrically.min,max, bound values, numeric fields, formatters, and callbacks stay in real units.stepis a base-10 exponent increment:1multiplies or divides by 10;0.1uses a factor of 10^0.1. Positive numeric drafts snap to this logarithmic grid and clamp to the allowed interval; zero and negative drafts are discarded. Both endpoints remain exactly selectable, even off the grid.
Props
| Prop | Default | Purpose |
|---|---|---|
value | [min, max] | Bindable [lower, upper] pair. |
min / max / step | 0 / 100 / 1 | Finite bounds and a positive step anchored at min. Max is always selectable, even between steps. |
scale | linear | linear uses additive steps; log uses base-10 decades and requires strictly positive bounds with distinct logarithms. |
label / description | Range / undefined | Visible group name and optional help text. |
lower_label / upper_label | Minimum / Maximum | Accessible endpoint names and input tooltips; translate these along with the label. |
format_value | String | Formats the selected values, limits, and announced slider values. Click a selected value to edit its underlying number. |
tick_position | below | below places min/max labels close beneath the track; sides shortens the track to fit labels at either end. |
tick_count | 2 | Total evenly spaced labels including min and max (integer ≥ 2). A count of 3 adds the midpoint. Intermediate labels appear below the track in both layouts, use format_value, and are independent of step. |
show_inputs / disabled | true / false | Make selected values read-only or disable every interaction. |
on_input / on_commit | — | Receive a fresh value pair for live and completed edits. |
External values must be finite, ordered, and inside the bounds. Update bounds and value together when changing the domain. Invalid configuration, including steps too small to change a representable value, throws with the offending values. Extra HTML attributes are forwarded to the group. Native form reset discards numeric drafts; reset the binding in your form handler to restore a saved interval.
Style with --range-slider-color, --range-slider-track, --range-slider-thumb, and --range-slider-input-bg. Touch targets are 44 pixels, focus rings remain visible, and the control supports reduced motion and forced colors.