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

颜色输入框

用户在里面设置一种颜色的那个方框——颜色的样本、可以阅读、键入和粘贴的文本值,以及一个用来请求选择器的按钮——它自己没有标签行、帮助文本和错误文本。用于已经为这种颜色命名的行或列,或者放进产品自己组合的字段里。

content_copy以 Markdown 格式查看

进阶

大多数产品直接使用包含此组件的Color field。

类别
文本输入
令牌
comp.color-input
层级
基础

概览

Web
tanrei-color-input
schedule
SwiftUI
TanreiColorInput
radio_button_unchecked
Jetpack Compose
TanreiColorInput
radio_button_unchecked
Flutter
TanreiColorInput
radio_button_unchecked
React Native
ColorInput
radio_button_unchecked
不提供的变体
tanrei: filled, outlined

生成自 docs/status/status.json, specs/color-input.spec.json

单独使用:一列色调中的各行,每个输入框由它所在的行命名

色调 40色调 80

颜色输入框就是颜色字段里的那个方框,单独拿出来:容器、色块、以文本形式呈现的值,以及选择器按钮。它上方没有标签行,下方没有帮助文本和错误文本。

用户读到的标签位于别处时,就单独使用它:

位置 用户读到的标签 输入框的 label
一列颜色或调色板各个色调中的一行 这一行自己的文本 列表和行:“主色,色调 40”
表格的单元格 列标题 列和行:“背景,深色主题”
工具栏 旁边的文本或字形 这种颜色的用途:“高亮颜色”

单独使用时,输入框需要它自己的 label。它就是无障碍名称。stacked 的输入框绝不会把它画出来;filled 或 outlined 的输入框把它画成浮在方框里的标签。

它是一个高级组件:一个不带任何附加功能的控件,供自己动手组合的产品使用。大多数表单需要的是颜色字段,也就是放在字段里的这个输入框,可以直接使用。

使用它的组件是颜色字段。要自己用字段框住它,就把它放进字段,由字段为它命名、描述它、把它标记为必填,并让它进入错误状态。

它是一个块,宽度与所在的位置相同,单独使用和放在字段里都是如此。它没有自己的宽度:想要窄一些的方框,就给它一个窄一些的位置。

在 Web 上它是 <tanrei-color-input>。其他平台尚未实现。

用法

value 是一个井号加六位小写的十六进制数字(#0f766e),或者用空字符串表示没有颜色。它绝不会是只键入了一半的文本:输入框里的内容不是颜色时,value 为空。

<!-- 调色板各个色调中的一行:这一行为色调命名,并给输入框宽度。 -->
<div class="tone-row">
  <span>色调 40</span>
  <tanrei-color-input name="primary-40" label="主色,色调 40" value="#0f766e"
    picker picker-label="选择“主色,色调 40”的颜色"></tanrei-color-input>
</div>

<script type="module">
  import '@tanrei/web/components/color-input';

  const tone = document.querySelector('[name="primary-40"]');
  // 值变了:一种颜色,或者空字符串。它已经是新的值。
  tone.addEventListener('input', () => preview(tone.value));
  // 用户确认了一个有变化的值:焦点离开、按下 Enter,或者选择器关闭。
  tone.addEventListener('change', () => save(tone.value));
  // 确认了一段不是颜色的文本。输入框保留这段文本,并画成错误状态。
  tone.addEventListener('entryerror', (e) => console.log(e.detail.text, e.detail.message));
</script>
// 进阶组件(用于构成其他组件的部件)从 advanced 入口导入。
import { ColorInput } from '@tanrei/react/advanced';

<ColorInput label="主色,色调 40" value={tone} picker pickerLabel="选择“主色,色调 40”的颜色"
  onChange={(event) => setTone(event.currentTarget.value)} />

手写在字段里

用字段包住一个颜色输入框,就是把颜色字段拆开来写。输入框自己的 label 留空:由字段为它命名。label、error、disabled 和必填设置写在字段上;name、value、invalidText 和选择器写在输入框上。

<tanrei-field label="品牌色" required required-text="必填"
  supporting-text="六位十六进制数字,例如 #0f766e。">
  <tanrei-color-input name="brand" value="#0f766e"
    invalid-text="请输入六位十六进制数字,例如 #0f766e。"
    picker picker-label="选择颜色"></tanrei-color-input>
</tanrei-field>

里面放着一个颜色输入框的字段:画面与颜色字段相同

只有输入框知道的事,由它告诉所在的字段。字段的帮助文本从值的文本开始的位置开始,也就是色块之后。filled 或 outlined 的输入框自己画出字段的标签,让它浮在方框里,所以字段不绘制标签行。确认的文本不是颜色时,字段会进入错误状态,显示输入框的 invalidText。

规格

单独使用的输入框:空的、白色、黑色、错误、禁用,以及带选择器按钮的大号

单独使用的 filled 和 outlined:输入框自己的标签浮在方框里

以 m3-like 显示

哪些属于输入框,哪些属于字段

方面 颜色输入框 包着它的字段
绘制 方框、色块、以文本形式呈现的值、选择器按钮,以及浮在 filled 或 outlined 方框里的标签 stacked 输入框上方的标签行、必填或选填标记、帮助文本、错误文本
保存 值、它在表单中的位置、事件、它呈现的选择器 什么都不保存
告诉辅助技术 以文本形式呈现的值;选择器按钮,作为一个单独的按钮 名称、帮助文本或错误文本、必填、无效、禁用

方框本身在单独使用、放在字段里和用在颜色字段里时都一样,只在颜色字段的页面上写一次:方框的各个部件、值和文本,以及选择器。

三种变体和三种尺寸——small(32)、medium(40)和 large(56)——都是文本输入框的。默认系统只提供 stacked。色块位于文本输入框放前置图标的位置,大小也与那个图标相同,所以颜色输入框放在带前置图标的文本输入框下方时,两者的起始边是对齐的。

单独使用,没有字段

  • 名称是 label。labelHidden 让 filled 或 outlined 的输入框不把它画出来。
  • 错误是 error,由你来设置:方框画成错误状态,并暴露为无效。输入框没有错误文本。请在它旁边用文字说明哪里不对,或者用字段框住它。
  • 确认的文本不是颜色时,方框画成错误状态,并触发 entryError。invalidText 会加进输入框的描述;没有任何东西把它画出来。
  • 必填要由字段来说明。单独使用的输入框没有必填设置:表单需要回答的地方,请自己校验。

构成

部件 说明
1 container The input's box: it holds the swatch, the input and the picker button. It measures and is drawn as the text input's container of the same variant and size, carries the hover state layer and shows focus by its edge.
2 outline · 可选 The border of an outlined color input, which opens a gap where the floated label crosses it; in a stacked color input, the line drawn inside the container's edge while it is focused or in error, which takes no layout space.
3 active-indicator · 可选 The line along the bottom of a filled color input; its focused state is thicker and colored.
4 label · 可选 In a filled or outlined input, its name drawn inside the box: it rests in the input line, after the swatch, while the input is empty and unfocused, and floats above the value otherwise. A stacked input draws none: the label above it is the row of the Field that frames it.
5 required-asterisk · 可选 After the floating label's text, an asterisk, where the Field that frames the input says the control is required and marks it (CLI-7). Kept from assistive technology.
6 swatch A sample of the value at the start of the container, where a text input's leading icon stands: a small square filled with exactly the value's color, with the one hairline inside its edge so that a color close to the box's own still shows where it ends. Empty, it is that edge alone. It is not a control, nothing opens from it, and it is hidden from assistive technology: the value's text says the color.
7 input The value as text, typed, pasted and read: a number sign and six hexadecimal digits. The platform's native text element.
8 picker-button · 可选 An icon-only Button of the text variant at the end of the container, showing the palette glyph: it asks for a picker. It is a Button with Button's own tokens, named by pickerLabel.
9 caret The text cursor of the input.

属性

属性 类型 默认值 说明
variant stacked | filled | outlined "stacked" The text input's three looks, so that a color input is drawn as the text inputs beside it. Stacked is a filled box that shows focus and error with a line inside its edge and draws no label: the label of the Field that frames it stands above it. Filled and outlined float the label inside the box. Use one style per form. A design system may leave some out (the Tanrei system ships stacked only) or add values.
size small | medium | large "medium" Minimum height of the container: stacked 32 / 40 / 56, as tall as a Button of the same size, so that the box and a Button side by side in one row stand as tall as each other; filled and outlined 40 / 48 / 56, which hold the label that floats inside them. These are the text input's three sizes, small for a bar, a toolbar or a dense row of controls. The hit area always meets the minimum target. A design system may add values.
value string "" The color the input holds: a number sign and six hexadecimal digits in lowercase ("#0f766e"), an opaque sRGB color; or empty for no color. It is never a half-typed text: while the input holds something that is not a color, value is empty.
label string "" Names the input for assistive technology where no Field frames it; a filled or outlined input also draws it, as the label that floats in its box. Inside a Field leave it empty: the Field's label names the input, and is what floats.
labelHidden boolean false Does not draw the floating label of a filled or outlined input, which stays the accessible name. Inside a Field, hide the label on the Field. A stacked input draws no label, so this changes nothing there.
error boolean false Draws the input in its error condition and exposes it as invalid. A Field sets it from its own error; set it here only where no Field frames the input. What a color means is the product's to validate (too light for its background, already taken); the input never sets this itself, and enters an error of its own only for a committed text that is not a color (CLI-20).
disabled boolean false Prevents focus, editing, the picker button and form submission. Inside a Field, disable the Field, so that its label follows.
invalidText string "" The words for an input committed with a text that is not a color ("Enter six hexadecimal digits, like #0f766e"), in the product's language: given to the Field that frames the input, which shows them as its error text (CLI-20). While it is empty that Field shows its own errorText.
picker boolean false Shows the picker button. Activated, it emits pickerRequest, and where the platform has a color picker of its own the input presents that picker unless the product cancelled the request. The input draws no picker surface itself.
pickerLabel string "" The accessible name of the picker button ("Choose color"). Required while picker is shown.

事件

事件 说明
input The person changed the value — by an edit of the text that made it a color, another color or no color, or by a pick in the platform's picker; carries the new value. Not emitted when the product sets value, nor for an edit that leaves value as it was.
change The person committed a changed value: focus left the input, the action key was pressed, or the platform's picker closed; carries the value.
pickerRequest The person activated the picker button; carries the value. Cancelling it keeps the input from presenting the platform's picker: the product then presents its own surface and sets value to what was picked.
entryError The person committed a text that is not empty and is not a color; carries the text as typed and invalidText, the words the input has for it (empty where the product gave none: the Field that frames the input then shows its own errorText).

状态

行为

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

ID 需求
CLI-1 THE color input SHALL draw its container at least comp.input-box.stacked.container.height.medium tall WHILE variant is stacked (or a variant a design system adds, which is drawn as a stacked box) and at least comp.input-box.container.height.medium tall WHILE variant is filled or outlined, for size medium (and so on for each size), with a stacked or outlined color input's four corners and a filled color input's top corners rounded by comp.input-box.container.shape, a filled color input's bottom corners by comp.input-box.container.shape-bottom, all eased by sys.shape.corner-smoothing, and SHALL lay out in it one row, centred vertically: the swatch (CLI-25) at the start, comp.input-box.container.padding-inline-with-icon.medium from the container's start edge; the input (CLI-17) taking the remaining width, comp.input-box.container.gap.medium after the swatch; and WHILE the picker button is shown (CLI-27) that button at the end, the input ending comp.input-box.container.gap.medium before the button's glyph. WHILE the picker button is not shown the input SHALL end comp.input-box.container.padding-inline.medium from the container's end edge. The row's tallest item SHALL have at least comp.input-box.stacked.container.padding-block.medium above and below it in a stacked box and comp.input-box.container.padding-block.medium in a filled or an outlined one (and so on for each size). THE color input SHALL be as wide as its layout gives it.
CLI-2 THE color input SHALL measure as the text input of the same variant and size measures (TXI-16): the same container height, paddings and corners, the swatch where a text input's leading icon stands and at that icon's size, the same text style and start edge for the value as the input text of a text input that has a leading icon, and the picker button where a date input's picker button stands (TXI-32), so that a color input and a text input side by side share every horizontal line and a color input below a text input shares its start edges. Framed, the two stand under the same label row and over the same supporting row without any token held equal for it, because both rows are the one Field's (FLD-1). The two are drawn from one set of tokens (CLI-45): what a layer changes of the box, it changes for both.
CLI-7 WHERE variant is filled or outlined, WHILE the floating label is drawn (CLI-15) and the Field that frames the input gives it an asterisk as its required mark (FLD-25) THE color input SHALL draw the character "*" after the label's text, comp.input-box.requirement.asterisk-gap from it, in the label's text style and at the label's place, resting and floated with it, colored by its required-asterisk part (comp.input-box.outlined.required-asterisk.color for an outlined input; its error. part WHILE the input is in error), and SHALL keep it from assistive technology, because the required state already says it (CLI-11). It SHALL draw no tag and no optional label: which mark a required control gets is the Field's to say (FLD-6), and a tag named there reaches a floating label as the asterisk, as it reaches a text input's (TXI-50). WHILE no Field frames it, or the Field gives no mark, or the label is not drawn, THE color input SHALL draw no mark.
CLI-9 WHILE error is true — set by the product, or by the Field that frames it (FLD-8) — or the entry error of CLI-20 lasts THE color input SHALL draw every part of its container, in every state, from the error parts of its variant (comp.input-box.stacked.error.outline.color and the other error. parts), so that the box itself is marked and not only a text below it, and SHALL expose its input as invalid to assistive technology; the swatch SHALL stay as it is drawn (CLI-25). THE color input SHALL never set error itself — what a color means is the product's to validate, and the one error the color input raises by itself is the entry error — and SHALL show no error text of its own: the words that say what is wrong are the errorText of the Field that frames it, which that Field draws and gives the input as its description (FLD-7, FLD-11).
CLI-11 THE color input SHALL take its name, its description and its required state from the Field that frames it, as every control a Field frames does (FLD-10, FLD-11): the Field's label is the accessible name of its input, whether or not any label is drawn, and the Field's supporting text with, in error, the error text after it is its description; it has no description of its own but the words of an entry error where nothing frames it (CLI-20). WHILE label is not empty THE color input SHALL use it as the accessible name instead, for an input no Field frames or one whose visible label is elsewhere (a table column, a row of a list of colors that names each). WHILE it has either name THE color input SHALL expose that one alone, over a name the product gives it on the element (aria-label or aria-labelledby); WHILE it has neither name and the product gives it a name of its own on the element — aria-label, or aria-labelledby naming an element — THE color input SHALL expose that name as its accessible name; IF it has none of the three it SHALL still render and work, and in debug builds SHALL report that it has no accessible name. WHILE its Field says it is required THE color input SHALL expose its input as required, whichever mark is drawn and where none is, and on the web SHALL report a missing value to the form's constraint validation WHILE value is the empty string; it has no requirement setting of its own, SHALL NOT validate because of one, and SHALL raise no entry error for an empty text (CLI-20).
CLI-13 THE color input SHALL add to the focus order its input and, WHILE the picker button is shown, that button after it, and no other stop: the swatch is not one (CLI-25). A press on the label row of the Field that frames it moves focus to its input and does nothing else — it asks for no picker and changes no value — and is that Field's (FLD-12).
CLI-15 WHERE variant is filled or outlined, WHILE the input is empty and not focused THE color input SHALL rest its label in the input line, after the swatch, in comp.input-box.label.typescale.medium for size medium (and so on), and otherwise SHALL float it as the text input of that variant floats its label (TXI-13): to the top of a filled container, above the input line, or onto an outlined container's top edge with a gap of comp.input-box.outline.notch-padding in the outline on each side of it, in comp.input-box.label.floated-typescale.medium for size medium (and so on); a filled color input that draws its label SHALL be at least twice comp.input-box.container.padding-block-with-label.medium plus one line of each of those two text styles tall (and so on for each size), so that it does not change height when the label floats. WHEN the label floats or rests THE color input SHALL move and resize it over comp.input-box.motion.label-duration with comp.input-box.motion.label-easing, and at once where motion is reduced. The label SHALL wrap rather than be cut and SHALL never be drawn over the value or the swatch. The label it floats SHALL be its accessible name (CLI-11): the label of the Field that frames it, or its own label where none does. WHILE labelHidden is true — its own, or that Field's (FLD-25) — or it has no name THE color input SHALL draw no label. WHERE variant is stacked, or a variant laid out as stacked (CLI-41), THE color input SHALL draw no label at all: the label above it is the Field's row (FLD-2).
CLI-16 THE color input SHALL hold as its value an opaque sRGB color written as a number sign and six hexadecimal digits in lowercase, two each for red, green and blue (#0f766e), or the empty string for no color. It SHALL hold no other form: no alpha, no three-digit form (a commit reads three digits as the six they stand for, CLI-19), no color name, no functional notation and no other color space. value, and what input and change carry, SHALL always be one of those two.
CLI-17 THE color input SHALL show its value as text in its input, on one line, in comp.input-box.input.typescale.medium for size medium (and so on) and the input color of its variant (comp.input-box.stacked.input.color for a stacked color input; its error. part WHILE the color input is in error), and SHALL let the person edit that text freely, as the text of a text input: it SHALL NOT refuse, replace or reformat a character while the person types, SHALL NOT limit the text's length, and SHALL leave a composition to the platform's native text element (TXI-4). WHEN the user changes the text — by typing, deleting, pasting, cutting, dictating or an input method committing text — THE color input SHALL read the whole text as CLI-18 says and set value to the color it reads, or to the empty string WHILE it reads as no color; WHEN that changes value THE color input SHALL emit input once with the new value, and an edit that leaves value as it was SHALL emit nothing.
CLI-18 THE color input SHALL read a text as a color WHEN, with the white space before and after it left out, it is exactly six hexadecimal digits in either case, with or without one number sign before them (0F766E, #0f766e); the color is those digits in lowercase after a number sign. Every other text — an empty one, fewer or more digits, any other character — SHALL read as no color. WHEN the user pastes THE color input SHALL insert the pasted text as a text input does and read the whole text by the same rule, so that a color copied with a space around it, in capitals or without its number sign is taken.
CLI-19 WHEN the input loses focus, or the user presses the keyboard's action key, THE color input SHALL commit: WHILE the text reads as a color it SHALL rewrite the text to the value's own form — the number sign added, the digits in lowercase, the white space gone — and WHILE the text, with the white space before and after it left out, is exactly three hexadecimal digits in either case, with or without one number sign before them (#fff, F0A), it SHALL read it as the color whose six digits are each of the three written twice (#ffffff, #ff00aa), as CSS reads that form, make that color value, rewrite the text to it and emit input; only a commit reads three digits, because while the person types they are on their way to six and the swatch must not show a color nobody meant (CLI-18). WHILE the text is not empty and reads as no color it SHALL leave the text as typed and raise the entry error of CLI-20; in every case, WHEN value differs from the value last committed (the value when the input gained focus, or at the last change), it SHALL emit change once with value. On the web, inside a form, the action key SHALL then request the form's submission as a native input does. The submission SHALL be requested through the form's default button (BTN-30): WHILE the form has a submit button — the platform's own or a Button of type submit — the first of them in document order SHALL be pressed, so that its click is emitted and its name and value are sent, and WHILE that button is disabled nothing SHALL be submitted; only a form with no submit button is asked directly.
CLI-20 WHEN the color input commits (CLI-19) WHILE its text is not empty and reads as no color THE color input SHALL emit entryError once with the text as typed and invalidText, the words it has for the refusal, and enter an entry error: it SHALL render and be exposed exactly as WHILE error is true (CLI-9), and SHALL report the refusal to the Field that frames it with invalidText as its words, which that Field shows in its supporting row and announces (FLD-28: the Field's errorText while invalidText is empty); WHILE no Field frames it invalidText SHALL be the input's description. The entry error SHALL end with the next edit of the text, WHEN the product sets value (CLI-21) or WHEN a pick gives a color (CLI-29), and THE color input SHALL then withdraw its report; while it lasts, on the web, the color input SHALL report badInput to the form's constraint validation. WHILE invalidText is empty THE color input SHALL still mark itself, and WHILE no Field frames it SHALL in debug builds report an entry error that has no words; framed, the Field reports a refusal it has no words for (FLD-28). THE color input SHALL raise no entry error for an empty text, whether or not its Field says it is required (CLI-11), and none before a commit: a person who is still typing is not in error.
CLI-21 WHEN the product sets value THE color input SHALL show it in its input and its swatch, end any entry error, and SHALL NOT emit input, change or entryError. WHEN the product sets a text that CLI-18 reads as a color but that is not in the value's own form (capitals, no number sign) THE color input SHALL hold and show it in the value's own form; WHEN it sets a text that is not empty and reads as no color THE color input SHALL treat it as empty and in debug builds report it. WHEN the product sets value to what value already is THE color input SHALL leave the text as the person typed it, so that a product that echoes the empty value back while a person is half-way through a color does not clear what they entered.
CLI-22 WHILE hovered or focused THE color input SHALL render its container, outline, active indicator, floating label and its asterisk, input, caret and opacity, and the widths of its outline and active indicator, from the component tokens of the highest-precedence active state, with precedence focused over hovered; unlike a button, focus gained by pointer or touch SHALL select the focused state, because a field shows where typing will go however it was focused. THE color input SHALL count as focused WHILE its input has focus, and not WHILE its picker button has it: the button shows its own focus. WHILE variant is stacked it SHALL draw no edge at rest (comp.input-box.stacked.outline.color is transparent), SHALL draw its focused outline color and width as a line inside the container's edge, following its corners, that takes no layout space, and WHILE in error SHALL draw that line at rest in comp.input-box.stacked.error.outline.color at comp.input-box.outline.width; a hovered stacked or filled color input SHALL show the state layer on its container, behind the swatch and never over it (CLI-25). WHEN its state changes THE color input SHALL animate colors and widths over the state duration of its size (comp.input-box.motion.state-duration.small, .medium or .large) with comp.input-box.motion.state-easing, and SHALL change them at once where motion is reduced. Selected text SHALL be highlighted in comp.input-box.selection.color and drawn in comp.input-box.selection.content.color in every variant and state, and the caret drawn in the caret color of its variant (comp.input-box.stacked.caret.color for a stacked color input; its error. part WHILE the color input is in error). The rows around it take their focused colors from the Field that frames it (FLD-13).
CLI-23 THE color input SHALL show the focus of its input by its focused tokens — the focused outline or active indicator is its focus indicator — and SHALL NOT draw the focus ring around its container; WHERE sys.behavior.focus-style is glow it SHALL also draw the glow around the container while focused.
CLI-24 WHERE the container is shorter than the minimum target THE color input SHALL extend its hit area vertically to sys.target.touch for touch input and sys.target.pointer for fine pointers, without changing its visual size; a platform that cannot tell the input type SHALL use sys.target.touch. WHEN the user presses anywhere on the color input outside its picker button — the container's padding, the swatch WHILE picker is false, a floating label — THE color input SHALL focus the input (WHILE picker is true a press on the swatch is the picker button's, CLI-25); it SHALL draw no press answer, because a press on a field is not an action. A press on the label row of the Field that frames it focuses the input too, and is that Field's (FLD-12).
CLI-25 THE color input SHALL draw its swatch as a square of side comp.input-box.icon.size.medium for size medium (and so on), its corners comp.color-input.swatch.shape, never more than half its side, eased by sys.shape.corner-smoothing. WHILE value is a color the swatch SHALL be filled with exactly that color, in sRGB, and edged inside its size by a line comp.color-input.swatch.outline.width wide in comp.color-input.swatch.outline.color, drawn over the fill, so that a color close to the container's — white in a light field — still shows where it ends. WHILE value is empty — no text, or a text that reads as no color — the swatch SHALL have no fill, the container showing through it, and the same edge, which is then all it draws. THE color input SHALL mix nothing into the swatch's fill: no state layer, no tint of a state or of the error condition, no opacity WHILE the color input is enabled, and no elevation. The swatch SHALL NOT be a control: it takes no focus and has no hover, focus or press answer. WHILE picker is false a press on it focuses the input (CLI-24). WHILE picker is true, WHEN the user presses the swatch with a pointer or by touch THE color input SHALL do what a press on the picker button does (CLI-28) and move no focus to the input, as a label passes a press to its control: the swatch is where the platform's own color input opens its picker, and a person reaches for it there; the keyboard's way, and the one focus stop for it, stays the picker button, so the swatch adds no stop and draws no answer; and THE color input SHALL keep it from assistive technology, because the value's text says the color and a sample alone says it to no one who cannot see it or tell it from another.
CLI-26 WHEN value changes — by an edit of the text, by a pick or because the product set it — THE color input SHALL draw the swatch in the new value at once, without a motion, so that the sample and the text never disagree.
CLI-27 WHILE picker is true THE color input SHALL draw a picker button at the end of its container: an icon-only Button of the text variant and of the Button size with the field's size name (Button's default size for a field size Button does not have), showing the palette glyph of the system's icon set, its glyph centred as far from the container's end edge as the swatch's centre is from the container's start edge. It SHALL be a Button in every respect — its own tokens, its press, focus ring and target (BTN-5, BTN-8, BTN-9, BTN-10) — named by pickerLabel (an empty pickerLabel reported in debug builds), exposed as opening a dialog, as the opener of a popover is (POP-18; aria-haspopup="dialog" on the web), and a focus stop after the input; WHILE the color input is disabled it SHALL be disabled with it. The palette glyph is not marked as mirrored and is never mirrored. WHILE picker is false THE color input SHALL draw no picker button, SHALL ignore pickerLabel and SHALL end its input as CLI-1 says.
CLI-28 WHEN the user activates the picker button THE color input SHALL emit pickerRequest once with value and then, unless the product cancelled that request, present the platform's own color picker WHERE the platform has one, showing value, or the picker's own starting color WHILE value is empty; it SHALL draw no picker surface of its own. WHERE the platform has no color picker of its own, or the product cancelled the request, THE color input SHALL present nothing, change nothing and move no focus: the product presents its own surface — anchored to the color input's container and opened by the picker button, as a popover is to its anchor and its opener (POP-18) — and sets value to what was picked (CLI-21), and that surface returns focus to the picker button when it closes (POP-22).
CLI-29 WHILE a platform picker that the color input presented is open, WHEN the person picks a color in it THE color input SHALL take the pick as an edit by the person: it SHALL write the color into its input in the value's own form, draw the swatch in it, end any entry error and emit input once with the new value, for every pick the platform reports, a drag across the picker included. A pick the value cannot hold exactly — one with an alpha, one outside sRGB — SHALL be held as the opaque sRGB color the platform converts it to. WHEN that picker closes THE color input SHALL emit change once WHEN value differs from the value last committed, and focus SHALL be on the picker button, as a popover returns focus to its opener (POP-22). THE color input SHALL leave the picker's look, placement, keys and dismissal to the platform.
CLI-30 THE color input SHALL give its input a general keyboard without autocapitalization, autocorrection, spell checking or suggestions, SHALL offer it no autofill, and SHALL expose it as a text field named as CLI-11 says whose value is the text it shows. It SHALL announce nothing of its own WHEN the value changes and SHALL add no name of the color in words: the text is the value, and a product that wants a name beside it ("Teal") gives it in the supportingText of the Field that frames the input, or beside an input nothing frames.
CLI-31 WHILE disabled is true — set by the product, or by the Field that frames it (FLD-14) — THE color input SHALL NOT be focusable or editable, nor its picker button, SHALL NOT emit input, change, pickerRequest or entryError, SHALL expose the disabled state to assistive technology, SHALL be left out of form submission on the web, and SHALL render every part of its container, the floating label and its asterisk included, from the disabled component tokens of its variant (of its error parts WHILE the color input is in error). It SHALL draw the swatch's fill at sys.state.disabled-content-opacity, as a disabled chip draws its avatar (CHP-6), and keep the swatch's edge.
CLI-33 WHILE the text size is enlarged THE color input SHALL grow its container with the input's line, keeping the height of its size as a minimum, SHALL keep the swatch at comp.input-box.icon.size.medium for size medium (and so on) and the picker button at its Button's size, both centred on the line, and SHALL keep the value on one line: WHERE the input is narrower than its text the text SHALL scroll inside the input, the caret kept in view, as in a single-line text input.
CLI-34 WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE color input SHALL draw the label that floats in its box and that label's asterisk in the platform's text color, and SHALL rely on no color of its own to show an error: the error is carried by the invalid state (CLI-9) and by the words of the Field that frames it, which that Field draws in the platform's text color (FLD-17).
CLI-35 WHERE the platform draws with a person's own forced colors THE color input SHALL draw an edge comp.input-box.outline.width wide in the platform's control text color around its container in every variant, that edge in the platform's highlight color at the focused width while focused, its value in the platform's text color, and a disabled color input in the platform's disabled text color. It SHALL still fill the swatch with the value's own color, kept out of the forced palette, because that color is the content the field shows and not a decoration of it, and SHALL draw the swatch's edge in the platform's text color, so that the sample is bounded on any background.
CLI-37 WHERE the layout direction is right-to-left THE color input SHALL mirror its container: the swatch at the right and the picker button at the left, all paddings applied by logical start and end, and the label of a filled or outlined color input floating from the right edge. It SHALL lay out the value left to right in every layout direction, aligned to the field's start edge — the right in a right-to-left layout — as a text input lays out an address or a number (TXI-24), because a number sign and its digits are one left-to-right token whose order a right-to-left context must not change.
CLI-38 THE color input SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the color input is shown THE color input SHALL draw itself for the new direction at once, without a motion of its own, keeping its value, its text as typed, its selection and caret, and its focus.
CLI-39 WHERE the layout direction is right-to-left THE color input SHALL mirror no drawing of its own: the swatch is never mirrored, and the palette glyph of its picker button is not one the icon set marks as mirrored (CLI-27). What changes with the direction is where its parts stand (CLI-37). The glyph before the label is the Field's, and is mirrored as FLD-20 says.
CLI-40 THE color input SHALL lay out the label that floats in its box as text of its own direction, isolated from the text around it: it takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word keeps its own order in a right-to-left layout and reorders nothing beside it; THE color input SHALL still place the label and align its lines by the layout direction, not by the text's own. The value is laid out as CLI-37 says. The texts of the rows around the input are the Field's and are laid out as FLD-21 says.
CLI-41 WHEN variant or size names a value that the active design system does not have THE color input SHALL render with the default value's tokens, and in debug builds report the unknown value; WHEN variant names a value the active system has but the color input does not know by name (one a layer added) it SHALL draw no label and draw its edge as a stacked color input does (CLI-15, CLI-22), with that value's own tokens. A required mark it does not know is the Field's to answer (FLD-22).
CLI-42 THE color input SHALL have no words of its own and SHALL read none of the product's words: invalidText and pickerLabel are said by the product for the one input they are set on, and WHILE either is empty THE color input SHALL draw and work as CLI-20 and CLI-27 say and SHALL put no word in its place. Its value is a number sign and digits, written the same in every language (CLI-16). The words of a requirement are the Field's (FLD-24).
CLI-43 THE color input SHALL say to the Field that frames it what only the input knows, and SHALL say it again WHEN it changes: that it draws the label itself WHILE its variant floats one (CLI-15), so that the Field draws no label row (FLD-25); how far the value's text stands from the input's own start edge — comp.input-box.container.padding-inline-with-icon.medium, the swatch's side comp.input-box.icon.size.medium and comp.input-box.container.gap.medium for size medium (and so on for each size, CLI-1) — and, for its end edge, comp.input-box.container.padding-inline.medium (and so on), whether or not the picker button is shown, so that the Field's supporting row starts at the value's text, after the swatch, and ends at the container's text padding (FLD-26); and an entry error with its words (CLI-20, FLD-28). It SHALL give no count: a color has one length. It SHALL take from that Field its name, its description and its required, invalid and disabled states (CLI-9, CLI-11, CLI-31), whether the label is hidden (CLI-15) and whether an asterisk follows it (CLI-7), so that a Field and a color input placed by hand are drawn, named, described and marked exactly as a color field is.
CLI-44 THE color input SHALL draw no label row above itself, no requirement tag, no help and no error text: those are the rows of the Field that frames it (FLD-2 to FLD-7). WHILE no Field frames it THE color input SHALL be complete as a bare control — its box, the swatch, the value as text, the picker button, the label that floats in the box where its variant floats one, its states and its events — and exactly as tall as its container. THE color input SHALL be block-level, framed and bare alike: exactly as wide as the place it stands in — the width its layout gives it, which inside a Field is the Field's whole width (FLD-1), so that the box fills its Field — with no width of its own and never the platform's default width for a text element, as the text input is (TXI-63). A product that wants a narrower box gives it a narrower place.
CLI-45 THE color input SHALL draw its box from the one set of tokens every input box is drawn from, the group comp.input-box (comp.input-box.container.shape, comp.input-box.container.height.medium, and so on): its container, its corners, its edges and their widths, the label that floats in it and the asterisk after it, the text of its value, the caret and the highlight of selected text, the paddings, the gaps and the least height of its size (a stacked box's from comp.input-box.stacked.container.height.medium and comp.input-box.stacked.container.padding-block.medium for size medium, as tall as a Button of the same size, and a filled or an outlined box's from comp.input-box.container.height.medium and comp.input-box.container.padding-block.medium, and so on), and the size of its swatch, which is the size of the glyph at the start of a box (comp.input-box.icon.size.medium, and so on), and the colors of each of these in its look, at rest, hovered, focused and disabled, plain and in error. It SHALL have no token of its own for any of them: the tokens of its own group are the swatch's shape and the hairline around it. WHEN a design system or a product sets a token of the box THE color input SHALL follow it, as the text input, the select, the combobox and the number input do, which read the same tokens; no token is held equal to another for this. WHERE one color input is to differ from the other boxes of a product, the token is set for that instance — on its element or on a subtree that holds it, in each platform's way of setting a token for a subtree — and THE color input SHALL draw itself from the value it finds there.
CLI-46 WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE color input SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role — an id reference by the elements it names in the host's tree or a tree around it, an error message as part of the description while the color input is invalid — except those the color input owns (aria-disabled), which it SHALL move and not expose. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE color input SHALL take it off that element. WHEN the product sets an aria- attribute the color input owns THE color input SHALL report it in debug builds.

各平台名称对照

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

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-color-input TanreiColorInput TanreiColorInput TanreiColorInput ColorInput
variant · 属性 variant variant variant variant variant
size · 属性 size size size size size
value · 属性 value hex value controller value
label · 属性 label label label semanticLabel accessibilityLabel
labelHidden · 属性 labelHidden labelsHidden labelHidden labelHidden labelHidden
error · 属性 error error isError isError error
disabled · 属性 disabled disabled enabled enabled disabled
invalidText · 属性 invalidText invalidText invalidText invalidText invalidText
picker · 属性 picker showsPicker onPickerRequest onPickerRequest onPickerRequest
pickerLabel · 属性 pickerLabel pickerLabel pickerContentDescription pickerSemanticLabel pickerAccessibilityLabel
input · 事件 input hex onValueChange onChanged onValueChange
change · 事件 change onCommit onCommit onCommit onEndEditing
pickerRequest · 事件 pickerrequest onPickerRequest onPickerRequest onPickerRequest onPickerRequest
entryError · 事件 entryerror onEntryError onEntryError onEntryError onEntryError
备注 The color field's control, without the frame: the class TanreiColorInput, React ColorInput. A form-associated custom element with a shadow root that takes name, submits value (the color in its own form; an empty string while empty), restores it on navigation, resets to the value it was first given, follows <fieldset disabled>, and reports valueMissing while its Field says it is required and value is empty, and badInput while an entry error lasts (CLI-20). The shadow root holds the container, the swatch and a real <input type="text" inputmode="text" autocapitalize="none" autocorrect="off" spellcheck="false" autocomplete="off" dir="ltr">. The swatch is a <span aria-hidden="true"> whose background is the value, with forced-color-adjust: none on it alone and a CanvasText border under forced-colors: active (CLI-35). The picker button is a <tanrei-button variant="text"> whose icon slot holds the palette glyph, with aria-haspopup="dialog". The platform's picker is the browser's: the shadow root holds a visually hidden <input type="color" tabindex="-1" aria-hidden="true"> placed under the picker button, so that the browser anchors its picker there; activation dispatches a cancelable pickerrequest and, unless preventDefault() was called, sets that input's value (black while the color input is empty) and calls showPicker() inside the same user activation. Its input events are the picks of CLI-29 and its change the close; where a browser gives no close signal the next focus of the page counts as one. The shadow root does not delegate focus — it has two stops — and focus() focuses the inner input. Parts: container, outline, active-indicator, label (the floating label), requirement-label (its asterisk), swatch, input, picker-button. The connection with a Field is tanrei-field-connect (src/primitives/field.ts), in both directions (CLI-43): the input says drawsLabel while its look floats the label, inset: { start, end } — lengths it writes from its own tokens: the padding beside the swatch, the swatch and the gap; and the text padding at the end — and refusal: { text } while an entry error lasts. It keeps no count. It takes labelHidden and requiredMark (asterisk or none) beside the name, the description and the three states. The name, the description, aria-invalid and aria-required are written on the inner input, the input's own label winning. Attributes are kebab-case: label-hidden, invalid-text, picker-label. input and change are composed events; pickerrequest and entryerror are composed CustomEvents whose detail is { value } (TanreiColorInputPickerRequestDetail) and { text, message } (TanreiColorInputEntryErrorDetail; message is invalid-text). What the value reads and writes is one module with no DOM in it (color-text.ts), which lives beside the element. Before the element is defined its host is an empty inline box: a page that must work before its scripts load reserves the room or renders a native <input> in its place. The host is display: block. The element has no words and reads none (CLI-42). Not built on this platform yet, nor is the color field. The input is a view of its own — TanreiColorInput(hex: Binding<String>, showsPicker:, pickerLabel:, onCommit:, onPickerRequest:, onEntryError:) — with a text element, the system color picker (UIColorPickerViewController presented as a popover from the picker button with supportsAlpha = false; NSColorPanel on macOS; SwiftUI's own ColorPicker is not used), the conversion of a pick to sRGB and the swatch as a decorative shape. label is its accessibility label where nothing frames it. The Field around it gives the name, the description and the states through the environment, and the input says back what it draws through a preference the Field reads (CLI-43); that upward channel is not tried yet. Not built on this platform yet. The input is a composable of its own, as BasicTextField: TanreiColorInput(value, onValueChange, …), the caller keeping value; enabled is the inverse flag and isError keeps Compose's name. KeyboardOptions(capitalization = None, autoCorrectEnabled = false, keyboardType = Ascii). Android has no color picker of its own, so the input presents none (CLI-28): the picker button is shown when onPickerRequest is not null. The swatch is drawn in a Canvas and cleared from semantics. The Field around it gives the name, the description and the states through a composition local, and the input writes what it says of itself to a scope the Field provides (CLI-43); not tried yet. Not built on this platform yet. The input is a widget of its own, as TextField: the text lives in a TextEditingController, and onChanged receives the value (a color or the empty string), not the text as typed. semanticLabel is its name where nothing frames it; enabled is the inverse flag. autocorrect: false, enableSuggestions: false, textCapitalization: none, textDirection: TextDirection.ltr. Flutter has no color picker of its own, so the input presents none (CLI-28): the picker button is shown when onPickerRequest is not null. The swatch is a DecoratedBox inside ExcludeSemantics. The Field around it gives the name, the description and the states through an inherited widget, and the input says back what it draws through an inherited notifier (CLI-43); not tried yet. Not built on this platform yet. <ColorInput accessibilityLabel="Brand color" value={value} onValueChange={setValue} />, built on the platform's text element with autoCapitalize="none", autoCorrect={false}, spellCheck={false} and left-to-right text. onValueChange receives the value (a color or the empty string), not the text as typed; onEndEditing is the commit. React Native has no color picker of its own on both platforms, so the input presents none (CLI-28): the picker button is shown when onPickerRequest is given. The swatch is a View with accessible={false}. The Field around it gives the name, the description and the states through a context, and the input says back what it draws through that context's setter (CLI-43); not tried yet.

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-color-input-swatch-outline-color sys.color.outline-variant #000000 · 8%
--tanrei-comp-color-input-swatch-outline-width sys.border.hairline 1px
--tanrei-comp-color-input-swatch-shape sys.shape.corner.extra-small 3px
--tanrei-comp-input-box-active-indicator-width sys.border.hairline 1px
--tanrei-comp-input-box-affix-gap sys.space.space25 2px
--tanrei-comp-input-box-container-gap-large sys.space.space200 16px
--tanrei-comp-input-box-container-gap-medium sys.space.space200 16px
--tanrei-comp-input-box-container-gap-small sys.space.space100 8px
--tanrei-comp-input-box-container-height-large — 56px
--tanrei-comp-input-box-container-height-medium — 48px
--tanrei-comp-input-box-container-height-small — 40px
--tanrei-comp-input-box-container-padding-block-with-label-large — 4px
--tanrei-comp-input-box-container-padding-block-with-label-medium — 4px
--tanrei-comp-input-box-container-padding-block-with-label-small — 2px
--tanrei-comp-input-box-container-padding-block-large — 14px
--tanrei-comp-input-box-container-padding-block-medium — 10px
--tanrei-comp-input-box-container-padding-block-small — 8px
--tanrei-comp-input-box-container-padding-inline-with-icon-large sys.space.space150 12px
--tanrei-comp-input-box-container-padding-inline-with-icon-medium sys.space.space150 12px
--tanrei-comp-input-box-container-padding-inline-with-icon-small sys.space.space100 8px
--tanrei-comp-input-box-container-padding-inline-large sys.space.space200 16px
--tanrei-comp-input-box-container-padding-inline-medium sys.space.space200 16px
--tanrei-comp-input-box-container-padding-inline-small sys.space.space150 12px
--tanrei-comp-input-box-container-shape sys.shape.corner.small 6px
--tanrei-comp-input-box-container-shape-bottom sys.shape.corner.none 0px
--tanrei-comp-input-box-disabled-active-indicator-width — 1px
--tanrei-comp-input-box-disabled-opacity — 1
--tanrei-comp-input-box-disabled-outline-width — 1px
--tanrei-comp-input-box-filled-active-indicator-color sys.color.outline #848484
--tanrei-comp-input-box-filled-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-caret-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-filled-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-input-box-filled-disabled-active-indicator-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-container-color — #eeeeee
--tanrei-comp-input-box-filled-disabled-error-active-indicator-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-container-color — #eeeeee
--tanrei-comp-input-box-filled-disabled-error-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-disabled-error-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-error-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-disabled-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-disabled-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-filled-error-active-indicator-color sys.color.error #cd262f
--tanrei-comp-input-box-filled-error-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-error-caret-color sys.color.error #cd262f
--tanrei-comp-input-box-filled-error-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-input-box-filled-error-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-filled-error-label-color sys.color.error #cd262f
--tanrei-comp-input-box-filled-error-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-error-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-error-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-error-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-filled-error-state-layer-color comp.input-box.filled.error.input.color #1b1b1b
--tanrei-comp-input-box-filled-error-trailing-icon-color sys.color.error #cd262f
--tanrei-comp-input-box-filled-focused-active-indicator-color — #0070ac
--tanrei-comp-input-box-filled-focused-affix-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-caret-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-container-color — #eeeeee
--tanrei-comp-input-box-filled-focused-error-active-indicator-color — #cd262f
--tanrei-comp-input-box-filled-focused-error-affix-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-error-caret-color — #cd262f
--tanrei-comp-input-box-filled-focused-error-container-color — #eeeeee
--tanrei-comp-input-box-filled-focused-error-input-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-error-label-color — #cd262f
--tanrei-comp-input-box-filled-focused-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-error-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-focused-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-filled-focused-input-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-label-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-focused-placeholder-color — #4b4b4b
--tanrei-comp-input-box-filled-focused-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-state-layer-color — #1b1b1b
--tanrei-comp-input-box-filled-focused-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-active-indicator-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-affix-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-caret-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-container-color — #dddddd
--tanrei-comp-input-box-filled-hovered-error-active-indicator-color — #cd262f
--tanrei-comp-input-box-filled-hovered-error-affix-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-error-caret-color — #cd262f
--tanrei-comp-input-box-filled-hovered-error-container-color — #dddddd
--tanrei-comp-input-box-filled-hovered-error-input-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-error-label-color — #cd262f
--tanrei-comp-input-box-filled-hovered-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-error-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-hovered-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-filled-hovered-input-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-label-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-hovered-placeholder-color — #4b4b4b
--tanrei-comp-input-box-filled-hovered-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-state-layer-color — #1b1b1b
--tanrei-comp-input-box-filled-hovered-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-filled-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-filled-label-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-outline-color — #000000 · 0%
--tanrei-comp-input-box-filled-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-filled-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-filled-state-layer-color comp.input-box.filled.input.color #1b1b1b
--tanrei-comp-input-box-filled-trailing-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-focused-active-indicator-width — 2px
--tanrei-comp-input-box-focused-opacity — 1
--tanrei-comp-input-box-focused-outline-width — 2px
--tanrei-comp-input-box-hovered-active-indicator-width — 1px
--tanrei-comp-input-box-hovered-opacity — 1
--tanrei-comp-input-box-hovered-outline-width — 1px
--tanrei-comp-input-box-icon-size-large sys.icon.medium 24px
--tanrei-comp-input-box-icon-size-medium sys.icon.medium 24px
--tanrei-comp-input-box-icon-size-small sys.icon.small 20px
--tanrei-comp-input-box-motion-label-duration sys.motion.role.state.default 250ms
--tanrei-comp-input-box-motion-label-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-input-box-motion-state-duration-large sys.motion.role.state.default 250ms
--tanrei-comp-input-box-motion-state-duration-medium sys.motion.role.state.default 250ms
--tanrei-comp-input-box-motion-state-duration-small sys.motion.role.state.compact 200ms
--tanrei-comp-input-box-motion-state-easing sys.motion.easing.state cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-input-box-outline-notch-padding sys.space.space50 4px
--tanrei-comp-input-box-outline-width sys.border.hairline 1px
--tanrei-comp-input-box-outlined-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-caret-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-outlined-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-disabled-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-disabled-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-disabled-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-disabled-error-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-disabled-error-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-outline-color — #1b1b1b · 12%
--tanrei-comp-input-box-outlined-disabled-error-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-error-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-outline-color — #1b1b1b · 12%
--tanrei-comp-input-box-outlined-disabled-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-disabled-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-outlined-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-error-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-error-caret-color sys.color.error #cd262f
--tanrei-comp-input-box-outlined-error-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-error-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-outlined-error-label-color sys.color.error #cd262f
--tanrei-comp-input-box-outlined-error-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-error-outline-color sys.color.error #cd262f
--tanrei-comp-input-box-outlined-error-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-error-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-outlined-error-state-layer-color comp.input-box.outlined.error.input.color #1b1b1b
--tanrei-comp-input-box-outlined-error-trailing-icon-color sys.color.error #cd262f
--tanrei-comp-input-box-outlined-focused-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-focused-affix-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-caret-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-focused-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-focused-error-affix-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-error-caret-color — #cd262f
--tanrei-comp-input-box-outlined-focused-error-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-focused-error-input-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-error-label-color — #cd262f
--tanrei-comp-input-box-outlined-focused-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-error-outline-color — #cd262f
--tanrei-comp-input-box-outlined-focused-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-outlined-focused-input-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-label-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-outline-color — #0070ac
--tanrei-comp-input-box-outlined-focused-placeholder-color — #4b4b4b
--tanrei-comp-input-box-outlined-focused-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-state-layer-color — #1b1b1b
--tanrei-comp-input-box-outlined-focused-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-hovered-affix-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-caret-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-hovered-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-outlined-hovered-error-affix-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-error-caret-color — #cd262f
--tanrei-comp-input-box-outlined-hovered-error-container-color — #000000 · 0%
--tanrei-comp-input-box-outlined-hovered-error-input-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-error-label-color — #cd262f
--tanrei-comp-input-box-outlined-hovered-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-error-outline-color — #cd262f
--tanrei-comp-input-box-outlined-hovered-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-outlined-hovered-input-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-label-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-outline-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-placeholder-color — #4b4b4b
--tanrei-comp-input-box-outlined-hovered-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-state-layer-color — #1b1b1b
--tanrei-comp-input-box-outlined-hovered-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-outlined-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-outlined-label-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-outline-color sys.color.outline #848484
--tanrei-comp-input-box-outlined-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-outlined-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-outlined-state-layer-color comp.input-box.outlined.input.color #1b1b1b
--tanrei-comp-input-box-outlined-trailing-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-requirement-asterisk-gap sys.space.space25 2px
--tanrei-comp-input-box-selection-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-selection-content-color sys.color.on-primary #ffffff
--tanrei-comp-input-box-stacked-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-caret-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-stacked-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-input-box-stacked-container-height-large comp.button.container.height.large 56px
--tanrei-comp-input-box-stacked-container-height-medium comp.button.container.height.medium 40px
--tanrei-comp-input-box-stacked-container-height-small comp.button.container.height.small 32px
--tanrei-comp-input-box-stacked-container-padding-block-large — 14px
--tanrei-comp-input-box-stacked-container-padding-block-medium — 6px
--tanrei-comp-input-box-stacked-container-padding-block-small — 4px
--tanrei-comp-input-box-stacked-disabled-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-disabled-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-container-color — #eeeeee
--tanrei-comp-input-box-stacked-disabled-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-disabled-error-affix-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-caret-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-container-color — #eeeeee
--tanrei-comp-input-box-stacked-disabled-error-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-outline-color — #000000 · 0%
--tanrei-comp-input-box-stacked-disabled-error-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-error-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-input-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-label-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-leading-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-outline-color — #000000 · 0%
--tanrei-comp-input-box-stacked-disabled-placeholder-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-required-asterisk-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-state-layer-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-disabled-trailing-icon-color — #1b1b1b · 38%
--tanrei-comp-input-box-stacked-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-error-affix-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-error-caret-color sys.color.error #cd262f
--tanrei-comp-input-box-stacked-error-container-color sys.color.surface-container-highest #eeeeee
--tanrei-comp-input-box-stacked-error-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-stacked-error-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-stacked-error-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-error-outline-color sys.color.error #cd262f
--tanrei-comp-input-box-stacked-error-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-error-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-stacked-error-state-layer-color comp.input-box.stacked.error.input.color #1b1b1b
--tanrei-comp-input-box-stacked-error-trailing-icon-color sys.color.error #cd262f
--tanrei-comp-input-box-stacked-focused-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-focused-affix-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-caret-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-container-color — #eeeeee
--tanrei-comp-input-box-stacked-focused-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-focused-error-affix-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-error-caret-color — #cd262f
--tanrei-comp-input-box-stacked-focused-error-container-color — #eeeeee
--tanrei-comp-input-box-stacked-focused-error-input-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-error-label-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-error-outline-color — #cd262f
--tanrei-comp-input-box-stacked-focused-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-stacked-focused-input-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-label-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-outline-color — #0070ac
--tanrei-comp-input-box-stacked-focused-placeholder-color — #4b4b4b
--tanrei-comp-input-box-stacked-focused-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-state-layer-color — #1b1b1b
--tanrei-comp-input-box-stacked-focused-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-hovered-affix-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-caret-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-container-color — #dddddd
--tanrei-comp-input-box-stacked-hovered-error-active-indicator-color — #000000 · 0%
--tanrei-comp-input-box-stacked-hovered-error-affix-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-error-caret-color — #cd262f
--tanrei-comp-input-box-stacked-hovered-error-container-color — #dddddd
--tanrei-comp-input-box-stacked-hovered-error-input-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-error-label-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-error-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-error-outline-color — #cd262f
--tanrei-comp-input-box-stacked-hovered-error-placeholder-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-error-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-error-state-layer-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-error-trailing-icon-color — #cd262f
--tanrei-comp-input-box-stacked-hovered-input-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-label-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-leading-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-outline-color — #000000 · 0%
--tanrei-comp-input-box-stacked-hovered-placeholder-color — #4b4b4b
--tanrei-comp-input-box-stacked-hovered-required-asterisk-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-state-layer-color — #1b1b1b
--tanrei-comp-input-box-stacked-hovered-trailing-icon-color — #4b4b4b
--tanrei-comp-input-box-stacked-input-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-stacked-label-color sys.color.on-surface #1b1b1b
--tanrei-comp-input-box-stacked-leading-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-outline-color — #000000 · 0%
--tanrei-comp-input-box-stacked-placeholder-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-stacked-required-asterisk-color sys.color.primary #1b1b1b
--tanrei-comp-input-box-stacked-state-layer-color comp.input-box.stacked.input.color #1b1b1b
--tanrei-comp-input-box-stacked-trailing-icon-color sys.color.on-surface-variant #4b4b4b
--tanrei-comp-input-box-input-typescale-large sys.typescale.body-large 400 16px/1.625
--tanrei-comp-input-box-input-typescale-medium sys.typescale.body-large 400 16px/1.625
--tanrei-comp-input-box-input-typescale-small sys.typescale.body 400 14px/1.5714
--tanrei-comp-input-box-label-floated-typescale-large sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-input-box-label-floated-typescale-medium sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-input-box-label-floated-typescale-small sys.typescale.label-small 500 12px/1.3333
--tanrei-comp-input-box-label-typescale-large sys.typescale.label 500 14px/1.4286
--tanrei-comp-input-box-label-typescale-medium sys.typescale.label 500 14px/1.4286
--tanrei-comp-input-box-label-typescale-small sys.typescale.label 500 14px/1.4286

测试样例

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

生成自 specs/color-input.spec.json, tokens/comp/color-input.tokens.json, tokens/comp/input-box.tokens.json, design/tokens/

Web 上绘制方式的不同之处

  • 这个元素是与表单关联的元素。有 name 时,它提交 value——颜色,或者空字符串——重置为 value 属性(attribute)的值,在导航返回时恢复,跟随被禁用的 <fieldset>;所在的字段说明它必填而它为空时报告缺少值,输入错误持续期间报告输入有误。
  • 这个元素是一个块。focus() 会把焦点交给原生的文本元素,绝不会交给选择器按钮;在方框上、这个按钮之外的任何地方按下,会让文本获得焦点;只是显示这个按钮时,按色块会打开选择器。
  • input 和 change 是普通事件:请从元素上读取 value。pickerrequest 是可以取消的 CustomEvent,带有 detail.value;entryerror 是 CustomEvent,带有 detail.text 和 detail.message,后者就是 invalidText。它们的类型是 TanreiColorInputPickerRequestDetail 和 TanreiColorInputEntryErrorDetail。
  • 部件:container、outline、active-indicator、label、requirement-label、swatch、input、picker-button。它没有插槽。
  • 这个元素没有自己的文字,也不读取产品的任何文字:label、invalidText 和 pickerLabel 在你给出之前都是空的。
  • 浏览器的选择器因浏览器而异:在 Chromium 中是页面里的一个弹出层,在 Firefox 和 Safari 中是系统的颜色窗口。它的外观、位置和按键都由浏览器决定。
  • 用全角字符写的文本(#0f766e)不会读作颜色。
  • 在元素完成定义之前,它没有尺寸。请预留方框的高度。

指南

颜色输入框、颜色字段,还是手写的字段

你需要 使用
标签、方框、帮助文本和错误 颜色字段
只要方框,放在已经为这种颜色命名的行或列里 颜色输入框,由它自己的 label 命名
在框架里面、方框旁边或下方放你自己的东西 一个字段,里面放一个颜色输入框和你自己的元素
只显示、不编辑的颜色 一个样本,旁边用文本写出它的值或名称

推荐

  • 给单独使用的输入框一个 label,把这一行和它所在的位置合起来表达的意思说出来:“主色,色调 40”。
  • 选择器按钮也要按它所在的行来命名:“选择‘主色,色调 40’的颜色”。否则,一个有很多行的页面上会有许多同名的按钮。
  • 让单独使用的输入框靠所在的位置得到宽度:网格的一列、一个单元格、工具栏里有宽度的一项。
  • 只要你需要的是方框上方的标签、帮助文本和错误,就使用颜色字段。

避免

  • 不要为了省下标签的位置,在表单里使用单独的输入框。哪里都看不到标签的输入框,对每个看到它的人来说都只能靠猜。
  • 不要只靠色块来说明颜色。值是文本;分辨不出两个样本的人,读到的是两个不同的值。
  • 不要在字段里的输入框上设置 label、error 或 disabled。把它们写在字段上,标签和帮助文本才会随之变化。
  • 不要把颜色字段放进字段。它本身已经是字段;字段框住的控件是颜色输入框。

无障碍

角色
textbox
标注
The accessible name of the input is the label of the Field that frames it, or its own label where no Field does; a filled or outlined input draws that name floating, and labelHidden only stops the drawing. The input's value is the text it shows: the color as a number sign and six hexadecimal digits. Its description is what the Field gives — the supporting text with, in error, the error text after it and the optional text — and, where nothing frames it, invalidText while an entry error lasts. The input is exposed as invalid while error is true, its Field is in error or an entry error lasts; as required while its Field says so, whichever mark is drawn; and as disabled while it or its Field is disabled. The picker button is a separate button named by pickerLabel that opens a dialog. The swatch is decorative and hidden.
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作
Tab / Shift+Tab Moves focus to the input, then to the picker button while it is shown, and on.
Text editing keys Edit the text as in a text input; nothing is refused while typing.
Enter (the action key) In the input: commits the text (change; an entry error for a text that is not a color) and, on the web inside a form, requests its submission.
Enter / Space on the picker button Asks for a picker: emits pickerRequest and, unless cancelled, opens the platform's own color picker where there is one.

备注

  • The color is never told by the swatch alone (WCAG 1.4.1): the value is text, read and typed, and the swatch is a sample of it for those who can see it. A person who cannot tell two samples apart reads two different values.
  • A hexadecimal value says little about what the color looks like. Where that matters, the product names the color in the supportingText of the Field that frames the input ("Teal") or beside it; the color input ships no names, which would need a table in every language.
  • The color input checks the form of what is typed, not its meaning: a text that is not a color raises an entry error after the person commits, never while they type (CLI-20), and the words for it are shown by the Field that frames the input. Whether a color suits its use — its contrast against a background, a color already taken — is the product's to say with the Field's error and errorText.
  • The swatch's edge is the hairline, far below 3:1 against the container. That is within WCAG 1.4.11: the swatch is not a control and is not what identifies the value. The value's text is held to 4.5:1 as a text input's is.
  • The picker is the platform's own where it has one, with the platform's own accessibility; where it has none the product's surface is a popover opened by the picker button, which is why the button is exposed as opening a dialog and receives focus back (CLI-28, CLI-29).
  • The container extends its hit area to the minimum target (CLI-24), and the picker button is a Button with its own target (BTN-5). The swatch is not a target of its own: a press on it lands in the input.
  • Text size: at 200% the container grows with the value's line and the swatch keeps its size (CLI-33); a floating label wraps and is never cut (CLI-15).
  • Forced colors (CLI-34, CLI-35): the box and the value take the person's colors; the swatch alone keeps the value's color, because showing that color is what it is for.
  • The input has no label row and no message of its own: a Field frames it and draws them (FLD-2 to FLD-11, FLD-25, FLD-26, FLD-28), or the product names it with label where its visible label is elsewhere. Unframed and unnamed, it is reported (CLI-11).
  • How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.

生成自 specs/color-input.spec.json, tokens/sys/measure.tokens.json

组件负责的部分

  • 它是一个文本框,值就是它显示的文本;设置 picker 时,还有一个单独的按钮,以 pickerLabel 命名,并暴露为会打开一个对话框。
  • 它的名称是它自己的 label;它没有 label 时,是包着它的字段的标签。
  • 它的描述是字段给它的内容:帮助文本或错误文本。没有字段框住它时,在输入错误持续期间,invalidText 是它的描述。
  • 处于错误状态时,它暴露为无效;所在的字段说明它必填时,暴露为必填;禁用时暴露为禁用。
  • 色块是装饰性的,对辅助技术隐藏:说明颜色的是值的文本。
  • 值变化时不朗读任何内容,它也不会给颜色加上名称。
  • 焦点由方框自己的边缘来显示,无论来自键盘还是指针。点击区域满足最小目标。
  • 在强制颜色模式下,方框会多出一道边线,并采用用户的颜色。只有色块保留值的颜色;它的边线是文本颜色。
  • 在从右到左的布局中,方框会镜像:色块在右,选择器按钮在左。值本身仍然从左到右书写。
  • 缺少名称会在调试构建中报告。

需要你做的事

  • 用 label 为每个单独使用的输入框命名。它旁边可见的文本并不能为它命名。
  • 只要设置了 picker,就给出 pickerLabel。
  • 单独使用的输入框可能出错的地方,要用辅助技术读得到的文字说明哪里不对:写上 invalidText,并在页面上放一条你自己的消息——或者用字段框住输入框,由字段把这些文字画出来。