Components

一次性密码字段

¥One-Time Password Field

一组用于处理一次性密码验证的单字符文本输入框。

import * as React from "react";
import { unstable_OneTimePasswordField as OneTimePasswordField } from "radix-ui";
const OneTimePasswordFieldDemo = () => (
<OneTimePasswordField.Root className="OTPRoot">
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.Input className="OTPInput" />
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>
);
export default OneTimePasswordFieldDemo;

Features

    Keyboard navigation mimicking the behavior of a single input field

    Overriding values on paste

    Password manager autofill support

    Input validation for numeric and alphanumeric values

    Auto-submit on completion

    Hidden input to provide a single value to form data

结构

¥Anatomy

导入所有部分并将它们组合在一起。

¥Import all parts and piece them together.

import { unstable_OneTimePasswordField as OneTimePasswordField } from "radix-ui";
export default () => (
<OneTimePasswordField.Root>
{/* one Input for each character of the value */}
<OneTimePasswordField.Input />
{/* single HiddenInput to store the full value */}
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>
);

API 参考

¥API Reference

¥Root

包含一次性密码输入框的所有部分。

¥Contains all the parts of a one-time password field.

PropTypeDefault
asChild
boolean
false
autoComplete
enum
one-time-code
autoFocus
boolean
No default value
value
string
No default value
defaultValue
string
No default value
onValueChange
function
No default value
autoSubmit
boolean
false
onAutoSubmit
function
No default value
disabled
boolean
false
dir
enum
"ltr"
orientation
enum
"vertical"
form
string
No default value
name
string
No default value
placeholder
string
No default value
readOnly
boolean
false
sanitizeValue
function
No default value
type
enum
"text"
validationType
enum
"numeric"
Data attributeValues
[data-orientation]"vertical" | "horizontal"

输入

¥Input

渲染表示值中单个字符的文本输入框。

¥Renders a text input representing a single character in the value.

PropTypeDefault
asChild
boolean
false
Data attributeValues
[data-index]

The index corresponding with the index of the character relative to the root field value

HiddenInput

PropTypeDefault
asChild
boolean
false

示例

¥Examples

基本用法

¥Basic usage

// This will render a field with 6 inputs, for use with
// 6-character passwords. Render an Input component for
// each character of accepted password's length.
<OneTimePasswordField.Root>
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>

分段控件

¥Segmented controls

Root 组件接受任意子组件,因此渲染视觉上分段的列表就像渲染输入之间的分隔符一样简单。我们建议在 aria-hidden 中隐藏辅助技术无法识别的装饰性元素,并避免在 Root 中渲染其他有意义的内容,因为每个子元素都应该属于具有 group 角色的父元素。

¥The Root component accepts arbitrary children, so rendering a visually segmented list is as simple as rendering separators between inputs. We recommend hiding decorative elements from assistive tech with aria-hidden and avoid rendering other meaningful content within Root since each child element is expected to belong to the parent with the group role.

<OneTimePasswordField.Root>
<OneTimePasswordField.Input />
<Separator.Root aria-hidden />
<OneTimePasswordField.Input />
<Separator.Root aria-hidden />
<OneTimePasswordField.Input />
<Separator.Root aria-hidden />
<OneTimePasswordField.Input />
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>

输入密码后自动提交表单

¥Auto-submit form when password is entered

使用 autoSubmit 属性在所有输入都填写完毕后提交关联表单。

¥Use the autoSubmit prop to submit an associated form when all inputs are filled.

function Verify({ validCode }) {
const PASSWORD_LENGTH = 6;
function handleSubmit(event) {
event.preventDefault();
const formData = event.formData;
if (formData.get("otp") === validCode) {
redirect("/authenticated");
} else {
window.alert("Invalid code");
}
}
return (
<form onSubmit={handleSubmit}>
<OneTimePasswordField.Root name="otp" autoSubmit>
{PASSWORD_LENGTH.map((_, i) => (
<OneTimePasswordField.Input key={i} />
))}
{/* HiddenInput is required for the form to have data associated with the field */}
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>
<button>Submit</button>
</form>
);
}

受控值

¥Controlled value

function Verify({ validCode }) {
const [value, setValue] = React.useState("");
const PASSWORD_LENGTH = 6;
function handleSubmit() {
if (value === validCode) {
redirect("/authenticated");
} else {
window.alert("Invalid code");
}
}
return (
<OneTimePasswordField.Root autoSubmit value={value} onAutoSubmit={handleSubmit} onValueChange={setValue} >
{PASSWORD_LENGTH.map((_, i) => (
<OneTimePasswordField.Input key={i} />
))}
</OneTimePasswordField.Root>
);
}

可访问性

¥Accessibility

在撰写本文时,WCAG 指南中尚未确立将一次性密码字段作为单独输入项实现的单一既定模式。此行为旨在尽可能接近将字段作为单一输入,但根据我们最初的研究、测试和收集的反馈,为了满足用户的期望,我们做了一些例外。

¥At the time of writing, there is no singular established pattern in WCAG guidelines for implementing one-time password fields as separate inputs. The behavior aims to get as close as possible to having the field act as a single input, with a few exceptions to match user expectations based on our initial research, testing, and gathering feedback.

此组件作为容器内的 input 元素实现,其角色为 group,以指示子输入是相关的。可以使用方向键导航和聚焦输入,输入内容会将焦点移动到下一个输入,直到最后一个输入。

¥This component is implemented as input elements within a container with a role of group to indicate that child inputs are related. Inputs can be navigated and focused using direction keys, and typing input will move focus to the next input until the last input is reached.

将值粘贴到字段中将替换所有输入框的内容,无论当前焦点所在的输入框是什么。根据我们的研究,这似乎符合大多数用户的期望,因为值通常是从密码管理器或电子邮件中粘贴过来的。

¥Pasting a value into the field will replace the contents of all inputs, regardless of the currently focused input. Based on our research this seems to align with most user expectations, where values are often pasted from password-managers or an email.

键盘交互

¥Keyboard Interactions

KeyDescription
Enter
Attempts to submit an associated form if one is found
Tab
Moves focus to the next focusable element outside of the Root
Shift + Tab
Moves focus to the previous focusable element outside of the Root
ArrowDown
Moves focus to the next Input when orientation is vertical.
ArrowUp
Moves focus to the previous Input when orientation is vertical.
ArrowRight
Moves focus to the next Input when orientation is horizontal.
ArrowLeft
Moves focus to the previous Input when orientation is horizontal.
Home
Moves focus to the first Input.
End
Moves focus to the last Input.
Delete
Removes the character in the currently focused Input and shifts later values back
Backspace
Removes the character in the currently focused Input and moves focus to the previous Input
Command + Backspace
Clears the value of all Input elements