Skip to content

BbNumberInput

Captures and validates numeric form values, emits a number value.

import { BbNumberInput } from 'bitboss-ui';

On this page

Props

NameTypeDefaultDescription
append:iconstring | undefined-

Name of the icon to be added at the end of the input.

The append position is contested, by priority: clear button → spinner (loading) → error icon (hasErrors) → this. On a clearable or validatable field your icon is the first thing displaced, so prefer prepend:icon for decoration.

See example
autocompletestring | undefined"off"

Guides the browser as to the type of information expected in the field.

autofocusBooleanish | undefined-

Sets autofocus on page load.

clearableboolean | undefinedfalse

Displays a clear button when the input has a value and is being interacted with.

Emits null, not 0 or ''. Suppressed on disabled and readonly fields, and it takes the append position from append:icon.

See example
compactboolean | undefinedfalse

Sets the component in a compact state.

The only density knob — this family has no size scale. Set it per view rather than per field, so a form does not mix two control heights.

See example
descriptionstring | undefined-

Descriptive text displayed below the label and above the input. Unlike the hint it is always visible, and it is linked to the input via aria-describedby (after any errors / warnings, before the hint).

For what the user needs before typing. Anything about the acceptable range reads better in hint, next to the field they are about to get wrong.

See example
directionInputDirection | undefined-

Direction of the layout of the component. Can either be a predefined value or a pattern separated by a space like xx xxxxx.

Ignored — silently — unless the resolved label mode is outside. floating and inside embed the label in the field and force the vertical layout, including when the mode comes from defaultInputLabelMode rather than from the call site.

See example
disabledboolean | undefinedfalse

Disables the component.

Blocks everything, arrow-key stepping included. For a number that is derived or detected rather than forbidden, readonly keeps it legible and copyable.

See example
errorsstring | string[] | undefined-

Can be a string or an array of string containing the messages to display. They render in an aria-live="polite" region (announced when they appear) and, while the list is non-empty, are referenced FIRST from the control's aria-describedby, so the reason the field is invalid is re-read whenever the control regains focus.

Where a business rule lives, since min and max can only express a range and do it without a message. Non-empty is enough — hasErrors is only for when the message itself is elsewhere. Inside a validated form these merge with the rule messages rather than replacing them.

See example
hasErrorsboolean | undefinedfalse

Define if the component should be in an error state. It usually attaches a CSS class for styling purposes.

Forces the error chrome without a message of its own. Reach for it when the text lives in a summary alert above the form.

See example
hasWarningsboolean | undefinedfalse

Define if the component should be in a warning state. Same chrome as errors with --bb-warn; errors take priority.

The amber counterpart of hasErrors, and equally a force-the-chrome flag. It never sets aria-invalid: a warning says "unusual", not "wrong".

See example
hideLabelboolean | undefinedfalse

Visually hides the label of the input while maintaining accessibility.

hintstring | undefined-

Text box to be displayed near the input, usually to indicate instructions.

The natural home for the range or the unit, because min and max correct a value in silence. Pair with persistentHint when the range matters before focus, not just during it.

See example
idstring | undefined-

The identifier of the component.

labelrequiredstring-

Text content of the label of the element.

Names the field for display and for assistive technology only. It does not set name, and it is not the field name in a validated form either — that one is a slug of this text.

See example
labelMode"outside" | "floating" | "inside" | undefined-

Label rendering mode.

Unset, it falls back to the project-wide defaultInputLabelMode, so a product can go all-floating from the plugin config without touching call sites. Do not pair floating with a placeholder — the resting label already occupies that spot.

See example
labelPosition"left" | "center" | "right" | undefined-

Sets the text alignment of the label.

loadingboolean | undefinedfalse

Sets the component in a loading state, usually triggering some visual styles.

Visual only. The field stays editable underneath the spinner, so if an async check has to settle before the value is usable, guard that yourself.

See example
maxnumber | undefinedNumber.MAX_SAFE_INTEGER

Maximum value cap.

Clamps the emitted value with no message and no event, so a user who types past it sees their number change under them. Say the ceiling in hint before they reach it.

See example
maxPrecisionnumber | undefined8

Maximum precision of the number.

0 pins the field to whole numbers and 2 to currency. It caps decimals as they are typed rather than rounding on blur.

See example
minnumber | undefinedNumber.MIN_SAFE_INTEGER

Minimum value cap.

Clamps the emitted value in silence, the same way max does. It also makes a min_value rule redundant in a validated form: the value can never get low enough to fail it.

See example
modelValuerequiredstring | number | nullnull

Used by v-model.

Accepts number | string | null and emits number | null. A cleared field emits null, never '' and never NaN, and an in-progress string (-, ., 12.) emits nothing until it parses.

See example
namestring | undefined-

Defines the name of the input.

Not derived from label. Leave it unset and the rendered <input> carries no name at all, so a native form post or a FormData read silently drops the value.

See example
persistentHintboolean | undefinedfalse

Keeps the hint displayed.

placeholderstring | undefined-

String displayed when there's no data.

prepend:iconstring | undefined-

Name of the icon to be added at the start of the input.

The uncontested position: nothing in the component competes for it. Put decorative iconography here and keep append:icon for fields that are neither clearable nor validatable.

See example
ptPtMap<TextControlPtPart, FormControlPtState> | undefined-

Passthrough, object form: { box: '…', 'box:errors': '…' } — the same keys as the pt:* attributes without the prefix. See the pt:<part> row.

pt:boxPtValue | undefined-
pt:box:disabledPtValue | undefined-
pt:box:errorsPtValue | undefined-
pt:box:has-valuePtValue | undefined-
pt:box:loadingPtValue | undefined-
pt:box:readonlyPtValue | undefined-
pt:box:warningsPtValue | undefined-
pt:clearPtValue | undefined-
pt:clear:disabledPtValue | undefined-
pt:clear:errorsPtValue | undefined-
pt:clear:has-valuePtValue | undefined-
pt:clear:loadingPtValue | undefined-
pt:clear:readonlyPtValue | undefined-
pt:clear:warningsPtValue | undefined-
pt:descriptionPtValue | undefined-
pt:description:disabledPtValue | undefined-
pt:description:errorsPtValue | undefined-
pt:description:has-valuePtValue | undefined-
pt:description:loadingPtValue | undefined-
pt:description:readonlyPtValue | undefined-
pt:description:warningsPtValue | undefined-
pt:hintPtValue | undefined-
pt:hint:disabledPtValue | undefined-
pt:hint:errorsPtValue | undefined-
pt:hint:has-valuePtValue | undefined-
pt:hint:loadingPtValue | undefined-
pt:hint:readonlyPtValue | undefined-
pt:hint:warningsPtValue | undefined-
pt:iconPtValue | undefined-
pt:icon:disabledPtValue | undefined-
pt:icon:errorsPtValue | undefined-
pt:icon:has-valuePtValue | undefined-
pt:icon:loadingPtValue | undefined-
pt:icon:readonlyPtValue | undefined-
pt:icon:warningsPtValue | undefined-
pt:inputPtValue | undefined-
pt:input:disabledPtValue | undefined-
pt:input:errorsPtValue | undefined-
pt:input:has-valuePtValue | undefined-
pt:input:loadingPtValue | undefined-
pt:input:readonlyPtValue | undefined-
pt:input:warningsPtValue | undefined-
pt:labelPtValue | undefined-
pt:label:disabledPtValue | undefined-
pt:label:errorsPtValue | undefined-
pt:label:has-valuePtValue | undefined-
pt:label:loadingPtValue | undefined-
pt:label:readonlyPtValue | undefined-
pt:label:warningsPtValue | undefined-
pt:messagePtValue | undefined-
pt:message:disabledPtValue | undefined-
pt:message:errorsPtValue | undefined-
pt:message:has-valuePtValue | undefined-
pt:message:loadingPtValue | undefined-
pt:message:readonlyPtValue | undefined-
pt:message:warningsPtValue | undefined-
pt:prefixPtValue | undefined-
pt:prefix:disabledPtValue | undefined-
pt:prefix:errorsPtValue | undefined-
pt:prefix:has-valuePtValue | undefined-
pt:prefix:loadingPtValue | undefined-
pt:prefix:readonlyPtValue | undefined-
pt:prefix:warningsPtValue | undefined-
pt:rootPtValue | undefined-
pt:root:disabledPtValue | undefined-
pt:root:errorsPtValue | undefined-
pt:root:has-valuePtValue | undefined-
pt:root:loadingPtValue | undefined-
pt:root:readonlyPtValue | undefined-
pt:root:warningsPtValue | undefined-
pt:spinnerPtValue | undefined-
pt:spinner:disabledPtValue | undefined-
pt:spinner:errorsPtValue | undefined-
pt:spinner:has-valuePtValue | undefined-
pt:spinner:loadingPtValue | undefined-
pt:spinner:readonlyPtValue | undefined-
pt:spinner:warningsPtValue | undefined-
pt:suffixPtValue | undefined-
pt:suffix:disabledPtValue | undefined-
pt:suffix:errorsPtValue | undefined-
pt:suffix:has-valuePtValue | undefined-
pt:suffix:loadingPtValue | undefined-
pt:suffix:readonlyPtValue | undefined-
pt:suffix:warningsPtValue | undefined-
readonlyboolean | undefinedfalse

Sets the input in a readonly state.

The right state for a number that is computed or detected rather than entered — a total, a weight read off a scale. Unlike disabled it stays legible and copyable, and it disables stepping just the same.

See example
requiredboolean | undefinedfalse

Sets the input as required.

Forwards to the native input and validates nothing on its own. In a validated form it is also one of the two things that raise the required asterisk, the other being a literal required rule.

reverseboolean | undefinedfalse

Reverses the layout. Applicable in every direction the order of the label and the input is swapped.

stepnumber | undefined1

Incremental unit used by ArrowUp / ArrowDown and by the increase and decrease functions the slots receive. It is NOT applied to manual input as a step of 5 would prevent the user from inserting a value like 115 because of rounding down.

Drives ArrowUp/ArrowDown and the increase/decrease slot functions, and never constrains typed input. If multiples are a real rule, enforce them through errors on blur or on submit.

See example
variantInputVariantType | undefined'outline'

Visual variant of the field box — the same names and tokens as the BbButton variants. Colours only: height, padding and border width are identical across variants, so a form never reflows when one changes. 'ghost' has no border in any state (errors and warnings show through the icon and the messages); every variant keeps the focus ring. Register extra names with the plugin's inputVariants option.

warningsstring | string[] | undefined-

Warning messages to display beneath the field, in their own aria-live region and amber (--bb-text-warn). A string or array; a non-empty list implies the warning state. Errors suppress warnings when both are set. While displayed they are also referenced from the control's aria-describedby, after any errors and before the description/hint.

For a number that is valid and still worth a second look. Errors win when both are set and the warnings are suppressed, so the field is never amber and red at once.

See example

v-model

Values kept in sync through v-model.

NameTypeDescription
modelValuestring | number | null

Seed it with null for an empty field rather than 00 is a number someone chose, and on a floating label it also stops the label from resting inside the field.

See example

Events

NameTypeDescription
blur(event: "blur", event: FocusEvent): void
change(event: "change", event: Event): void
click(event: "click", event: MouseEvent): void
compositionend(event: "compositionend", event: CompositionEvent): void
compositionstart(event: "compositionstart", event: CompositionEvent): void
decrease(event: "decrease", value: number): voidSee example
focus(event: "focus", event: FocusEvent): void
increase(event: "increase", value: number): void

Fires with the **new**, already clamped number, alongside update:modelValue. It is for reacting to a step, not for reading the value — v-model already has that.

See example
input(event: "input", event: Event): void
keydown(event: "keydown", event: KeyboardEvent): void
keyup(event: "keyup", event: KeyboardEvent): void
mousedown(event: "mousedown", event: MouseEvent): void
mouseup(event: "mouseup", event: MouseEvent): void
paste(event: "paste", event: ClipboardEvent): void
update:modelValue(event: "update:modelValue", value: number | null): void

Emits number | null. Do not add a watcher that re-parses or re-clamps what arrives here: the component has already done both.

See example

Slots

The listed properties are the ones exposed to the slot scope.

NameTypeDescription
appendBbNumberInputStepSlotProps

Content rendered after the number input, at the end of the inner container. Typically used to place increment/decrement buttons next to the input.

Same { increase, decrease } scope as prepend, and the same accessible-name obligation.

See example
append-outerBbNumberInputStepSlotProps

Content rendered after the entire input control, outside the input chrome.

The uncontested place for an action beside the field, since nothing inside the component competes for it.

descriptionBbNumberInputDescriptionSlotProps

Replaces the description text. Provided alone (no description prop) it still renders the description region and wires it into aria-describedby.

labelBbNumberInputLabelSlotProps

Replaces the default label text rendered above the number input.

Receives { text, hasErrors, hasWarnings }. Replacing it removes anything the control drew beside the label, the required asterisk included, so put BbAsterisk back by hand.

See example
prefixBbNumberInputStepSlotProps

Inline content rendered at the start of the input field area, before the typed number.

Decoration only, inside the field. A currency symbol belongs here and never in the model.

See example
prependBbNumberInputStepSlotProps

Content rendered before the number input, at the start of the inner container.

Receives { increase, decrease }, which is how a minus button is built with no state on your side. It is icon-only, so give it an aria-label.

See example
prepend-outerBbNumberInputStepSlotProps

Content rendered before the entire input control, outside the input chrome.

Outside the field chrome entirely. Reach for it when a stepper button should not sit inside the border — or when the append position is already taken by a clear button or a spinner.

suffixBbNumberInputStepSlotProps

Inline content rendered at the end of the input field area, after the typed number.

The unit — kg, °C, %. Like prefix it is inert, so anything interactive goes in prepend/append or the outer pair.

See example

Changes from v2

Props removed or renamed in 3.0. If you are coming from v2, the answer is here.

  • hasWarninghasWarningsfails silently