-
Notifications
You must be signed in to change notification settings - Fork 643
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: handle account balance abbreviation (#494)
* fix: handle account balance abbreviation * fix: handle values less than 1 * fix: do not round decimals * chore: clean up test suite * chore: remove redundant tests
- Loading branch information
1 parent
e82caf0
commit 11ed088
Showing
4 changed files
with
110 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@rainbow-me/rainbowkit': patch | ||
--- | ||
|
||
Abbreviate large account balances using standard k/m/b units, fixes cases where balances appeared in exponential notation. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
packages/rainbowkit/src/components/ConnectButton/abbreviateETHBalance.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { abbreviateETHBalance } from './abbreviateETHBalance'; | ||
|
||
const K = 1000; | ||
const M = 1000 * K; | ||
const B = 1000 * M; | ||
|
||
describe('abbreviateETHBalance', () => { | ||
it('truncates to 3 decimal places for numbers under 1', () => { | ||
expect(abbreviateETHBalance(0.002)).toEqual('0.002'); | ||
expect(abbreviateETHBalance(0.9009)).toEqual('0.9'); | ||
expect(abbreviateETHBalance(0.0009)).toEqual('0'); | ||
expect(abbreviateETHBalance(0.5194)).toEqual('0.519'); | ||
expect(abbreviateETHBalance(0.5199)).toEqual('0.519'); | ||
expect(abbreviateETHBalance(0.5499)).toEqual('0.549'); | ||
expect(abbreviateETHBalance(0.5999)).toEqual('0.599'); | ||
}); | ||
|
||
it('truncates to 2 decimal places for numbers under 100', () => { | ||
expect(abbreviateETHBalance(1)).toEqual('1'); | ||
expect(abbreviateETHBalance(1.002)).toEqual('1'); | ||
expect(abbreviateETHBalance(1.04)).toEqual('1.04'); | ||
expect(abbreviateETHBalance(1.09)).toEqual('1.09'); | ||
expect(abbreviateETHBalance(1.1)).toEqual('1.1'); | ||
expect(abbreviateETHBalance(10)).toEqual('10'); | ||
expect(abbreviateETHBalance(10.0)).toEqual('10'); | ||
expect(abbreviateETHBalance(12)).toEqual('12'); | ||
}); | ||
|
||
it('truncates to 1 decimal place and adds commas for numbers under 10k', () => { | ||
expect(abbreviateETHBalance(123)).toEqual('123'); | ||
expect(abbreviateETHBalance(1234)).toEqual('1,234'); | ||
expect(abbreviateETHBalance(1234.22)).toEqual('1,234.2'); | ||
expect(abbreviateETHBalance(1234.02)).toEqual('1,234'); | ||
expect(abbreviateETHBalance(9999)).toEqual('9,999'); | ||
expect(abbreviateETHBalance(9999.1)).toEqual('9,999.1'); | ||
expect(abbreviateETHBalance(9999.99)).toEqual('9,999.9'); // no round | ||
}); | ||
|
||
it('abbreviates past 10k', () => { | ||
expect(abbreviateETHBalance(10 * K)).toEqual('10k'); | ||
expect(abbreviateETHBalance(12.3 * K)).toEqual('12.3k'); | ||
expect(abbreviateETHBalance(123.4 * K)).toEqual('123.4k'); | ||
expect(abbreviateETHBalance(999.99 * K)).toEqual('999.9k'); // no rounds | ||
}); | ||
|
||
it('abbreviates past 1m', () => { | ||
expect(abbreviateETHBalance(1 * M)).toEqual('1m'); | ||
expect(abbreviateETHBalance(1.23 * M)).toEqual('1.2m'); | ||
expect(abbreviateETHBalance(10 * M)).toEqual('10m'); | ||
expect(abbreviateETHBalance(12.3 * M)).toEqual('12.3m'); | ||
expect(abbreviateETHBalance(123.4 * M)).toEqual('123.4m'); | ||
expect(abbreviateETHBalance(999.99 * M)).toEqual('999.9m'); // no rounds | ||
}); | ||
|
||
it('abbreviates past 1b', () => { | ||
expect(abbreviateETHBalance(1 * B)).toEqual('1b'); | ||
expect(abbreviateETHBalance(1.23 * B)).toEqual('1.2b'); | ||
expect(abbreviateETHBalance(10 * B)).toEqual('10b'); | ||
expect(abbreviateETHBalance(12.3 * B)).toEqual('12.3b'); | ||
expect(abbreviateETHBalance(123.4 * B)).toEqual('123.4b'); | ||
expect(abbreviateETHBalance(999.99 * B)).toEqual('999.9b'); // no rounds | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
packages/rainbowkit/src/components/ConnectButton/abbreviateETHBalance.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* Adapted from https://github.com/domharrington/js-number-abbreviate | ||
*/ | ||
const units = ['k', 'm', 'b', 't']; | ||
|
||
export function toPrecision(number: number, precision: number = 1) { | ||
return number | ||
.toString() | ||
.replace(new RegExp(`(.+\\.\\d{${precision}})\\d+`), '$1') | ||
.replace(/(\.[1-9]*)0+$/, '$1') | ||
.replace(/\.$/, ''); | ||
} | ||
|
||
export function abbreviateETHBalance(number: number): string { | ||
if (number < 1) return toPrecision(number, 3); | ||
if (number < 10 ** 2) return toPrecision(number, 2); | ||
if (number < 10 ** 4) | ||
return new Intl.NumberFormat().format(parseFloat(toPrecision(number, 1))); | ||
|
||
const decimalsDivisor = 10 ** 1; // 1 decimal place | ||
|
||
let result = String(number); | ||
|
||
for (let i = units.length - 1; i >= 0; i--) { | ||
const size = 10 ** ((i + 1) * 3); | ||
|
||
if (size <= number) { | ||
number = (number * decimalsDivisor) / size / decimalsDivisor; | ||
|
||
result = toPrecision(number, 1) + units[i]; | ||
|
||
break; | ||
} | ||
} | ||
|
||
return result; | ||
} |
11ed088
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
rainbowkit-example – ./
rainbowkit-example.vercel.app
rainbowkit-example-git-main-rainbowdotme.vercel.app
rainbowkit-example-rainbowdotme.vercel.app
11ed088
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
rainbowkit-site – ./
rainbowkit.vercel.app
rainbowkit-site-git-main-rainbowdotme.vercel.app
rainbowkit.com
www.rainbowkit.com
rainbowkit-site-rainbowdotme.vercel.app