Skip to content

AmountDisplay 金额显示

格式化显示加密货币金额,支持平滑数字动画


功能描述

将原始金额值格式化为人类可读的形式,支持多种显示配置。使用 @number-flow/react 实现专业的数字动画效果。

核心特性

  • Amount 类型支持: 直接接收 Amount 对象,自动提取元数据
  • 数字动画: 数值变化时逐位平滑过渡动画
  • 加载状态: 显示 "0" 配合呼吸动画,数据到达后平滑过渡到真实值
  • 完整可访问性: 屏幕阅读器正确读取数值
  • 等宽字体: 使用 font-mono 确保数字宽度一致

与 Amount 类型集成

推荐使用 Amount 对象作为 value 属性,组件会自动提取 decimals 和 symbol:

tsx
import { Amount } from '@/types/amount'
import { AmountDisplay } from '@/components/amount-display'

const balance = Amount.fromRaw('1500000000000000000', 18, 'ETH')

// 使用 Amount 对象(推荐)
<AmountDisplay value={balance} />
// 自动显示: 1.5 ETH

// 也支持直接使用 number
<AmountDisplay value={balance.toNumber()} symbol="ETH" />

更多关于 Amount 类型的信息,请参阅 Amount 类型系统


属性规范

属性类型必需默认值说明
valuenumber | bigint | string | AmountY-金额值(推荐使用 Amount)
symbolstringN-货币符号(使用 Amount 时自动提取)
decimalsnumberN8小数位数(使用 Amount 时自动提取)
signenumN'never'符号显示模式
colorenumN'default'颜色模式
sizeenumN'md'尺寸
weightenumN'normal'字重
loadingbooleanNfalse是否加载中
animatedbooleanNtrue是否启用动画
hiddenbooleanNfalse隐私模式(显示 ••••••)
compactbooleanNfalse紧凑模式(1K, 1M)
monobooleanNtrue是否等宽字体

sign 符号模式

说明示例
always始终显示 +/-+100, -50
negative仅负数显示 -100, -50
never不显示符号100, 50

color 颜色模式

说明
default默认颜色
auto正数绿色,负数红色
positive强制绿色
negative强制红色

weight 字重

说明
normal正常字重
medium中等
semibold半粗
bold粗体

格式化规则

小数位处理

输入: 1000000000 (decimals: 8)
输出: 10.00000000

输入: 123456789 (decimals: 8)
输出: 1.23456789

输入: 1234567890123456789n (decimals: 18)
输出: 1.234567890123456789

displayDecimals 显示精度

value: 1.23456789
displayDecimals: 4
输出: 1.2346 (四舍五入)

displayDecimals: auto
小数 < 0.0001 → 显示全部有效数字
其他 → 最多显示 8 位

千分位分隔

1234567.89 → 1,234,567.89

极端值处理

value: 0
输出: 0 SYMBOL

value: 0.000000001 (极小值)
输出: < 0.00000001 SYMBOL

value: 999999999999 (极大值)
输出: 999.99B SYMBOL (使用 K/M/B 后缀)

行为规范

必须 (MUST)

  1. 使用千分位分隔符
  2. 金额使用等宽数字字体(font-mono
  3. 正确处理 bigint 类型
  4. 可访问性: 必须提供 aria-label 供屏幕阅读器读取
  5. 加载状态: 显示 "0" 配合呼吸动画(animate-pulse),不使用色块骨架屏

建议 (SHOULD)

  1. 金额右对齐
  2. 符号跟随金额,不换行
  3. 使用 @number-flow/react 实现数字动画
  4. 数值变化时平滑过渡,而非直接跳变

可选 (MAY)

  1. 支持点击复制原始值
  2. 支持显示法币估值

动画规范

数字动画

使用 @number-flow/react 库实现专业的数字动画:

tsx
import NumberFlow from '@number-flow/react'

<NumberFlow
  value={10015.12345678}
  format={{
    minimumFractionDigits: 0,
    maximumFractionDigits: 8,
  }}
  locales="en-US"
/>

加载状态动画

加载时显示 "0" 配合呼吸动画,数据到达后 NumberFlow 会自动从 0 平滑过渡到真实值:

tsx
// 加载中
<span className="animate-pulse">
  <NumberFlow value={0} aria-hidden="true" />
</span>

// 数据到达后
<NumberFlow value={10015.12345678} aria-hidden="true" />
// NumberFlow 会自动动画过渡 0 → 10015.12345678

可访问性规范

屏幕阅读器支持

由于 NumberFlow 使用 SVG 渲染数字,需要正确处理可访问性:

tsx
// ✅ 正确:外层提供 aria-label,内层 aria-hidden
<span role="text" aria-label="10,015.12345678 BFM">
  <NumberFlow value={10015.12345678} aria-hidden="true" />
  <span aria-hidden="true">BFM</span>
</span>

// ❌ 错误:屏幕阅读器会读成 "image: 10015.12345678"
<NumberFlow value={10015.12345678} />

加载状态可访问性

tsx
<span role="status" aria-label="Loading...">
  <NumberFlow value={0} aria-hidden="true" />
</span>

布局规范

标准布局

1,234.5678 BFM

带符号

+1,234.5678 BFM  (绿色)
-1,234.5678 BFM  (红色)

带估值

1,234.5678 BFM
≈ ¥ 1,234.56

设计标注

尺寸金额字号符号字号
sm14px12px
md16px14px
lg24px18px
xl32px24px

颜色

状态颜色
默认--color-foreground
正数--color-success (#22c55e)
负数--color-destructive (#ef4444)

Released under the MIT License.