2023-07-08 11:11:58 +02:00
import { memo } from 'react' ;
2024-10-21 10:03:44 +02:00
import type { JSX } from 'react' ;
2023-07-08 11:11:58 +02:00
import { FormattedMessage , FormattedNumber } from 'react-intl' ;
import { toShortNumber , pluralReady , DECIMAL_UNITS } from '../utils/numbers' ;
type ShortNumberRenderer = (
displayNumber : JSX.Element ,
2023-07-13 11:26:45 +02:00
pluralReady : number ,
2023-07-08 11:11:58 +02:00
) = > JSX . Element ;
interface ShortNumberProps {
value : number ;
renderer? : ShortNumberRenderer ;
children? : ShortNumberRenderer ;
}
export const ShortNumberRenderer : React.FC < ShortNumberProps > = ( {
value ,
renderer ,
children ,
} ) = > {
const shortNumber = toShortNumber ( value ) ;
const [ , division ] = shortNumber ;
if ( children && renderer ) {
console . warn (
2023-07-13 11:26:45 +02:00
'Both renderer prop and renderer as a child provided. This is a mistake and you really should fix that. Only renderer passed as a child will be used.' ,
2023-07-08 11:11:58 +02:00
) ;
}
2023-07-13 11:49:16 +02:00
const customRenderer = children ? ? renderer ? ? null ;
2023-07-08 11:11:58 +02:00
const displayNumber = < ShortNumberCounter value = { shortNumber } / > ;
return (
2023-07-13 11:49:16 +02:00
customRenderer ? . ( displayNumber , pluralReady ( value , division ) ) ? ?
2023-07-08 11:11:58 +02:00
displayNumber
) ;
} ;
export const ShortNumber = memo ( ShortNumberRenderer ) ;
interface ShortNumberCounterProps {
value : number [ ] ;
}
const ShortNumberCounter : React.FC < ShortNumberCounterProps > = ( { value } ) = > {
const [ rawNumber , unit , maxFractionDigits = 0 ] = value ;
const count = (
< FormattedNumber
2024-05-27 11:24:59 +02:00
value = { rawNumber ? ? 0 }
2023-07-08 11:11:58 +02:00
maximumFractionDigits = { maxFractionDigits }
/ >
) ;
const values = { count , rawNumber } ;
switch ( unit ) {
case DECIMAL_UNITS . THOUSAND : {
return (
< FormattedMessage
id = 'units.short.thousand'
defaultMessage = '{count}K'
values = { values }
/ >
) ;
}
case DECIMAL_UNITS . MILLION : {
return (
< FormattedMessage
id = 'units.short.million'
defaultMessage = '{count}M'
values = { values }
/ >
) ;
}
case DECIMAL_UNITS . BILLION : {
return (
< FormattedMessage
id = 'units.short.billion'
defaultMessage = '{count}B'
values = { values }
/ >
) ;
}
// Not sure if we should go farther - @Sasha-Sorokin
default :
return count ;
}
} ;