JumboForm
JumboForm is the @jumbo wrapper around React Hook Form. It accepts a Zod schema via the
validationSchema prop and wires zodResolver automatically. All @jumbo field components
(JumboInput, JumboSelect, etc.) read context from JumboForm and wire themselves without
explicit register or control prop drilling.
All form components live under @jumbo/vendors/react-hook-form.
JumboForm props
| Prop | Type | Description |
|---|---|---|
validationSchema | ZodSchema | Optional Zod schema; wired to zodResolver automatically |
onSubmit | (data: FormValues) => void | Submit handler called with validated form data |
sx | SxProps | MUI sx overrides applied to the <form> element |
children | ReactNode | Form fields and submit button |
Field components
| Component | HTML element | Notes |
|---|---|---|
JumboInput | <input> / MUI TextField | Standard text, email, number fields |
JumboOutlinedInput | MUI OutlinedInput | Outlined variant without label |
JumboSelect | MUI Select | Dropdown; accepts options prop |
JumboCheckbox | MUI Checkbox | Single checkbox with label |
JumboAvatarField | Custom | Avatar upload with preview |
JumboColorPickerField | react-color | Inline color picker |
Each field component accepts name (maps to the schema key) and any MUI props for the
underlying component.
Complete example
The LoginForm in src/components/LoginForm/LoginForm.tsx is a representative example:
// src/components/LoginForm/LoginForm.tsx
'use client';
import { JumboForm } from '@jumbo/vendors/react-hook-form';
import { JumboOutlinedInput } from '@jumbo/vendors/react-hook-form';
import { Button } from '@mui/material';
import { signIn } from 'next-auth/react';
import { validationSchema } from './validation';
export function LoginForm() {
const handleSubmit = async (data: { email: string; password: string }) => {
await signIn('credentials', {
email: data.email,
password: data.password,
callbackUrl: '/dashboards/misc',
});
};
return (
<JumboForm validationSchema={validationSchema} onSubmit={handleSubmit}>
<JumboOutlinedInput
name="email"
label="Email"
type="email"
fullWidth
/>
<JumboOutlinedInput
name="password"
label="Password"
type="password"
fullWidth
/>
<Button type="submit" variant="contained" fullWidth>
Sign In
</Button>
</JumboForm>
);
}Zod validation schema
Define schemas in a co-located validation.tsx or validation.ts file:
// src/components/LoginForm/validation.tsx
import { z } from 'zod';
export const validationSchema = z.object({
email: z
.string()
.min(1, 'Enter a valid email')
.email('Invalid email address'),
password: z
.string()
.min(6, 'Password must be at least 6 characters')
.max(32, 'Password must not exceed 32 characters'),
});
export type LoginFormValues = z.infer<typeof validationSchema>;Always infer TypeScript types from Zod schemas with z.infer<typeof schema>. This keeps
the schema and the type in sync without manual duplication.
Accessing RHF methods
If you need direct access to React Hook Form methods (e.g. reset, setValue, watch), use
useJumboFormContext inside a child component:
'use client';
import { useJumboFormContext } from '@jumbo/vendors/react-hook-form';
export function ResetButton() {
const { reset } = useJumboFormContext();
return <button type="button" onClick={() => reset()}>Reset</button>;
}Error display
Validation errors are displayed automatically by each field component beneath the input.
No additional error rendering code is needed; fields read from the RHF formState.errors
object internally.
For custom error display, read errors from useJumboFormContext:
const { formState: { errors } } = useJumboFormContext();