Loading...
Loading...
Loading...
Reusable form components with field พร้อม copy ไปใช้ — react-hook-form + zod + shadcn/ui
ติดตั้ง shadcn-ui และ dependencies ที่จำเป็นสำหรับสร้างฟอร์มด้วย react-hook-form และ zod
pnpm dlx shadcn@latest add input field select radio-group checkboxpnpm add zodpnpm add react-hook-form @hookform/resolversimport { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useTransition } from 'react';
import { Button } from '@/components/ui/button';
import { BaseFormTextField } from '@/components/forms/base-form-text-field';
import { z } from 'zod';
const schema = z.object({
email: z.string().email(),
password: z.string().min(6),
});
type FormInput = z.infer<typeof schema>;
export default function ExampleForm() {
const [isPending, startTransition] = useTransition();
const form = useForm<FormInput>({
resolver: zodResolver(schema),
defaultValues: {
email: '',
password: '',
},
mode: 'all',
});
function onSubmit(data: FormInput) {
startTransition(async () => {
// 👉 call API หรือ server action
// await login(data);
form.reset();
});
}
return (
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<BaseFormTextField
control={form.control}
name="email"
type="email"
label="Email"
placeholder="john@example.com"
/>
<BaseFormTextField
control={form.control}
name="password"
type="password"
label="Password"
placeholder="••••••••"
/>
<Button type="submit" disabled={isPending}>
{isPending ? 'Submitting...' : 'Submit'}
</Button>
</form>
);
}src/components/forms/base-form-text-field.tsx
src/components/forms/field-form-select.tsx
src/components/forms/field-form-radio-group.tsx
src/components/forms/field-form-checkbox-group.tsx