91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			91 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { memo } from 'react';
 | 
						|
 | 
						|
import { FormattedMessage, FormattedNumber } from 'react-intl';
 | 
						|
 | 
						|
import { toShortNumber, pluralReady, DECIMAL_UNITS } from '../utils/numbers';
 | 
						|
 | 
						|
type ShortNumberRenderer = (
 | 
						|
  displayNumber: JSX.Element,
 | 
						|
  pluralReady: number,
 | 
						|
) => 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(
 | 
						|
      '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.',
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  const customRenderer = children ?? renderer ?? null;
 | 
						|
 | 
						|
  const displayNumber = <ShortNumberCounter value={shortNumber} />;
 | 
						|
 | 
						|
  return (
 | 
						|
    customRenderer?.(displayNumber, pluralReady(value, division)) ??
 | 
						|
    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
 | 
						|
      value={rawNumber}
 | 
						|
      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;
 | 
						|
  }
 | 
						|
};
 |