NumberInput

The NumberInput component is a numeric text input field that provides built-in step controls for incrementing and decrementing the value. It supports custom formatting and parsing functions, allowing you to display numbers in various formats (e.g., currency, percentages) while maintaining a numeric value internally.

Basic

Controlled number input with simple step controls and live value preview.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

NumberInput

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

quantity

,

setQuantity

]

 

=

useState

<

number

 

|

 

undefined

>

(

2

)

;

 

  

return

 

(

    

<NumberInput

      

label

=

"Quantity"

      

placeholder

=

"Enter amount"

      

value

=

{

quantity

}

      

onChange

=

{

setQuantity

}

      

min

=

{

0

}

      

step

=

{

1

}

    

/>

  

)

;

}

Formats

Showcases currency formatting, percentage suffixes, and a derived total.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

NumberInput

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

price

,

setPrice

]

 

=

useState

<

number

 

|

 

undefined

>

(

249.99

)

;

  

const

 

[

discount

,

setDiscount

]

 

=

useState

<

number

 

|

 

undefined

>

(

10

)

;

 

  

const

finalPrice

=

price

!=

 

null

 

&&

discount

!=

 

null

    

?

price

*

 

(

1

 

-

discount

/

 

100

)

    

:

 

undefined

;

 

  

return

 

(

    

<Block

>

      

<Block

>

        

<NumberInput

          

label

=

"List price"

          

value

=

{

price

}

          

onChange

=

{

setPrice

}

          

format

=

"currency"

          

currency

=

"USD"

          fixedDecimalScale

          

decimalScale

=

{

2

}

          

min

=

{

0

}

          

allowNegative

=

{

false

}

        

/>

        

<NumberInput

          

label

=

"Discount"

          

value

=

{

discount

}

          

onChange

=

{

setDiscount

}

          

suffix

=

"%"

          

min

=

{

0

}

          

max

=

{

100

}

          

step

=

{

0.5

}

          allowDecimal

        

/>

      

</Block

>

 

      

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

        

Final

price

:

 

{

finalPrice

!=

 

null

 

?

 

`$${finalPrice.toFixed(2)}`

 

:

 

'—'

}

      

</Text

>

    

</Block

>

  

)

;

}

Side buttons

Side button controls with shift multipliers for both fine and coarse adjustments.

Loading demo…

import

 

{

useMemo

,

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

NumberInput

,

 

Row

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

const

 

EnhancedNumberInput

 

=

 

NumberInput

as

any

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

value

,

setValue

]

 

=

 

useState

(

32

)

;

  

const

 

[

step

,

setStep

]

 

=

 

useState

(

1

)

;

  

const

effectiveStep

=

 

useMemo

(

(

)

 

=>

step

||

 

1

,

 

[

step

]

)

;

 

  

return

 

(

    

<Block

 

style

=

{

{

maxWidth

:

 

360

 

}

}

>

      

<Text

 

weight

=

"semibold"

>

Side

buttons and shift multiplier

</Text

>

      

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

        

Combine

side buttons with the

default

controls to support coarse and fine adjustments

.

      

</Text

>

 

      

<Block

>

        

<EnhancedNumberInput

          

label

=

"Playback speed"

          

value

=

{

value

}

          

min

=

{

0

}

          

max

=

{

200

}

          

step

=

{

effectiveStep

}

          

shiftMultiplier

=

{

10

}

          

suffix

=

"%"

          withSideButtons

          withControls

          

onChange

=

{

(

next

:

 

number

 

|

 

undefined

)

 

=>

 

{

            

if

 

(

typeof next

===

 

'number'

)

 

{

              

setValue

(

next

)

;

            

}

          

}

}

        

/>

        

<Row

 

justify

=

"space-between"

 

align

=

"center"

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

Current

speed

:

 

{

value

}

%

          

</Text

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

Shift

-

click

=

±

{

effectiveStep

*

 

10

}

          

</Text

>

        

</Row

>

      

</Block

>

 

      

<Block

>

        

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

          

Adjust

the base step

        

</Text

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Update

the increment to see how the multiplier scales

.

        

</Text

>

        

<EnhancedNumberInput

          

label

=

"Base step"

          

value

=

{

step

}

          

min

=

{

1

}

          

max

=

{

25

}

          

step

=

{

1

}

          withSideButtons

          

onChange

=

{

(

next

:

 

number

 

|

 

undefined

)

 

=>

 

{

            

if

 

(

typeof next

===

 

'number'

)

 

{

              

setStep

(

next

)

;

            

}

          

}

}

        

/>

      

</Block

>

    

</Block

>

  

)

;

}

Drag gesture

Press-and-drag interactions for horizontal and vertical number adjustments.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

 

import

 

{

 

Block

,

 

NumberInput

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

horizontalValue

,

setHorizontalValue

]

 

=

useState

<

number

 

|

 

undefined

>

(

32

)

;

  

const

 

[

verticalValue

,

setVerticalValue

]

 

=

useState

<

number

 

|

 

undefined

>

(

120

)

;

  

const

 

[

dragging

,

setDragging

]

 

=

 

useState

(

false

)

;

 

  

const

handleDragStateChange

=

 

(

state

:

 

boolean

)

 

=>

 

{

    

setDragging

(

state

)

;

  

}

;

 

  

return

 

(

    

<Block

>

      

<Text

 

weight

=

"semibold"

>

Press

-

and

-

drag adjustment

</Text

>

      

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

        

Drag

across the input to nudge values without lifting your pointer

.

 

The

status below reflects the current drag state

.

      

</Text

>

      

<Text

 

size

=

"xs"

 

color

=

{

dragging

?

 

'primary'

 

:

 

'secondary'

}

>

        

Dragging

:

 

{

dragging

?

 

'active'

 

:

 

'idle'

}

      

</Text

>

 

      

<Block

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

            

Horizontal

drag

          

</Text

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Step

every 14px drag movement with a multiplier

for

faster adjustments

.

          

</Text

>

          

<NumberInput

            

label

=

"Temperature"

            

value

=

{

horizontalValue

}

            

onChange

=

{

setHorizontalValue

}

            withDragGesture

            

dragAxis

=

"horizontal"

            

dragStepDistance

=

{

14

}

            

dragStepMultiplier

=

{

2

}

            

step

=

{

1

}

            

allowDecimal

=

{

false

}

            

min

=

{

0

}

            

suffix

=

" °C"

            

onDragStateChange

=

{

handleDragStateChange

}

          

/>

        

</Block

>

 

        

<Block

>

          

<Text

 

size

=

"sm"

 

weight

=

"semibold"

>

            

Vertical

drag

          

</Text

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Drag

up or down to adjust between

0

and

200

with built

-

in controls

.

          

</Text

>

          

<NumberInput

            

label

=

"Light intensity"

            

value

=

{

verticalValue

}

            

onChange

=

{

setVerticalValue

}

            withDragGesture

            

dragAxis

=

"vertical"

            

dragStepDistance

=

{

18

}

            

step

=

{

5

}

            

allowDecimal

=

{

false

}

            

min

=

{

0

}

            

max

=

{

200

}

            withControls

            

hideControlsOnMobile

=

{

false

}

            

onDragStateChange

=

{

handleDragStateChange

}

          

/>

        

</Block

>

      

</Block

>

    

</Block

>

  

)

;

}

Scan to open this page on your phonereact-ui-library.com/components/NumberInput

</>

react-ui-library

100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.

A Platform Blocks product.