+ data-stepper cannot reach: formatted units, currency, time, token-snap scales, discrete enums."> + data-stepper cannot reach: formatted units, currency, time, token-snap scales, discrete enums."> + data-stepper cannot reach: formatted units, currency, time, token-snap scales, discrete enums.">
Vanilla Breeze

stepper-wc

Stepper for values that + data-stepper cannot reach: formatted units, currency, time, token-snap scales, discrete enums.

Overview

<stepper-wc> is a stepper for values that the native number input cannot represent: formatted units (e.g. $5.00, 12px, 50%), durations (15:00), byte sizes, token-snap design-system scales, and discrete enums. Plus optional long-press acceleration for large ranges.

It participates in form submission via ElementInternals. The inner display element carries role="spinbutton" with the appropriate aria-valuenow / aria-valuemin / aria-valuemax / aria-valuetext for assistive tech.

Modes

The mode is auto-detected from attributes, first match wins:

Trigger attributeModeWhat it does
data-optionsenumStep through a labeled list of options.
data-valuestokenStep through a fixed scale (e.g. spacing tokens).
data-format or data-suffixformattedNumeric value with formatting (currency, percent, duration, bytes, suffix).
nonenumericPlain numeric stepping. Logs a console hint pointing at data-stepper.

Formatted units

Numeric value with locale-aware formatting via Intl.NumberFormat for number, currency, and percent; custom formatters for duration (seconds → M:SS / H:MM:SS) and bytes (decimal SI: KB, MB, GB…).

The percent formatter treats the stored value as a 0–100 percentage (the displayed string divides by 100 internally for Intl.NumberFormat's style: 'percent'). So value="50" renders as 50%, not 5000%.

Token-snap

Step through a curated list of values. Useful for design-system scales where you want quantization rather than arbitrary numbers.

If the current value is off-scale, the first step snaps to the nearest entry by numeric distance (numeric values) or to index 0 (non-numeric). data-show-label strips a leading -- from custom-property tokens for nicer display.

Discrete enum

Step through labeled options. data-options accepts JSON [{value, label}] or a comma-separated shorthand where value equals label.

Long-press acceleration

Opt in with data-accelerate. Hold a button for 500ms to start auto-stepping at 1× step every 100ms; another 1000ms in, the rate switches to 5× step every 50ms. Intended for large ranges where multiple taps would be tedious.

Form participation

Form-associated via ElementInternals. Set name, drop it inside a <form>, and the value submits like any input.

Attributes

AttributeTypeDefaultDescription
valuestringCurrent value. Reflected.
namestringForm field name.
data-minnumberNumeric lower bound (numeric/formatted modes).
data-maxnumberNumeric upper bound (numeric/formatted modes).
data-stepnumber1Step increment.
data-valuescsvToken-snap scale (comma-separated).
data-optionsJSON or csvEnum options ([{value,label}] or csv shorthand).
data-formatstringnumber | currency | percent | duration | bytes
data-currencystringUSDISO 4217 code (when data-format="currency").
data-suffixstringStatic suffix appended to display.
data-show-labelbooleanfalseToken mode: show token name (strips leading --).
data-acceleratebooleanfalseEnable long-press acceleration.
disabledbooleanfalseDisables the stepper.
readonlybooleanfalseLocks the value (still focusable).

Events

EventBubblesWhen
inputyesEvery value change (button or programmatic).
changeyesEvery committed value change. (For now, fires alongside input.)

Keyboard

KeyAction
/ Step up (1×).
/ Step down (1×).
Page UpStep up (10×).
Page DownStep down (10×).
HomeJump to min (or first option).
EndJump to max (or last option).

The +/- buttons take tabindex="-1" by design — tab focus lands on the spinbutton itself, matching the data-stepper convention.

States

Component-computed flags exposed via CustomStateSet:

See also