import classNames from 'classnames'; import * as React from 'react'; import { ConfigContext } from '../config-provider'; import { cloneElement } from '../_util/reactNode'; import SingleNumber from './SingleNumber'; export interface ScrollNumberProps { prefixCls?: string; className?: string; motionClassName?: string; count?: string | number | null; children?: React.ReactElement; component?: React.ComponentType; style?: React.CSSProperties; title?: string | number | null; show: boolean; } export interface ScrollNumberState { animateStarted?: boolean; count?: string | number | null; } const ScrollNumber = React.forwardRef, ScrollNumberProps>( ( { prefixCls: customizePrefixCls, count, className, motionClassName, style, title, show, component: Component = 'sup', children, ...restProps }, ref, ) => { const { getPrefixCls } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('scroll-number', customizePrefixCls); // ============================ Render ============================ const newProps = { ...restProps, 'data-show': show, style, className: classNames(prefixCls, className, motionClassName), title: title as string, }; // Only integer need motion let numberNodes: React.ReactNode = count; if (count && Number(count) % 1 === 0) { const numberList = String(count).split(''); numberNodes = numberList.map((num, i) => ( )); } // allow specify the border // mock border-color by box-shadow for compatible with old usage: // if (style && style.borderColor) { newProps.style = { ...style, boxShadow: `0 0 0 1px ${style.borderColor} inset`, }; } if (children) { return cloneElement(children, (oriProps) => ({ className: classNames( `${prefixCls}-custom-component`, oriProps?.className, motionClassName, ), })); } return ( {numberNodes} ); }, ); export default ScrollNumber;