Number stepper
Integer stepper whose number rolls over a dotted wash; holding a button repeats faster, and stepping past a limit shakes and flashes red.
Playground
Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.
<HfNumber
value={12}
min={1}
max={50}
label="Seats"
price={24}
currency="€"
name="seats"
/>Installation
pnpm dlx shadcn@latest add @lumesec/hf-numberFirst timeRegister the @lumesec registry once, or install by URL+
Adds @lumesec to your components.json:
pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.jsonOr skip the setup and install by URL:
npx shadcn@latest add https://elements.lumesec.ai/r/hf-number.jsonUsage
import { HfNumber } from "@/components/lumesec/hf-number";
export function Example() {
return (
<HfNumber name="seats" label="Seats" value={12} min={1} max={50} price={24} />
);
}Behaviour
The number rolls up or down over a dotted wash, and a scan line crosses the dots on every step. Hold a button to repeat faster, with heat and sparks building up; bumping the limit flashes red. Click the number to type.
API reference
Attributes
valueReact propvalueTypenumberDefault5Current value, rounded and clamped to min–max. Observed: a change rolls to the new number. Reflects the current value.
minReact propminTypenumberDefault1Lowest allowed value.
maxReact propmaxTypenumberDefault50Highest allowed value.
labelReact proplabelTypestringDefaultSeatsLabel text, also used as the field's aria-label.
priceReact proppriceTypenumberUnit price. When set, the line below reads <value> × <currency><price> = <currency><total> / month.
currencyReact propcurrencyTypestringDefault€Currency symbol used with price.
unitReact propunitTypestringText shown below the stepper when price is not set.
nameReact propnameTypestringForm field name used when the element is inside a form.
Events
Events bubble and cross the shadow boundary unless the description says otherwise.
inputReact proponInputDetail{ value: number }Fires on each change from the buttons, keys, typed entry or the value attribute.
changeReact proponChangeDetail{ value: number }Fires 300 ms after the last input, so holding a button produces one change.
Properties
valueTypenumberCurrent value. Setting it writes the value attribute.
min (read-only)TypenumberThe min attribute, or 1.
max (read-only)TypenumberThe max attribute, or 50.
form (read-only)TypeHTMLFormElement | nullThe owning form, from ElementInternals.
name (read-only)Typestring | nullThe name attribute. There is no setter; set the attribute instead.
Keyboard
| Keys | Action |
|---|---|
| ArrowUp / ArrowDown | In the number field: add or subtract 1. |
| PageUp / PageDown | In the number field: add or subtract 10. If that would pass min or max, the value stays and the field flashes red. |
| Enter | In the number field: commit the typed number and leave the field. |
| Enter / Space | On the − or + button: step by 1. |
Accessibility
- The number is an
<input>withrole="spinbutton",inputmode="numeric",aria-valuenow,aria-valuemin,aria-valuemaxand anaria-labelfromlabel. - The − and + buttons have
aria-labelDecreaseandIncreaseand are disabled at the limits. - The price or unit line below is an
aria-live="polite"region. - The visible number is text marked
aria-hidden, because the spinbutton already exposes the value; while the input has focus, its own text replaces it. The wash and sparks are on anaria-hiddencanvas. - Form-associated through
ElementInternals. - Submits the integer as a string under
name. There is no validation, and form reset anddisabledare not handled. - Reduced motion: the number and the line below change without rolling, and the scan line, shake and sparks are skipped; the red flash and heat tint remain.
Theming
The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.
This component reads --border, --card, --foreground, --lumesec, --muted and --muted-foreground.
To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-border, --ui-fg, --ui-mono, --ui-muted, --ui-raised and --ui-surface.
Notes
- Holding − or + repeats after 420 ms, speeding up from 160 ms to 35 ms per step. While a button is held, the number and the line below swap without rolling.
- Clicking the number focuses the field for typing. The typed text is parsed as an integer and clamped when the field loses focus.
- Programmatic changes to
valuefireinputandchange, the same as user changes. - While typing, the inner field's native
inputevents stay inside the shadow root; only the element's owninputandchangeevents, withvalueindetail, reach the host. - The host is
inline-block; the buttons and number area are 40px tall. The number is set in the mono font with tabular figures.
Related
Was this page helpful?