monday-ui-react-core
Version:
Official monday.com UI resources for application development in React.js
121 lines (107 loc) • 2.95 kB
JSX
import React, { useMemo, forwardRef } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import { baseClassName } from "./FormattedNumberConsts";
import {
formatNumber,
formatNumberConsts
} from "../../helpers/textManipulations";
import { customPropTypes, validateValue } from "./FormattedNumberHelpers";
import "./FormattedNumber.scss";
const { MAX_PRECISION, MIN_PRECISION } = formatNumberConsts;
const FormattedNumber = forwardRef(
(
{
value,
className,
local,
prefix,
suffix,
emptyPlaceHolder,
decimalPrecision,
compact,
rtl
},
ref
) => {
const renderSuffix = useMemo(() => {
if (!suffix) return null;
return <span className={`${baseClassName}__suffix`}>{suffix}</span>;
}, [suffix]);
const renderPrefix = useMemo(() => {
if (!prefix) return null;
return <span className={`${baseClassName}__prefix`}>{prefix}</span>;
}, [prefix]);
const calculatedValue = useMemo(() => {
return formatNumber(value, {
local,
precision: decimalPrecision,
isCompact: compact
});
}, [value, decimalPrecision, local, compact]);
if (validateValue(value)) {
return (
<span className={`${baseClassName}__place-holder`}>
{emptyPlaceHolder}
</span>
);
}
return (
<div ref={ref} className={classNames(className, baseClassName)}>
{rtl ? renderSuffix : renderPrefix}
<span className={`${baseClassName}__number`}>{calculatedValue}</span>
{rtl ? renderPrefix : renderSuffix}
</div>
);
}
);
FormattedNumber.formatNumber = formatNumber;
FormattedNumber.localFallBack = formatNumberConsts.DEFAULT_LOCAL;
const { range } = customPropTypes;
FormattedNumber.propTypes = {
/**
* A numeric value to format.
*/
value: PropTypes.number,
/**
* Add external styling. Will be added to the main container.
*/
className: PropTypes.string,
/**
* If included, will be added as a prefix to the number.
*/
prefix: PropTypes.string,
/**
* If included, will be added as a suffix to the number.
*/
suffix: PropTypes.string,
/**
* The text that will be shown if no value is provided.
*/
emptyPlaceHolder: PropTypes.string,
/**
* Determines the number of decimal numbers (0 ~ 20).
*/
decimalPrecision: range(MIN_PRECISION, MAX_PRECISION),
/**
* Format number into compact number and initial (if required).
*/
compact: PropTypes.bool,
/**
* Determines the number's local (Unicode BCP 47 locale identifier).
*/
local: PropTypes.string,
/**
* Determines suffix and prefix location
*/
rtl: PropTypes.bool
};
FormattedNumber.defaultProps = {
emptyPlaceHolder: "N/A",
decimalPrecision: 2,
compact: true,
local: FormattedNumber.localFallBack,
rtl: false,
className: ""
};
export default FormattedNumber;