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

文本输入框

用户在里面键入的那个方框,以及在里面键入的一切——单行或多行、日期或时间、代码——它自己没有标签行、帮助文本和错误文本。用于标签位于别处的地方,或者放进产品自己组合的字段里。

content_copy以 Markdown 格式查看

进阶

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

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

概览

Web
tanrei-text-input
schedule
SwiftUI
TanreiTextInput
radio_button_unchecked
Jetpack Compose
TanreiTextInput
radio_button_unchecked
Flutter
TanreiTextInput
radio_button_unchecked
React Native
TextInput
radio_button_unchecked
不提供的变体
tanrei: filled, outlined

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

单独使用:列表上方的一个筛选框,以及标签位于输入框旁边的一行

search
显示名称

文本输入框就是文本字段里的那个方框,单独拿出来:容器、文本、图标、前缀和后缀、日期的分段、选择器按钮和调整手柄。它上方没有标签行,下方没有帮助文本和错误文本,也不绘制计数。

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

位置 用户读到的标签 输入框的 label
工具栏里或列表上方的筛选框 占位符和字形说明它是做什么的 它筛选的是什么:“筛选令牌”
表格的单元格 列标题 列和行:“数量,橡木书桌”
标签位于输入框旁边的一行 旁边的文本 同样的词

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

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

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

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

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

用法

<!-- 工具栏里的筛选框:宽度由工具栏给它。 -->
<tanrei-text-input name="q" type="search" label="筛选令牌" placeholder="筛选令牌"
  style="inline-size: 16rem">
  <span slot="leading-icon">search</span>
</tanrei-text-input>

<!-- 表格的单元格:列标题就是可见的标签。 -->
<td><tanrei-text-input name="quantity-oak-desk" type="number" label="数量,橡木书桌" value="2"></tanrei-text-input></td>

<!-- 标签位于输入框旁边的一行。 -->
<div class="row">
  <span>显示名称</span>
  <tanrei-text-input name="display-name" label="显示名称" autocomplete="nickname"></tanrei-text-input>
</div>

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

  const filter = document.querySelector('[name="q"]');
  filter.addEventListener('input', () => show(filter.value)); // 每一次编辑
  filter.addEventListener('change', () => remember(filter.value)); // 焦点离开或按下 Enter,并且值有变化
</script>
// 进阶组件(用于构成其他组件的部件)从 advanced 入口导入。
import { TextInput } from '@tanrei/react/advanced';

<TextInput name="q" type="search" label="筛选令牌" placeholder="筛选令牌"
  value={query} onInput={(event) => setQuery(event.currentTarget.value)} />

手写在字段里

用字段包住一个文本输入框,就是把文本字段拆开来写。输入框自己的 label 留空:由字段为它命名。label、error、disabled 和必填设置写在字段上;name、value 以及与键入有关的一切写在输入框上。

<tanrei-field label="邮箱" required required-text="必填"
  supporting-text="仅用于登录。">
  <tanrei-text-input name="email" type="email" autocomplete="email"></tanrei-text-input>
</tanrei-field>

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

只有输入框知道的事,由它告诉所在的字段。字段的帮助文本从输入框里文本开始的位置开始,也就是越过内边距和前置图标之后。filled 或 outlined 的输入框自己画出字段的标签,让它浮在方框里,所以字段不绘制标签行。日期或时间只填了一半时,字段会进入错误状态,显示输入框的 invalidText 或 unavailableText。

有一样东西要你自己动手:计数。设置 counter 后,计数由输入框来记,而字段只绘制作为 count-text 交给它的内容。请在每次变化时把它交给字段:

<tanrei-field label="显示名称">
  <tanrei-text-input name="display-name" maxlength="40" counter></tanrei-text-input>
</tanrei-field>

<script type="module">
  const field = document.querySelector('tanrei-field');
  const input = field.querySelector('tanrei-text-input');
  field.countText = input.countText;
  input.addEventListener('input', () => (field.countText = input.countText));
</script>

文本字段会自己做这件事。文本字段做了、而手写的字段和文本输入框没有做的事,只有这一件。

规格

单独使用的输入框:错误、禁用、只读、带前缀和后缀,以及小号和大号

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

以 m3-like 显示

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

方面 文本输入框 包着它的字段
绘制 方框、文本、占位符、前缀和后缀、图标、日期或时间的分段、选择器按钮、调整手柄,以及浮在 filled 或 outlined 方框里的标签 stacked 输入框上方的标签行、必填或选填标记、帮助文本、错误文本、计数
保存 值、它在表单中的位置、事件 什么都不保存
告诉辅助技术 它自己的描述:前缀和后缀、计数 名称、帮助文本或错误文本、必填、无效、禁用

方框里发生的事,在单独使用、放在字段里和用在文本字段里时都一样,只在文本字段的页面上写一次:输入类型、多行和调整手柄、代码,以及带选择器按钮的日期和时间。

单独使用,没有字段

  • 名称是 label。labelHidden 让 filled 或 outlined 的输入框不把它画出来。
  • 错误是 error,由你来设置:方框画成错误状态,并暴露为无效。输入框没有错误文本。请在它旁边用文字说明哪里不对,或者用字段框住它。
  • 日期或时间只填了一半,或者填的值不可用时,方框画成错误状态,并触发 entryError。invalidText 或 unavailableText 会加进输入框的描述;没有任何东西把它画出来。
  • 计数会被记录、写进描述并朗读,但不绘制。countText 是文本形式的计数(“12/40”),留给你来绘制。
  • 必填要由字段来说明。单独使用的输入框没有必填设置:表单需要回答的地方,请自己校验。
  • 小号(32,文字 14)用于应用栏、工具栏或一排紧凑控件中的输入框:它与小号下拉选择框或小号按钮高度一致。medium(40)和 large(56)用于表单。无论哪种尺寸,它的点击区域都满足最小目标尺寸。
  • 从右到左页面中的前缀。 邮箱、URL、电话、数字或密码输入框的值从左往右书写。有前缀时,值紧贴着前缀,所以在从右到左的页面里,https:// 和地址也读作一个字符串;没有前缀时,值位于输入框的起始边。

已经输入的内容

entries 插槽是方框里位于键入文本之前的一个位置,用来放用户已经输入的内容:例如一列地址对应的纸片。输入框把插槽里的内容和键入部分排成可以换行的若干行,方框按整行增高。只要插槽里有内容,浮动标签就保持浮起,占位符也不显示。

<tanrei-text-input label="收件人" type="email">
  <tanrei-chip slot="entries" kind="input" size="small" label="[email protected]"
    remove-label="移除 [email protected]"></tanrei-chip>
</tanrei-text-input>

输入框不给这些项任何角色,不把它们排进焦点顺序,也不为它们处理任何按键:这些都由你负责。在方框里、所有项之外的地方按下,会让键入部分获得焦点。如果需要的是一列条目,连同它的按键、检查和表单值,请使用建立在这个位置之上的纸片字段。

构成

部件 说明
1 container The box around the input. A stacked or filled input fills it and carries the hover state layer on it; a press anywhere on it focuses the input.
2 active-indicator · 可选 The line along the bottom of a filled field; its focused state is thicker and colored.
3 outline · 可选 The border of an outlined input, which opens a gap where the floated label crosses it; in a stacked input, the line drawn inside the container's edge while it is focused or in error, which takes no layout space. 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 while the input is empty and unfocused, and floats above the input once focused or filled. 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 (TXI-50). Kept from assistive technology.
6 input The platform's own text element, which holds the value, the selection and any input-method composition. A date, time or date-time field draws a row of segments in its place. In a code field it is a left-to-right box in the code face that begins at the left in every layout direction, and the part that scrolls sideways while its lines do not wrap.
7 segment · 可选 One unit of a date or a time — year, month, day, hour, minute, day period — in the input line of a date, time or date-time field: focusable on its own, stepped, typed into and cleared on its own. The separators between segments are not segments.
8 placeholder · 可选 A hint shown in the empty input line; never a label. In a date, time or date-time field each empty segment shows its own.
9 prefix · 可选 Fixed text before the value (a currency sign). Colored by the affix part.
10 suffix · 可选 Fixed text after the value (a unit). Colored by the affix part.
11 leading-icon · 可选 An icon at the start of the field.
12 trailing-icon · 可选 An icon, or the product's icon-only Button, at the end of the field.
13 picker-button · 可选 In a date, time or date-time field, an icon-only Button of the text variant at the end of the container, showing the calendar_month glyph (date, date-time) or the schedule glyph (time); it asks the product to present Calendar or DateTimePicker.
14 resize-handle · 可选 In a multi-line field that is resized by hand, a Handle of size small in the container's bottom corner at its end edge — a short line while it resizes vertically, an arc while it resizes both ways — that the person drags, or moves from the keyboard, to resize the field. It is drawn by the Handle, never by a glyph of the icon set.
15 caret The insertion point, drawn by the platform in the caret color.
16 entries · 可选 What was entered already, inside the container and before the typing part, in lines that wrap: the content of the entries slot. The text input lays it out and draws none of it.

属性

属性 类型 默认值 说明
variant stacked | filled | outlined "stacked" 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, marked by a tinted box and a bottom line, or by a border. 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 a single-line input's container: stacked 32 / 40 / 56, as tall as a Button of the same size, so that an input 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. Medium and large are for forms; small is for an input in an app bar, a toolbar or a dense row of controls, beside a small select or button. The hit area always meets the minimum target.
type text | email | password | number | search | tel | url | code | date | time | date-time "text" What the value is: chooses the keyboard, autocorrection, obscured entry and semantics. code is text written for a machine rather than for a reader — a snippet of configuration, a pattern, an identifier, a query, a key: a left-to-right run in the code face that the platform does not correct, capitalise, check for spelling or complete, on one line or, with multiline, on many. date, time and date-time are entered segment by segment in the locale's numeric form and held as ISO 8601. The value is a string for every type.
value string "" The text in the field; for date, time and date-time, the ISO 8601 form of what its segments give (2026-09-27, 14:30, 2026-09-27T14:30), or empty while a segment is empty or the value is not available.
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.
placeholder string "" A hint shown while the value is empty and the label is not in the input line (above, floated or hidden). Never a replacement for label. In a code field it is an example of the code and is drawn as code (TXI-53, TXI-54); a hint in words belongs in the supportingText of its Field. Ignored by a date, time or date-time field, whose empty segments each show their own.
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 value means is the product's to validate; the input never sets this itself. A date or time input also enters an error of its own while it is committed half-filled or with a value that is not available (TXI-30).
disabled boolean false Prevents focus, editing and form submission. Inside a Field, disable the Field, so that its label follows.
readOnly boolean false The value can be focused, selected and copied, but not changed.
multiline boolean false Accepts line breaks and shows several lines, sized as resize says. Ignored for password, date, time and date-time.
minRows number 2 The fewest lines a multi-line field shows: the height of an empty auto-resized field, the starting and smallest height of a manually resized one, and the height of a fixed one.
maxRows number 0 The most lines an auto-resized field grows to before it scrolls, and the tallest a manually resized one can be made; 0 is no limit. Ignored while resize is fixed.
resize auto | manual | fixed "auto" How a multi-line field gets its height. auto: it follows the number of lines between minRows and maxRows, with an animated change, and has no handle. manual: it starts at minRows lines and the person resizes it with the handle in its bottom end corner. fixed: it stays at minRows lines, with no handle. Ignored unless multiline.
resizeAxis vertical | both "vertical" What the person can resize by hand: the height only, or the height and the width. Ignored unless resize is manual.
resizeLabel string "" The accessible name of the resize handle, in the product's language ("Resize"). The product's: Tanrei has no word for it. Empty reads the product's words. Required while the handle is shown.
wrap boolean true Whether a multi-line code field continues a line that does not fit on following rows (true), or keeps every line of the code on one row and scrolls sideways inside its container (false) — for code whose lines are read as rows: a table of values, a log, a file in which a line break means something. The value is the same either way. Ignored unless type is code and multiline is true: prose always wraps, and a single line always scrolls in its line.
maxLength number 0 The most user-perceived characters the user can enter; 0 is no limit. Ignored for date, time and date-time.
counter boolean false Keeps the character count (and maxLength, when set): part of the input's description and announced when typing pauses (TXI-19). The input draws none: a text field gives the count to its Field, which draws it at the end of its supporting row, and a product that frames the input by hand gives it to the Field's countText.
counterText string "" The count said to assistive technology while counter is true and maxLength is greater than 0: the whole sentence in the product's language with three places the input fills — {count} with the characters entered, {limit} with maxLength and {remaining} with how many more can be entered ("{remaining} characters left", "{limit}文字中{count}文字"). Empty reads the product's words; with neither, the count is said as the digits it is drawn in ("12/40"). A sentence that is right for every number, or a prop set per count where the language needs another form for one.
counterNoLimitText string "" The count said to assistive technology while counter is true and maxLength is 0: the whole sentence with one place, {count}, filled with the characters entered ("{count} characters", "{count}文字"). Empty reads the product's words; with neither, the count is said as its digits.
prefixText string "" Fixed text before the value, not part of it. In a code field it is code: drawn in the code face at the left of the value in every layout direction (TXI-53).
suffixText string "" Fixed text after the value, not part of it. In a code field it is code: drawn in the code face at the right of the value in every layout direction (TXI-53).
autocomplete string "" The autofill hint, as an HTML autofill field name (email, current-password, new-password, one-time-code, tel, postal-code, …); each platform maps it to its own content type. A code field left without one asks the platform to offer no remembered entry (TXI-55).
locale string "" A BCP 47 language tag ("en-US", "ja-JP") for how a date, time or date-time field shows and reads its value: the order of the year, month and day segments, the separators, the clock, the digits and the names of the units. Empty uses the platform's current locale. The calendar is the Gregorian calendar in every locale.
min string "" The earliest value a date, time or date-time field accepts from the person, in its ISO 8601 form; empty for no limit.
max string "" The latest value a date, time or date-time field accepts from the person, in its ISO 8601 form; empty for no limit.
disabledDates strings Dates inside min and max that a date or date-time field does not accept from the person, as ISO 8601 calendar dates — the same list the product gives its DateTimePicker. Ignored by a time field.
invalidText string "" The words for a date, time or date-time input committed with some segments filled and others empty: given to the Field that frames it, which shows them as its error text (TXI-30).
unavailableText string "" The words for a date, time or date-time input committed with a value before min, after max or, for a date, listed in disabledDates: given to the Field that frames it, which shows them as its error text (TXI-30).
segmentEmptyText string "" What assistive technology reads as the value of a date or time segment that holds nothing yet, in the product's language ("Empty"). The product's: Tanrei has no word for it. Empty reads the product's words; with neither, an empty segment has no value text.
picker boolean false Shows the picker button in a date, time or date-time field. The field presents no picker itself: it emits pickerRequest, and the product presents a DateTimePicker in the matching mode and sets value to what was picked.
pickerLabel string "" The accessible name of the picker button ("Choose date"). Required while picker is shown.

插槽

插槽 说明
leading-icon An icon at the start of the input.
trailing-icon An icon at the end of the input, or the product's own icon-only Button (clear, reveal password). A date or time field's picker button comes after it.
entries What was entered already — the product's own elements, or the chips of a component that holds the input (a chip field): laid out inside the box before the typing part, in lines that wrap (TXI-64). The text input gives them no role, no focus order and no key (TXI-66).

事件

事件 说明
input The user changed the value; carries the new value. Emitted for every change, not when the product sets value. A date, time or date-time field emits it when its value changes — when its last segment is filled, a filled field is edited, or it is emptied — not for a segment that leaves the value empty.
change The user committed a changed value (focus left the field, or the action key was pressed in a single-line field); carries the value.
action The user pressed the keyboard's action key (Enter, Return, Go, Search, Done) in a single-line field.
pickerRequest The user activated the picker button of a date, time or date-time field; carries the value, type, min and max. The product presents the picker and sets value to the picked value.
entryError The user committed a date, time or date-time field that is half-filled or whose value is not available; carries the reason (invalid: some segments are empty; unavailable: before min, after max or a listed date) and the text of the row of segments as drawn. The entry error itself is shown by the Field that frames the input (TXI-30).
resizeEnd The person finished changing the size of a field resized by hand: a drag of its handle ended, or a key or an activation of the handle changed the size (TXI-69). Carries lines, the number of lines the input shows, and width, the field's width in pixels WHILE resizeAxis is both (null otherwise). Not emitted when a change of resize, resizeAxis, minRows or maxRows gives the size back.

状态

行为

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

ID 需求
TXI-1 WHEN the user changes the value — by typing, deleting, pasting, cutting, dictating, autofill or an input method committing text — THE text input SHALL emit input once per change with the new value; WHEN the product sets value THE text input SHALL show it and SHALL NOT emit input or change.
TXI-2 WHEN the input loses focus (for a date, time or date-time field, when focus leaves its segments as TXI-43 says), or the user presses the keyboard's action key in a single-line field, with a value different from the one last committed (the value when the input gained focus, or at the last change) THE text input SHALL emit change once with the value.
TXI-3 WHEN the user presses the keyboard's action key in a single-line field THE text input SHALL emit action after any change it causes, and on the web, inside a form, SHALL then request the form's submission as a native input does unless action was cancelled; WHILE multiline is true the key SHALL insert a line break and SHALL NOT emit action. 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.
TXI-4 WHILE an input method is composing text THE text input SHALL leave the composition to the platform's native text element: it SHALL NOT write the value back into the element, trim, truncate, reformat or apply maxLength to it, and SHALL NOT emit change; input during a composition SHALL be the platform's own (marked as composing where the platform marks it), a committed composition SHALL always produce an input, and a value the product sets during a composition SHALL be applied when the composition ends.
TXI-5 WHILE disabled is true — set by the product, or by the Field that frames it (FLD-14) — THE text input SHALL NOT be focusable or editable, SHALL NOT emit input, change or action, SHALL expose the disabled state to assistive technology, SHALL be left out of form submission on the web, and SHALL render every part from the disabled component tokens of its variant (of its error parts WHILE error is true).
TXI-6 WHILE hovered or focused THE text input SHALL render its container, active indicator, outline, floating label and its asterisk, input, placeholder, prefix and suffix, icons, 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. 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.
TXI-7 THE text input SHALL show focus by its focused tokens — the focused active indicator or outline is its focus indicator, drawn inside the container's edge by a stacked field (TXI-26) — and SHALL NOT draw the focus ring; WHERE sys.behavior.focus-style is glow it SHALL also draw the glow around the container while focused.
TXI-8 WHERE the container is shorter than the minimum target THE text 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 input outside an interactive slot element, the picker button and the resize handle — the container's padding, a floating label, the prefix, the suffix, a decorative icon — THE text input SHALL focus the input (in a date, time or date-time field, the segment TXI-43 names); 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).
TXI-9 WHEN variant or size names a value that the active design system does not have THE text 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 text input does not know by name (one a layer added) it SHALL draw no label of its own and draw its edge as a stacked input does (TXI-26), with that value's own tokens; WHEN type names a value the text input does not know it SHALL behave as text and in debug builds report the unknown value.
TXI-10 WHILE readOnly is true and disabled is false THE text input SHALL stay focusable, selectable and copyable, SHALL NOT let the user change the value, SHALL NOT emit input or change, SHALL expose the read-only state to assistive technology, SHALL be submitted with its form on the web, and SHALL render as an enabled field, including its hovered and focused states.
TXI-11 WHILE error is true — set by the product, or by the Field that frames it (FLD-8) — or an entry error lasts (TXI-30) THE text input SHALL render every part, in every state, from the error parts of its variant (comp.input-box.outlined.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 the invalid state to assistive technology (aria-invalid on the web). THE text input SHALL never set error itself 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).
TXI-13 WHERE variant is filled or outlined, WHILE the input is focused, the value is not empty, or the platform reports the field autofilled, THE text input SHALL show its label floated, and otherwise rest it centred vertically in the container (for an outlined field, the input line) in comp.input-box.label.typescale.medium for size medium (and so on). A filled field floats the label to the top of the container, above the input line; an outlined field floats it onto the outline's top edge, centred on the line, and leaves a gap of comp.input-box.outline.notch-padding in the outline on each side of it. The floated label is drawn in comp.input-box.label.floated-typescale.medium for size medium (and so on). Beside a leading icon, an outlined field's floated label starts at comp.input-box.container.padding-inline.medium for size medium (and so on), over the icon, while its resting label starts at the input text; a filled field's label starts at the input text in both positions. WHEN the label does not fit on one line in the width it is given (a narrow field, a long or translated label, or enlarged text) THE text input SHALL wrap the label rather than cut it, resting and floated, and grow to hold it: a resting label wraps inside the container, which grows to hold its lines; a filled field's floated label takes as many lines as it needs above the input line; an outlined field's floated label sits on the outline's top edge with its last line centred on the line, the field reserving room above its container for the lines above that, and opens the outline's gap by the width of its widest line. The label SHALL never be drawn over the input or the value, and never be cut with an ellipsis, because text enlarged to 200% must lose no content. Neither variant SHALL change height when its label floats: an outlined field keeps the room for the floated lines above the last reserved while its label rests, as a filled field keeps its band (TXI-16). The label it floats SHALL be its accessible name (TXI-23): its own label where it has one, and otherwise the label of the Field that frames it. WHILE labelHidden is true — its own, or that Field's (FLD-25) — or it has no name THE text input SHALL draw no label (TXI-15). WHERE variant is stacked, or a variant laid out as stacked (TXI-9), THE text input SHALL draw no label at all: the label above it is the Field's row (FLD-2).
TXI-14 WHEN the label floats or rests THE text input SHALL move and resize it, and open or close the outline's gap, over comp.input-box.motion.label-duration with comp.input-box.motion.label-easing; WHEN its state changes it 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; WHERE motion is reduced it SHALL make both changes at once.
TXI-15 WHILE labelHidden is true or it has no name to float (TXI-13) THE text input SHALL NOT draw the floating label; WHILE the value is empty THE text input SHALL show placeholder only while the label is not in the input line — a stacked input, whose label is the row of its Field; floated; or not drawn — so that the two never overlap, and the segments of a date, time or date-time field SHALL be shown by the same rule (TXI-42); and it SHALL show prefixText before the value, comp.input-box.affix.gap from it, and suffixText at the end of the input line, comp.input-box.affix.gap after the input, both in the input's text style, exactly while the label is not in the input line; while shown, the prefix and suffix SHALL be part of the input's description, so that a unit or currency is read with the value.
TXI-16 THE text input SHALL be 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), and centre a single input line in it with at least comp.input-box.stacked.container.padding-block.medium above and below it in a stacked field and comp.input-box.container.padding-block.medium in a filled or an outlined field that does not draw its label (and so on) (a multi-line field sets its lines from the top instead, TXI-51); WHILE a filled field draws its label, resting or floated, it SHALL be at least twice comp.input-box.container.padding-block-with-label.medium plus one line of comp.input-box.label.floated-typescale.medium plus one line of comp.input-box.input.typescale.medium tall for size medium (and so on), so that it does not change height when the label floats. It SHALL grow with enlarged text and never clip it, pad its text by comp.input-box.container.padding-inline.medium and an icon by comp.input-box.container.padding-inline-with-icon.medium from the container's edge (and so on), round a stacked or outlined field's four corners and a filled field's top corners by comp.input-box.container.shape and a filled field's bottom corners by comp.input-box.container.shape-bottom, and ease them by sys.shape.corner-smoothing.
TXI-17 WHILE multiline is true and type is not password, date, time or date-time THE text input SHALL show its input as lines of comp.input-box.input.typescale.medium for size medium (and so on) and give it the height resize names — auto follows the number of lines (TXI-37, TXI-38), manual is the height the person gives it with its resize handle, starting at minRows lines (TXI-39–TXI-41), and fixed is minRows lines, with no handle, whatever maxRows is — scroll what does not fit, keeping the caret in view, align its floating label, icons, prefix and suffix with the first line, which keeps its place at the top of the container (TXI-51), and insert a line break on Enter; a minRows below 1 SHALL be 1. WHEN resize or resizeAxis names a value the text input does not know it SHALL behave as auto, or as vertical, and in debug builds report the unknown value; WHILE multiline is false it SHALL ignore resize, resizeAxis, minRows, maxRows and wrap; WHILE type is password, date, time or date-time THE text input SHALL stay single-line and in debug builds report a multi-line field of that type.
TXI-18 WHILE maxLength is greater than 0 THE text input SHALL refuse a user edit that would make the value longer than maxLength user-perceived characters (grapheme clusters: an emoji, or a letter with its accents, counts once) and shorten a paste to fit; it SHALL NOT cut a composition in progress but apply the limit when the composition is committed, and SHALL NOT shorten a value the product sets.
TXI-19 WHILE counter is true THE text input SHALL keep a count: the number of user-perceived characters in the value, counted as TXI-18 counts them — followed by a slash and maxLength WHILE maxLength is greater than 0 — written as digits and that one character, with no word. The count SHALL be part of the input's own description, before the description its Field gives (FLD-11), and WHEN typing pauses for one second THE text input SHALL announce the count once, politely, never on every keystroke — in both, as the product's sentence WHERE it has one: counterText WHILE maxLength is greater than 0, with {count}, {limit} and {remaining} filled, and counterNoLimitText WHILE it is 0, with {count} filled, each from the instance's prop or, WHILE that is empty, from the product's words of the keys characterCountText and characterCountNoLimitText, every number in the current locale's digits; and as the text of digits WHERE it has none, or WHILE the count is greater than maxLength (a value the product set: TXI-18 refuses typing past it), because a sentence of how many are left cannot say that. Another text between braces, and a brace that opens or closes nothing, SHALL be said as written and reported in debug builds. THE text input SHALL NOT draw the count: it SHALL let what holds it read the count, as the text of digits whatever sentence is said, at every moment, and SHALL say that it changed with every change of the value or of maxLength, a value the product sets included — so that a text field gives it to its Field, which draws it at the end of its supporting row (TXF-67, FLD-27), and a product that frames the input by hand gives it to that Field's countText. WHILE nothing draws it THE text input SHALL still keep, describe and announce the count.
TXI-20 THE text input SHALL give its input the keyboard and semantics of type: text a general keyboard; email an email keyboard without autocapitalization or autocorrection; password obscured, secure entry without autocorrection; number a numeric keyboard with a decimal separator; search a general keyboard whose action key reads as search; tel a phone keypad; url a URL keyboard without autocapitalization or autocorrection; code a general keyboard with nothing the platform would do to prose (TXI-55); date, time and date-time a numeric keypad on each number segment (TXI-45), without autocapitalization, autocorrection or suggestions. The value SHALL be a string for every type: number SHALL NOT parse, round or validate it, and date, time and date-time hold the ISO 8601 form of TXI-28.
TXI-21 THE text input SHALL pass autocomplete to the platform as its autofill hint (mapped to the platform's content type where it has one), and WHEN the platform autofills the field it SHALL float the label where its variant floats it (TXI-13) and emit input with the filled value; on the web, a field the browser marks as autofilled SHALL float its label even before the browser exposes the value to script.
TXI-22 THE text input SHALL draw an icon in the leading-icon or trailing-icon slot at comp.input-box.icon.size.medium for size medium (and so on), with the family and fill of an unselected icon, sys.icon.weight and an optical size clamped between sys.icon.optical-size.min and sys.icon.optical-size.max, colored by its leading-icon or trailing-icon part and comp.input-box.container.gap.medium from the text (and so on). Every glyph the text input draws — in these slots, and in the picker button (TXI-32) — SHALL be a glyph of the system's icon set at a step of the sys.icon scale; the text input SHALL draw no mark of its own. An interactive element the product places in a slot SHALL keep its own tokens and be its own focus stop after the input. THE text input SHALL build in no clear, reveal or other action except the picker button of a date or time field (TXI-32), and SHALL hide those a platform draws inside its native element (the web's search cancel button and password reveal button).
TXI-23 THE text 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 its accessible name, whether or not any label is drawn, and the Field's supporting text with, in error, the error text after it its description, after its own (the prefix and the suffix, TXI-15; the count, TXI-19). WHILE label is not empty THE text input SHALL use it as the accessible name instead, for an input no Field frames or one whose visible label is elsewhere. It SHALL never use placeholder as the name, WHILE it has either name THE text input SHALL expose that one alone, over a name the product gives it on the element (aria-label or aria-labelledby); and 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 text 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 text input SHALL expose the required state to assistive technology (and, on the web, a missing value to the form's constraint validation), whichever mark is drawn and where none is; it has no requirement setting of its own, SHALL NOT validate because of one, and SHALL NOT raise an entry error on an empty date for it (TXI-30).
TXI-24 WHEN the layout direction is right-to-left THE text input SHALL mirror its layout — leading icon on the right, trailing icon and picker button on the left, the prefix at the field's start edge and the suffix at its end edge beside a value laid out by its own direction (beside one that is always left-to-right they stand as TXI-67 says), the label floating from the right edge with its asterisk to its left, the resize handle in the container's bottom-left corner, where a drag or an arrow to the left widens a field that resizes both ways — and SHALL lay out the typed text by its own direction: the base direction of the value's first strong character and, WHILE the value is empty or holds no strong character (digits, spaces, punctuation), the layout direction, so that the caret of an empty field and its placeholder stand at the field's start edge. A single-line value SHALL be aligned to the start edge of its own direction (left-to-right text typed into a right-to-left field sits at the left), and in a multiline field each paragraph SHALL take the direction and the alignment of its own first strong character; except that the values of email, url, tel, number and password fields SHALL be laid out left-to-right, aligned to the field's start edge or, beside a prefix, to the prefix (TXI-67), the input line of a code field as one left-to-right row that begins at the left (TXI-53), and the segments of a date, time or date-time field as one left-to-right row at the field's start edge, in the order the locale's own form gives (TXI-42).
TXI-26 WHILE variant is stacked THE text input SHALL draw its container in its container color with no edge at rest (comp.input-box.stacked.outline.color is transparent), and WHILE focused SHALL draw its focused outline color and width as a line inside the container's edge, following its corners, that takes no layout space: the container's size and the places of the input text, the icons, the affixes and the picker button SHALL NOT change as the line appears, thickens or goes, and it SHALL change over the state duration of its size (comp.input-box.motion.state-duration.small, .medium or .large) with comp.input-box.motion.state-easing (TXI-14). WHILE the field is in error — error is true, or the entry error of TXI-30 — it SHALL draw the same inner line at rest, in comp.input-box.stacked.error.outline.color at comp.input-box.outline.width, so that the field itself is marked and not only its text. A hovered stacked field SHALL show the state layer on its container and draw no edge.
TXI-28 WHILE type is date, time or date-time THE text input SHALL hold as its value the ISO 8601 form of what its segments give — a calendar date (2026-09-27), a time of day in hours and minutes on the 24-hour clock (14:30), or both joined by T (2026-09-27T14:30), with no time zone — or an empty string (TXI-46), and SHALL show it not as one editable text but as a row of segments in the locale's numeric form (TXI-42), each entered, stepped and cleared on its own (TXI-43–TXI-45). The locale SHALL be locale, or the platform's current locale while locale is empty, and the calendar the Gregorian calendar in every locale. THE text input SHALL ignore placeholder, maxLength, prefixText and suffixText for these types, because every empty segment shows its own placeholder and the row is not free text, and in debug builds SHALL report one that is set.
TXI-29 WHEN the user pastes text while a segment of a date, time or date-time field has focus, or dictation or the platform's autofill hands the field text, THE text input SHALL read the whole text, whichever segment has focus: as a date WHEN it holds exactly three groups of digits (ASCII or the locale's) separated by one or more other characters, in the order of the locale's numeric form, or year, month, day WHEN the first group has four digits, with a four-digit year and a month and day that exist in that year, leading zeros optional; as a time WHEN it holds an hour and minutes as two groups of digits separated by one or more other characters, the hour from 0 to 23, or from 1 to 12 WHEN the locale's name for the morning or the afternoon, or a, p, am or pm in any case, comes before or after them; as a date-time WHEN it holds such a date and then such a time, separated by white space, a comma or T. WHEN the text reads as a value of the field's type THE text input SHALL fill every segment from it, move focus to the last segment and emit input as TXI-46 says; WHEN it reads as nothing THE text input SHALL leave every segment as it was. WHEN the user copies while a segment has focus THE text input SHALL put the whole row on the clipboard as drawn — the locale's form, with an empty segment's placeholder left out — and WHEN the user cuts it SHALL do the same and then empty every segment, unless readOnly is true.
TXI-30 WHEN the user commits a date, time or date-time field (TXI-43: focus leaves it, or the action key is pressed) WHILE some of its segments are filled and others are empty, or WHILE every segment is filled and what they give is not available (TXI-46), THE text input SHALL keep its segments as they are, emit change if the value changed since the last commit (TXI-2), emit entryError once with the reason — invalid for a field that is not completely filled, unavailable for a date or time before min, after max or listed in disabledDates — and the text of its row of segments as drawn, and enter an entry error: it SHALL render and be exposed exactly as WHILE error is true (TXI-11), and SHALL report the refusal to the Field that frames it with invalidText or unavailableText as its words, which that Field shows in its supporting row and announces (FLD-28: its errorText while that one is empty); WHILE no Field frames it that text SHALL be part of the input's description. The entry error SHALL end with the next edit of a segment or WHEN the product sets value, and THE text input SHALL then withdraw its report; while it lasts, on the web, the field SHALL report badInput for a half-filled row, rangeUnderflow or rangeOverflow for a value before min or after max, and a custom error for a listed date, to the form's constraint validation. A field whose segments are all empty SHALL commit without an entry error, whether or not its Field says it is required (TXI-23).
TXI-31 WHEN the product sets value on a date, time or date-time field THE text input SHALL fill every segment from it — or empty every segment for an empty value, except as TXI-46 keeps a half-filled row — and end any entry error, and SHALL NOT emit input or change (TXI-1) nor check it against min, max and disabledDates, because the field validates what the person enters and the product what it sets; WHEN value, min or max is neither empty nor the ISO 8601 form of the type THE text input SHALL treat it as empty, and an entry of disabledDates that is not an ISO 8601 calendar date as absent, and in debug builds report it, and it SHALL report a min later than max.
TXI-32 WHILE type is date, time or date-time, picker is true and readOnly is false THE text 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 calendar_month glyph for date and date-time and the schedule glyph for time, its glyph centred where a trailing icon's would be, with the trailing-icon slot's content, if any, before it, comp.input-box.container.gap.medium away for size medium (and so on). 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 (aria-haspopup="dialog" on the web), and a focus stop after the last segment and any interactive slot element; WHILE the field is disabled it SHALL be disabled with it. WHERE type is not date, time or date-time THE text input SHALL ignore picker and, WHILE picker is true, report it in debug builds.
TXI-33 WHEN the user activates the picker button THE text input SHALL emit pickerRequest once with the value, type, min and max — the empty value WHILE the row is half-filled or not available, without raising the entry error of TXI-30, because the picker is about to give a whole value — and SHALL NOT itself change the value, move focus or present anything: the product presents the picker — a DateTimePicker whose mode is the field's type (date, time or date-time), a docked one anchored to the field — and that picker returns focus to the picker button when it closes (DTM-4). WHEN the product then sets value to the picked value THE text input SHALL fill its segments as TXI-31 says, without emitting input or change, because the picker's own change already told the product.
TXI-34 THE text 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 text input is shown THE text input SHALL draw itself for the new direction at once, without a motion of its own, keeping its value, its selection and caret, and its focus.
TXI-35 WHERE the layout direction is right-to-left THE text input SHALL draw the glyphs of its leading-icon and trailing-icon slots mirrored left to right exactly when the system's icon set marks that glyph's name as mirrored or the product forces mirroring for that use, and unmirrored when the product forbids it: the icon helper mirrors the glyph inside its own box, about the box's vertical centre line, changing neither its place, size, color and fill nor the order TXI-24 gives. THE text input SHALL NOT mirror a glyph itself, and SHALL NOT mirror content the product gives as an image or a view of its own rather than by a glyph's name. The picker button's calendar_month and schedule (TXI-32) are not marked and are never mirrored.
TXI-36 THE text input SHALL lay out its floating label, its placeholder, its prefix and its suffix as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE text input SHALL still place each and align its lines by the layout direction, not by the text's own, except the prefix and the suffix of a value that is always left-to-right, which TXI-67 places. WHILE type is code the placeholder, the prefix and the suffix are code and SHALL be laid out as TXI-53 says instead; the floating label stays as this sentence says.
TXI-37 WHILE multiline is true and resize is auto THE text input SHALL place no resize handle and SHALL make its input exactly as tall as its lines of text — a line the text wraps onto counts as a line, and in a code field whose lines do not wrap (TXI-58) only the lines of the code count — never fewer than minRows lines and never more than maxRows lines (no upper limit while maxRows is 0, and exactly minRows lines while maxRows is smaller than minRows); WHILE the text has more lines than maxRows it SHALL scroll inside the input and keep the caret in view, and WHILE every line fits it SHALL show no scrollbar. THE height SHALL follow every cause of a changed number of lines — typing, deleting, pasting, a value the product sets, a changed width, enlarged text — and the container and whatever follows the input in the layout — the supporting row of its Field first — SHALL move with it.
TXI-38 WHEN the number of lines an auto-resized field shows changes because its value changed — by the person, or because value was set — THE text input SHALL change its height from the one shown to the new one over comp.text-input.motion.resize-duration with comp.text-input.motion.resize-easing, as one motion: however many lines arrive or leave at once, the height SHALL go from the one shown straight to the end height, which maxRows bounds, and never through a height for each line; a change that arrives while a motion is running SHALL continue from the height then shown to the new end height, and changes SHALL never be queued one after another. At every frame of the motion the first line and everything TXI-51 centres on it SHALL stay where they are, the container's bottom edge and whatever follows the input SHALL move with the height, the line that holds the caret SHALL stay in view, and no scrollbar SHALL be shown WHILE the end height holds every line. THE text input SHALL make the change at once, without that motion, WHEN it is first drawn or drawn again after it was not shown; WHEN the height changes because its width, its text size, minRows or maxRows changed; WHILE a pointer or a touch is held down in its text, so that text under a selection being dragged never moves away from the finger; and WHERE motion is reduced.
TXI-39 WHILE multiline is true, resize is manual and disabled is false THE text input SHALL start at minRows lines, SHALL NOT change its height with its content, and SHALL place a Handle in the container's bottom corner at its end edge, its box against both edges, over the text and inside a stacked field's inner line: size small, axis vertical WHILE resizeAxis is vertical and both WHILE it is both, corner bottom-end, and revealed WHILE a fine pointer is over the field or the input has focus (out of sight otherwise until it is used, HDL-23). Everything the handle draws — its line or arc, its box, its states, its focus ring — and its target and resize cursor are the Handle's (HDL-1 to HDL-5, HDL-13, HDL-14, HDL-23): the text input draws no glyph for it and gives it no color of its own, so that it is drawn alike in every variant and in error. WHEN the person drags the handle (its resize, HDL-6) THE text input SHALL follow without motion: vertically, the input's height between minRows lines and maxRows lines (no upper limit while maxRows is 0); and WHILE resizeAxis is both also horizontally, the field's own width, its end edge following the pointer, no wider and no narrower than its layout allows and never narrower than its inline paddings, its icons and sys.target.touch; WHILE resizeAxis is vertical a horizontal movement SHALL change nothing. THE text input SHALL keep the size the person gave it until resize, resizeAxis, minRows or maxRows changes, SHALL wrap its text to a new width and scroll what does not fit, and SHALL NOT select text, move the caret or take focus from the input because of a drag. WHILE readOnly is true the handle SHALL stay, because a person may need more of the text in view; WHILE disabled is true THE text input SHALL keep its size and place no handle.
TXI-40 THE text input SHALL leave the handle's hit area and its resize cursor to the Handle (HDL-5): at least sys.target.touch for touch input and sys.target.pointer for fine pointers, centred on the handle's box and reaching past the container's edges where it must, without changing the handle's drawn size or the field's layout. A press that begins inside that area SHALL belong to the handle and SHALL NOT place the caret, the text under it staying reachable from the keyboard and by scrolling.
TXI-41 THE text input SHALL make the handle one focus stop after the input, any interactive slot element and the picker button — a window splitter (HDL-8) — and give it the number of lines the input shows as its value, minRows as its min, as its max maxRows or, WHILE maxRows is 0, the greater of the lines shown and the lines the text needs, and resizeLabel as its label; WHILE resizeLabel is empty and the product's words give none it SHALL still render and in debug builds report that the handle has no accessible name. WHEN the handle asks for a step (HDL-9, HDL-10) THE text input SHALL answer it: along the block axis, amount one makes the input one line taller for direction 1 and one line shorter for −1, amount large as many lines as minRows, and amount limit returns it to minRows lines for −1 (Home) and takes it to maxRows lines for 1 (End; WHILE maxRows is 0, to the height that shows every line of the text); along the inline axis, which the handle has WHILE resizeAxis is both, direction 1 (the arrow that points to the field's end edge: Right Arrow in a left-to-right layout, Left Arrow in a right-to-left one) widens the field by one line height of its input text — as many as minRows for amount large — and −1 narrows it by as much, each within the limits of TXI-39. WHEN the handle is activated (HDL-7: a click or a tap that ends where it began, Enter or Space) THE text input SHALL make the input as tall as its text needs, within minRows and maxRows, and WHEN it is already that tall SHALL return it to minRows lines; and WHILE resizeAxis is both the same activation SHALL also make the field as wide as its layout allows — its own maximum width, or the width of its place where it has none — and, WHEN it already is that wide, give it back the width it had before the person resized it, so that neither the height nor the width of a field depends on a drag (WCAG 2.5.7, which a keyboard alone does not meet). A change made from the keyboard or by activation SHALL move as TXI-38 says.
TXI-69 WHEN the person has changed the size of a field resized by hand — a drag of its handle ended (its resizeEnd, HDL-6), or a step or an activation of the handle (TXI-41) changed the lines the input shows or the field's width — THE text input SHALL emit resizeEnd once with the lines the input shows and, WHILE resizeAxis is both, the field's width, so that a product can keep the size a person chose; a step or an activation that changed nothing, and a size given back because resize, resizeAxis, minRows or maxRows changed, SHALL emit none.
TXI-42 WHILE type is date, time or date-time THE text input SHALL draw in its input line, in place of one text input, one segment for each unit of the value, in the order and with the separators of the locale's numeric form: year, month and day for a date (month, day, year with "/" in en-US, "09/27/2026"; year, month, day in ja-JP, "2026/09/27"; day, month, year with "." in de-DE, "27.09.2026"); hour and minute, and a day-period segment where the locale's clock is the 12-hour one, for a time ("2:30 PM" in en-US, "14:30" in ja-JP); and for a date-time the date's segments, the text the locale joins them with, then the time's ("09/27/2026, 2:30 PM" in en-US). A filled segment SHALL show its number in the locale's digits — the year with four digits, the month, the day and the minute with two, the hour as the locale writes it — or the locale's name for the morning or the afternoon, in the input's text style and color; an empty segment SHALL show its placeholder in the placeholder color (the focused one as TXI-43 says): yyyy, mm, dd, hh and mm, and for the day period the locale's name for the morning. The separators and the joining text are not segments: they SHALL be drawn in the placeholder color WHILE every segment is empty and in the input color otherwise, SHALL NOT take focus, and SHALL be kept from assistive technology. Each segment SHALL be as wide as the wider of its placeholder and its widest filled form — four digits for a year, two for the month, the day, the hour and the minute, the wider of the locale's two names for a day period — with comp.text-input.segment.padding-inline on each side, whether it is empty, half typed or filled, so that the row never shifts as it fills or empties and no placeholder runs into a separator; a filled number stands at the end of its cell where it is narrower than the cell (an hour of one digit), and every other one in its middle. The row SHALL start where the input text starts, at the field's start edge, and SHALL be laid out left to right in every layout direction, a day-period segment isolated in its own direction.
TXI-43 WHILE type is date, time or date-time and disabled is false THE text input SHALL make each segment a focus stop of its own, in the row's order: Tab SHALL move from a segment to the next, and from the last to whatever follows it in the field (an interactive slot element, the picker button), and Shift+Tab the other way; Right Arrow SHALL move focus to the segment drawn to the right and Left Arrow to the one drawn to the left, stopping at the row's ends — the same segments in a right-to-left layout, because the row runs left to right there too. THE text input SHALL count as focused (TXI-6, TXI-7) WHILE any of its segments has focus, and SHALL draw the focused segment as selected text — comp.input-box.selection.color behind it across its width, and its text, the placeholder of an empty segment included, in comp.input-box.selection.content.color — with no caret; no part of the row can be selected on its own. WHEN the user presses a segment THE text input SHALL focus that segment; WHEN the user presses the field anywhere else that TXI-8 gives to the input THE text input SHALL focus the first empty segment, or the last segment WHILE none is empty. Moving focus between its segments, or between them and its picker button, SHALL NOT commit the field: it commits (TXI-2, TXI-30) WHEN focus leaves its segments and its picker button for anything else, or WHEN the action key is pressed on a segment.
TXI-44 WHEN the user presses Up Arrow or Down Arrow on a segment, and readOnly is false, THE text input SHALL raise or lower that segment by one within its own range — a year from 1 to 9999, a month from 1 to 12, a day from 1 to the last day of the month that the month and year segments give (31 while the month is empty, 29 for a February whose year is empty), an hour from 0 to 23 or from 1 to 12 by the locale's clock, a minute from 0 to 59, a day period between its two names — wrapping from the last value to the first and back, and changing no other segment, except that a day beyond the last day of a newly chosen month or year SHALL become that last day. On an empty segment either key SHALL fill it with the current date's or time's value for that unit, from the device's clock. Page Up and Page Down SHALL step by 5 years, 2 months, 7 days, 2 hours or 15 minutes, and Home and End SHALL set a month, day, hour or minute to the first and the last value of its range. min, max and disabledDates SHALL NOT limit a step: a value that is not available is refused as a whole (TXI-46), so that a person can pass through a month that is not available on the way to one that is.
TXI-45 WHEN the user types a digit — ASCII or the locale's, from a keyboard, a touch keypad or the text an input method commits — on a number segment, and readOnly is false, THE text input SHALL take it as the next digit of that segment's number WHILE the digits typed since the segment took focus still form a number in its range (TXI-44), and SHALL otherwise start the number again with that digit; a segment that holds one digit SHALL show it in its filled form, with its leading zero. WHEN no further digit could extend the number — after two digits of a month, day, hour or minute, after a first digit too large to begin a two-digit value in the range (a month's 2 to 9), after four digits of a year — THE text input SHALL move focus to the next segment, and it SHALL do the same WHEN the user types a character of the separator that follows a segment that is not empty ("/", ".", "-", ":" or a space). On a day-period segment the first letter of the locale's name for the morning or for the afternoon, or a or p in any case, SHALL set it. Backspace or Delete SHALL remove the last digit of the focused segment, or the whole of a day period, and Backspace on a segment that is already empty SHALL move focus to the previous segment without clearing it. A year segment that holds fewer than four digits SHALL count as empty for the value, because a short year is never guessed into a century. THE text input SHALL ignore every other character, SHALL take nothing from an input method while it is composing (TXI-4), and on a touch platform SHALL ask for the numeric keypad while a number segment has focus. WHILE readOnly is true the segments SHALL take focus and be copied from (TXI-29) and SHALL NOT change.
TXI-46 WHILE type is date, time or date-time THE text input SHALL have a value other than the empty string only WHILE every segment is filled and the date or time they give is available: not before min, not after max and, for a date or a date-time, its date not listed in disabledDates. WHEN an edit of a segment changes the value — the last empty segment is filled, a segment of a filled row is typed over, stepped or cleared, or what the row gives becomes or stops being available — THE text input SHALL emit input once with the new value (TXI-1); an edit that leaves the value as it was, such as a segment filled while another is still empty, SHALL emit nothing. WHEN the product sets value to what the field's value already is THE text input SHALL leave its segments as they are, so that a product that echoes the empty value back while a person is half-way through a date does not clear what they entered.
TXI-47 WHILE type is date, time or date-time THE text input SHALL expose its row of segments as a group named as the input is (TXI-23) and each segment as a spin button: its name the locale's own name for its unit (in English "year", "month", "day", "hour", "minute" and "AM/PM") followed by that name; its minimum and maximum the range TXI-44 gives it; its current value its number, with as its value text the number and the locale's month name for a month ("9 – September"), the hour with its day period on a 12-hour clock ("2 PM") and the period's name for a day period; and WHILE the segment is empty no current value, and segmentEmptyText as its value text. The description the input has (TXI-23) SHALL be the description of the first segment, and of every segment WHILE the field is in error; every segment SHALL be exposed as invalid WHILE the field is in error (TXI-11, TXI-30), as required WHILE its Field says it is required (TXI-23) and as read-only WHILE readOnly is true, and WHILE disabled is true SHALL be exposed as disabled and left out of the focus order. THE text input SHALL keep the separators, the joining text and the placeholders from assistive technology, and SHALL add no announcement of its own WHEN a segment changes: a spin button's new value is read by the platform.
TXI-50 WHERE variant is filled or outlined, WHILE the floating label is drawn (TXI-13) and the Field that frames the input gives it an asterisk as its required mark (FLD-25) THE text 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 (TXI-23). It SHALL draw no tag: 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. WHILE the floating label is drawn and the Field gives it an optional text (FLD-25) THE text input SHALL draw that text after the label's text, one word space from it, in the label's text style and color, at the label's place, resting and floated with it and wrapping with it, and SHALL keep it from assistive technology, which hears it in the description (FLD-11): a form that marks its optional fields shows which ones may be left out in a label that floats as in one above the box. WHILE no Field frames it, or the Field gives no mark, or the label is not drawn, THE text input SHALL draw no mark.
TXI-51 WHILE multiline is true THE text input SHALL align the content of its container to the container's top edge, not to its middle. It SHALL draw the first line of its input at the distance from the top edge at which a single-line field of the same variant, size, label and text size draws its one line (TXI-16): centred half of comp.input-box.stacked.container.height.medium below the top edge in a stacked field and half of comp.input-box.container.height.medium in an outlined field, for size medium (and so on), lower by the band of the label in a filled field that draws its label, and lower where enlarged text makes a single-line field taller. It SHALL centre on that first line the leading and the trailing icon, an interactive element the product placed in a slot, the prefix and the suffix, the first line of the placeholder and the resting label of an outlined field, and SHALL rest a filled field's label where a single-line filled field rests it; every further line SHALL follow below the first, and any height the container has beyond one line — further lines of text, the room minRows asks for, the height a person gave it with the handle — SHALL lie below the first line, never above it. WHEN the container's height changes — by an auto resize and its motion (TXI-38), by the resize handle (TXI-39, TXI-41), or because minRows or maxRows changed — the first line, the label, the icons, the slot elements, the prefix and the suffix SHALL keep their distance from the container's top edge during the change and after it, and SHALL NOT move at any frame of the motion; and the resize handle SHALL stay against the container's bottom edge and its end edge (TXI-39). WHILE the text scrolls inside the input (TXI-37) only the text SHALL move. A multi-line field that shows one line SHALL be drawn exactly as a single-line field of the same variant and size; WHILE multiline is false THE text input SHALL lay out as TXI-16 says, unchanged.
TXI-52 THE text input SHALL have no words of its own: it SHALL take resizeLabel and segmentEmptyText from the instance's prop and, WHILE that is empty, from the product's words of the same name, and counterText and counterNoLimitText as TXI-19 says, — the words a product sets once for all its components — and from nowhere else. WHILE neither gives resizeLabel the handle is as TXI-41 says: drawn, working and reported. IF neither gives segmentEmptyText THE text input SHALL expose an empty segment with no value and no value text, and in debug builds SHALL report the missing words once. The name of a segment's unit, the month's name and the period's name (TXI-47) are the platform's locale data and not the text input's words; the count (TXI-19) is drawn as digits and a slash, and said as the product's sentence where it has one; and the words of a requirement are the Field's (FLD-24).
TXI-53 WHILE type is code THE text input SHALL lay out its input line — the prefix, the value with its caret and its selection, the placeholder and the suffix — as one left-to-right row in every layout direction (COD-20, ICD-8): the row begins at the left end of the room the input line has between the icons, with the prefix first, the value beside it and the suffix at the row's right end; the value SHALL be aligned to the left, on one line and on many, in a field that is empty and in one that holds anything — never to the field's start edge, which TXI-24 gives the values of email, url, tel, number and password fields and which is the right in a right-to-left layout; the value's base direction left-to-right whatever its first strong character is and whether or not it holds one, so that an empty field, a field that holds only a bracket and a field whose first string is written in a right-to-left script are laid out alike; every line of a multi-line field left-to-right and beginning at the left; the caret of an empty field and its placeholder at the left; and sideways scrolling starting at the left. Text of a right-to-left script inside the code — a string, a comment — SHALL be laid out by the bidirectional algorithm inside its left-to-right line and SHALL reorder nothing outside its own run. WHERE the layout direction is right-to-left THE text input SHALL mirror everything else as TXI-24 says, and nothing of the row: the label floated from the right, the leading icon on the right and the trailing icon on the left of the row, and the resize handle in the container's bottom-left corner; the label row and the supporting row of its Field follow the page too (FLD-18, FLD-21). WHILE the layout direction is right-to-left and resize is manual — the one case in which the resize handle stands in the corner where a line of code begins — THE text input SHALL give the input room after its last line of the handle's box (comp.handle.container.breadth.small), as room the input scrolls through and not as height: the field SHALL be exactly as tall as the same field in a left-to-right layout, and WHEN the input is scrolled to its end the last line SHALL stand wholly above the handle's box. In a left-to-right layout, and while resize is auto or fixed, THE text input SHALL add no such room. WHEN the layout direction changes (TXI-34) the row SHALL keep its direction, its scroll offsets, its selection and its caret.
TXI-54 WHILE type is code THE text input SHALL draw the value, the placeholder, the prefix and the suffix in the code face: the family, the weight and the letter spacing of comp.text-input.code.typescale at the font size and the line height of comp.input-box.input.typescale.medium for size medium (and so on), so that a code field is exactly as tall as a text input of its variant and size, sets its first line where that field does (TXI-16, TXI-51) and keeps the text size below which a touch browser zooms into a field. It SHALL draw the characters as they are held — every space kept, at the start, in the middle and at the end of a line; a tab character advancing to the next multiple of comp.text-input.code.tab-size columns of the face; no two characters joined into a ligature; nothing hyphenated, transformed or substituted — and in the colors of its variant and state, unchanged: THE text input SHALL NOT color any part of the code by what it means. The floating label SHALL keep its own text style, and the rows of the Field that frames it theirs.
TXI-55 WHILE type is code THE text input SHALL ask its platform to leave the text alone: no spelling or grammar check and no marks of one; no autocorrection; no autocapitalization; no predictive or suggested words; no substitution of typed characters (straight quotation marks for curved ones, hyphens for dashes, two spaces for a full stop and a space, a text replacement of the person's device); no space added or removed around what is pasted or cut; no offer to translate the value; and, WHILE autocomplete is empty, no offer of an earlier entry. It SHALL give touch input a general keyboard — the one that puts ASCII letters and punctuation first where the platform has such a keyboard — SHALL NOT keep the person from another keyboard, script or input method, and SHALL leave a composition to the platform as TXI-4 says, because a string or a comment inside code may be in any language. THE text input SHALL hold the value exactly as it was entered: it SHALL NOT trim it, change its line breaks beyond what TXI-56 says, normalize its characters, parse it or validate it. What the code means, and whether it is well formed, is the product's: the product reads the value, and sets error, and its Field's errorText (TXI-11, FLD-7).
TXI-56 WHEN text is pasted, dropped or dictated into a field whose type is code THE text input SHALL take its plain text alone — no font, size, color, link, list or table of a formatted source — character for character: tab characters, no-break spaces and other spaces as they are, nothing converted to another character, and in a multi-line field every line break of the text as one line break of the value, whichever form the source wrote it in. A single-line field SHALL take a line break in such text as its platform's one-line text element does and SHALL NOT commit, submit or emit action because of one. maxLength SHALL apply as TXI-18 says. WHEN the person copies or cuts from a code field THE text input SHALL put on the clipboard the selected characters of the value alone, with the line breaks of the value and none that wrapping added (TXI-57).
TXI-57 WHILE type is code, multiline is true and wrap is true THE text input SHALL continue a line that does not fit on following rows: it breaks first at the spaces of the line and, where a part with no space is wider than the row, between any two characters; a following row SHALL begin at the left edge of the input, SHALL add no character and no mark, and SHALL NOT change the value, which holds the line breaks of the code alone; and the input SHALL NOT scroll sideways. A row the code wraps onto counts as a line for the field's height (TXI-37). WHILE type is not code, or multiline is false, THE text input SHALL ignore wrap — prose wraps as TXI-17 says and a single line scrolls within its line — and WHILE wrap is false there SHALL report it in debug builds.
TXI-58 WHILE type is code, multiline is true and wrap is false THE text input SHALL NOT break a line of the code: WHEN a line is wider than the input THE input SHALL scroll sideways inside the container — by pointer, touch and the wheel, and from the keyboard by moving the caret, which SHALL be kept in view (TXI-37) — beginning at the left, with the input's inline padding after the longest line scrolling with the code so that its last character can be brought clear of the container's edge. Only the code SHALL move (TXI-51): the container and its edge, the floating label, the icons, the prefix and the suffix and the resize handle SHALL keep their places, as do the rows of its Field. The length of a line SHALL change the width of nothing: the field is as wide as its layout makes it whatever it holds, no part of it SHALL count toward the width of the page or of a scrolling region the field stands in, and the page SHALL NOT scroll sideways for it. WHILE resize is auto the field's height SHALL be the lines of the code (TXI-37) and, WHERE the platform draws a sideways scrollbar that takes room, that room besides, so that no line stands under the scrollbar and none is scrolled up or down for its sake; a gesture or a wheel movement up or down over an input that cannot scroll that way SHALL scroll the page. THE input SHALL stay the field's one text stop in the focus order — the scrolling adds none — and the field SHALL show focus as TXI-7 says, on the container, which does not scroll; WHILE readOnly is true the caret SHALL still move and the input still scroll with it (TXI-10).
TXI-59 WHILE type is code THE text input SHALL change what no key does: Tab and Shift+Tab SHALL move focus out of the input as from every text input and SHALL never insert a character or an indent, so that the keyboard is never held in the field; Enter SHALL do what TXI-3 says for a single-line and for a multi-line field, with no indent added to the new line; and no key SHALL insert a matching bracket or quotation mark, change the indent of a selection, or comment a line. A tab character that reaches the value by a paste (TXI-56) or from the product SHALL be kept and drawn as TXI-54 says, and SHALL be removed by Backspace or Delete as one character.
TXI-60 WHILE type is code THE text input SHALL be exposed to assistive technology exactly as the text input of its other types is: a text box — a multi-line one WHILE multiline is true — named and described as TXI-23 says, and invalid, required, read-only or disabled as TXI-5, TXI-10, TXI-11 and TXI-23 say. It SHALL add no role, no role description, no word and no announcement for holding code, because Tanrei has no words (TXI-52) and what the field expects is said by the product in the label and the help of its Field; it SHALL expose the value character for character, with no part of it marked as misspelled; it SHALL keep the caret's and the selection's reporting to the platform's text element; and it SHALL NOT announce that a line wrapped or that the input scrolled.
TXI-61 WHERE the platform draws with a person's own forced colors THE text input SHALL draw a code field as it draws any field of its variant — its edge, its value and its placeholder in the platform's colors, the focused edge in the platform's highlight color — and nothing more: the code face, not a color, is what tells code from words. WHILE the text size is enlarged a code field SHALL grow with its text as TXI-16 and TXI-37 say, the code face keeping the input's size; at twice the text size in a container 320 wide a multi-line code field SHALL wrap (TXI-57) or scroll inside its container (TXI-58), a single-line one SHALL scroll within its line as every single-line field does, the floating label SHALL wrap (TXI-13), as the rows of its Field do (FLD-16), no content SHALL be cut, and the page SHALL NOT scroll sideways.
TXI-62 THE text 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 (TXI-13), so that the Field draws no label row (FLD-25); how far its text stands from its own start edge — its inline padding and, beside a leading icon, that icon and its gap (TXI-16, TXI-22) — and the padding it keeps at its end edge (TXI-16), so that the Field's supporting row starts and ends there (FLD-26); and an entry error with its words (TXI-30, FLD-28). Its count is not among them: the Field is given a count as words (FLD-27), by what holds the two (TXI-19). It SHALL take from that Field its name, its description and its required, invalid and disabled states (TXI-5, TXI-11, TXI-23), whether the label is hidden (TXI-13) and whether an asterisk follows it (TXI-50), so that a Field and a text input placed by hand are drawn, named, described and marked exactly as a text field is.
TXI-63 THE text input SHALL draw no label row above itself, no requirement tag, no help, no error text and no count: those are the rows of the Field that frames it (FLD-2 to FLD-7, FLD-27). WHILE no Field frames it THE text input SHALL be complete as a bare control — its box, the label that floats in it where its variant floats one, everything typed in it, its states and its events — THE text 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, never the platform's default width for a text element, and never the width of what it holds (TXI-58); the one width it keeps of its own is the one a person gives it with the resize handle (TXI-39). It SHALL be exactly as tall as its container, and the room TXI-13 keeps above an outlined one. A product that wants a narrower box gives it a narrower place.
TXI-64 WHILE the entries slot holds content THE text input SHALL lay that content and its typing part out inside the container, between the leading and the trailing parts, in lines from the start edge: each item comp.text-input.entries.gap after the one before, a line comp.text-input.entries.row-gap below the one above, every item centred on the middle of its line, an item that does not fit going whole to the next line and never wider than a line. The typing part SHALL follow the last item on its line and take what is left of it WHILE that is at least comp.text-input.entries.typing-min-width, and otherwise a line of its own. The first line SHALL stand where a single-line input of the same size draws its one line, centred in the size's height (comp.input-box.container.height.medium, and so on) or the block padding (comp.input-box.container.padding-block.medium, and so on) below the container's top where that is more, and the last line as far above its bottom, so that the container is the size's height while one line fits, as every input of a form is, and grows by one line and comp.text-input.entries.row-gap for each line after that. WHILE the text input is read-only and holds no typed text THE typing part SHALL take no room on a line and no line of its own, the entries ending the content, since nothing can be typed there; it SHALL stay focusable and exposed as the text input. WHILE the text input is disabled the typing part SHALL keep its room, so that the field keeps the shape it has when enabled and does not change height when it is enabled again.
TXI-65 WHILE the entries slot holds content THE text input SHALL treat itself as not empty for its label: a filled or outlined input floats it (TXI-13), and its placeholder is not shown. WHEN the input first appears holding entries it SHALL draw its label floated in its first frame, without the motion of TXI-14: appearing is no change of the label's place.
TXI-66 WHEN the user presses the container outside every item of the entries slot THE text input SHALL treat it as a press on the container (TXI-8). THE text input SHALL give the items of the entries slot no role, no focus order and no key: they are the product's, or those of the component that holds the input.
TXI-67 WHILE type is email, url, tel, number or password — a value THE text input lays out left-to-right whatever it holds (TXI-24) — THE text input SHALL treat the prefix, the value and the suffix as one run of writing and SHALL lay the three out in that order along the run's own direction in every layout direction, as the number input does (NMI-39): the run's direction SHALL be that of the first strong character of prefixText and, WHERE prefixText has none, of suffixText — a letter, or a direction mark the product wrote there — and left-to-right WHERE neither has one, so that "$ 120 USD", "https://" before an address and "@example.com" after a name stand in a right-to-left layout as in a left-to-right one, and a unit written in a right-to-left script stands at the value's left. THE text input SHALL decide that direction from prefixText and suffixText alone, never from the value. WHILE prefixText is not empty THE value, and an empty field's placeholder, SHALL stand beside the prefix, at the start of the run, in every layout direction, so that "https://" and the address after it read as one string and are not set apart by the width of the field; WHILE it is empty the value SHALL stay aligned to the field's start edge (TXI-24), the suffix after it. The icons, the picker button, the floating label and the paddings SHALL follow the layout. For every other type the value's direction is the person's and may change at any keystroke, so the row SHALL NOT follow it: the prefix stands at the field's start edge and the suffix at its end edge (TXI-24); a code field's row is TXI-53's, and a date, time or date-time field draws no affix (TXI-28).
TXI-68 THE text 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 typed text and the placeholder, the prefix and the suffix, the icons at either end, 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 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 those of what only a text input draws — the motion of a height that follows its text (TXI-38), a segment of a date or a time (TXI-42), the code face (TXI-53) and the entries place (TXI-64). WHEN a design system or a product sets a token of the box THE text input SHALL follow it, as the select, the combobox, the number input and the color input do, which read the same tokens; no token is held equal to another for this. WHERE one text 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 text input SHALL draw itself from the value it finds there.
TXI-70 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 text 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 text input is invalid — except those the text 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 text input SHALL take it off that element. WHEN the product sets an aria- attribute the text input owns THE text input SHALL report it in debug builds.

各平台名称对照

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

规格 Web SwiftUI Jetpack Compose Flutter React Native
组件 tanrei-text-input TanreiTextInput TanreiTextInput TanreiTextInput TextInput
variant · 属性 variant variant variant variant variant
size · 属性 size size size size size
type · 属性 type type type type type
value · 属性 value text value controller value
label · 属性 label label label labelText label
labelHidden · 属性 labelHidden labelsHidden labelHidden labelHidden labelHidden
placeholder · 属性 placeholder prompt placeholder hintText placeholder
error · 属性 error error isError isError error
disabled · 属性 disabled disabled enabled enabled disabled
readOnly · 属性 readOnly readOnly readOnly readOnly readOnly
multiline · 属性 multiline axis singleLine multiline multiline
minRows · 属性 minRows lineLimit minLines minLines minRows
maxRows · 属性 maxRows lineLimit maxLines maxLines maxRows
resize · 属性 resize resize resize resize resize
resizeAxis · 属性 resizeAxis resizeAxis resizeAxis resizeAxis resizeAxis
resizeLabel · 属性 resizeLabel resizeLabel resizeContentDescription resizeSemanticLabel resizeAccessibilityLabel
wrap · 属性 noWrap wrap softWrap softWrap wrap
maxLength · 属性 maxLength maxLength maxLength maxLength maxLength
counter · 属性 counter counter counter showCounter counter
counterText · 属性 counterText counterText counterText counterSemanticText counterAccessibilityText
counterNoLimitText · 属性 counterNoLimitText counterNoLimitText counterNoLimitText counterNoLimitSemanticText counterNoLimitAccessibilityText
prefixText · 属性 prefixText prefix prefix prefixText prefix
suffixText · 属性 suffixText suffix suffix suffixText suffix
autocomplete · 属性 autocomplete textContentType contentType autofillHints autoComplete
locale · 属性 locale locale locale locale locale
min · 属性 min min min min min
max · 属性 max max max max max
disabledDates · 属性 disabledDates disabledDates disabledDates disabledDates disabledDates
invalidText · 属性 invalidText invalidText invalidText invalidText invalidText
unavailableText · 属性 unavailableText unavailableText unavailableText unavailableText unavailableText
segmentEmptyText · 属性 segmentEmptyText segmentEmptyText segmentEmptyText segmentEmptyText segmentEmptyText
picker · 属性 picker onPickerRequest onPickerRequest onPickerRequest onPickerRequest
pickerLabel · 属性 pickerLabel pickerLabel pickerContentDescription pickerSemanticLabel pickerAccessibilityLabel
input · 事件 input text onValueChange onChanged onChangeText
change · 事件 change onCommit onCommit onCommit onEndEditing
action · 事件 action onSubmit keyboardActions onSubmitted onSubmitEditing
pickerRequest · 事件 pickerrequest onPickerRequest onPickerRequest onPickerRequest onPickerRequest
entryError · 事件 entryerror onEntryError onEntryError onEntryError onEntryError
resizeEnd · 事件 resizeend onResizeEnd onResizeEnd onResizeEnd onResizeEnd
备注 The input without the frame: the class TanreiTextInput, React TextInput. The host is display: block and as wide as its place, framed and bare (TXI-63): a Field keeps an inline-level control at its own size, at the start edge, so an inline host would not fill its Field. A form-associated custom element with a shadow root and delegatesFocus that takes name, submits its value, restores it and reports validity (a missing value while its Field says it is required; for date, time and date-time also badInput, rangeUnderflow and rangeOverflow while an entry error lasts, TXI-30). It renders an <input>, or a <textarea> while multiline, or the role="group" of spin buttons of a date or a time; the leading-icon and trailing-icon slots are named slots; the picker button is a <tanrei-button variant="text"> in the shadow root. What the text field's note says of the inner element, of the types, of the segments, of the handle, of noWrap (attribute no-wrap, the inverse of wrap) and of code holds here for this element, with --tanrei-comp-input-box-* for the box (TXI-68) and --tanrei-comp-text-input-* for what is the text input's own. Parts: container, outline, active-indicator, label (the floating label), requirement-label (its asterisk), input, segment, prefix, suffix, leading-icon, trailing-icon, picker-button, resize-handle. The connection with a Field is tanrei-field-connect (src/primitives/field.ts), in both directions (TXI-62): the control's side gains what it says of itself — drawsLabel, inset: { start, end } (lengths written by the input from its own tokens and its measured icon boxes), refusal: { text } — and the frame's side gains labelHidden and requiredMark (asterisk or none) beside the name, the description and the three states; a Field that does not read the three ignores them, and an input no Field answers is drawn as a bare one. The count is not in the exchange: countText is a read-only property of the element (the text of TXI-19, empty while counter is false), new after each of the element's updates, which a composed element reads as it reads the value and a product reads in its own input listener. The routine of TXI-37 and TXI-38 that measures the lines and moves the height is one file, src/primitives/auto-height.ts, which draws nothing and reads no token; the web's tests of the height are one suite, so that another element that types on several lines is held to the same behaviour. The name, the description, aria-invalid, aria-required and aria-readonly are written on the inner element, the input's own label winning. Attributes are kebab-case (label-hidden, min-rows, max-rows, prefix-text, suffix-text, invalid-text, unavailable-text, picker-label, resize-axis, resize-label, disabled-dates, segment-empty-text, no-wrap) except readonly, maxlength, autocomplete, min and max, which keep HTML's names. input and change are composed events; action is cancelable; pickerrequest and entryerror are composed CustomEvents whose detail carries { value, type, min, max } and { reason, text }. Words: resize-label and segment-empty-text left empty read the product's words (setWords()). For the types email, url, tel, number and password the row of prefix, input and suffix takes the direction TXI-67 gives as its own dir; for every other type it keeps the host's. The resize handle is a <tanrei-handle size="small"> in the shadow root (part resize-handle), whose events stay in that root: the element answers them and fires resizeend, a composed CustomEvent whose detail is { lines, width } (width null unless resize-axis is both). Planned: this platform has the text field as one view, the frame and the input together. It owes the input as a view of its own, with the names its text field uses today for these props; the Field around it gives the name, the description and the states through the platform's own channel, and the input says what it draws back up (TXI-62). Planned: this platform has the text field as one view, the frame and the input together. It owes the input as a view of its own, with the names its text field uses today for these props; the Field around it gives the name, the description and the states through the platform's own channel, and the input says what it draws back up (TXI-62). Planned: this platform has the text field as one view, the frame and the input together. It owes the input as a view of its own, with the names its text field uses today for these props; the Field around it gives the name, the description and the states through the platform's own channel, and the input says what it draws back up (TXI-62). Planned: this platform has the text field as one view, the frame and the input together. It owes the input as a view of its own, with the names its text field uses today for these props; the Field around it gives the name, the description and the states through the platform's own channel, and the input says what it draws back up (TXI-62). The name is the one React Native's own text input has: a file that needs both imports one under another name.

令牌

令牌 引用 解析值(浅色)
--tanrei-comp-text-input-code-tab-size — 2
--tanrei-comp-text-input-entries-gap sys.space.space100 8px
--tanrei-comp-text-input-entries-row-gap sys.space.space100 8px
--tanrei-comp-text-input-entries-typing-min-width sys.space.space900 72px
--tanrei-comp-text-input-motion-resize-duration sys.motion.role.resize.default 300ms
--tanrei-comp-text-input-motion-resize-easing sys.motion.easing.spatial cubic-bezier(0.2, 0, 0, 1)
--tanrei-comp-text-input-segment-padding-inline sys.space.space25 2px
--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-text-input-code-typescale sys.typescale.code 400 13px/1.5385
--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/text-input.spec.json, tokens/comp/text-input.tokens.json, tokens/comp/input-box.tokens.json, design/tokens/

Web 上绘制方式的不同之处

  • 这个元素是与表单关联的元素。有 name 时,它提交 value,重置为 value 属性(attribute)的值,在导航返回时恢复,跟随被禁用的 <fieldset>,并在所在的字段说明它必填而它为空时报告缺少值。处于输入错误的日期或时间也会被报告。
  • 文本在 shadow root 里的原生 <input> 中编辑,multiline 时是 <textarea>。日期或时间是一组微调按钮(spin button)。
  • 这个元素是一个块。focus() 会把焦点交给原生元素;在方框上、按钮之外的任何地方按下,也会让它获得焦点。
  • input 和 change 是 composed 事件。action 是可以取消的 CustomEvent:取消它,Enter 就不会提交表单。pickerrequest 和 entryerror 是 CustomEvent,它们的 detail 分别是 { value, type, min, max } 和 { reason, text }。它们的类型是 TanreiTextInputActionDetail、TanreiTextInputPickerRequestDetail 和 TanreiTextInputEntryErrorDetail。
  • countText 是只读属性,值每次变化之后都是新的。它没有对应的属性(attribute)。
  • 属性(attribute)用 kebab-case 书写,例如 label-hidden、min-rows、prefix-text,以及表示 wrap 为 false 的 no-wrap。readonly、maxlength、autocomplete、min 和 max 沿用 HTML 的名称。
  • 部件:container、outline、active-indicator、label、requirement-label、input、entries、segment、prefix、suffix、leading-icon、trailing-icon、picker-button、resize-handle。
  • 插槽:leading-icon、trailing-icon 和 entries。后置图标可以是你自己的纯图标 Button。entries 部件没有自己的方框:它里面的项就排在方框自己的各行里。
  • resize-label 和 segment-empty-text 留空时,从产品的文字里读取(setWords())。
  • 在元素完成定义之前,它没有尺寸。请预留方框的高度。

指南

文本输入框、文本字段,还是手写的字段

你需要 使用
标签、方框、帮助文本、错误和计数 文本字段
只要方框,标签位于别处:工具栏里的筛选框、表格的单元格、标签在旁边的一行 文本输入框,由它自己的 label 命名
在框架里面、方框旁边或下方放你自己的东西 一个字段,里面放一个文本输入框和你自己的元素
会展开建议或结果的搜索 搜索
可以步进、并限制在范围之内的数字 数字字段

推荐

  • 给单独使用的输入框一个 label,措辞与可见的标签相同,或者把可见的标签和它所在的位置合起来表达的意思说出来:“数量,橡木书桌”。
  • 让单独使用的输入框靠所在的位置得到宽度:网格的一列、一个单元格、工具栏里有宽度的一项。
  • 让可见的标签离得足够近,使看得见页面的人把两者读成一体。
  • 只要你需要的是方框上方的标签、帮助文本和错误,就使用文本字段。

避免

  • 不要为了省下标签的位置,在表单里使用单独的输入框。除了靠字形标明的筛选框或搜索框之外,哪里都看不到标签的输入框,对每个看到它的人来说都只能靠猜。
  • 不要把占位符当作标签。一有人键入它就消失,而且它绝不是名称。
  • 不要在字段里的输入框上设置 label、error 或 disabled。把它们写在字段上,标签和帮助文本才会随之变化。
  • 不要把文本字段放进字段。它本身已经是字段;字段框住的控件是文本输入框。
  • 不要用自己的样式在方框里绘制计数、帮助文本或错误。它们是字段的行。

无障碍

角色
textbox
标注
The accessible name is the label of the Field that frames the input, or its own label where no Field does; a filled or outlined input draws that name floating, and labelHidden only stops the drawing. The placeholder is never the name. The description is the input's own — the prefix and the suffix while shown, the count while counter is true — followed by what the Field gives: its supporting text with, in error, the error text after it and its optional text. 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 read-only while readOnly is true. A search input is exposed as a search box where the platform has that role. A date, time or date-time input is a group, named as the input is, whose segments are spin buttons named by their unit and that name, with a range, a value and a value text (segmentEmptyText while empty). The picker button is named by pickerLabel and exposed as opening a dialog. The resize handle is a window splitter named by resizeLabel whose value is the number of lines shown. A code input is the same text box as any other type: no role or word says that it holds code (TXI-60).
最小目标
即使外观尺寸更小,点击区域也满足最小目标尺寸。 minimum 32px · pointer 44px · spacing 8px · touch 48px

键盘操作

按键 动作
Tab Moves focus to the input; further Tabs move to an interactive element in the trailing slot, then to the picker button, then to the resize handle, where there are any. In a date, time or date-time field Tab visits each segment in turn first. In a code field too: Tab never inserts a character or an indent (TXI-59).
Typing, Backspace, Delete, arrows, Home, End, selection and clipboard shortcuts Edit the value as the platform's own text element does (types other than date, time and date-time).
Enter In a single-line field, commits the value and emits action (and submits the enclosing form on the web). In a multi-line field, inserts a line break.
Arrow keys, Home, End in a multi-line code field whose lines do not wrap Move the caret as in any text; the input scrolls sideways to keep it in view (TXI-58).
Left Arrow, Right Arrow on a segment Move focus to the segment drawn to the left or to the right (TXI-43).
Up Arrow, Down Arrow on a segment Raise or lower the segment by one, wrapping; fill an empty segment from the current date or time (TXI-44).
Page Up, Page Down, Home, End on a segment Step by a larger amount; go to the first or the last value of the segment (TXI-44).
Digits on a segment Fill the segment and move to the next once it can take no more; the separator's character also moves on (TXI-45).
Backspace / Delete on a segment Remove the segment's last digit; Backspace on an empty segment moves to the previous one (TXI-45).
Paste, copy and cut on a segment Paste reads a whole date or time into every segment; copy and cut take the whole row (TXI-29).
Enter / Space on the picker button Emits pickerRequest (TXI-33).
Up Arrow, Down Arrow, Page Up, Page Down, Home, End on the resize handle Make the field one line shorter or taller (with Shift, or with Page Up and Page Down, as many lines as minRows); return it to minRows or take it to its tallest (TXI-41).
Left Arrow, Right Arrow on the resize handle Where the field resizes both ways, narrow or widen it; the arrow toward the end edge widens (TXI-41).
Enter / Space on the resize handle Fit the height to the text, or return to minRows when it already fits (TXI-41).

备注

  • Text entry happens in the platform's native element: on the web an <input> or <textarea> in the shadow root, with the label, description and invalid state set on that element — not through ElementInternals, which axe cannot see. The host is form-associated: it takes name, submits the value and joins constraint validation. A date, time or date-time field is the one exception: its segments are spin buttons that take digits one unit at a time, as the platforms' own date fields do, because one free text cannot give each unit a name, a range and a step.
  • Heights are minimums: at 200% text size the field grows, the floated label wraps rather than clips, and the input keeps its line height.
  • Web: iOS Safari zooms the page into an input whose text is smaller than 16 px. Both default sizes use 16 px text (comp.input-box.input.typescale); a layer that sets a smaller style brings the zoom back.
  • A trailing action (clear, reveal password, voice input) is the product's own icon-only Button, with its own accessible name in the product's language. The field builds none in except a date or time field's picker button, which the product names with pickerLabel, because each needs a localized name and a policy the field cannot know.
  • A date or a time is entered unit by unit: each segment says what it is, shows its own placeholder and cannot hold a value outside its range, so the format never has to be explained or remembered (WCAG 3.3.2), and a whole date can still be pasted. The picker is an alternative, never the only way.
  • Resizing by hand never depends on a drag (WCAG 2.5.7): the handle is a focus stop that the arrow keys move, and a click, a tap, Enter or Space fits the field to its text. Its hit area meets the minimum target although its line is small (WCAG 2.5.8).
  • A field that follows its text changes height with a short motion; where motion is reduced it changes at once (WCAG 2.3.3).
  • 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.
  • 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 to FLD-28), or the product names it with label where its visible label is elsewhere. Unframed and unnamed, it is reported (TXI-23).
  • Code is not prose (type code): it is left to right in every language, so a code field's input line keeps that direction and begins at the left while the label, the icons and the messages follow the page (TXI-53); and the platform's help for prose — spelling marks, autocorrection, capitals, curved quotation marks — changes or misreports it, so the field asks for none (TXI-55).
  • Tab always leaves a code field (WCAG 2.1.2). A field that indents with Tab needs a way out, words that say what it is, and a state that assistive technology is told — an editor's contract, which a product that embeds an editor takes on with it.
  • A code field whose lines do not wrap scrolls in two directions inside its container; the page never does (WCAG 1.4.10 allows it for content whose lines carry meaning). The caret is how the keyboard scrolls it, so a value that nobody may edit but that must be read whole is readOnly, not disabled, or is a Code block.
  • A screen reader reads punctuation and capitals in a code field as the person has set it to: the field cannot and does not change that. Color carries nothing in a code field — no part of the code is colored by its meaning — so nothing is lost in forced colors (TXI-61).

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

组件负责的部分

  • 它是一个文本框,multiline 时是多行文本框;type 为 search 时,在有这个角色的平台上是搜索框;日期或时间是一组微调按钮。
  • 它的名称是它自己的 label;它没有 label 时,是包着它的字段的标签。占位符绝不是名称。
  • 它的描述依次是:显示出来的前缀和后缀,计数,然后是字段给它的内容,也就是帮助文本或错误文本。
  • 处于错误状态时,它暴露为无效;所在的字段说明它必填时,暴露为必填;只读和禁用时,也分别暴露出来。
  • 键入停顿一秒之后朗读一次计数,绝不是每按一次键就朗读,也不管有没有东西把它画出来。朗读的是当前的样子(“12/40”),或者在你给出句子时朗读你的句子:有 maxLength 时是 counterText,带占位符 {count}、{limit} 和 {remaining}(“还可输入 {remaining} 个字”);没有时是 counterNoLimitText,带 {count}。可以写在元素上,也可以用 setWords({ characterCountText, characterCountNoLimitText }) 只给一次。超过上限的值只能由你设置,这时按数字朗读。同一个句子也是输入框的描述;画出来的仍然是数字。
  • 焦点由方框自己的边缘来显示,无论来自键盘还是指针。点击区域满足最小目标。
  • 浮动标签后面的星号对辅助技术隐藏:必填状态已经说明了这一点。
  • 缺少名称会在调试构建中报告。

需要你做的事

  • 用 label 为每个单独使用的输入框命名。它旁边可见的文本并不能为它命名。
  • 单独使用的输入框可能出错的地方,要用辅助技术读得到的文字说明哪里不对:一条与页面关联的、你自己的消息,或者包着输入框的字段。
  • 对日期或时间,给出 segmentEmptyText,并且即使没有字段显示它们,也要写上 invalidText 和 unavailableText:它们会随输入框一起朗读。
  • 用 resizeLabel 为调整手柄命名,用 pickerLabel 为选择器按钮命名。