Radix UI — это библиотека низкоуровневых компонентов для React, ориентированных на доступность и расширяемость. Несмотря на то, что она не предоставляет встроенной системы валидации форм, её компоненты идеально сочетаются с библиотеками для управления формами и валидацией, такими как React Hook Form, Formik или Zod. Использование Radix UI позволяет создавать интерфейсные элементы с высокой степенью доступности, а логику валидации делегировать проверенным инструментам.
Для создания форм с валидацией обычно используют useForm
из React Hook Form. Пример структуры:
import * as React from 'react';
import { useForm } from 'react-hook-form';
import * as TextField from '@radix-ui/react-label';
function MyForm() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSub mit = data => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<div>
<TextField.Root>
<TextField.Label htmlFor="email">Email</TextField.Label>
<input
id="email"
{...register("email", { required: "Email обязателен", pattern: { value: /^\S+@\S+$/i, message: "Неверный формат email" } })}
/>
{errors.email && <span>{errors.email.message}</span>}
</TextField.Root>
</div>
<div>
<TextField.Root>
<TextField.Label htmlFor="password">Пароль</TextField.Label>
<input
type="password"
id="password"
{...register("password", { required: "Пароль обязателен", minLength: { value: 6, message: "Минимум 6 символов" } })}
/>
{errors.password && <span>{errors.password.message}</span>}
</TextField.Root>
</div>
<button type="submit">Отправить</button>
</form>
);
}
Ключевые моменты интеграции:
register связывает поля формы с React
Hook Form и задаёт правила валидации.formState.errors позволяет выводить
пользовательские сообщения об ошибках.TextField.Root,
TextField.Label) обеспечивают доступность и стилизуемую
обертку для стандартных <input>.Если компонент Radix UI не поддерживает прямое подключение к
register, применяют Controller:
import { Controller, useForm } from 'react-hook-form';
import * as Slider from '@radix-ui/react-slider';
function SliderForm() {
const { control, handleSubmit } = useForm({ defaultValues: { volume: 50 } });
const onSub mit = data => console.log(data);
return (
<form onSub mit={handleSubmit(onSubmit)}>
<Controller
name="volume"
control={control}
rules={{ min: 0, max: 100 }}
render={({ field }) => (
<Slider.Root value={[field.value]} onValueCha nge={([val]) => field.onChange(val)} max={100}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
)}
/>
<button type="submit">Сохранить</button>
</form>
);
}
Особенности подхода с Controller:
ref для формы.rules) и получать
текущее состояние (field.value).Для форм с комплексной логикой валидации удобно сочетать Zod и React Hook Form:
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form';
const schema = z.object({
username: z.string().min(3, "Минимум 3 символа"),
age: z.number().min(18, "Возраст должен быть 18+"),
});
function AdvancedForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: zodResolver(schema)
});
return (
<form onSub mit={handleSubmit(console.log)}>
<div>
<label htmlFor="username">Имя</label>
<input id="username" {...register("username")} />
{errors.username && <span>{errors.username.message}</span>}
</div>
<div>
<label htmlFor="age">Возраст</label>
<input id="age" type="number" {...register("age", { valueAsNumber: true })} />
{errors.age && <span>{errors.age.message}</span>}
</div>
<button type="submit">Отправить</button>
</form>
);
}
Преимущества Zod:
Radix UI позволяет строить наглядные и доступные сообщения об ошибках:
aria-invalid и
aria-describedby для уведомления
скринридеров о проблемах с формой.FormError на основе
Radix Tooltip для подсказок при наведении или фокусе.Пример:
import * as Tooltip from '@radix-ui/react-tooltip';
function ErrorTooltip({ message, children }) {
return (
<Tooltip.Provider>
<Tooltip.Root>
<Tooltip.Trigger asChild>
{children}
</Tooltip.Trigger>
<Tooltip.Content side="right">
{message}
<Tooltip.Arrow />
</Tooltip.Content>
</Tooltip.Root>
</Tooltip.Provider>
);
}
aria-* атрибуты и стилизованные компоненты сообщений об
ошибках.Такой подход позволяет построить формы с высокой степенью контроля, качественной валидацией и адаптируемым UX, сохраняя чистую и модульную архитектуру приложения.