114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
// Copyright 2017-2019 @polkadot/util authors & contributors
|
|
// This software may be modified and distributed under the terms
|
|
// of the Apache-2.0 license. See the LICENSE file for details.
|
|
|
|
import { SiDef, ToBn } from '../types';
|
|
|
|
import BN from 'bn.js';
|
|
|
|
import bnToBn from '../bn/toBn';
|
|
import isBoolean from '../is/boolean';
|
|
import isUndefined from '../is/undefined';
|
|
import formatDecimal from './formatDecimal';
|
|
import { SI, SI_MID, calcSi, findSi } from './si';
|
|
|
|
interface Defaults {
|
|
decimals: number;
|
|
unit: string;
|
|
}
|
|
|
|
type Options = boolean | { forceUnit?: string; withSi?: boolean };
|
|
|
|
interface BalanceFormatter {
|
|
<ExtToBn extends ToBn> (input?: number | string | BN | ExtToBn, options?: Options, decimals?: number): string;
|
|
calcSi (text: string, decimals?: number): SiDef;
|
|
findSi (type: string): SiDef;
|
|
getDefaults (): Defaults;
|
|
getOptions (decimals?: number): SiDef[];
|
|
setDefaults (defaults: Partial<Defaults>): void;
|
|
}
|
|
|
|
const DEFAULT_DECIMALS = 0;
|
|
const DEFAULT_UNIT = SI[SI_MID].text;
|
|
|
|
let defaultDecimals = DEFAULT_DECIMALS;
|
|
let defaultUnit = DEFAULT_UNIT;
|
|
|
|
// Formats a string/number with <prefix>.<postfix><type> notation
|
|
function _formatBalance <ExtToBn extends ToBn> (input?: number | string | BN | ExtToBn, options: Options = true, decimals: number = defaultDecimals): string {
|
|
let text = bnToBn(input).toString();
|
|
|
|
if (text.length === 0 || text === '0') {
|
|
return '0';
|
|
}
|
|
|
|
// strip the negative sign so we can work with clean groupings, re-add this in the
|
|
// end when we return the result (from here on we work with positive numbers)
|
|
const isNegative = text[0].startsWith('-');
|
|
|
|
if (isNegative) {
|
|
text = text.substr(1);
|
|
}
|
|
|
|
// extract options - the boolean case is for backwards-compat
|
|
const { forceUnit = undefined, withSi = true } = isBoolean(options)
|
|
? { withSi: options }
|
|
: options;
|
|
|
|
// NOTE We start at midpoint (8) minus 1 - this means that values display as
|
|
// 123.456 instead of 0.123k (so always 6 relevant). Additionally we us ceil
|
|
// so there are at most 3 decimal before the decimal seperator
|
|
const si = calcSi(text, decimals, forceUnit);
|
|
const mid = text.length - (decimals + si.power);
|
|
const prefix = text.substr(0, mid);
|
|
const padding = mid < 0 ? 0 - mid : 0;
|
|
const postfix = `${`${new Array(padding + 1).join('0')}${text}`.substr(mid < 0 ? 0 : mid)}000`.substr(0, 3);
|
|
const units = withSi
|
|
? (
|
|
si.value === '-'
|
|
? ` ${si.text}`
|
|
: `${si.value} ${SI[SI_MID].text}`
|
|
)
|
|
: '';
|
|
|
|
return `${isNegative ? '-' : ''}${formatDecimal(prefix || '0')}.${postfix}${units}`;
|
|
}
|
|
|
|
const formatBalance = _formatBalance as BalanceFormatter;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
formatBalance.calcSi = (text: string, decimals: number = defaultDecimals): SiDef =>
|
|
calcSi(text, decimals);
|
|
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
formatBalance.findSi = findSi;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
formatBalance.getDefaults = (): Defaults => {
|
|
return {
|
|
decimals: defaultDecimals,
|
|
unit: defaultUnit
|
|
};
|
|
};
|
|
|
|
// get allowable options to display in a dropdown
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
formatBalance.getOptions = (decimals: number = defaultDecimals): SiDef[] => {
|
|
return SI.filter(({ power }): boolean =>
|
|
power < 0
|
|
? (decimals + power) >= 0
|
|
: true
|
|
);
|
|
};
|
|
|
|
// Sets the default decimals to use for formatting (ui-wide)
|
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
formatBalance.setDefaults = ({ decimals, unit }: Partial<Defaults>): void => {
|
|
defaultDecimals = isUndefined(decimals) ? defaultDecimals : decimals;
|
|
defaultUnit = isUndefined(unit) ? defaultUnit : unit;
|
|
|
|
SI[SI_MID].text = defaultUnit;
|
|
};
|
|
|
|
export default formatBalance;
|