Skip to content

Commit e23682f

Browse files
committed
feat(form): add AsyncValidatorResolver to enhance validation and update package.json with async-validator dependency
1 parent 00b8704 commit e23682f

File tree

4 files changed

+95
-3
lines changed

4 files changed

+95
-3
lines changed

packages/ui/src/components/form/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
export {
44
ComputedField as FormComputedField,
5-
createStandardResolver,
6-
createZodResolver,
75
Form,
86
List as FormList,
97
useEffectField,

playground/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
"bugs": {
1818
"url": "https://github.com/Ohh-889/soybean-react-ui/issues"
1919
},
20-
"keywords": ["UI", "tailwind-css", "shadcn-ui", "react"],
20+
"keywords": [
21+
"UI",
22+
"tailwind-css",
23+
"shadcn-ui",
24+
"react"
25+
],
2126
"scripts": {
2227
"build": "next build",
2328
"build:ui": "pnpm --filter soybean-react-ui build",
@@ -34,6 +39,7 @@
3439
},
3540
"dependencies": {
3641
"@hookform/resolvers": "^5.2.1",
42+
"async-validator": "^4.2.5",
3743
"embla-carousel-autoplay": "8.6.0",
3844
"grapheme-splitter": "1.0.4",
3945
"lucide-react": "0.525.0",
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use client';
2+
3+
import Schema from 'async-validator';
4+
import type { RuleItem } from 'async-validator';
5+
import { Button, Card, Form, FormField, Input, useForm } from 'soybean-react-ui';
6+
7+
// 定义 async-validator 规则
8+
const descriptor: Record<string, RuleItem | RuleItem[]> = {
9+
email: { message: 'Email is not valid', required: true, type: 'email' },
10+
11+
username: { message: 'Username must be at least 3 characters', min: 3, required: true, type: 'string' }
12+
};
13+
14+
const validator = new Schema(descriptor);
15+
16+
type Inputs = {
17+
email: string;
18+
19+
username: string;
20+
};
21+
22+
const initialValues: Inputs = {
23+
email: '',
24+
username: ''
25+
};
26+
27+
function normalizeKeys(name?: string | string[]): string[] | undefined {
28+
if (!name) return undefined;
29+
if (typeof name === 'string') {
30+
return [name];
31+
}
32+
return name;
33+
}
34+
// 将 async-validator 封装成符合 GenericResolver 的函数
35+
async function asyncValidatorResolver(state: Inputs, name: string | string[] | undefined) {
36+
try {
37+
await validator.validate(state, {
38+
keys: normalizeKeys(name)
39+
});
40+
return []; // ✅ 校验通过
41+
} catch (err: any) {
42+
// ❌ 校验失败
43+
return (
44+
err.errors?.map((e: any) => ({
45+
message: e.message,
46+
path: e.field ? [e.field] : []
47+
})) ?? []
48+
);
49+
}
50+
}
51+
52+
const AsyncValidatorDemo = () => {
53+
const [form] = useForm<Inputs>();
54+
55+
return (
56+
<Card title="Form with AsyncValidator (function resolver)">
57+
<Form
58+
className="w-[480px] max-sm:w-full space-y-4"
59+
form={form}
60+
initialValues={initialValues}
61+
schema={asyncValidatorResolver} // ✅ 非标准库 → 传函数
62+
>
63+
<FormField
64+
label="Username"
65+
name="username"
66+
>
67+
<Input />
68+
</FormField>
69+
70+
<FormField
71+
label="Email"
72+
name="email"
73+
>
74+
<Input />
75+
</FormField>
76+
77+
<div className="flex gap-2">
78+
<Button type="submit">Submit</Button>
79+
</div>
80+
</Form>
81+
</Card>
82+
);
83+
};
84+
85+
export default AsyncValidatorDemo;

playground/src/app/(demo)/form/page.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import AsyncValidatorResolver from './modules/AsyncValidatorResolver';
12
import ClearDestroy from './modules/ClearDestroy';
23
import ComputedDemo from './modules/ComputedDemo';
34
import Default from './modules/Default';
@@ -33,6 +34,8 @@ const FormPage = () => {
3334

3435
<ZodResolver />
3536

37+
<AsyncValidatorResolver />
38+
3639
<UseWatch />
3740

3841
<UseSelector />

0 commit comments

Comments
 (0)