valibot-form-fields
v0.5.0
Published
The `valibot-form-fields` package maps Valibot validation schemas to standard HTML input attributes, providing strict type safety and inference for forms in React and other UI frameworks.
Downloads
521
Readme
valibot-form-fields
The valibot-form-fields package maps Valibot validation schemas to standard HTML input attributes, providing strict type safety and inference for forms in React and other UI frameworks.
Requirements: You must install
valibotas a peer dependency to use this package.
Core Concept
Valibot schemas define the shape and validation constraints of your data. Instead of manually mirroring these constraints as HTML attributes (such as type="number", required, or minLength="5"), this package automatically translates your schema into standard HTML input attributes. This guarantees that your UI remains strictly synchronized with your validation logic, reducing boilerplate and preventing drift between your schema and your form elements.
API Reference
createFormFields(schema, prefix?)
Transforms a Valibot object schema into a structured set of HTML form field attributes.
schema: The Valibot object schema defining the form structure.prefix: An optional string to prepend to all generated field names, useful for nested forms.- Returns: An object mapping each schema key to its corresponding HTML field attributes.
useFormFields(schema, prefix?)
A React hook that memoizes the output of createFormFields for efficient rendering in React components.
schema: The Valibot object schema defining the form structure.prefix: An optional string to prepend to all generated field names.- Returns: An object mapping each schema key to its corresponding HTML field attributes.
Usage
You can use the core utility createFormFields in any framework, or the useFormFields hook within React applications.
Basic React Example
import { object, string, minLength, pipe } from "valibot";
import { useFormFields } from "valibot-form-fields";
const userSchema = object({
username: pipe(string(), minLength(3)),
email: string(),
});
export function UserForm() {
const fields = useFormFields(userSchema);
return (
<form>
<label htmlFor={fields.username.id}>Username</label>
<input {...fields.username} />
<label htmlFor={fields.email.id}>Email</label>
{/* You can override generated attributes if necessary */}
<input {...fields.email} type="email" />
<button type="submit">Submit</button>
</form>
);
}Comprehensive Example: Enums, Arrays, and Nested Objects
The library strictly infers types and generates appropriate configurations for complex structures, including enumerations and nested objects.
import { object, string, number, enum_, array, minLength, pipe } from "valibot";
import { createFormFields } from "valibot-form-fields";
enum Role {
Admin = "ADMIN",
User = "USER",
}
const profileSchema = object({
personalInfo: object({
fullName: pipe(string(), minLength(2)),
age: number(),
}),
role: enum_(Role),
tags: array(string()),
});
// Generate field attributes using the framework-agnostic utility
const fields = createFormFields(profileSchema);
// 1. Nested Objects
// fields.personalInfo.fullName generates:
// { id: "...", name: "personalInfo.fullName", type: "text", required: true, minLength: 2 }
// fields.personalInfo.age generates:
// { id: "...", name: "personalInfo.age", type: "text", inputMode: "numeric", pattern: "[0-9]*", required: true }
// 2. Enum Fields (Select and Radio options)
// fields.role exposes multiple rendering strategies:
// Rendering as a <select>
<select {...fields.role.select}>
{fields.role.options.map(option => (
<option key={option.value} value={option.value}>
{option.name}
</option>
))}
</select>
// Rendering as <input type="radio">
{Object.entries(fields.role.radio).map(([key, radioAttr]) => (
<label key={radioAttr.id}>
<input {...radioAttr} />
{radioAttr.value}
</label>
))}
// 3. Arrays
// Arrays of basic types or objects are recursively resolved.
// fields.tags yields the attributes for a single array item input.
<input {...fields.tags} />Attribute Translation Rules
The library translates Valibot types and pipes into HTML attributes according to these mapping rules:
- Types:
boolean()becomestype="checkbox".number()yieldsinputMode="numeric"andpattern="[0-9]*".date()yieldstype="date".blob()yieldstype="file".
- Validation Pipes:
minLength(x)becomesminLength={x}.maxValue(x)becomesmax={x}.regex(r)converts the RegExp into apatternstring.
- Optionality:
- Any schema wrapped in
optional(),nullable(), ornullish()setsrequired={false}. By default, all fields receiverequired={true}.
- Any schema wrapped in
