# 表单层规范（react-hook-form + zod）

所有需要校验的表单**必须**使用此模式，禁止再写手动 useState + 散落的 if 校验。

## 标准用法

```tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { phoneCN, description, requiredEnum } from "@/lib/forms/schemas";

const schema = z.object({
  phone: phoneCN,
  reason: requiredEnum(["quality_issue", "wrong_item"]),
  detail: description(5, 500),
});
type Values = z.infer<typeof schema>;

const form = useForm<Values>({
  resolver: zodResolver(schema),
  defaultValues: { phone: "", reason: undefined as any, detail: "" },
  mode: "onBlur",
});

const onSubmit = async (values: Values) => { /* ... */ };

return (
  <Form {...form}>
    <form onSubmit={form.handleSubmit(onSubmit)}>
      <FormField control={form.control} name="phone" render={({ field }) => (
        <FormItem>
          <FormLabel>联系电话</FormLabel>
          <FormControl><Input {...field} /></FormControl>
          <FormMessage />
        </FormItem>
      )} />
      ...
    </form>
  </Form>
);
```

## 共享 Schema 位置

`src/lib/forms/schemas.ts` —— 复用字段（手机号、描述、图片数组、必选枚举）集中在这里，组件只组合不重写。

## 多步表单

使用 `form.trigger(["fieldA", "fieldB"])` 分步校验当前 step 的字段后再 setStep；不要用手写 `canProceedToStepN` 布尔。
