组件

表单

使用验证规则从您的用户处收集信息。

import * as React from "react";
import { Form } from "radix-ui";
import "./styles.css";
const FormDemo = () => (
<Form.Root className="FormRoot">
<Form.Field className="FormField" name="email">
<div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", }} >
<Form.Label className="FormLabel">Email</Form.Label>
<Form.Message className="FormMessage" match="valueMissing">
Please enter your email
</Form.Message>
<Form.Message className="FormMessage" match="typeMismatch">
Please provide a valid email
</Form.Message>
</div>
<Form.Control asChild>
<input className="Input" type="email" required />
</Form.Control>
</Form.Field>
<Form.Field className="FormField" name="question">
<div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", }} >
<Form.Label className="FormLabel">Question</Form.Label>
<Form.Message className="FormMessage" match="valueMissing">
Please enter a question
</Form.Message>
</div>
<Form.Control asChild>
<textarea className="Textarea" required />
</Form.Control>
</Form.Field>
<Form.Submit asChild>
<button className="Button" style={{ marginTop: 10 }}>
Post question
</button>
</Form.Submit>
</Form.Root>
);
export default FormDemo;

特性

    构建于原生浏览器之上 约束验证 API。

    支持内置验证。

    支持自定义验证。

    完全自定义验证消息。

    可访问的验证消息。

    支持客户端和服务端场景。

    焦点完全受管理。

安装

从命令行安装组件。

npm install @radix-ui/react-form

解剖

导入所有部件并将它们拼合在一起。

import { Form } from "radix-ui";
export default () => (
<Form.Root>
<Form.Field>
<Form.Label />
<Form.Control />
<Form.Message />
<Form.ValidityState />
</Form.Field>
<Form.Message />
<Form.ValidityState />
<Form.Submit />
</Form.Root>
);

API 参考

Root

包含表单的所有部件。

Prop类型默认值
asChild
boolean
false
onClearServerErrors
function
无默认值

Field

字段的包装器。它自动处理 id/name 和标签可访问性。

Prop类型默认值
asChild
boolean
false
name*
string
无默认值
serverInvalid
boolean
无默认值
数据属性
[data-invalid]

当字段无效时出现

[data-valid]

当字段有效时出现

Label

标签元素,当嵌套在 Field 部件中时会自动连接。

Prop类型默认值
asChild
boolean
false
数据属性
[data-invalid]

当字段无效时出现

[data-valid]

当字段有效时出现

Control

控件元素(默认为 input),当嵌套在 Field 部件中时会自动连接。

Prop类型默认值
asChild
boolean
false
数据属性
[data-invalid]

当字段无效时出现

[data-valid]

当字段有效时出现

Message

验证消息,当嵌套在 Field 部件中时,会自动连接(功能和可访问性)到给定的控件。它可用于内置和自定义客户端验证,以及服务端验证。当在 Field 外部使用时,您必须传递与字段匹配的 name prop。

Form.Message 接受一个 match prop,用于确定何时应显示消息。它匹配原生 HTML 验证状态 (ValidityState,请参阅 MDN),它根据诸如 requiredminmax 等属性进行验证。如果给定的 match 在控件的验证状态中为 true,则消息将显示。

您还可以将函数传递给 match 以提供自定义验证规则。

Prop类型默认值
asChild
boolean
false
match
匹配器
无默认值
forceMatch
boolean
false
name
string
无默认值

ValidityState

使用此渲染 prop 组件可在渲染中访问给定字段的验证状态(请参阅 ValidityState,请参阅 MDN)。当嵌套在 Field 部件中时,字段的有效性自动可用,否则您必须传递 name prop 以将其关联。

Prop类型默认值
children
function
无默认值
name
string
无默认值

提交

提交按钮。

Prop类型默认值
asChild
boolean
false

示例

与您自己的组件组合

使用 asChild,您可以将 Form 原始组件部件与您自己的组件组合。

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.Control asChild>
<TextField.Input variant="primary" />
</Form.Control>
</Form.Field>

它也可以用于组合其他类型的控件,例如 select

<Form.Field name="country">
<Form.Label>Country</Form.Label>
<Form.Control asChild>
<select>
<option value="uk">United Kingdom</option>
</select>
</Form.Control>
</Form.Field>

注意:目前,无法将 Form 与 Radix 的其他表单原始组件(如 CheckboxSelect 等)组合。我们正在为此寻找解决方案。

提供您自己的验证消息

当未提供 children 时,Form.Message 将为给定的 match 渲染默认错误消息。

// will yield "This value is missing"
<Form.Message match="valueMissing" />

您可以通过传递您自己的 children 来提供更有意义的消息。 这对于国际化也很有用。

// will yield "Please provide a name"
<Form.Message match="valueMissing">Please provide a name</Form.Message>

自定义验证

除了上面描述的所有内置客户端验证匹配之外,您还可以提供自己的自定义验证,同时仍然利用平台的验证能力。它使用 customError 类型,该类型存在于约束验证 API 中。

您可以将您自己的验证函数传递到 Form.Message 上的 match prop 中。 这是一个例子

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.Control />
<Form.Message match={(value, formData) => value !== "John"}>
Only John is allowed.
</Form.Message>
</Form.Field>

match 将被调用,控件的当前值作为第一个参数,整个 FormData 作为第二个参数。match 也可以是 async 函数(或返回 promise)以执行异步验证。

基于有效性设置样式

我们向相关部件添加了 data-validdata-invalid 属性。 使用它来相应地设置组件的样式。 这是一个设置 Label 部件样式的示例。

//index.jsx
import * as React from "react";
import { Form } from "radix-ui";
export default () => (
<Form.Root>
<Form.Field name="email">
<Form.Label className="FormLabel">Email</Form.Label>
<Form.Control type="email" />
</Form.Field>
</Form.Root>
);
/* styles.css */
.FormLabel[data-invalid] {
color: red;
}
.FormLabel[data-valid] {
color: green;
}

访问有效性状态以获得更多控制

您可能需要访问字段的原始有效性状态,以便显示您自己的图标,或通过其定义的 props 与组件库交互。 您可以使用 Form.ValidityState 部件来实现此目的

<Form.Field name="name">
<Form.Label>Full name</Form.Label>
<Form.ValidityState>
{(validity) => (
<Form.Control asChild>
<TextField.Input variant="primary" state={getTextFieldInputState(validity)} />
</Form.Control>
)}
</Form.ValidityState>
</Form.Field>

服务端验证

该组件还支持使用相同的 Form.Message 组件进行服务端验证。 您可以通过传递 forceMatch prop 来重用为客户端错误定义的相同消息,这将强制消息显示,而无需考虑客户端匹配逻辑。

如果客户端不存在该消息,您也可以渲染不带 matchForm.Message。 通过将 serverInvalid 布尔 prop 传递给 Form.Field 部件,字段被标记为无效。

这是一个服务端错误处理的示例

import * as React from "react";
import { Form } from "radix-ui";
function Page() {
const [serverErrors, setServerErrors] = React.useState({
email: false,
password: false,
});
return (
<Form.Root // `onSubmit` only triggered if it passes client-side validation onSubmit={(event) => { const data = Object.fromEntries(new FormData(event.currentTarget)); // Submit form data and catch errors in the response submitForm(data) .then(() => {}) /** * Map errors from your server response into a structure you'd like to work with. * In this case resulting in this object: `{ email: false, password: true }` */ .catch((errors) => setServerErrors(mapServerErrors(errors))); // prevent default form submission event.preventDefault(); }} onClearServerErrors={() => setServerErrors({ email: false, password: false }) } >
<Form.Field name="email" serverInvalid={serverErrors.email}>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" required />
<Form.Message match="valueMissing">
Please enter your email.
</Form.Message>
<Form.Message match="typeMismatch" forceMatch={serverErrors.email}>
Please provide a valid email.
</Form.Message>
</Form.Field>
<Form.Field name="password" serverInvalid={serverErrors.password}>
<Form.Label>Password</Form.Label>
<Form.Control type="password" required />
<Form.Message match="valueMissing">
Please enter a password.
</Form.Message>
{serverErrors.password && (
<Form.Message>
Please provide a valid password. It should contain at least 1 number
and 1 special character.
</Form.Message>
)}
</Form.Field>
<Form.Submit>Submit</Form.Submit>
</Form.Root>
);
}

您应该使用 Form.Root 部件上的 onClearServerErrors 回调 prop 清除服务器错误。 它将在重新提交表单之前以及重置表单时清除服务器错误。

此外,这提供了对何时重置单个服务器错误的控制。 例如,您可以在用户编辑电子邮件后立即重置电子邮件服务器错误

<Form.Field name="email" serverInvalid={serverErrors.email}>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" onChange={() => setServerErrors((prev) => ({ ...prev, email: false }))} />
<Form.Message match="valueMissing">Please enter your email.</Form.Message>
<Form.Message match="typeMismatch" forceMatch={serverErrors.email}>
Please provide a valid email.
</Form.Message>
</Form.Field>

可访问性

该组件遵循用于验证的“内联错误”模式

  • 标签和控件使用 Form.Field 上提供的 name 相关联
  • 当显示一个或多个客户端错误消息时,它们会自动与其匹配的控件关联并相应地宣布
  • 焦点移动到第一个无效控件
上一个下拉菜单
下一个悬停卡片