پرتوپرتو

فرم با اعتبارسنجی

الگوی کامل فرم با React Hook Form، نمایش خطاها، و aria-invalid

معرفی

این الگو نشان می‌دهد چگونه یک فرم با اعتبارسنجی کامل بسازید که:

  • خطاهای فیلدها را با aria-invalid و aria-describedby نمایش می‌دهد
  • با react-hook-form کار می‌کند
  • برای کاربران صفحه‌خوان قابل دسترس است

نمونه بصری

نام کاربری شما در پنل نمایش داده می‌شود.

کد کامل

'use client'

import { useForm } from 'react-hook-form'
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@parto-system-design/ui'
import { Input } from '@parto-system-design/ui'
import { Button } from '@parto-system-design/ui'

interface ProfileForm {
  name: string
  email: string
}

export function ProfileFormExample() {
  const form = useForm<ProfileForm>({
    defaultValues: { name: '', email: '' },
  })

  function onSubmit(data: ProfileForm) {
    console.log(data)
  }

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
        <FormField
          control={form.control}
          name="name"
          rules={{ required: 'نام الزامی است' }}
          render={({ field, fieldState }) => (
            <FormItem>
              <FormLabel>نام</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  aria-invalid={fieldState.invalid}
                  aria-describedby={fieldState.invalid ? 'name-error' : undefined}
                  placeholder="نام خود را وارد کنید"
                />
              </FormControl>
              <FormMessage id="name-error" />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="email"
          rules={{
            required: 'ایمیل الزامی است',
            pattern: {
              value: /^[^@]+@[^@]+\.[^@]+$/,
              message: 'فرمت ایمیل صحیح نیست',
            },
          }}
          render={({ field, fieldState }) => (
            <FormItem>
              <FormLabel>ایمیل</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  type="email"
                  aria-invalid={fieldState.invalid}
                  aria-describedby={fieldState.invalid ? 'email-error' : undefined}
                  placeholder="example@domain.com"
                />
              </FormControl>
              <FormMessage id="email-error" />
            </FormItem>
          )}
        />

        <Button htmlType="submit" variant="primary">
          ذخیره
        </Button>
      </form>
    </Form>
  )
}

نکات

  • aria-invalid={fieldState.invalid} وضعیت خطا را به صفحه‌خوان‌ها منتقل می‌کند
  • aria-describedby پیام خطا را به فیلد مرتبط می‌کند
  • FormMessage پیام خطا را از react-hook-form نمایش می‌دهد