Package Exports
- @wandry/inertia-form
- @wandry/inertia-form/dist/index.mjs
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@wandry/inertia-form) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme

A simple way to create forms for Inertia applications.
Project Goal
Simplify form development in Inertia.js/React applications.
Of course, Inertia.js has its own useForm and Form component, but it doesn't provide as many capabilities that everyone is used to when using react-hook-form.
We've made it so that anyone who has used react-hook-form can immediately use our library without studying the documentation from cover to cover.\
What we offer:
- form value tracking with
useWatch - getting field values anywhere in the code with
getValues() - adding values to the form with
setValue() - simpler and more flexible form key management, support for nested keys as a regular string
user.info.name - creating custom fields with
FieldoruseFieldcomponents
How it's implemented
The root point is the Form component, which implements a wrapper over useForm from inertia.js and creates a React.Context that wraps all form state and the ability to manipulate it. That's it. All you need to do is call the <Form> component and all child components will already be able to work with your form.
Wandry UI
We have created shadcn/registry for UI form components that are fully controlled — you can simply insert them into the code and your form will already be working.
Install and enjoy
npx shadcn@latest add @wandry-ui/text-fieldThis way, your forms will look like this:
import { Form } from "@wandry/inertia-form";
import TextField from "@/components/text-field";
import PasswordField from "@/components/password-field";
import { Button } from "@/components/ui/button";
const Login: React.FC = () => {
const loginSchema = z.object({
email: z.email(),
password: z.string(),
});
return (
<Form action="/login" validationSchema={loginSchema}>
<TextField name="email" label="Email" />
<PasswordField name="password" label="Password" />
<Button type="submit">Submit</Button>
</Form>
);
};Just describe the fields - don't worry about how to link them to the form, we'll do that for you.
Components and Hooks
Form
Usage Example:
<Form
action="/api/submit"
method="post"
defaultValues={{ name: "" }}
onSubmit={(values) => console.log(values)}
>
{/* form fields */}
</Form>| Prop | Type | Required | Description |
|---|---|---|---|
action |
string |
Yes | URL or form action object. |
id |
string |
No | HTML id for the form. |
method |
"get" | "post" | "put" | "patch" | "delete" |
No | HTTP method for form submission. Default is "post". |
defaultValues |
Record<string, any> |
No | Initial values for form fields. |
options |
FormOptions |
No | Options for form submission (except data). |
className |
string |
No | CSS class for the form. |
validationSchema |
any |
No | Validation schema (e.g., for Yup). |
validator |
ValidationAdapter |
No | Custom validation adapter. |
sharedProps |
Record<string, any> |
No | Shared props that will be available to all form fields. |
preventFormAction |
boolean |
No | If true, prevents default form behavior on submission. |
onSubmit |
(value: any) => void |
No | Callback called when the form is submitted. |
useWayfinder |
boolean |
No | Whether to use Wayfinder mode for form submission. |
| ...FormAttrs | HTMLAttributes<HTMLFormElement> (without defaultValue, onSubmit) |
No | Any other standard HTML form attributes, except defaultValue and onSubmit. |
Field
Usage Example:
<Field
name="email"
controller={({ value, onChange, error }) => (
<div>
<input
type="email"
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder="Enter email"
/>
{error && <span style={{ color: "red" }}>{error}</span>}
</div>
)}
/>| Prop | Type | Required | Description |
|---|---|---|---|
id |
string |
No | HTML id for the field. |
name |
string |
Yes | Field name (key in the form). |
controller |
(field: FieldControllerProps<TValue>) => ReactElement |
Yes | Controller function that returns a React element for the field. |
defaultValue |
FieldValue |
No | Initial field value. |
FieldControllerProps is passed to controller:
| Prop | Type | Required | Description |
|---|---|---|---|
onChange |
(value: TValue) => void |
Yes | Value change handler. |
value |
TValue |
Yes | Current field value. |
error |
string |
No | Error message (if any). |
disabled |
boolean |
No | Whether the field is disabled. |
useField
Usage Example:
const { value, onChange, error } = useField("username", { defaultValue: "" });
return (
<div>
<input
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder="Enter username"
/>
{error && <span style={{ color: "red" }}>{error}</span>}
</div>
);| Return Value | Type | Description |
|---|---|---|
value |
FieldValue |
Current field value. |
onChange |
(value: FieldValue) => void |
Function for updating field value. |
error |
string | undefined |
Error message for the field (if any). |
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Field name (key in the form). |
options |
{ defaultValue?: any } |
No | Options, e.g., initial field value. |
useFormContext
Note: The
useFormContexthook should only be used inside theFormcomponent.
Usage Example:
const { getValues, setValue, form } = useFormContext();
// Get all form values
const allValues = getValues();
// Get a specific field value
const email = getValues("email");
// Set field value
setValue("username", "newUser");| Return Value | Type | Description |
|---|---|---|
form |
FormContextType |
Form context, includes state and form management methods. |
getValues |
(name?: string, defaultValue?: any) => any |
Get all form values or a specific field value by name. |
setValue |
(name: string, value: any) => void |
Set field value by name. |
useWatch
A hook for tracking changes to form values or a specific field in real-time.
Usage Example:
import { useWatch } from "@wandry/inertia-form";
function ProfileForm() {
const username = useWatch("username");
const allValues = useWatch();
return (
<div>
<div>Username: {username}</div>
<pre>{JSON.stringify(allValues, null, 2)}</pre>
</div>
);
}| Name | Type | Required | Description |
|---|---|---|---|
name |
string |
No | Field name to track (nested keys are supported via dot notation). |
options |
{ defaultValue?: any } |
No | Options, e.g., default value if the field is missing. |