@ug666/react 文档演示
Form 表单
Form 系列组件通过 Context 向下传递字段名、id 与错误信息,配合 useForm hook 实现完整的受控表单体验。
导入方式
所有示例均直接使用 @ug666/react 中的真实组件导出。
import {
Form, FormField, FormItem, FormLabel,
FormControl, FormDescription, FormMessage,
} from '@ug666/react'
import { useForm } from '@ug666/react'基础表单
用户注册场景:包含必填校验、邮箱格式校验、密码长度校验与 Checkbox 必勾项,提交成功后触发 toast。
状态展示
演示带帮助文字(FormDescription)的字段与已有错误(FormMessage 红字)的字段。
输入邀请码后可加入团队协作空间
用于接收团队通知
该邮箱已被其他账号占用
代码示例
完整注册表单,演示 useForm + Form 系列组件的典型组合用法。
import {
Form, FormField, FormItem, FormLabel,
FormControl, FormDescription, FormMessage,
Input, Button, Checkbox, toast, Toaster,
} from '@ug666/react'
import { useForm } from '@ug666/react'
interface RegisterValues {
username: string
email: string
password: string
agree: boolean
}
export function RegisterForm() {
const { values, errors, handleChange, setError, clearErrors } = useForm<RegisterValues>({
username: '',
email: '',
password: '',
agree: false,
})
function handleSubmit() {
clearErrors()
let hasError = false
if (!values.username.trim()) {
setError('username', '用户名不能为空')
hasError = true
}
if (!values.email.includes('@')) {
setError('email', '请输入有效的邮箱地址')
hasError = true
}
if (values.password.length < 8) {
setError('password', '密码长度至少 8 位')
hasError = true
}
if (!values.agree) {
setError('agree', '请阅读并同意服务条款')
hasError = true
}
if (!hasError) {
toast.success('注册成功,欢迎加入!')
}
}
return (
<>
<Toaster />
<Form onSubmit={handleSubmit} className="w-full max-w-md space-y-4">
<FormField name="username" error={errors.username}>
<FormItem>
<FormLabel required>用户名</FormLabel>
<FormControl>
<Input
placeholder="请输入用户名"
value={values.username}
onChange={(e) => handleChange('username', e.target.value)}
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField name="email" error={errors.email}>
<FormItem>
<FormLabel required>邮箱地址</FormLabel>
<FormControl>
<Input
type="email"
placeholder="you@example.com"
value={values.email}
onChange={(e) => handleChange('email', e.target.value)}
/>
</FormControl>
<FormDescription>用于接收系统通知与验证码</FormDescription>
<FormMessage />
</FormItem>
</FormField>
<FormField name="password" error={errors.password}>
<FormItem>
<FormLabel required>密码</FormLabel>
<FormControl>
<Input
type="password"
placeholder="至少 8 位字符"
value={values.password}
onChange={(e) => handleChange('password', e.target.value)}
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField name="agree" error={errors.agree}>
<FormItem>
<div className="flex items-start gap-2">
<FormControl>
<Checkbox
checked={values.agree as boolean}
onCheckedChange={(checked) => handleChange('agree', checked as boolean)}
/>
</FormControl>
<FormLabel className="cursor-pointer font-normal leading-relaxed">
我已阅读并同意服务条款
</FormLabel>
</div>
<FormMessage />
</FormItem>
</FormField>
<Button type="submit" className="w-full">立即注册</Button>
</Form>
</>
)
}Props 说明
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| Form.onSubmit | (event: FormEvent) => void | — | 表单提交回调,已内部阻止默认行为。 |
| FormField.name | string | 必填 | 字段唯一名称,用于关联 label/message/control。 |
| FormField.error | string | — | 字段错误文本,有值时 FormMessage 显示红字。 |
| FormLabel.required | boolean | false | 显示必填红星。 |
| FormControl.children | ReactElement | 必填 | 单个表单控件,自动注入 id 与 aria 属性。 |
| FormDescription | ReactNode | — | 字段说明文字,显示为灰色小字。 |
| FormMessage | ReactNode | — | 错误提示,无错误时不渲染。 |