Building forms involves more than just rendering anDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/rijvi-mahmud/shaddy/llms.txt
Use this file to discover all available pages before exploring further.
<input> element — every field needs a label, validation feedback, accessible structure, and a connection to the form’s state manager. Fields in Shaddy Form encapsulate all of that into a single, reusable component.
What Is a Field?
A Field is a self-contained form control that wraps a UI input and integrates automatically withShaddyForm’s context. Rather than wiring up FormField, FormItem, FormLabel, FormControl, and FormMessage by hand for every input, a Field component does all of that internally.
Fields follow a consistent naming convention — the Field suffix — so they are easy to identify and locate in your codebase (e.g., TextField, PasswordField, TextAreaField).
Field vs Raw Input
Raw <input> | Shaddy Field | |
|---|---|---|
Connected to react-hook-form | Manual register or Controller | Automatic via useFormContext |
| Label rendering | Manual | Built-in via label prop |
| Validation errors | Manual formState.errors lookup | Built-in FormMessage |
| Accessible structure | Manual | Built-in FormItem / FormControl |
| Reusable across forms | Copy-paste | Drop-in component |
How Fields Connect to the Form
Every Field component callsuseFormContext() internally to retrieve the control object from the nearest ShaddyForm. This means fields work anywhere inside a <ShaddyForm> without receiving any form-specific props — just the field’s own name, label, and any input-specific options.
Fields must be rendered as descendants of a
ShaddyForm. Using a field outside of ShaddyForm will throw an error because there is no form context to connect to.Available Built-in Fields
Shaddy Form ships with a set of ready-to-use field components, all built onshadcn/ui primitives:
TextField— Standard text input for any string value, supportstypeprop foremail,number,url, etc.PasswordField— ExtendsTextFieldwith a show/hide password toggle.TextAreaField— Multi-line text input for longer content.SubmitButton— Submits the form with loading and disabled state support.ResetButton— Resets the form to itsinitialValues.
Why Fields Are Separated by Responsibility
Fields are intentionally modular and purpose-driven. For example:TextFieldhandles all single-line text input, butPasswordFieldextends it with additional UI for toggling password visibility.SubmitButtonandResetButtonare both buttons, but they are separated so each has a single, explicit responsibility — submitting or resetting — without conditionals or ambiguity.
Creating a Custom Field
If you need a field type that does not exist yet — a date picker, a select menu, a file uploader — you can build one following the same pattern as all built-in fields.Define your props type
Use
FieldValues and Path<T> from react-hook-form to make the component generic and type-safe.Read control from useFormContext
Call
useFormContext<T>() inside the component to obtain the control object.PasswordField:
ShaddyForm exactly like a built-in field:
Validation logic lives in the Zod schema, not in the field component. Field components are responsible only for rendering and UI interactions — this keeps them lean and reusable.