跳到主要内容
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
开始使用WebReactSwiftUIJetpack ComposeFlutterReact Native预设你自己的设计系统与 AI 代理一起使用 Tanrei品牌设计令牌设计系统与定制Theme Studio颜色字体排印图标形状层级动效交互状态行为布局无障碍文字颜色令牌字阶令牌形状令牌层级令牌动效令牌状态令牌间距与度量令牌组件按钮主操作按钮分段按钮按钮组带菜单的按钮工具栏复制按钮复选框单选按钮开关纸片(Chip)菜单滑块滑块字段日历DateTimePicker字段组单选组复选框组下拉选择框下拉选择字段菜单栏文件上传文件选择器 进阶放置区文本输入框 进阶文本字段纸片字段字段组合框 进阶组合框字段数字输入框 进阶数字字段颜色输入框 进阶颜色字段一次性验证码输入框 进阶一次性验证码字段嵌入式文本输入框 进阶聊天输入栏卡片分隔线模态层 进阶对话框列表列表行底部面板侧边面板轮播代码块表格弹出框步骤折叠面板描述列表图示应用外壳页头树视图时间线图片预览调整手柄可调整大小的框滚动区域徽标进度指示器计量条数字滚动器加载指示器消息条(Snackbar)工具提示键盘快捷键标签(Tag)行内代码提示块(Callout)头像空状态标签组(Tag group)骨架屏文件项色块跑马灯文本标签页标签页视图应用栏导航栏导航抽屉搜索链接分页上一页/下一页链接步骤条面包屑目录链接卡片FAB 菜单状态Tanrei 是如何构建的参与贡献许可与致谢
首页组件计量条

计量条

以条形或圆环显示一个已知的值在已知范围中的位置,例如已用存储空间、电池电量、配额用量或密码强度。外观与进度指示器相同,但不表示有任何事情正在进行。

content_copy以 Markdown 格式查看
类别
信息传达
令牌
comp.meter
层级
基础

概览

Web
tanrei-meter
clock_loader_40
SwiftUI
TanreiMeter
radio_button_unchecked
Jetpack Compose
TanreiMeter
radio_button_unchecked
Flutter
TanreiMeter
radio_button_unchecked
React Native
Meter
radio_button_unchecked

生成自 docs/status/status.json, specs/meter.spec.json

线性和环形

用法

Web 和 React 的示例展示的是当前的规格。SwiftUI、Compose、Flutter 和 React Native 尚在计划中:它们还没有提供计量条。

<tanrei-meter value="0.62" label="已用存储空间" value-text="已用 9.3 GB,共 15 GB"></tanrei-meter>
<tanrei-meter value="37" max="50" label="已占座位" value-text="已占 37 个,共 50 个座位"></tanrei-meter>

<!-- 值意味着什么由产品决定,并且也要用文字说出来。 -->
<tanrei-meter value="0.85" status="warning" label="已用存储空间" value-text="即将用满:已用 12.8 GB,共 15 GB"></tanrei-meter>

<tanrei-meter variant="circular" size="small" value="0.62" label="电池"></tanrei-meter>

<script type="module">
  import '@tanrei/web/components/meter';
  const meter = document.querySelector('tanrei-meter');
  meter.value = used / quota;
  meter.status = used / quota > 0.8 ? 'warning' : 'default';
</script>
import { Meter } from '@tanrei/react';

<Meter value={used / quota} label="已用存储空间" valueText={`已用 ${usedText},共 ${quotaText}`} />
<Meter value={seats} max={50} label="已占座位" valueText={`已占 ${seats} 个,共 50 个座位`} />
<Meter
  value={used / quota}
  status={used / quota > 0.8 ? 'warning' : 'default'}
  label="已用存储空间"
  valueText={used / quota > 0.8 ? `即将用满:已用 ${usedText},共 ${quotaText}` : `已用 ${usedText},共 ${quotaText}`}
/>
<Meter variant="circular" size="small" value={charge} label="电池" />

规格

语义状态:default、info、success、warning、error

各种尺寸、范围的两端,以及自定义范围

分隔方式:divider(默认系统的选择)和 gap

构成

构成

绘制在 Web 包所绘的测试样例 linear 之上。
部件 说明
1 track The full length of the bar, or the full circle of the ring: the whole range from min to max.
2 indicator The part of the track drawn in the indicator color of the meter's status: the fraction of the range up to the value. It meets the rest of the track, or stands a gap from it (separation).
3 stop-indicator · 可选 A dot at the end of a bar's track that marks where the range ends, drawn whenever its size is above 0.

属性

属性 类型 默认值 说明
variant linear | circular "linear" Linear is a bar that fills the width its layout gives it; circular is a ring of a fixed size, for tight places and beside text. A structural choice drawn by code, not a token axis, as the progress indicator's is.
size small | medium | large "medium" The bar's thickness or the ring's box, the progress indicator's three sizes by default (2 / 4 / 8 and 16 / 24 / 40). A design system may add values.
separation auto | divider | gap "auto" How the indicator is told from the rest of its track. divider: drawn on the track with no space between them. gap: empty space between them. Auto takes comp.meter.track.separation, which follows the design system's choice.
value number 0 Where the measured quantity stands, between min and max. Always a number: a meter has no unknown value, and a task under way is a progress indicator.
min number 0 The low end of the range.
max number 1 The high end of the range.
status default | info | success | warning | error "default" What the product says the value means, in the names the tag and the snackbar use: default draws the indicator in the meter's own color; info, success, warning and error in that status's color. The product decides it — the meter has no thresholds of its own — and it changes colors only: the words that say so are valueText's and the product's.
label string "" The accessible name: what is measured ("Storage used"). Required: a bar alone is not a name.
valueText string "" How assistive technology reads the value when a percentage is not the natural reading ("12.4 GB of 15 GB", "Strong"). Empty reads the platform's percentage. Where status means something, say it here too ("Almost full: 14.2 GB of 15 GB").

状态

行为

以 EARS 形式写成的需求。每个平台的实现都按这些 ID 逐条测试。需求原文取自规格文件,原样以英文呈现。

ID 需求
MTR-1 THE meter SHALL draw the indicator over the fraction (value − min) / (max − min) of the track, from the track's start: the inline-start of a bar, the top of a ring, turning clockwise.
MTR-2 THE meter SHALL draw a bar comp.meter.linear.thickness.medium high for medium (and so on for each size) across the full inline size its layout gives it, and a ring whose outer edge fills a comp.meter.circular.size.medium square with a stroke of comp.meter.circular.thickness.medium for medium (and so on for each size).
MTR-3 THE meter SHALL draw the track in comp.meter.track.color and the indicator over it in the indicator color of its status — comp.meter.indicator.color WHILE status is default, comp.meter.info.indicator.color WHILE it is info, comp.meter.success.indicator.color WHILE it is success, comp.meter.warning.indicator.color WHILE it is warning and comp.meter.error.indicator.color WHILE it is error; the ends of a bar's track and indicator SHALL be rounded by comp.meter.track.shape, clamped to half the thickness, and a ring's arcs SHALL have round caps unless comp.meter.track.shape is sys.shape.corner.none.
MTR-4 THE meter SHALL tell the indicator from the rest of its track as its separation names — WHILE separation is auto, as comp.meter.track.separation names; WHILE it is divider or gap, as that value names — and WHILE the separation is gap and value lies strictly between min and max SHALL leave comp.meter.track.gap of empty space, measured along the track, between the indicator and the rest of the track (on a ring, at both ends of the indicator's arc); WHILE it is divider THE meter SHALL draw the indicator on the track with nothing between them.
MTR-5 WHILE comp.meter.stop-indicator.size is above 0 THE meter SHALL draw at the end of a bar's track a round dot of that size, centred across the track, in the indicator color of its status; a ring SHALL draw none.
MTR-6 WHEN value, min, max or status changes after the first frame THE meter SHALL move the indicator's end to the new fraction over comp.meter.motion.value-duration with comp.meter.motion.value-easing, and change the indicator's color over the same duration; WHEN it changes again during that motion THE meter SHALL go on from the place and the color then shown. THE meter SHALL draw its first frame at its value and in its status's color without a motion, and WHERE reduced motion is requested SHALL move the end at once and keep the change of color as a fade over the same duration.
MTR-7 THE meter SHALL expose to assistive technology a meter — the platform's own meter where it has one, and otherwise an element with a value range and no busy state — named by label, with min and max as its range, the clamped value as its current value, and valueText as the value's text WHILE valueText is not empty; it SHALL NOT expose the progressbar role or a busy state, because nothing is under way.
MTR-8 THE meter SHALL NOT be focusable, SHALL take no input and SHALL NOT announce a change of its value or its status by itself; assistive technology SHALL read the current value when it reaches the meter.
MTR-9 THE meter SHALL expose nothing of status by itself: status SHALL change the indicator's color and nothing else, so that what the color means reaches every person only through the words the product gives in valueText, label or the text beside the meter.
MTR-10 IF value is below min or above max THE meter SHALL draw and expose it clamped to that range; IF value is not a finite number THE meter SHALL draw and expose min; IF max is not greater than min THE meter SHALL draw the track with no indicator and expose a current value of 0 in a range of 0 to 1; in each case debug builds SHALL report the values.
MTR-11 WHEN size names a value that the active design system does not have, or variant, separation or status a value the meter does not define, THE meter SHALL render with the default value's tokens (medium, linear, auto, default), and in debug builds report the unknown value.
MTR-12 WHERE the layout direction is right-to-left THE meter SHALL fill a bar from the right and draw its stop indicator at the left; a ring SHALL NOT be mirrored: it starts at the top and turns clockwise in every direction, as a clock does.
MTR-13 THE meter SHALL take its layout direction from where it is used and SHALL have no direction setting of its own; WHEN that direction changes while the meter is shown THE meter SHALL draw itself for the new direction at once, without a motion of its own, keeping its value.
MTR-14 WHILE label is empty THE meter SHALL still render, and in debug builds report that it has no accessible name.
MTR-15 WHERE the platform draws with a person's own forced colors THE meter SHALL draw its track as an edge sys.border.hairline wide in the platform's text color and its indicator filled in the platform's text color, whatever its status, so that the value is still read from where the indicator ends.
MTR-16 WHERE the platform has ARIA attributes (the web), the host carries its meter role (MTR-7) itself, so what the product writes on it is not moved, but for a name: WHILE label is not empty THE meter SHALL hold the product's aria-label and aria-labelledby on that host as their data-aria- twins, so that label is its whole name although the platform gives aria-labelledby the precedence, and WHEN label is emptied SHALL give them back as they were written; WHILE label is empty a name the product gives so — aria-label, or aria-labelledby naming an element — SHALL be its name and SHALL NOT be reported as having none in debug builds (MTR-14). WHEN the product removes one, or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaLabelledByElements) to null, THE meter SHALL take it away.

各平台名称对照

对等并不意味着 API 完全相同。同一份契约,由各平台以自己的惯用方式表达。

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-meter TanreiMeter TanreiMeter TanreiMeter Meter
variant · 属性 variant variant variant variant variant
size · 属性 size size size size size
separation · 属性 separation separation separation separation separation
value · 属性 value value value value value
min · 属性 min bounds.lowerBound valueRange.start min min
max · 属性 max bounds.upperBound valueRange.endInclusive max max
status · 属性 status status status status status
label · 属性 label label label label label
valueText · 属性 valueText valueText valueText valueText valueText
备注 Drawn as the progress indicator is (the two share the drawing code; the meter never runs the indeterminate animation). The host carries role="meter", aria-valuemin, aria-valuemax, aria-valuenow, aria-label and aria-valuetext while value-text is set. separation and status are attributes; auto reads the name in --tanrei-comp-meter-track-separation. TanreiMeter("Storage used", value: 9.3, in: 0...15). Exposed as SwiftUI exposes a Gauge: an element with the label and an accessibility value, accessibilityValue(valueText) while it is set; no updates-frequently trait. Semantics progressBarRangeInfo with the range (Android has no separate meter role) and stateDescription from valueText; never the indeterminate range info. Semantics(label:, value:) with the value text or the percentage; on the web renderer the role is meter. accessibilityRole="progressbar" is not used; the view carries accessibilityValue={{ min, max, now, text }} with role="meter" where React Native passes it through (web), and the label.

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-meter-circular-size-large comp.progress-indicator.circular.size.large 40px
--tanrei-comp-meter-circular-size-medium comp.progress-indicator.circular.size.medium 24px
--tanrei-comp-meter-circular-size-small comp.progress-indicator.circular.size.small 16px
--tanrei-comp-meter-circular-thickness-large comp.progress-indicator.circular.thickness.large 2px
--tanrei-comp-meter-circular-thickness-medium comp.progress-indicator.circular.thickness.medium 2px
--tanrei-comp-meter-circular-thickness-small comp.progress-indicator.circular.thickness.small 2px
--tanrei-comp-meter-error-indicator-color sys.color.error #cd262f
--tanrei-comp-meter-indicator-color comp.progress-indicator.indicator.color #1b1b1b
--tanrei-comp-meter-info-indicator-color sys.color.info #3066cb
--tanrei-comp-meter-linear-thickness-large comp.progress-indicator.linear.thickness.large 8px
--tanrei-comp-meter-linear-thickness-medium comp.progress-indicator.linear.thickness.medium 4px
--tanrei-comp-meter-linear-thickness-small comp.progress-indicator.linear.thickness.small 2px
--tanrei-comp-meter-motion-value-duration comp.progress-indicator.motion.value-duration 300ms
--tanrei-comp-meter-motion-value-easing comp.progress-indicator.motion.value-easing cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-meter-stop-indicator-size comp.progress-indicator.stop-indicator.size 0px
--tanrei-comp-meter-success-indicator-color sys.color.success #077b32
--tanrei-comp-meter-track-color comp.progress-indicator.track.color #eeeeee
--tanrei-comp-meter-track-gap comp.progress-indicator.track.gap 4px
--tanrei-comp-meter-track-separation comp.progress-indicator.track.separation 0
--tanrei-comp-meter-track-shape comp.progress-indicator.track.shape 9999px
--tanrei-comp-meter-warning-indicator-color sys.color.warning #9b5c00

测试样例

作为基准的渲染结果。所有平台都以相同的 ID 为每个样例截取快照,以便相互比较。

生成自 specs/meter.spec.json, tokens/comp/meter.tokens.json, design/tokens/

指南

何时使用

当你要显示某个量在一个有真实最小值和最大值的范围中处于什么位置时,使用计量条:配额中已用的存储空间、电池电量、房间里已占的座位、新密码的强度。它显示的是一个水平;没有任何事情正在进行,也没有任何事情会结束。

对于正在运行的任务,例如上传、导入、耗时较长的保存,请改用进度指示器。两者外观相同,但辅助技术会告诉用户某件事正在进行,而计量条绝不能这样说。没有有意义的最大值的值,例如消息数量,两者都不适用:请用文本显示。

如何选择变体

变体 用途
线性 属于某个页面或某个区域的水平:设置页上的存储空间、卡片里的配额、套餐列表中的一行。条形会占满布局分配给它的宽度。
环形 空间紧凑的地方,以及文本旁边的水平:状态栏里的电池、设备列表中的一行。圆环的尺寸是固定的。

如何选择尺寸

尺寸 默认系统中的条形粗细 / 圆环尺寸 用途
Small 2 / 16 紧凑的行、小号文本旁边。
Medium 4 / 24 大多数地方。这是默认尺寸。
Large 8 / 40 整个视图所围绕的那一个水平,例如账户的存储空间页面。

尺寸、轨道和默认颜色与进度指示器相同,因此计量条和进度指示器并排放置时也能保持一致。设计系统可以通过计量条自己的令牌,只改变计量条。

如何选择语义状态

计量条不决定一个值意味着什么。值越多越好还是越坏,是你的产品才知道的事:存储空间快满了是 warning,密码接近最高强度是 success。请自己计算语义状态并传入。语义状态的名称与标签和消息条所用的相同。

语义状态 用途
Default 不需要任何说明的水平。大多数计量条都保持这个状态。
Info 值得知道、但不要求任何操作的水平,例如即将重置的配额。
Success 处于应有位置的水平,例如强度高的密码。
Warning 很快就需要注意的水平,例如快用满的存储空间或电量低的电池。
Error 已经妨碍了某件事的水平,例如已经用满的存储空间。

语义状态只改变指示部分的颜色,不改变其他任何东西。请同时用文字说明它的含义:写在值文本里,以及计量条旁边的文字里。

建议

  • 给它一个说明测量对象的标签:“已用存储空间”,而不是“计量条”。如果旁边显示了说明文字,请使用相同的措辞。
  • 当百分比不是自然的读法时,使用值文本:“已用 9.3 GB,共 15 GB”“已占 37 个,共 50 个座位”“强”。
  • 当语义状态有含义时,也把它写进值文本:“即将用满:已用 12.8 GB,共 15 GB”。

不建议

  • 不要把它用于正在运行的任务。那是进度指示器。
  • 不要只依靠语义状态的颜色。看不到颜色的人也必须能得知存储空间快满了。
  • 不要显示范围之外的值。计量条会把它限制在范围内再绘制和公开,用户听到的数字就不是你手上的那个数字了。

无障碍

角色
meter
标注
label is the accessible name. valueText, when given, replaces the platform's percentage as the spoken value. A visible caption beside the meter is the product's composition; when it exists, use the same words as label. status is never announced: say in valueText what it means.
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作

备注

  • Not interactive: the meter takes no input and is never focusable (MTR-8), so the minimum target holds without extending anything.
  • A meter shows where a value stands in a known range; it is not progress (WAI-ARIA APG, Meter: not for loading or percent completion) and not for a value without a meaningful maximum. A task under way is a progress indicator.
  • The value is read from the boundary between indicator and track, so every indicator color — default and the four statuses — must stay at least 3:1 against comp.meter.track.color and the surface behind it (WCAG 1.4.11). In the default system each is above 4.6:1 in light and 7.3:1 in dark.
  • Color is never the only sign of a status (WCAG 1.4.1): MTR-9.
  • Web: the host carries role="meter" and the aria-value attributes; the native <meter> element is not drawn, because its look cannot be styled in every engine.

生成自 specs/meter.spec.json, tokens/sys/measure.tokens.json

组件负责的部分

  • 它公开计量条(meter)角色,以标签作为名称,并公开范围、当前值(限制在范围内)以及值文本(如果有)。它从不表示自己处于忙碌状态,也不表示有任务正在进行。
  • 它永远不可获得焦点,也不会主动播报自己的变化。辅助技术会在用户到达它时读出当前值。
  • 语义状态从不被单独播报:它只改变颜色。
  • 值变化时,指示部分的末端会移动;语义状态变化时,颜色会渐变。在请求减弱动态效果时,末端立即移动,只有颜色渐变。
  • 在强制颜色模式下,无论语义状态如何,轨道都变成一条细的边线,指示部分则被填充,两者都使用文本颜色绘制,因此仍可以从指示部分结束的位置读出值。
  • 空标签、范围之外的值、不是数字的值,以及未知的 size、variant、separation 或 status,都会在调试构建中报告。

你需要做的

  • 用文字说明语义状态的含义:写在值文本里,以及计量条旁边的文字里。
  • 重要的变化(例如存储空间已满)要由你自己告知:用实时区域中的消息,或用户会看到的通知。计量条不会说出来。
  • 如果你更改了指示部分的颜色(默认颜色和四种语义状态),请让每一种颜色相对于轨道和其背后的表面都至少保持 3:1。值是从指示部分与轨道相接的位置读出的。默认系统中,这五种颜色在浅色下都高于 4.6:1,在深色下都高于 7.3:1。