Motion Number

Animated Number component with transition, format, and localization. It's accessible, customizable, and ideal for smooth UI interactions.

Read Docs to know more motion number

124.23

After

$124.23

Before

$124.23

Last

$124.23

First

$124.23

Installation

npm install motion-number
number-shuffle.tsx
// @ts-nocheck
import React, { useState, useEffect, ReactNode } from 'react'
import dynamic from 'next/dynamic'
import { cn } from '@/lib/utils'
 
// Dynamically import MotionNumber with SSR disabled
const MotionNumber = dynamic(() => import('motion-number'), { ssr: false })
interface NumberFormat extends Intl.NumberFormatOptions {}
interface MotionNumberProps {
  value: number
  format?: NumberFormat
  className?: string
  animate?: Record<string, any>
  transition?: Record<string, any>
}
 
interface OptionProps extends MotionNumberProps {
  content?: ReactNode
}
 
interface NumberShuffleProps {
  currentValue: number
  format?: NumberFormat
  before?: OptionProps
  first?: OptionProps
  last?: OptionProps
  after?: OptionProps
  clasname?: string
}
 
const NumberShuffle: React.FC<NumberShuffleProps> = ({
  currentValue,
  format = {},
  before,
  first,
  last,
  after,
  clasname,
}) => {
  const [isClient, setIsClient] = useState(false)
 
  useEffect(() => {
    setIsClient(true)
  }, [])
 
  if (!isClient) {
    return (
      <div className="w-fit grid place-content-center mx-auto space-y-4 py-10">
        <div className="text-6xl">
          {new Intl.NumberFormat('en-US', format).format(currentValue)}
        </div>
      </div>
    )
  }
 
  const renderOption = (option, defaultContent = null) => {
    if (option && typeof option === 'object') {
      return (
        <MotionNumber
          value={option.value}
          format={option.format || {}}
          className={option.className || ''}
          animate={option.animate || {}}
          transition={option.transition || {}}
        >
          {option.content}
        </MotionNumber>
      )
    }
    return defaultContent
  }
 
  return (
    <div className="w-fit grid place-content-center mx-auto space-y-4 py-10">
      <div>
        <MotionNumber
          value={currentValue}
          format={format}
          className={cn('text-6xl', clasname)}
          before={() => renderOption(before)}
          first={() => renderOption(first)}
          last={() => renderOption(last)}
          after={() => renderOption(after)}
        />
      </div>
    </div>
  )
}
 
export default NumberShuffle

Props

PropTypeDefaultDescription
currentValuenumberThe current number value to be displayed.
formatNumberFormat{}Options for formatting the number.
beforeOptionPropsOptional props for content displayed before the number.
firstOptionPropsOptional props for content displayed before the first number.
lastOptionPropsOptional props for content displayed after the last number.
afterOptionPropsOptional props for content displayed after the number.
clasnamestringOptional CSS class for styling the component.