Inputs@knitui/components
NumberInput
NumberInput is a numeric text field built on InputBase with built-in increment/decrement controls and keyboard stepping. It mirrors the Mantine NumberInput API and supports min/max clamping, decimal scale, negative numbers and a hold-to-step mode.
import { NumberInput } from "@knitui/components";Playground
Loading playground…
<NumberInput
placeholder="Enter a number"
size="sm"
disabled={false}
readOnly={false}
hideControls={false}
allowNegative
allowDecimal
step={1}
/>Examples
Sizes
Seven sizes displayed side by side, from xxs to xxl.
Loading example…
Shadows
Each elevation of the inherited shadow prop applied to the input frame.
Loading example…
Disabled
Disabled state — the field is not interactive and has reduced opacity.
Loading example…
Read Only
Read-only state — the value is visible but cannot be changed; controls are hidden.
Loading example…
With Min Max
Min and max bounds clamp the value on blur (the default clampBehavior).
Loading example…
Decimal Scale
Decimal scale limits the number of digits after the decimal point.
Loading example…
Hidden Controls
Hides the built-in stepper controls while keeping keyboard stepping active.
Loading example…
Controlled
Controlled value managed via React.useState — demonstrates the onChange callback.
Loading example…
External Handlers
External increment/decrement via handlersRef — useful for custom control UIs.
Loading example…
With Label And Error
With a label, helper description and inline error message.
Loading example…
Styles
Per-slot styles targets individual parts — here the label, increment and decrement controls.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
allowDecimal | boolean | undefined | true | Whether decimal values are allowed. |
allowLeadingZeros | boolean | undefined | true | Whether leading zeros are preserved while typing. When `false`, leading zeros are stripped as you type (e.g. `007` → `7`). Works together with `trimLeadingZeroesOnBlur`. |
allowNegative | boolean | undefined | true | Whether negative values are allowed. |
autoCapitalize | "none" | (string & {}) | "off" | "on" | "sentences" | "words" | "characters" | undefined | — | |
autoComplete | string | undefined | — | |
autoCorrect | string | boolean | undefined | — | |
autoFocus | boolean | undefined | — | |
autosize | boolean | undefined | false | Grows with content on web (scrollHeight-based); tracks onContentSizeChange on native. |
children | ReactNode | — | Rendered inside the host element. Only meaningful for the `button` host (e.g. FileInput's trigger displays the picked file name); ignored for the native `input`/`textarea`/`select` hosts. |
clampBehavior | "none" | "strict" | "blur" | undefinedblur · strict · none | "blur" | When out-of-range values are clamped. |
component | InputHostTag | undefined | — | Override the host element tag (defaults to `input`/`textarea`). |
cursorColor | "unset" | ColorTokens | undefined | — | |
decimalScale | number | undefined | — | Decimal digits limit. |
defaultValue | NumberInputValue | undefined | — | Uncontrolled component default value. |
description | ReactNode | — | |
descriptionProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
disabled system | boolean | undefined | false | |
enterKeyHint | "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | undefined | — | |
error | ReactNode | — | |
errorProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
handlersRef | Ref<NumberInputHandlers> | undefined | — | Ref populated with `{ increment, decrement }` handlers. |
hideControls | boolean | undefined | false | Hides the up/down stepper controls. |
id | string | undefined | — | Same as the web id property for setting a uid on an element |
inputContainer | ((children: ReactNode) => ReactNode) | undefined | — | |
inputSize | string | undefined | — | Host size attribute for the input element |
inputWrapperOrder | InputWrapperOrderItem[] | undefined | — | |
label | ReactNode | — | |
labelElement | "div" | "label" | undefined | — | |
labelProps | InputLabelProps | undefined | — | |
leftSection | ReactNode | — | Content section displayed on the left side of the input |
leftSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the left section element |
leftSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the left section element |
leftSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Left section width, by default equals to the input height |
loading | boolean | undefined | — | Displays loading indicator in the left or right section |
loadingPosition | "left" | "right" | undefined | "right" | Position of the loading indicator |
max | number | undefined | — | Maximum possible value. |
maxLength | number | undefined | — | |
maxRows | number | undefined | — | Maximum number of rows before scrolling (web). Caps height on native when autosize is on. |
min | number | undefined | — | Minimum possible value. |
minLength | number | undefined | — | |
minRows | number | undefined | — | Minimum number of rows. Sets initial/minimum height on web; maps to numberOfLines on native. |
multiline | boolean | undefined | — | Adjusts padding and sizing calculations for multiline inputs |
multiple | boolean | undefined | — | |
name | string | undefined | — | |
onChange | ((value: NumberInputValue) => void) | undefined | — | Called when the value changes. |
onChangeText | ((text: string) => void) | undefined | — | Fires on every change with just the string value. |
onMaxReached | (() => void) | undefined | — | Called when the value reaches `max` via a control or ArrowUp. |
onMinReached | (() => void) | undefined | — | Called when the value reaches the lower bound via a control or ArrowDown. |
onSelectionChange | ((event: InputSelectionChangePayload) => void) | undefined | — | Fires when the text selection changes. |
onSubmitEditing | ((event: InputTextEventPayload) => void) | undefined | — | Fires when Enter/Return is pressed. |
pattern | string | undefined | — | |
placeholder | string | undefined | Enter a number | |
placeholderTextColor | "unset" | ColorTokens | undefined | — | |
pointer | boolean | undefined | — | Determines whether the input should have cursor: pointer style |
prefix | string | undefined | — | Prefix/suffix added before/after the value — accepted for Mantine API parity. Inline display formatting (prefix/suffix in the value, live thousands grouping) needs `react-number-format`, which is not a cross-platform dependency here, so these are not rendered. The numeric stepping/clamping behaviour below is complete. |
radius system | string | number | undefined | — | Key of theme radius or a valid CSS value to set border-radius |
readOnly | boolean | undefined | false | |
required | boolean | undefined | — | |
rightSection | ReactNode | — | Content section displayed on the right side of the input |
rightSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the right section element |
rightSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the right section element |
rightSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Right section width, by default equals to the input height |
rootRef | Ref<TamaguiElement> | undefined | — | Root element ref |
rows | number | undefined | — | Rows for textarea (when render="textarea") |
selectAllOnFocus | boolean | undefined | false | Selects the input's contents when it receives focus (web only). |
selection | { start: number; end?: number; } | undefined | — | Selection range |
selectionColor | "unset" | ColorTokens | undefined | — | |
selectionHandleColor | "unset" | ColorTokens | undefined | — | |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined | — | |
size system | InputSize | undefinedxxs · xs · sm · md · lg · xl · xxl | sm | Controls height, horizontal padding and font size. |
spellCheck | boolean | undefined | — | Controls spell checking. |
startValue | number | undefined | 0 | Value used when stepping from an empty input. |
step | number | undefined | 1 | Amount added/subtracted per step. |
stepHoldDelay | number | undefined | — | Initial delay (ms) before hold-to-step repeats. Requires `stepHoldInterval`. |
stepHoldInterval | number | ((count: number) => number) | undefined | — | Interval (ms) between steps while a control is held. Number or `(count) => ms`. |
styles system | SlotStyles<NumberInputStyles> | undefined | — | Per-slot style sugar for the stepper — props spread onto the matching part. |
suffix | string | undefined | — | See `prefix`. |
textContentType | InputTextContentType | undefined | — | Text content type for iOS autofill. Use `autoComplete` where available. |
theme system | ThemeName | null | undefined | — | Applies a theme to this element |
trimLeadingZeroesOnBlur | boolean | undefined | true | Whether a preserved leading-zero value is normalised on blur. |
type | string | undefined | — | |
underlineColorAndroid | "unset" | ColorTokens | undefined | — | |
value | NumberInputValue | undefined | — | Controlled component value. |
variant system | InputVariant | undefined | "default" | Visual variant |
withAria | boolean | undefined | true | Determines whether accessibility attributes should be added |
withAsterisk | boolean | undefined | — | |
withKeyboardEvents | boolean | undefined | true | Whether ArrowUp/ArrowDown step the value. |
wrapperProps | ({ readonly br?: number | "$xs" | "$sm" | "$md" | "$lg" | "$xl" | "unset" | "$0" | "$true" | "$xxs" | "$xxl" | Variable<any> | `${number}rem` | UnionableNumber | "inherit" | `var(${string})` | Animated.AnimatedNode | null | undefined; label… | — | Props passed down to the root element (`Input.Wrapper` component) |
Style slots
Every part of NumberInput can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
controls | styles={{ controls: { … } }} |
decrement | styles={{ decrement: { … } }} |
description | styles={{ description: { … } }} |
error | styles={{ error: { … } }} |
increment | styles={{ increment: { … } }} |
label | styles={{ label: { … } }} |
leftSection | styles={{ leftSection: { … } }} |
required | styles={{ required: { … } }} |
rightSection | styles={{ rightSection: { … } }} |
root | styles={{ root: { … } }} |
wrapper | styles={{ wrapper: { … } }} |
Accessibility & DOM props (217)
| Prop | Type |
|---|---|
about | string | undefined |
accept | string | undefined |
accessKey | string | undefined |
alt | string | undefined |
aria-activedescendant | string | undefined |
aria-atomic | (boolean | "true" | "false") | undefined |
aria-autocomplete | "none" | "inline" | "list" | "both" | undefined |
aria-braillelabel | string | undefined |
aria-brailleroledescription | string | undefined |
aria-colcount | number | undefined |
aria-colindex | number | undefined |
aria-colindextext | string | undefined |
aria-colspan | number | undefined |
aria-controls | string | undefined |
aria-current | boolean | "time" | "true" | "false" | "page" | "step" | "location" | "date" | undefined |
aria-describedby | string | undefined |
aria-description | string | undefined |
aria-details | string | undefined |
aria-dropeffect | "link" | "none" | "copy" | "move" | "execute" | "popup" | undefined |
aria-errormessage | string | undefined |
aria-flowto | string | undefined |
aria-grabbed | (boolean | "true" | "false") | undefined |
aria-haspopup | boolean | "dialog" | "menu" | "true" | "false" | "grid" | "tree" | "listbox" | undefined |
aria-invalid | boolean | "true" | "false" | "grammar" | "spelling" | undefined |
aria-keyshortcuts | string | undefined |
aria-level | number | undefined |
aria-multiline | (boolean | "true" | "false") | undefined |
aria-multiselectable | (boolean | "true" | "false") | undefined |
aria-orientation | "horizontal" | "vertical" | undefined |
aria-owns | string | undefined |
aria-placeholder | string | undefined |
aria-posinset | number | undefined |
aria-pressed | boolean | "true" | "false" | "mixed" | undefined |
aria-readonly | (boolean | "true" | "false") | undefined |
aria-relevant | "all" | "text" | "additions" | "additions removals" | "additions text" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined |
aria-required | (boolean | "true" | "false") | undefined |
aria-roledescription | string | undefined |
aria-rowcount | number | undefined |
aria-rowindex | number | undefined |
aria-rowindextext | string | undefined |
aria-rowspan | number | undefined |
aria-setsize | number | undefined |
aria-sort | "none" | "ascending" | "descending" | "other" | undefined |
autoSave | string | undefined |
capture | boolean | "user" | "environment" | undefined |
checked | boolean | undefined |
contentEditable | "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined |
contextMenu | string | undefined |
datatype | string | undefined |
defaultChecked | boolean | undefined |
dir | string | undefined |
draggable | (boolean | "true" | "false") | undefined |
exportparts | string | undefined |
form | string | undefined |
formAction | string | ((formData: FormData) => void | Promise<void>) | undefined |
formEncType | string | undefined |
formMethod | string | undefined |
formNoValidate | boolean | undefined |
formTarget | string | undefined |
hidden | boolean | undefined |
inert | boolean | undefined |
inlist | any |
inputMode | "search" | "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined |
is | string | undefined |
itemID | string | undefined |
itemProp | string | undefined |
itemRef | string | undefined |
itemScope | boolean | undefined |
itemType | string | undefined |
key | Key | null | undefined |
lang | string | undefined |
list | string | undefined |
nonce | string | undefined |
onAbort | ReactEventHandler<HTMLInputElement> | undefined |
onAbortCapture | ReactEventHandler<HTMLInputElement> | undefined |
onAnimationEnd | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationEndCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationIteration | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationIterationCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationStart | AnimationEventHandler<HTMLInputElement> | undefined |
onAnimationStartCapture | AnimationEventHandler<HTMLInputElement> | undefined |
onAuxClick | MouseEventHandler<HTMLInputElement> | undefined |
onAuxClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onBeforeInputCapture | InputEventHandler<HTMLInputElement> | undefined |
onBeforeToggle | ToggleEventHandler<HTMLInputElement> | undefined |
onBlurCapture | FocusEventHandler<HTMLInputElement> | undefined |
onCanPlay | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayCapture | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayThrough | ReactEventHandler<HTMLInputElement> | undefined |
onCanPlayThroughCapture | ReactEventHandler<HTMLInputElement> | undefined |
onChangeCapture | ChangeEventHandler<HTMLInputElement, Element> | undefined |
onClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onCompositionEnd | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionEndCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionStart | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionStartCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionUpdate | CompositionEventHandler<HTMLInputElement> | undefined |
onCompositionUpdateCapture | CompositionEventHandler<HTMLInputElement> | undefined |
onContextMenuCapture | MouseEventHandler<HTMLInputElement> | undefined |
onCopyCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onCutCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onDoubleClickCapture | MouseEventHandler<HTMLInputElement> | undefined |
onDragCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragEndCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragEnterCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragExit | DragEventHandler<HTMLInputElement> | undefined |
onDragExitCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragLeaveCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragOverCapture | DragEventHandler<HTMLInputElement> | undefined |
onDragStartCapture | DragEventHandler<HTMLInputElement> | undefined |
onDropCapture | DragEventHandler<HTMLInputElement> | undefined |
onDurationChange | ReactEventHandler<HTMLInputElement> | undefined |
onDurationChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEmptied | ReactEventHandler<HTMLInputElement> | undefined |
onEmptiedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEncrypted | ReactEventHandler<HTMLInputElement> | undefined |
onEncryptedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onEnded | ReactEventHandler<HTMLInputElement> | undefined |
onEndedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onError | ReactEventHandler<HTMLInputElement> | undefined |
onErrorCapture | ReactEventHandler<HTMLInputElement> | undefined |
onFocusCapture | FocusEventHandler<HTMLInputElement> | undefined |
onGotPointerCapture | PointerEventHandler<HTMLInputElement> | undefined |
onGotPointerCaptureCapture | PointerEventHandler<HTMLInputElement> | undefined |
onInputCapture | InputEventHandler<HTMLInputElement> | undefined |
onInvalid | ReactEventHandler<HTMLInputElement> | undefined |
onInvalidCapture | ReactEventHandler<HTMLInputElement> | undefined |
onKeyDownCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyPress | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyPressCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onKeyUpCapture | KeyboardEventHandler<HTMLInputElement> | undefined |
onLoad | ReactEventHandler<HTMLInputElement> | undefined |
onLoadCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedData | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedDataCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedMetadata | ReactEventHandler<HTMLInputElement> | undefined |
onLoadedMetadataCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLoadStart | ReactEventHandler<HTMLInputElement> | undefined |
onLoadStartCapture | ReactEventHandler<HTMLInputElement> | undefined |
onLostPointerCapture | PointerEventHandler<HTMLInputElement> | undefined |
onLostPointerCaptureCapture | PointerEventHandler<HTMLInputElement> | undefined |
onMouseDownCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseMoveCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseOutCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseOverCapture | MouseEventHandler<HTMLInputElement> | undefined |
onMouseUpCapture | MouseEventHandler<HTMLInputElement> | undefined |
onPasteCapture | ClipboardEventHandler<HTMLInputElement> | undefined |
onPause | ReactEventHandler<HTMLInputElement> | undefined |
onPauseCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPlay | ReactEventHandler<HTMLInputElement> | undefined |
onPlayCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPlaying | ReactEventHandler<HTMLInputElement> | undefined |
onPlayingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onPointerOut | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOutCapture | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOver | PointerEventHandler<HTMLInputElement> | undefined |
onPointerOverCapture | PointerEventHandler<HTMLInputElement> | undefined |
onProgress | ReactEventHandler<HTMLInputElement> | undefined |
onProgressCapture | ReactEventHandler<HTMLInputElement> | undefined |
onRateChange | ReactEventHandler<HTMLInputElement> | undefined |
onRateChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onReset | ReactEventHandler<HTMLInputElement> | undefined |
onResetCapture | ReactEventHandler<HTMLInputElement> | undefined |
onScrollCapture | UIEventHandler<HTMLInputElement> | undefined |
onScrollEnd | UIEventHandler<HTMLInputElement> | undefined |
onScrollEndCapture | UIEventHandler<HTMLInputElement> | undefined |
onSeeked | ReactEventHandler<HTMLInputElement> | undefined |
onSeekedCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSeeking | ReactEventHandler<HTMLInputElement> | undefined |
onSeekingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSelect | ReactEventHandler<HTMLInputElement> | undefined |
onSelectCapture | ReactEventHandler<HTMLInputElement> | undefined |
onStalled | ReactEventHandler<HTMLInputElement> | undefined |
onStalledCapture | ReactEventHandler<HTMLInputElement> | undefined |
onSubmit | SubmitEventHandler<HTMLInputElement> | undefined |
onSubmitCapture | SubmitEventHandler<HTMLInputElement> | undefined |
onSuspend | ReactEventHandler<HTMLInputElement> | undefined |
onSuspendCapture | ReactEventHandler<HTMLInputElement> | undefined |
onTimeUpdate | ReactEventHandler<HTMLInputElement> | undefined |
onTimeUpdateCapture | ReactEventHandler<HTMLInputElement> | undefined |
onToggle | ToggleEventHandler<HTMLInputElement> | undefined |
onTouchCancelCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTouchMoveCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTouchStartCapture | TouchEventHandler<HTMLInputElement> | undefined |
onTransitionCancel | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionCancelCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionEnd | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionEndCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionRun | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionRunCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionStart | TransitionEventHandler<HTMLInputElement> | undefined |
onTransitionStartCapture | TransitionEventHandler<HTMLInputElement> | undefined |
onVolumeChange | ReactEventHandler<HTMLInputElement> | undefined |
onVolumeChangeCapture | ReactEventHandler<HTMLInputElement> | undefined |
onWaiting | ReactEventHandler<HTMLInputElement> | undefined |
onWaitingCapture | ReactEventHandler<HTMLInputElement> | undefined |
onWheelCapture | WheelEventHandler<HTMLInputElement> | undefined |
part | string | undefined |
popover | "" | "auto" | "manual" | "hint" | undefined |
popoverTarget | string | undefined |
popoverTargetAction | "hide" | "show" | "toggle" | undefined |
property | string | undefined |
radioGroup | string | undefined |
ref | Ref<TamaguiElement> | undefined |
resource | string | undefined |
results | number | undefined |
rev | string | undefined |
security | string | undefined |
slot | string | undefined |
src | string | undefined |
suppressContentEditableWarning | boolean | undefined |
suppressHydrationWarning | boolean | undefined |
title | string | undefined |
translate | "yes" | "no" | undefined |
typeof | string | undefined |
unselectable | "off" | "on" | undefined |
vocab | string | undefined |
Plus 522 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.