HelixOverviewComponentsMapsGraphIntroductionInstallationDeriving a themeSandboxTheme builderVisual testingCortexDocsEngramBuildingTraceBuildingRecallDeclaredServicesInsightsGet in touchSource on GitHub
Loading the reference
Number InputView SourceEdit in SandboxView MarkdownCopy MarkdownOpen in ClaudeOpen in CursorA field for a number, typed or changed with step buttons.StableSince 0.1.0FormsUsageimport'@fusion.dev/helix/number-input'import'@fusion.dev/helix-headless/number-input'Preview
API ReferenceRoothelix-number-inputA field for a number, typed or changed with step buttons.
PropTypeDescriptionautocompletestringDefault""What the browser may autofill, as an HTML autocomplete token.badInputMessagestringDefault"Please enter a number."The message the browser shows when the field holds something that is not a
number.decrementLabelstringDefault"Decrease"The name of the step down button, read by screen readers. The field's
label follows it, so a reader hears "Decrease Quantity", as React Aria
names its steppers.defaultValuestringDefault""The value the control starts with. A form reset returns it to this value,
and to the value attribute where this one is not written, as a native
control resets to the value it declares.disabledbooleanDefaultfalseWhether the control is disabled and cannot be used.feedbackstringDefault""The validation message shown under the control. It replaces the
browser's message.formatOptionsIntl.NumberFormatOptionsIntl.NumberFormat options the number is shown with while the field is
not being edited: a currency, a percent, a unit, or a number of decimals.
Written as JSON in the attribute.hintstringDefault""Help text shown under the control. A validation message replaces it.incrementLabelstringDefault"Increase"The name of the step up button, read by screen readers. The field's
label follows it, so a reader hears "Increase Quantity", as React Aria
names its steppers.labelstringDefault""The field's label, which is also its accessible name. Content in the
label slot replaces it.largeStepnumberHow many steps PageUp and PageDown move.localestringDefault""The locale a typed number is read in, such as de-DE. Empty reads it in
the browser's language.maxnumberThe largest value allowed.minnumberThe smallest value allowed.namestringDefault""The name the control's value is submitted under.placeholderstringDefault""Shown while the field is empty.rangeOverflowMessagestringDefault"Value must be {max} or less."The message the browser shows when the number is above max, with {max}
filled in, written in the locale.rangeUnderflowMessagestringDefault"Value must be {min} or more."The message the browser shows when the number is below min, with {min}
filled in, written in the locale.readOnlybooleanDefaultfalsePrevents editing. The value is still submitted with the form.requiredbooleanDefaultfalseWhether the field needs a value before the form can submit.roleLabelstringDefault"number field"The words screen readers announce for the field's role, set as its
aria-roledescription. Translate it with the rest of your text, or empty
it to leave the role as spinbutton.scrubbooleanDefaultfalseMakes the label a grip that changes the value when it is dragged.stepnumber|"any"How far one step moves. A value off the step grid, counted from min, is
invalid, as it is in a native number field.stepMismatchMessagestringDefault"Please enter a valid value. The two nearest valid values are {below} and {above}."The message the browser shows when the number is off the step grid, with
{below} and {above} filled in with the nearest valid values, written in
the locale.valuestringThe control's current value, which its form submits.valueAsNumbernumberThe value as a number, or NaN while the control is empty or does not
hold a number.valueMissingMessagestringThe message shown when the field is required and empty.valueTextstringDefault""What a screen reader says for the value, with {value} filled in, such as
{value} kilograms.wheelbooleanDefaultfalseWhether the mouse wheel steps the number while the field has focus, as
React Aria's NumberField does unless told not to. Off, the wheel scrolls
the page, which is what a reader passing over a form expects.
ReadTypeDescriptionformHTMLFormElement|nullThe form the control belongs to, or null.labelsNodeListThe labels associated with the control.validationMessagestringThe message the browser would show for the control, or an empty string.validityValidityStateWhether the control meets its constraints, and why not.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.willValidatebooleanWhether the control is checked when its form is submitted.
SlotDescriptiondecrement-iconReplaces the icon on the step down button.endContent after the number, such as a unit.feedbackThe message that says what is wrong, for content richer than a string. It shows while there is a message.hintHelp under the control, for content richer than the hint text.increment-iconReplaces the icon on the step up button.labelThe label, for content richer than the label text.startContent before the number, such as a unit or an icon.
EventTypeDescriptionchangeEventThe user finished changing the value. Relayed from the native field.helix-before-changeHelixBeforeChangeEventThe value is about to change. Cancelable: cancel it to keep the current value.inputEventThe value changed.
MethodTypeDescriptioncheckValidity() => booleanReturns whether the control is valid, and fires invalid on it when it is
not. The control shows no message for it: reportValidity() does that.focus(options: FocusOptions) => voidMoves focus to the control, as focusing a native control does.reportValidity() => booleanReturns whether the control is valid, and when it is not, fires invalid
and shows the browser's message at the control.requestValue(next: string) => booleanRequests a new value, and returns whether the change was applied.select() => voidSelects the number, so typing replaces it.setCustomValidity(message: string) => voidMarks the control invalid with message, or clears that with an empty
string, as on a native control. The form does not submit while it is set.stepDown(count: number | boolean) => voidSteps the value down by step, count times. true takes largeStep
steps, as PageDown does.stepUp(count: number | boolean) => voidSteps the value up by step, count times, as the native method and
Input.stepUp do. true takes largeStep steps, as PageUp does.
PartDescriptioncontrolThe input that holds the number.decrementThe button that steps the value down.decrement-markThe icon on the step down button.feedbackThe message that says what is wrong.fieldThe box that holds the whole control.hintHelp text under the field, shown while there is no feedback.incrementThe button that steps the value up.increment-markThe icon on the step up button.labelThe label above the field. It is also the grip you drag when scrub is set.
CSS PropertyDescription--number-input-background-colorThe fill behind the number.--number-input-border-colorEdge of the field at rest. Hover, focus and an error still draw their own.--number-input-padding-inlineSpace at each side of the number, inside the steppers.--number-input-radiusCorner radius of the field.--number-input-sizeHeight of the field.--number-input-stepper-background-colorFill behind each stepper button at rest.--number-input-stepper-background-color-hoverFill behind a stepper button under the pointer.--number-input-stepper-border-colorThe rule between each stepper button and the number.--number-input-stepper-colorIcon color of the stepper buttons at rest.--number-input-stepper-color-hoverIcon color of a stepper button under the pointer.--number-input-stepper-icon-sizeWidth and height of the stepper icons, drawn or slotted.--number-input-stepper-sizeWidth of each stepper button.
Custom stateDescriptionat-maxThe number is at max, so it cannot step up, as React Aria's NumberField says with canIncrement.at-minThe number is at min, so it cannot step down.invalidThe control has an error to show, from the browser's validation or from your feedback.scrubbingThe label is being dragged to change the value, under scrub, as Zag's scrubber says while it is held.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Roothelix-headless-number-inputA field for a number, typed or changed with step buttons.
PropTypeDescriptionautocompletestringDefault""What the browser may autofill, as an HTML autocomplete token.badInputMessagestringDefault"Please enter a number."The message the browser shows when the field holds something that is not a
number.decrementLabelstringDefault"Decrease"The name of the step down button, read by screen readers. The field's
label follows it, so a reader hears "Decrease Quantity", as React Aria
names its steppers.defaultValuestringDefault""The value the control starts with. A form reset returns it to this value,
and to the value attribute where this one is not written, as a native
control resets to the value it declares.disabledbooleanDefaultfalseWhether the control is disabled and cannot be used.feedbackstringDefault""The validation message shown under the control. It replaces the
browser's message.formatOptionsIntl.NumberFormatOptionsIntl.NumberFormat options the number is shown with while the field is
not being edited: a currency, a percent, a unit, or a number of decimals.
Written as JSON in the attribute.hintstringDefault""Help text shown under the control. A validation message replaces it.incrementLabelstringDefault"Increase"The name of the step up button, read by screen readers. The field's
label follows it, so a reader hears "Increase Quantity", as React Aria
names its steppers.labelstringDefault""The field's label, which is also its accessible name. Content in the
label slot replaces it.largeStepnumberHow many steps PageUp and PageDown move.localestringDefault""The locale a typed number is read in, such as de-DE. Empty reads it in
the browser's language.maxnumberThe largest value allowed.minnumberThe smallest value allowed.namestringDefault""The name the control's value is submitted under.placeholderstringDefault""Shown while the field is empty.rangeOverflowMessagestringDefault"Value must be {max} or less."The message the browser shows when the number is above max, with {max}
filled in, written in the locale.rangeUnderflowMessagestringDefault"Value must be {min} or more."The message the browser shows when the number is below min, with {min}
filled in, written in the locale.readOnlybooleanDefaultfalsePrevents editing. The value is still submitted with the form.requiredbooleanDefaultfalseWhether the field needs a value before the form can submit.roleLabelstringDefault"number field"The words screen readers announce for the field's role, set as its
aria-roledescription. Translate it with the rest of your text, or empty
it to leave the role as spinbutton.scrubbooleanDefaultfalseMakes the label a grip that changes the value when it is dragged.stepnumber|"any"How far one step moves. A value off the step grid, counted from min, is
invalid, as it is in a native number field.stepMismatchMessagestringDefault"Please enter a valid value. The two nearest valid values are {below} and {above}."The message the browser shows when the number is off the step grid, with
{below} and {above} filled in with the nearest valid values, written in
the locale.valuestringThe control's current value, which its form submits.valueAsNumbernumberThe value as a number, or NaN while the control is empty or does not
hold a number.valueMissingMessagestringThe message shown when the field is required and empty.valueTextstringDefault""What a screen reader says for the value, with {value} filled in, such as
{value} kilograms.wheelbooleanDefaultfalseWhether the mouse wheel steps the number while the field has focus, as
React Aria's NumberField does unless told not to. Off, the wheel scrolls
the page, which is what a reader passing over a form expects.
ReadTypeDescriptionformHTMLFormElement|nullThe form the control belongs to, or null.labelsNodeListThe labels associated with the control.validationMessagestringThe message the browser would show for the control, or an empty string.validityValidityStateWhether the control meets its constraints, and why not.whenSettledPromise<void>Resolves a frame after the first update, when transitions are switched on.willValidatebooleanWhether the control is checked when its form is submitted.
SlotDescriptiondecrement-iconReplaces the icon on the step down button.endContent after the number, such as a unit.feedbackThe message that says what is wrong, for content richer than a string. It shows while there is a message.hintHelp under the control, for content richer than the hint text.increment-iconReplaces the icon on the step up button.labelThe label, for content richer than the label text.startContent before the number, such as a unit or an icon.
EventTypeDescriptionchangeEventThe user finished changing the value. Relayed from the native field.helix-before-changeHelixBeforeChangeEventThe value is about to change. Cancelable: cancel it to keep the current value.inputEventThe value changed.
MethodTypeDescriptioncheckValidity() => booleanReturns whether the control is valid, and fires invalid on it when it is
not. The control shows no message for it: reportValidity() does that.focus(options: FocusOptions) => voidPuts the cursor in the field.reportValidity() => booleanReturns whether the control is valid, and when it is not, fires invalid
and shows the browser's message at the control.requestValue(next: string) => booleanRequests a new value, and returns whether the change was applied.select() => voidSelects the number, so typing replaces it.setCustomValidity(message: string) => voidMarks the control invalid with message, or clears that with an empty
string, as on a native control. The form does not submit while it is set.stepDown(count: number | boolean) => voidSteps the value down by step, count times. true takes largeStep
steps, as PageDown does.stepUp(count: number | boolean) => voidSteps the value up by step, count times, as the native method and
Input.stepUp do. true takes largeStep steps, as PageUp does.
PartDescriptioncontrolThe input that holds the number.decrementThe button that steps the value down.decrement-markThe icon on the step down button.feedbackThe message that says what is wrong.fieldThe box that holds the whole control, a role="group" around the field and its buttons.hintHelp text under the field, shown while there is no feedback.incrementThe button that steps the value up.increment-markThe icon on the step up button.labelThe label above the field. It is also the grip you drag when scrub is set.
Custom stateDescriptionat-maxThe number is at max, so it cannot step up, as React Aria's NumberField says with canIncrement.at-minThe number is at min, so it cannot step down.invalidThe control has an error to show, from the browser's validation or from your feedback.scrubbingThe label is being dragged to change the value, under scrub, as Zag's scrubber says while it is held.settledSet one frame after the first render. Transitions wait for it, so an element does not animate its own arrival.
Examples
NameDescriptionBoundedA number in a range, and a number with a step.DisabledTwo disabled fields, one with a value and one empty. They submit nothing, and their step buttons do nothing.EventsA step and a keystroke send the same events, and change is sent when you finish.InvalidA number outside its range, and the message the field shows.PreviewA number with buttons to step it.PreviewA number with buttons to step it.Read OnlyA read-only field. It cannot be edited, and its value is still submitted.ScrubA label you drag to change the value, with Shift for larger steps and Alt for slower dragging.StepsA large step for Page Up and Page Down, and a small one for the arrow keys.UnitsA unit shown next to the number, in the end slot.