ワンタイムコードフィールド
ユーザーへ送った短いコードを、完成した 1 つのフィールドとして受け取ります。ラベルの下にマス目があり、補足の 1 行と、コードが違うときの言葉が付きます。支援技術に対して 1 つに結び付けられ、フォームには 1 つのコントロールとして加わります。
- カテゴリ
- テキスト入力
- トークン
comp.field- レベル
- 合成
- 構成要素
- Field, One-time-code input
- Web
tanrei-one-time-code-fieldschedule - SwiftUI
TanreiOneTimeCodeFieldradio_button_unchecked - Jetpack Compose
TanreiOneTimeCodeFieldradio_button_unchecked - Flutter
TanreiOneTimeCodeFieldradio_button_unchecked - React Native
OneTimeCodeFieldradio_button_unchecked
生成元 docs/status/status.json, specs/one-time-code-field.spec.json
ワンタイムコードフィールドと、プロダクトがコードを受け付けなかったもの
ワンタイムコードフィールドは、プロダクトが送った短いコードを入力してもらう場面で使います。サインイン、メールアドレスや電話番号の確認、支払いの承認などです。ラベル、マス目、コードの送り先を伝える 1 行、コードが違うときの言葉という、いつもの組み合わせが、そのまま使える形でそろっています。
構成要素は、フィールドとワンタイムコード入力欄です。フィールドは枠で、ラベル、必須または任意の印、補足、エラーを受け持ちます。ワンタイムコード入力欄はコントロールで、マス目と、その中でユーザーが行うすべてを受け持ちます。ワンタイムコードフィールドが自分で描くものはなく、トークンもありません。プロパティはどれも 2 つのどちらかのもので、そのまま渡されます。
幅は置かれた場所に合わせて広がり、マス目は先頭の端から並びます。
Web では <tanrei-one-time-code-field> です。ほかのプラットフォームはまだ実装していません。
value は、そこまでに入力されたコードです。グループをどう描いていても、区切りは含みません。4 つのイベントはワンタイムコード入力欄のもので、どれが届いた時点でも、フィールドの value はすでに新しい値になっています。
<form>
<tanrei-one-time-code-field name="code" label="確認コード"
supporting-text="携帯電話に送った 6 桁のコードを入力してください。"
error-text="コードが正しくありません。メッセージを確かめて、もう一度入力してください。"
required required-text="必須"
group-size="3"></tanrei-one-time-code-field>
</form>
<script type="module">
import '@tanrei/web/components/one-time-code-field';
const code = document.querySelector('tanrei-one-time-code-field');
// ユーザーが値を変えました。値はすでに新しいものです。
code.addEventListener('input', () => (code.error = false));
// 最後のマスが埋まったか、コード全体が貼り付けられた、または自動入力されました。ほかには何も起きません。
code.addEventListener('complete', async (e) => {
code.readOnly = true;
const right = await verify(e.detail.value);
code.readOnly = false;
code.error = !right;
});
</script>import { OneTimeCodeField } from '@tanrei/react';
<OneTimeCodeField name="code" label="確認コード" error={wrong}
supportingText="携帯電話に送った 6 桁のコードを入力してください。"
errorText="コードが正しくありません。メッセージを確かめて、もう一度入力してください。"
groupSize={3} value={code}
onInput={(event) => setCode(event.currentTarget.value)}
onComplete={(event) => verify(event.detail.value)} />同じフィールドを 2 つの構成要素から自分で書いても、見た目は同じで、支援技術にとっても同じテキストボックスになります。
<tanrei-field label="確認コード"
supporting-text="携帯電話に送った 6 桁のコードを入力してください。"
error-text="コードが正しくありません。メッセージを確かめて、もう一度入力してください。">
<tanrei-one-time-code-input name="code" group-size="3"></tanrei-one-time-code-input>
</tanrei-field>同じフィールドを自分で書いたもの。フィールドの中にワンタイムコード入力欄があります
ワンタイムコードフィールドにない並べ方が必要なときに、1 つ下の階層で書きます。
| 必要なもの | 使うもの |
|---|---|
| ラベル、マス目、補足、エラー | ワンタイムコードフィールド |
| 枠の中、マス目の隣に置く自分の要素(コードを送り直すコントロール、残り時間の表示など) | フィールドに、ワンタイムコード入力欄と自分の要素を入れる |
| マス目だけ。ラベルは別の場所(ダイアログの見出し、ステップのタイトルなど)に描かれている | ワンタイムコード入力欄を単独で使い、入力欄の label で名前を付ける |
| マス目のない 1 つの入力欄。コードの長さがわからない | autocomplete="one-time-code" を付けたテキストフィールド |
1 つ下の階層で変わるのは、何をどこに指定するかです。name と value はワンタイムコード入力欄に指定し、フォームに加わるコントロールもイベントが届く先も入力欄になります。label、error、disabled はフィールドに指定したままにします。フィールドがコントロールに伝えるので、入力欄の側には指定しません。
プロダクトの言葉で示した必須、任意、無効、4 桁の隠したコード
| 観点 | フィールドから | ワンタイムコード入力欄から |
|---|---|---|
| プロパティ | label、labelHidden、supportingText、errorText、error、disabled、required、optional、requiredMark、requiredText、optionalText |
value、length、type、groupSize、mask、readOnly |
| イベント | — | input、change、complete、action |
| スロット | label-icon |
— |
| トークン | comp.field.* |
comp.one-time-code-input.* |
ワンタイムコード入力欄は、自分の label、error、disabled を持っています。これらはワンタイムコードフィールドのプロパティではありません。フィールドの label がコントロールに名前を付け、error がマス目をエラーの状態にし、disabled がマス目を無効にします。そのため、どれもワンタイムコードフィールドに 1 回指定すればよく、ラベルもコントロールと一緒に変わります。
マス目の動き(入力、貼り付け、矢印キー、グループ)はワンタイムコード入力欄のページに、枠の動き(必須の印、補足、エラーとその読み上げ)はフィールドのページにあります。
ワンタイムコードフィールドに自分のトークンはありません。枠はフィールドのトークンを、マス目はワンタイムコード入力欄のトークンを、どこで設定されていても読みます。1 つだけ変えるには、構成要素のトークンをその要素に設定します。
<tanrei-one-time-code-field label="確認コード"
style="--tanrei-comp-field-label-gap: 12px"></tanrei-one-time-code-field>構成要素
構成要素
supporting の上に描いています。| パーツ | 説明 |
|---|---|
1 field | The frame: a Field, whole — its label row with the label glyph and the requirement mark, and its supporting row, where the error text stands in the help's place or below it (FLD-7). Drawn by the Field from the Field's tokens (FLD-1 to FLD-9). |
2 one-time-code-input | The frame's one control: a One-time-code input, whole — its cells, its characters, its caret and its group marks. Drawn by the One-time-code input from its own tokens (OTC-1 to OTC-3, OTC-15). |
プロパティ
| プロパティ | 型 | 既定値 | 説明 |
|---|---|---|---|
label | string | "" | Names the control, visibly and to assistive technology. Required, unless the control names itself (a checkbox or a switch with its own label): then leave it empty and the field adds only help and an error. — Field Always given: the control of a one-time-code field never names itself, so the case of an empty label does not arise. |
labelHidden | boolean | false | Does not draw the label, which stays the accessible name. For a control whose visible label is elsewhere (a table column, a toolbar). — Field |
supportingText | string | "" | Help shown below the control and given to assistive technology as the control's description. While the field is in error it gives way to errorText, unless the design system keeps both (comp.field.error-text.placement append). — Field |
errorText | string | "" | Shown while error is true, in supportingText's place — or below it, which then stays, where the design system's comp.field.error-text.placement is append: what is wrong and how to put it right, in words. — Field |
error | boolean | false | Puts the field in the error condition: the error text is drawn, the control is exposed as invalid and, where it has an error condition of its own, drawn in it. What a value means is the product's to validate; the field never sets this itself. — Field The one error of the one-time-code field: the Field passes it to the control (FLD-8, OTC-17), whose own error is not a prop here. |
disabled | boolean | false | Disables the control and draws the frame as disabled. Disable a framed control here, not on the control, so that its label follows. — Field The one disabled of the one-time-code field: the Field passes it to the control (FLD-14, OTC-20), whose own disabled is not a prop here. |
required | boolean | false | What the form asks of the control: true exposes it as required and draws the required mark beside the label. It never validates: a missing answer is the product's to report with error. — Field |
optional | boolean | false | Draws the optional tag after the label and adds optionalText to the control's description, because assistive technology has no state for it. Ignored while required is true: a control is never both. — Field |
requiredMark | auto | tag | asterisk | none | "auto" | How this control shows that it is required: tag is a small filled Tag with requiredText, asterisk is "*" after the label, none draws nothing and keeps the semantics. Auto takes comp.field.requirement.mark, which follows sys.behavior.requirement-mark, the system's one answer. Ignored unless required is true. — Field |
requiredText | string | "" | The text of the required tag, in the product's language ("Required", "必須"). The product's: Tanrei has no word for it. Empty reads the product's words; with neither, FLD-24 says what is drawn. — Field |
optionalText | string | "" | The text of the optional tag, in the product's language ("Optional", "任意"); also read to assistive technology as part of the description. The product's: Tanrei has no word for it. Empty reads the product's words. — Field |
value | string | "" | The code entered so far: at most length characters, digits or, for alphanumeric, digits and upper-case letters, with no separator. One string, whatever the cells and groups drawn. — One-time-code input |
length | number | 6 | How many characters the code has, and so how many cells are drawn. A whole number of 1 or more. — One-time-code input |
type | numeric | alphanumeric | "numeric" | What a cell takes: numeric is the digits 0 to 9, with a numeric keypad; alphanumeric is digits and the letters A to Z, held in upper case, with a general keyboard. — One-time-code input |
groupSize | number | 0 | Draws the cells in groups of this many, counted from the first, with a mark between two groups (3 for a six-character code written "123 456"). 0 draws one group. It changes the drawing only: the value has no separator. — One-time-code input |
mask | boolean | false | Draws the platform's obscuring mark in each filled cell in place of its character, and exposes the field as protected. For a screen other people can see; a code that is used once and expires rarely needs it. — One-time-code input |
readOnly | boolean | false | Keeps the field focusable and its value readable, and lets nothing change it: for the moment a complete code is being checked, when taking focus away would lose the place of a person who must then correct it. — One-time-code input |
スロット
| スロット | 説明 |
|---|---|
label-icon | A glyph before the label. — Field |
イベント
| イベント | 説明 |
|---|---|
input | The person changed the value; carries the new value. Emitted for every change, not when the product sets value. — One-time-code input |
change | The person committed a changed value (focus left the field, or the action key was pressed); carries the value. — One-time-code input |
complete | A change by the person left the value length characters long; carries the value. Emitted after input, once for that change. The field does nothing else: checking the code is the product's. — One-time-code input |
action | The person pressed the keyboard's action key (Enter, Return, Done). — One-time-code input |
状態
振る舞い
EARS 記法による要件です。各プラットフォームの実装は、この ID に対応するテストで検証されます。要件の原文は仕様ファイルのものをそのまま掲載しています。
| ID | 要件 |
|---|---|
OTF-1 | THE one-time-code field SHALL be a Field whose one control is a One-time-code input, and SHALL draw nothing of its own: every row, text, mark, cell and line it shows is drawn by one of the two, from that component's own tokens, as FLD-1 to FLD-8 and OTC-1 to OTC-3, OTC-7 and OTC-15 to OTC-17 say. THE one-time-code field SHALL have no token, no size and no gap of its own: the Field places the control and gives it its width (FLD-1), and the One-time-code input lays its row out in that width (OTC-1, OTC-23). What it shows SHALL be the picture a product gets by placing that One-time-code input in that Field by hand with the same values, and what assistive technology is told SHALL be the same name, description and states (FLD-10, FLD-11, OTC-22). |
OTF-2 | THE one-time-code field SHALL give each of its props, unchanged, to the member it is from and SHALL hold no state between the two: label, labelHidden, supportingText, errorText, error, disabled, required, optional, requiredMark, requiredText and optionalText are the Field's; value, length, type, groupSize, mask and readOnly are the One-time-code input's. A value a member does not know SHALL be passed on as given and answered by that member (FLD-22, OTC-19). THE one-time-code field SHALL never set the One-time-code input's own label, error or disabled: the Field's label names the control (FLD-10, OTC-22), the Field's error puts it in its error condition (FLD-8, OTC-17) and the Field's disabled disables it (FLD-14, OTC-20), so that each is said once, in the place where the label follows. |
OTF-3 | THE one-time-code field SHALL hold one value, the One-time-code input's. WHEN the person changes it THE one-time-code field's value SHALL be the new one before any event is reported, and THE one-time-code field SHALL report input, change, complete and action as the One-time-code input emits them — the same events, carrying the same value, in the same order and as often (OTC-13, OTC-14) — as its own, adding none and holding none back. WHEN the product sets value THE one-time-code field SHALL show it as OTC-18 says and SHALL report no event. |
OTF-4 | WHERE the platform has forms (the web) THE one-time-code field SHALL be the one control the form meets, and what OTC-29 says of a One-time-code input SHALL hold of the one-time-code field as a whole: it takes name; it submits the code alone, an empty string WHILE it holds none, and nothing WHILE disabled (OTC-20); it is restored on navigation and resets to the value it was first given; and it reports a missing value WHILE required is true and the value is empty, and nothing for a code shorter than length. Its members SHALL add no entry of their own to the form, and the action key SHALL submit the form the one-time-code field belongs to as OTC-13 says, unless action was cancelled. |
OTF-5 | THE one-time-code field SHALL be one stop in the focus order, its control's (FLD-12, OTC-2). WHEN the product moves focus to the one-time-code field THE one-time-code field SHALL pass it to the control, whose active cell is then the one OTC-5 names. A press on the label row SHALL move focus to the control and a press on the supporting row SHALL do nothing (FLD-12); THE one-time-code field SHALL take focus for no other press, SHALL add no key, and SHALL draw no focus indicator of its own: the frame's focused tokens and the active cell's focused line are the members' (FLD-13, OTC-7). |
OTF-6 | THE one-time-code field SHALL hold exactly one control and SHALL take no other from the product: it has no place for a child but the Field's label glyph (FLD-3, FLD-20), so that the cases of FLD-15 — no control, several controls — and of FLD-23 — a control replaced by another — never arise in it. IF the one-time-code field is placed in a Field THEN THE one-time-code field SHALL be drawn as it is and reported in debug builds as a field placed in a Field (FLD-15); WHERE it is placed in a field group THE one-time-code field SHALL follow the group's disabled as a Field does (FGR-14) and SHALL take nothing else from the group. |
OTF-7 | THE one-time-code field SHALL have no words of its own: every word it shows or says is a prop of the Field's, read as FLD-24 says — the instance's, else the product's words of the same name — and the One-time-code input has none (OTC-30). THE one-time-code field SHALL read no key of the product's words itself. |
OTF-8 | THE one-time-code field SHALL add nothing to how its members answer the place they are used in: the layout direction (FLD-18 to FLD-21; OTC-27 and OTC-28, by which the cells stay a left-to-right run and stand at the start edge, under the label), enlarged text (FLD-16, OTC-23, OTC-24), a person's own forced colors (FLD-17, OTC-26) and the caret's reduced motion are each member's own answer. THE one-time-code field SHALL have no direction, size, color or motion setting of its own, and SHALL never be wider than its layout gives it. |
OTF-9 | 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 one-time-code field 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 one-time-code field is invalid — except those the one-time-code field owns (aria-label, aria-labelledby, aria-disabled), which it SHALL move and not expose: its name is label (OTF-1). 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 one-time-code field SHALL take it off that element. WHEN the product sets an aria- attribute the one-time-code field owns THE one-time-code field SHALL report it in debug builds. |
プラットフォーム別の名前対応
パリティは API が同一であることを意味しません。同じ契約を、各プラットフォームの流儀で表現します。
| 仕様 | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| コンポーネント | tanrei-one-time-code-field | TanreiOneTimeCodeField | TanreiOneTimeCodeField | TanreiOneTimeCodeField | OneTimeCodeField |
label · プロパティ | label | label | label | labelText | label |
labelHidden · プロパティ | labelHidden | labelsHidden | labelHidden | labelHidden | labelHidden |
supportingText · プロパティ | supportingText | supportingText | supportingText | helperText | supportingText |
errorText · プロパティ | errorText | errorText | errorText | errorText | errorText |
error · プロパティ | error | error | isError | isError | error |
disabled · プロパティ | disabled | disabled | enabled | enabled | disabled |
required · プロパティ | required | isRequired | required | required | required |
optional · プロパティ | optional | isOptional | optional | optional | optional |
requiredMark · プロパティ | requiredMark | requiredMark | requiredMark | requiredMark | requiredMark |
requiredText · プロパティ | requiredText | requiredText | requiredText | requiredText | requiredText |
optionalText · プロパティ | optionalText | optionalText | optionalText | optionalText | optionalText |
value · プロパティ | value | code | value | controller | value |
length · プロパティ | length | length | length | length | length |
type · プロパティ | type | type | type | type | type |
groupSize · プロパティ | groupSize | groupSize | groupSize | groupSize | groupSize |
mask · プロパティ | mask | isMasked | masked | obscureText | secureTextEntry |
readOnly · プロパティ | readOnly | readOnly | readOnly | readOnly | readOnly |
input · イベント | input | code | onValueChange | onChanged | onChangeText |
change · イベント | change | onCommit | onCommit | onCommit | onEndEditing |
complete · イベント | complete | onComplete | onComplete | onCompleted | onComplete |
action · イベント | action | onSubmit | keyboardActions | onSubmitted | onSubmitEditing |
| 備考 | <tanrei-one-time-code-field name="code" label="Verification code" supporting-text="Enter the 6-digit code we sent to your phone." group-size="3"></tanrei-one-time-code-field>. Composed: a custom element with a shadow root that holds its members' own elements — <tanrei-field part="field" exportparts="label, label-icon, requirement-label, supporting-text"><tanrei-one-time-code-input part="one-time-code-input" exportparts="input, cell, character, caret, separator"></tanrei-one-time-code-input></tanrei-field> — and nothing else but the passage of the label-icon slot; its module imports both members' modules, so where it is defined they are. Each prop is a property and an attribute of the element under its member's own attribute name (label-hidden, supporting-text, error-text, required-mark, required-text, optional-text, group-size, readonly) and is set on that member as a property; the element writes no custom property and reads no token, so every --tanrei-comp-field-* and --tanrei-comp-one-time-code-input-* value reaches the members by inheritance, and one instance is set apart by setting such a property on this element. One level down, the same by hand: <tanrei-field label="Verification code" supporting-text="…"><tanrei-one-time-code-input name="code" group-size="3"></tanrei-one-time-code-input></tanrei-field>. Form-associated itself (static formAssociated = true): its members stand in its shadow root, outside any form, so it takes name and form, repeats on its own ElementInternals the value, the state and the validity its One-time-code input tells its own — the same flags, the same message and the same anchor, the native input, so the browser's message points where it points one level down — resets to its value attribute, and passes a disabled <fieldset> on to its Field (OTF-4); Enter in the cells presses the default button of this element's form. The shadow root does not delegate focus — a press on the supporting row must do nothing (FLD-12) — so focus() and blur() are passed to the control, a click that arrives on the element itself (a page's own <label for>) moves focus there, and autofocus is copied to the control (OTF-5). The four events are the One-time-code input's own composed, bubbling CustomEvents: they leave the shadow root by themselves with the element as their target, and the element's value is at every moment its One-time-code input's — what was last set on the element until the input has taken it, and from then on what the input holds — so event.target.value is the code in every listener, capturing or bubbling (OTF-3); it dispatches nothing itself. The name, the description and the states reach the native input as values, by the tanrei-field-connect exchange between the two members inside the one shadow root, exactly as in a product's markup; the element's own host has no role, and an aria-* attribute the product writes on it moves to data-aria-* and reaches the cells' input, as its accessibility notes say — but for the name: name it with label (and label-hidden), never with aria-label, which a debug build reports. Inside a tanrei-field-group it follows the group's disabled through its Field (OTF-6). custom-elements.json shows it whole — sixteen attributes with their members' descriptions, four events with TanreiOneTimeCodeInputDetail, the label-icon slot, the two member parts and the nine exported ones, and the form attribute — and the React wrapper OneTimeCodeField is generated from that, with onInput, onChange, onComplete and onAction. Before the element is defined it has no size and shows nothing but a label-icon child, which a page hides with tanrei-one-time-code-field:not(:defined) > *; a page that must not jump gives the tag a block size of its own, and a page that must work without script writes a <label> around a plain <input autocomplete="one-time-code" inputmode="numeric"> with its help beside it. The host is display: block. Words: the element has none; required-text and optional-text left empty are read by its Field from the product's words. | TanreiOneTimeCodeField("Verification code", code: $code, supportingText: "…", groupSize: 3, onComplete: verify): a view whose body is TanreiField(…) { TanreiOneTimeCodeInput(…) } with each argument passed to the member it is from, and nothing else. code is the input's Binding<String>; labelHidden follows .labelsHidden() and disabled follows .disabled(_:), as the Field's do; the glyph is the Field's labelIcon:. One field is set apart by .tanreiTheme(_:) on this view. Planned: owed after the One-time-code input itself. | TanreiOneTimeCodeField(label = "Verification code", value = code, onValueChange = { code = it }, supportingText = …, groupSize = 3, onComplete = ::verify): a composable that calls TanreiField(…) { TanreiOneTimeCodeInput(…) } with each argument passed to the member it is from, and nothing else. enabled is the Field's inverse flag; the glyph is the Field's labelIcon. One field is set apart by a TanreiTheme(…) { } around this call. Planned: owed after the One-time-code input itself. | TanreiOneTimeCodeField(labelText: 'Verification code', controller: code, helperText: …, groupSize: 3, onCompleted: verify): a widget whose build returns TanreiField(…, child: TanreiOneTimeCodeInput(…)) with each argument passed to the member it is from, and nothing else. The names follow the members'; enabled is the Field's inverse flag; the glyph is the Field's labelIcon. One field is set apart by a TanreiTheme widget around it. Planned: owed after the One-time-code input itself. | <OneTimeCodeField label="Verification code" value={code} onChangeText={setCode} supportingText="…" groupSize={3} onComplete={verify} />: a component that returns <Field …><OneTimeCodeInput … /></Field> with each prop passed to the member it is from, and nothing else. The glyph is the Field's labelIcon prop. One field is set apart by a provider around it. Planned: owed after the One-time-code input itself. |
トークン
| トークン | 参照先 | 解決値(ライト) |
|---|---|---|
--tanrei-comp-field-counter-gap | sys.space.space200 | 16px |
--tanrei-comp-field-error-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-error-text-placement | — | 0 |
--tanrei-comp-field-label-icon-gap | sys.space.space100 | 8px |
--tanrei-comp-field-label-icon-size | sys.icon.small | 20px |
--tanrei-comp-field-label-gap | sys.space.space100 | 8px |
--tanrei-comp-field-motion-state-duration | sys.motion.role.state.default | 250ms |
--tanrei-comp-field-motion-state-easing | sys.motion.easing.state | cubic-bezier(0.2, 0, 0, 1) |
--tanrei-comp-field-requirement-asterisk-gap | sys.space.space25 | 2px |
--tanrei-comp-field-requirement-gap | sys.space.space100 | 8px |
--tanrei-comp-field-requirement-mark | sys.behavior.requirement-mark | 0 |
--tanrei-comp-field-standard-counter-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-disabled-counter-color | — | |
--tanrei-comp-field-standard-disabled-error-text-color | — | |
--tanrei-comp-field-standard-disabled-error-counter-color | — | |
--tanrei-comp-field-standard-disabled-error-label-icon-color | — | |
--tanrei-comp-field-standard-disabled-error-label-color | — | |
--tanrei-comp-field-standard-disabled-error-required-asterisk-color | — | |
--tanrei-comp-field-standard-disabled-error-supporting-text-color | — | |
--tanrei-comp-field-standard-disabled-error-value-text-color | — | |
--tanrei-comp-field-standard-disabled-label-icon-color | — | |
--tanrei-comp-field-standard-disabled-label-color | — | |
--tanrei-comp-field-standard-disabled-required-asterisk-color | — | |
--tanrei-comp-field-standard-disabled-supporting-text-color | — | |
--tanrei-comp-field-standard-disabled-value-text-color | — | |
--tanrei-comp-field-standard-error-text-color | sys.color.error | |
--tanrei-comp-field-standard-error-counter-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-label-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-label-color | sys.color.on-surface | |
--tanrei-comp-field-standard-error-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-standard-error-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-error-value-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-focused-counter-color | — | |
--tanrei-comp-field-standard-focused-error-text-color | — | |
--tanrei-comp-field-standard-focused-error-counter-color | — | |
--tanrei-comp-field-standard-focused-error-label-icon-color | — | |
--tanrei-comp-field-standard-focused-error-label-color | — | |
--tanrei-comp-field-standard-focused-error-required-asterisk-color | — | |
--tanrei-comp-field-standard-focused-error-supporting-text-color | — | |
--tanrei-comp-field-standard-focused-error-value-text-color | — | |
--tanrei-comp-field-standard-focused-label-icon-color | — | |
--tanrei-comp-field-standard-focused-label-color | — | |
--tanrei-comp-field-standard-focused-required-asterisk-color | — | |
--tanrei-comp-field-standard-focused-supporting-text-color | — | |
--tanrei-comp-field-standard-focused-value-text-color | — | |
--tanrei-comp-field-standard-label-icon-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-label-color | sys.color.on-surface | |
--tanrei-comp-field-standard-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-standard-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-standard-value-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-supporting-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-value-text-gap | sys.space.space200 | 16px |
--tanrei-comp-field-label-typescale | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-field-supporting-text-typescale | sys.typescale.label-small | 500 12px/1.3333 |
--tanrei-comp-field-value-text-typescale | sys.typescale.label | 500 14px/1.4286 |
フィクスチャ
基準となる描画パターンです。全プラットフォームが同じ ID でスナップショットを撮り、結果を比較できるようにしています。
supporting
label: Verification code supportingText: Enter the 6-digit code we sent to your p… value: 123 groupSize: 3 error
label: Verification code supportingText: Enter the 6-digit code we sent to your p… errorText: That code is not right. Check the messag… error: true value: 123456 groupSize: 3 disabled
label: Verification code supportingText: Enter the 6-digit code we sent to your p… disabled: true value: 123456 groupSize: 3 required-rtl
label: رمز التحقق supportingText: أدخل الرمز المكوّن من 6 أرقام الذي أرسلن… required: true requiredText: مطلوب value: 123 groupSize: 3 direction: rtl 生成元 specs/one-time-code-field.spec.json, tokens/comp/field.tokens.json, design/tokens/
- 要素のシャドウルートにあるのは、
<tanrei-one-time-code-input>を入れた<tanrei-field>だけです。要素をインポートすると、2 つとも定義されます。 - 要素はフォームに関連付けられます。
nameとformを受け取り、コードだけを送信します(無効の間は何も送信しません)。リセットするとvalue属性の値に戻り、無効な<fieldset>に従い、requiredが設定されていて値が空の間は、値がないことを報告します。2 つの構成要素がフォームに項目を加えることはありません。マス目で Enter を押すと、要素のフォームの既定のボタンが押されます。actionをキャンセルすると押されません。 input、change、complete、actionは、detail.valueを持つ、ワンタイムコード入力欄の CustomEvent です。イベントのターゲットはこの要素で、どのリスナーでもevent.target.valueがコードです。- パーツ:
fieldとone-time-code-inputが 2 つの構成要素です。構成要素のパーツは、1 つ下の階層と同じ名前です。label、label-icon、requirement-label、supporting-textと、input、cell、character、caret、separatorです。 - 要素そのものはフォーカスを受け取りません。
focus()はマス目に移り、ページの<label for>もフォーカスをマス目に移します。要素にautofocusを付けると、ほかにフォーカスがなければ、最初に描かれたときにマス目がフォーカスを受け取ります。 - 要素にロールはありません。名前は
labelで付けます。ラベルが別の場所に描かれているときはlabel-hiddenを併せて指定します。aria-labelはここでは何にも名前を付けないので、使いません。 - 属性は構成要素のものと同じです。
label-hidden、supporting-text、error-text、required-mark、required-text、optional-text、group-size、readonlyです。 - スロットは
label-iconの 1 つです。中に 2 つ目のコントロールを置いても、描かれません。 - 要素が定義されるまでは大きさがなく、
label-iconの子だけが表示されます。tanrei-one-time-code-field:not(:defined) > *で隠し、高さを確保してください。スクリプトなしで動く必要があるページでは、素の<input autocomplete="one-time-code" inputmode="numeric">を<label>で囲み、補足を隣に置きます。
supportingTextで、何文字のコードか、どこに送ったかを伝えます。- グループは、メッセージに書いたとおりに描きます。「123 456」と送ったコードなら
groupSize="3"です。 - コードが違うことは、
errorとerrorTextを使って言葉で伝えます。違っていたコードを消すかどうかは、利用者側で決めます。違うのは 1 桁だけ、ということがよくあります。 - 入力し終えたコードを確かめている間は、
disabledではなくreadOnlyを使います。無効にするとフォーカスが外れ、コードを直すことになったユーザーが、どこにいたかを見失います。 - コードを送り直す手段と、時間の制限は、フィールドの隣に置きます。枠の中に置きたいときは、1 つ下の階層でフィールドを自分で書きます。
- ワンタイムコードフィールドをフィールドの中に入れないでください。すでにフィールドです。デバッグビルドがそう知らせます。
aria-labelで名前を付けないでください。ラベルを描きたくないときは、labelとlabelHiddenを指定します。- 隠しているかどうかにかかわらず、貼り付けを妨げないでください。前もって伝えずにフォーカスを移したり、フォームを送信したりしないでください。
- 習慣で
maskを使わないでください。1 回使えば失効するコードを隠す必要はほとんどなく、隠すと間違いに気付きにくくなります。 - このフィールドのためだけに、マス目を写して作り直さないでください。構成要素のトークンをフィールドに設定します。
- ロール
textbox- ラベル付け
- One text box, the One-time-code input's (OTC-2); the frame has no role. Its accessible name is label, drawn or not (labelHidden), and its description is the supporting text with, in error, the error text after it, with optionalText while optional is true (FLD-10, FLD-11, OTC-22). It is exposed as invalid while error is true, required while required is true, disabled while disabled is true, read-only while readOnly is true, and as a protected text entry while mask is true. The label's drawn text, the requirement mark, the cells, the caret and the group marks are not exposed a second time (FLD-11, OTC-2).
- 最小ターゲット
- 見た目のサイズが小さくても、ヒット領域は最小ターゲットサイズを満たします。 minimum 32px · pointer 44px · spacing 8px · touch 48px
キーボード操作
| キー | 動作 |
|---|---|
| Tab / Shift+Tab | Moves focus to the control and on from it: the one-time-code field is one stop, its control's, and adds none (OTF-5). |
| Every other key | The One-time-code input's own, as its spec's keyboard table says (OTC-6, OTC-8 to OTC-11, OTC-13). The one-time-code field handles no key. |
備考
- What the one-time-code field adds to its members is their being one thing: one tag or one call, one set of props, one value and one entry in a form (OTF-2 to OTF-4). The tie between the two — the name, the description, required, invalid, disabled — is not the one-time-code field's: it is what a Field gives any control it frames, and it runs here exactly as it runs in a product's own Field.
- One level down: a Field with a One-time-code input in it, written by the product, is the same picture and the same text box, and the Field's fixtures code-supporting, code-error, code-disabled and code-required-rtl are this component's twins. A product drops to it for an arrangement the one-time-code field does not offer: something of its own inside the frame beside the cells (a resend control, a countdown), or the One-time-code input alone under a dialog's headline, named by its own label.
- The members' notes hold as written and are not repeated: errors are words (the Field's); nothing happens by itself when the code is complete, and paste and the platform's autofill are never blocked (the One-time-code input's).
- The hit area is the control's (OTC-25); the label widens where a press can land without widening what a press does (FLD-12).
- Not pressable: a press focuses the control and is not an action (OTC-25), so BTN-8, BTN-9 and BTN-10 are not copied.
- How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
生成元 specs/one-time-code-field.spec.json, tokens/sys/measure.tokens.json
- ワンタイムコード入力欄の、1 つのテキストボックスです。名前は
labelで、描かれていてもいなくても変わりません。説明は、表示されている補足またはエラーのテキストで、フィールドが任意の間は任意のテキストが加わります。 errorが true の間は不正として、requiredが設定されている間は必須として、disabledが true の間は無効として、readOnlyが true の間は読み取り専用として、maskが true の間はパスワードの入力欄として伝わります。- 名前、説明、状態は、フィールドが自分の囲むコントロールに結び付けるのとまったく同じ方法で結び付けられます。1 つ下の階層で自分で書いたフィールドも、同じテキストボックスになります。
- 描かれたラベル、必須や任意の印、マス目、キャレット、グループの印が、もう一度伝わることはありません。
- Tab で止まる位置は 1 つです。ラベルを押すとフォーカスがマス目に移り、何も操作されません。補足を押しても何も起きません。
- フォーカスがワンタイムコードフィールドの中にある間に現れたエラーは、構成要素のフィールドが 1 回だけ、控えめに読み上げます。
- 書字方向、文字の拡大、強制カラーには、構成要素がそれぞれ応えます。右から左へのレイアウトでは、枠は左右が入れ替わり、マス目は左から右への並びのまま先頭の端に置かれます。文字を 200% にしても、切れるものはなく、横にスクロールすることもありません。
- 自分の言葉は持ちません。
requiredTextとoptionalTextを空にすると、フィールドがプロダクトの言葉から読みます。
Web での既知の不足は、構成要素のものです。コードを入力している間にスクリーンリーダーが何を読むかは、ブラウザーのアクセシビリティツリーから読んだもので、スクリーンリーダーで聞いて確かめてはいません。要素が定義されるまでは、何も描かれません。
labelを必ず指定します。ユーザーがそのコードを呼ぶときの言葉にします。- 何を入力するのかを言葉で伝えます。何文字か、どこに送ったかです。マス目が長さを示せるのは、見えているユーザーに対してだけです。
- コードが違う、失効した、必須である、といったことは、
errorText、supportingText、requiredで伝えます。色だけを手がかりにしません。 - コードを入力できる時間に制限があるときは、それを伝え、時間の延長や新しいコードを求められるようにします。