Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
+ 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.">
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
Stepper for values that + data-stepper cannot reach: formatted units, currency, time, token-snap scales, discrete enums.
<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.
The mode is auto-detected from attributes, first match wins:
| Trigger attribute | Mode | What it does |
|---|---|---|
data-options | enum | Step through a labeled list of options. |
data-values | token | Step through a fixed scale (e.g. spacing tokens). |
data-format or data-suffix | formatted | Numeric value with formatting (currency, percent, duration, bytes, suffix). |
| none | numeric | Plain numeric stepping. Logs a console hint pointing at data-stepper. |
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…).
<stepper-wc data-min="0" data-max="64" data-suffix="px" value="12"></stepper-wc>
<stepper-wc data-format="currency" data-currency="USD" data-min="0" data-step="0.5" value="5"></stepper-wc>
<stepper-wc data-format="duration" data-min="0" data-max="3600" data-step="300" value="900"></stepper-wc>
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%.
Step through a curated list of values. Useful for design-system scales where you want quantization rather than arbitrary numbers.
<stepper-wc data-values="0,4,8,12,16,24,32,48,64" data-suffix="px" value="16"></stepper-wc>
<stepper-wc data-values="--size-0,--size-1,--size-2,--size-3,--size-4" data-show-label value="--size-2"></stepper-wc>
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.
Step through labeled options. data-options accepts JSON
[{value, label}] or a comma-separated shorthand where value equals label.
<stepper-wc data-options="low,medium,high,critical" value="medium"></stepper-wc>
<stepper-wc value="m" data-options='[{"value":"s","label":"Small"},{"value":"m","label":"Medium"},{"value":"l","label":"Large"},{"value":"xl","label":"X-Large"}]'></stepper-wc>
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.
<stepper-wc data-min="0" data-max="1000" data-step="1" data-accelerate value="0"></stepper-wc>
Form-associated via ElementInternals. Set name, drop it inside a
<form>, and the value submits like any input.
<form> <form-field> <label for="qty">Quantity</label> <stepper-wc id="qty" name="qty" data-min="0" data-max="99" value="1"></stepper-wc> </form-field></form>
| Attribute | Type | Default | Description |
|---|---|---|---|
value | string | — | Current value. Reflected. |
name | string | — | Form field name. |
data-min | number | — | Numeric lower bound (numeric/formatted modes). |
data-max | number | — | Numeric upper bound (numeric/formatted modes). |
data-step | number | 1 | Step increment. |
data-values | csv | — | Token-snap scale (comma-separated). |
data-options | JSON or csv | — | Enum options ([{value,label}] or csv shorthand). |
data-format | string | — | number | currency | percent | duration | bytes |
data-currency | string | USD | ISO 4217 code (when data-format="currency"). |
data-suffix | string | — | Static suffix appended to display. |
data-show-label | boolean | false | Token mode: show token name (strips leading --). |
data-accelerate | boolean | false | Enable long-press acceleration. |
disabled | boolean | false | Disables the stepper. |
readonly | boolean | false | Locks the value (still focusable). |
| Event | Bubbles | When |
|---|---|---|
input | yes | Every value change (button or programmatic). |
change | yes | Every committed value change. (For now, fires alongside input.) |
| Key | Action |
|---|---|
| ↑ / → | Step up (1×). |
| ↓ / ← | Step down (1×). |
| Page Up | Step up (10×). |
| Page Down | Step down (10×). |
| Home | Jump to min (or first option). |
| End | Jump to max (or last option). |
The +/- buttons take tabindex="-1" by design — tab focus lands on
the spinbutton itself, matching the data-stepper convention.
Component-computed flags exposed via CustomStateSet:
stepper-wc:state(at-min) .stepper-dec { /* lowest bound */ }stepper-wc:state(at-max) .stepper-inc { /* upper bound */ }
<input type="number"> vs data-stepper vs <stepper-wc><input type="number">Intl.NumberFormat