RollingNumber

RollingNumber displays a number and animates every digit that changes, rolling it to its new position. Use it for counters, live totals, prices and metric readouts where the change itself is part of the information.

Basic

A counter whose digits roll to their new positions. Only the columns that changed move.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

Button

,

 

Flex

,

 

RollingNumber

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

value

,

setValue

]

 

=

 

useState

(

1234

)

;

 

  

return

 

(

    

<Flex

 

direction

=

"column"

 

align

=

"center"

 

gap

=

"md"

>

      

<RollingNumber

 

value

=

{

value

}

 

size

=

{

48

}

 

weight

=

"bold"

thousandSeparator

/>

      

<Flex

 

gap

=

"sm"

>

        

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setValue

(

(

current

)

 

=>

current

-

 

1

)

}

>-

1

</Button

>

        

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setValue

(

(

current

)

 

=>

current

+

 

1

)

}

>+

1

</Button

>

        

<Button

 

onPress

=

{

(

)

 

=>

 

setValue

(

Math

.

floor

(

Math

.

random

(

)

 

*

 

100000

)

)

}

>

Random

</Button

>

      

</Flex

>

    

</Flex

>

  

)

;

}

Currency

prefix, suffix and the decimal options cover currency formatting without an external formatter. Copying the value on web yields the formatted string, not the digit strips.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

Button

,

 

Flex

,

 

RollingNumber

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

total

,

setTotal

]

 

=

 

useState

(

1299.99

)

;

 

  

return

 

(

    

<Flex

 

direction

=

"column"

 

align

=

"center"

 

gap

=

"md"

>

      

<RollingNumber

        

value

=

{

total

}

        

prefix

=

"$ "

        

suffix

=

" USD"

        

decimalScale

=

{

2

}

        fixedDecimalScale

        thousandSeparator

        

size

=

{

36

}

        

weight

=

"semibold"

      

/>

      

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setTotal

(

(

current

)

 

=>

current

+

 

149.5

)

}

>

        

Add

item

      

</Button

>

    

</Flex

>

  

)

;

}

Timing

transitionDuration, timingFunction and stagger shape the roll. Stagger delays each column right-to-left, so the carries trail the ones place the way an odometer does.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

Button

,

 

Flex

,

 

RollingNumber

,

 

Text

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

value

,

setValue

]

 

=

 

useState

(

407219

)

;

 

  

return

 

(

    

<Flex

 

direction

=

"column"

 

gap

=

"lg"

>

      

<Flex

 

direction

=

"column"

 

gap

=

"xs"

>

        

<Text

 

size

=

"xs"

 

c

=

"dimmed"

>

Snappy

— 200ms

,

no stagger

</Text

>

        

<RollingNumber

 

value

=

{

value

}

 

transitionDuration

=

{

200

}

 

size

=

{

32

}

thousandSeparator

/>

      

</Flex

>

 

      

<Flex

 

direction

=

"column"

 

gap

=

"xs"

>

        

<Text

 

size

=

"xs"

 

c

=

"dimmed"

>

Odometer

— 900ms

,

60ms stagger

</Text

>

        

<RollingNumber

          

value

=

{

value

}

          

transitionDuration

=

{

900

}

          

timingFunction

=

"ease-out"

          

stagger

=

{

60

}

          

size

=

{

32

}

          thousandSeparator

        

/>

      

</Flex

>

 

      

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setValue

(

Math

.

floor

(

Math

.

random

(

)

 

*

 

999999

)

)

}

>

        

Shuffle

      

</Button

>

    

</Flex

>

  

)

;

}

Live metric

A ticking metric tile. Values that change faster than the roll retarget mid-flight rather than snapping.

Loading demo…

import

 

{

useEffect

,

useState

}

 

from

 

'react'

;

import

 

{

 

Card

,

 

Flex

,

 

RollingNumber

,

 

Text

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

requests

,

setRequests

]

 

=

 

useState

(

84213

)

;

 

  

useEffect

(

(

)

 

=>

 

{

    

const

timer

=

 

setInterval

(

(

)

 

=>

 

{

      

setRequests

(

(

current

)

 

=>

current

+

 

Math

.

floor

(

Math

.

random

(

)

 

*

 

40

)

)

;

    

}

,

 

1200

)

;

    

return

 

(

)

 

=>

 

clearInterval

(

timer

)

;

  

}

,

 

[

]

)

;

 

  

return

 

(

    

<Card

 

p

=

"lg"

 

style

=

{

{

minWidth

:

 

220

 

}

}

>

      

<Flex

 

direction

=

"column"

 

gap

=

"xs"

>

        

<Text

 

size

=

"xs"

 

c

=

"dimmed"

uppercase

>

Requests

today

</Text

>

        

<RollingNumber

          

value

=

{

requests

}

          thousandSeparator

          

size

=

{

40

}

          

weight

=

"bold"

          

transitionDuration

=

{

500

}

          

stagger

=

{

40

}

        

/>

      

</Flex

>

    

</Card

>

  

)

;

}

</>

react-ui-library

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

A Platform Blocks product.