Display balance with calculated SI units (#583)

* Display balance with calculated SI units

* Unused auto-import

* Update tests (format params)
This commit is contained in:
Jaco Greeff 2019-01-10 17:28:49 +01:00 committed by GitHub
parent 8847473e8d
commit ecb61d02ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 19 deletions

View File

@ -6,7 +6,7 @@ import { BareProps, BitLength, I18nProps } from './types';
import BN from 'bn.js';
import React from 'react';
import { balanceFormat } from '@polkadot/ui-react-rx/util/index';
import { balanceFormat, calcSi } from '@polkadot/ui-react-rx/util/index';
import classes from './util/classes';
import { BitLengthOption } from './constants';
@ -29,6 +29,7 @@ type Props = BareProps & I18nProps & {
};
type State = {
defaultValue?: string,
isPreKeyDown: boolean,
isValid: boolean,
siOptions: Array<{ value: string, text: string }>,
@ -68,6 +69,17 @@ class InputNumber extends React.PureComponent<Props, State> {
InputNumber.units = units;
}
static getDerivedStateFromProps ({ isDisabled, isSi, defaultValue = '0' }: Props): Partial<State> | null {
if (!isDisabled || !isSi) {
return null;
}
return {
defaultValue: balanceFormat(defaultValue, false),
siUnit: calcSi(defaultValue).value
};
}
render () {
const { bitLength = DEFAULT_BITLENGTH, className, defaultValue = '0', isSi, isDisabled, maxLength, style, t } = this.props;
const { isValid } = this.state;
@ -80,7 +92,7 @@ class InputNumber extends React.PureComponent<Props, State> {
>
<Input
{...this.props}
defaultValue={defaultValue}
defaultValue={this.state.defaultValue || defaultValue}
isAction={isSi}
isDisabled={isDisabled}
isError={!isValid}

View File

@ -9,7 +9,6 @@ import BN from 'bn.js';
import React from 'react';
import { BitLengthOption } from '@polkadot/ui-app/constants';
import { InputNumber } from '@polkadot/ui-app/index';
import { balanceFormat } from '@polkadot/ui-react-rx/util/index';
import Bare from './Bare';
@ -20,9 +19,7 @@ const DEFAULT_BITLENGTH = BitLengthOption.CHAIN_SPEC as BitLength;
class Balance extends React.PureComponent<Props> {
render () {
const { className, defaultValue: { value }, isDisabled, isError, label, style, withLabel } = this.props;
const defaultValue = isDisabled
? balanceFormat(value)
: new BN(value as BN || '0').toString(10);
const defaultValue = new BN((value as BN || '0').toString()).toString(10);
return (
<Bare

View File

@ -11,43 +11,49 @@ describe('balanceFormat', () => {
it('formats 123,456,789,000 (decimals=15)', () => {
expect(
balanceFormat(TESTVAL, 15)
balanceFormat(TESTVAL, true, 15)
).toEqual('123.456µ');
});
it('formats 123,456,789,000 (decimals=12)', () => {
expect(
balanceFormat(TESTVAL, 12)
balanceFormat(TESTVAL, true, 12)
).toEqual('123.456m');
});
it('formats 123,456,789,000 (decimals=12, no SI)', () => {
expect(
balanceFormat(TESTVAL, false, 12)
).toEqual('123.456');
});
it('formats 123,456,789,000 (decimals=9)', () => {
expect(
balanceFormat(TESTVAL, 9)
balanceFormat(TESTVAL, true, 9)
).toEqual('123.456');
});
it('formats 123,456,789,000 (decimals=6)', () => {
expect(
balanceFormat(TESTVAL, 6)
balanceFormat(TESTVAL, true, 6)
).toEqual('123.456k');
});
it('formats 123,456,789,000 * 10 (decimals=12)', () => {
expect(
balanceFormat(TESTVAL.muln(10), 12)
balanceFormat(TESTVAL.muln(10), true, 12)
).toEqual('1.234');
});
it('formats 123,456,789,000 * 100 (decimals=12)', () => {
expect(
balanceFormat(TESTVAL.muln(100), 12)
balanceFormat(TESTVAL.muln(100), true, 12)
).toEqual('12.345');
});
it('formats 123,456,789,000 * 1000 (decimals=12)', () => {
expect(
balanceFormat(TESTVAL.muln(1000), 12)
balanceFormat(TESTVAL.muln(1000), true, 12)
).toEqual('123.456');
});

View File

@ -3,7 +3,6 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { UInt } from '@polkadot/types/codec';
import decimalFormat from './decimalFormat';
@ -14,7 +13,7 @@ type SiDef = {
};
interface BalanceFormatter {
(input: string | BN | UInt, decimals?: number): string;
(input: string | BN, withSi?: boolean, decimals?: number): string;
findSi (type: string): SiDef;
getDefaultDecimals (): number;
getOptions (decimals?: number): Array<SiDef>;
@ -45,8 +44,12 @@ const SI_MID = 8;
let defaultDecimals = 0;
export function calcSi (text: string, decimals: number = defaultDecimals): SiDef {
return SI[(SI_MID - 1) + Math.ceil((text.length - decimals) / 3)];
}
// Formats a string/number with <prefix>.<postfix><type> notation
function _balanceFormat (input: string | BN | UInt, decimals: number = defaultDecimals): string {
function _balanceFormat (input: string | BN, withSi: boolean = true, decimals: number = defaultDecimals): string {
const text = (input || '').toString();
if (text.length === 0 || text === '0') {
@ -56,12 +59,12 @@ function _balanceFormat (input: string | BN | UInt, decimals: number = defaultDe
// 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 = SI[(SI_MID - 1) + Math.ceil((text.length - decimals) / 3)];
const si = calcSi(text, decimals);
const mid = text.length - (decimals + si.power);
const prefix = text.substr(0, mid);
const postfix = `${text.substr(mid)}000`.substr(0, 3);
return `${decimalFormat(prefix || '0')}.${postfix}${si.value === '-' ? '' : si.value}`;
return `${decimalFormat(prefix || '0')}.${postfix}${withSi ? (si.value === '-' ? '' : si.value) : ''}`;
}
const balanceFormat = _balanceFormat as BalanceFormatter;

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import balanceFormat from './balanceFormat';
import balanceFormat, { calcSi } from './balanceFormat';
import decimalFormat from './decimalFormat';
import intervalObservable from './intervalObservable';
import intervalTimer from './intervalTimer';
@ -13,6 +13,7 @@ import triggerChange from './triggerChange';
export {
balanceFormat,
calcSi,
decimalFormat,
intervalObservable,
intervalTimer,