MeterGroup 占比条

以一条分段的横条表示各部分占总量的比例。

存储空间90%
文档42%图片27%视频13%其他8%
import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '文档', value: 42 },
  { label: '图片', value: 27 },
  { label: '视频', value: 13 },
  { label: '其他', value: 8 },
]

export default function Demo() {
  return <MeterGroup label="存储空间" items={items} className="w-96" />
}
tsx

用法

import { MeterGroup } from '@hina-ui/react'
ts

items 中每一项有 label 与 value,可以指定 tone;max 是总量,默认为 100。各段按各自的比例并排在同一条轨道上,下方的图例列出每段的标签与数值。

已读56%在读19%
import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '已读', value: 56 },
  { label: '在读', value: 19 },
]

export default function Demo() {
  return <MeterGroup items={items} className="w-96" />
}
tsx

示例

标题与总量

label 显示在轨道上方,同一行的末尾显示各段之和。

今年的书87%
已读56%在读19%想读12%
import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '已读', value: 56 },
  { label: '在读', value: 19 },
  { label: '想读', value: 12 },
]

export default function Demo() {
  return <MeterGroup label="今年的书" items={items} className="w-96" />
}
tsx

数值变化

多段的值同时变化时,各段的宽度各自平滑过渡到新的比例,图例中的数值同步更新。

存储空间90%
文档42%图片27%视频13%其他8%
'use client'

import { useState } from 'react'
import { Button, MeterGroup, Stack, type MeterItem } from '@hina-ui/react'

const labels = ['文档', '图片', '视频', '其他']
const sets = [
  [42, 27, 13, 8],
  [12, 36, 31, 6],
  [25, 8, 48, 14],
]

export default function Demo() {
  const [index, setIndex] = useState(0)

  const items: MeterItem[] = labels.map((label, i) => ({ label, value: sets[index]![i]! }))

  return (
    <Stack gap="md" align="start" className="w-96">
      <MeterGroup label="存储空间" items={items} className="w-full" />
      <Button
        size="sm"
        variant="soft"
        tone="neutral"
        onClick={() => setIndex((index + 1) % sets.length)}
      >
        换一组数据
      </Button>
    </Stack>
  )
}
tsx

色调

未指定 tone 的段按强调色、信息色、成功色、警告色、危险色、中性色的顺序分配,也可以逐段指定。

审核结果92%
通过62%待定21%退回9%
import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '通过', value: 62, tone: 'success' },
  { label: '待定', value: 21, tone: 'warning' },
  { label: '退回', value: 9, tone: 'danger' },
]

export default function Demo() {
  return <MeterGroup label="审核结果" items={items} className="w-96" />
}
tsx

数值格式

format 接收每段的值与总量,返回要显示的文字。这段文字同时作为辅助技术朗读的数值。

存储空间108 GB
文档38 GB图片24 GB视频46 GB
'use client'

import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '文档', value: 38 },
  { label: '图片', value: 24 },
  { label: '视频', value: 46 },
]

const format = (value: number) => `${value} GB`

export default function Demo() {
  return <MeterGroup label="存储空间" items={items} max={256} format={format} className="w-96" />
}
tsx

尺寸

三档高度与 Progress 相同,md 是默认值。

import { MeterGroup, Stack, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '已读', value: 56 },
  { label: '在读', value: 19 },
]

export default function Demo() {
  return (
    <Stack gap="lg" className="w-96">
      <MeterGroup items={items} size="sm" legend={false} />
      <MeterGroup items={items} legend={false} />
      <MeterGroup items={items} size="lg" legend={false} />
    </Stack>
  )
}
tsx

不显示图例

legend 设为 false 时只保留轨道。

存储空间82%
import { MeterGroup, type MeterItem } from '@hina-ui/react'

const items: MeterItem[] = [
  { label: '文档', value: 42 },
  { label: '图片', value: 27 },
  { label: '视频', value: 13 },
]

export default function Demo() {
  return <MeterGroup label="存储空间" items={items} legend={false} className="w-96" />
}
tsx

行为

  • 各段的宽度随值平滑过渡,时长与曲线取自动效变量。
  • 越界的值按端点处理:小于 0 视为 0,大于 max 视为 max。
  • 各段之和超过 max 时,超出的部分被轨道裁掉,每段的数值与宽度仍然对应。

无障碍

  • 每段带 role="meter",名称取该段的 label,aria-valuenow、aria-valuemin 与 aria-valuemax 随值与 max 给出。
  • 轨道整体带 role="group",名称取 label。
  • 传入 format 时其结果同时写入每段的 aria-valuetext。
  • 图例中的圆点对辅助技术隐藏,标签与数值以文字呈现。

API

Props

属性
类型
默认值
说明
items
MeterItem[]
—
必填。各段
max
number
100
总量
label
string
—
轨道上方的标题
legend
boolean
true
是否显示图例
format
(value: number, max: number) => string
百分比
数值文字的格式
size
'sm' | 'md' | 'lg'
'md'
高度
className
string
—
追加至根元素的类名

其余属性透传到带 role="group" 的轨道元素上。

类型

字段
类型
说明
label
string
必填。该段的标签
value
number
必填。该段的值
tone
'accent' | 'neutral' | 'success' | 'warning' | 'danger' | 'info'
该段的颜色,默认按序