react-hook-form-mantine
v4.1.0
Published
React hook form wrapper for Mantine components
Maintainers
Readme
React Hook Form Mantine
Give Mantine fields a name—and let React Hook Form do the wiring.
React Hook Form Mantine wraps Mantine inputs with React Hook Form’s controller model. Add name and control to a familiar Mantine component, keep Mantine’s props, and get field values and validation errors without hand-writing the same adapter in every form.
A source-level sketch of the wrapper contract.
The five-minute win
import { useForm } from "react-hook-form";
import { TextInput } from "react-hook-form-mantine";
type Profile = { displayName: string };
export function ProfileForm() {
const { control, handleSubmit } = useForm<Profile>();
return (
<form onSubmit={handleSubmit(console.log)}>
<TextInput
name="displayName"
control={control}
label="Display name"
rules={{ required: "Give yourself a name" }}
/>
<button type="submit">Save profile</button>
</form>
);
}The wrapper forwards Mantine’s UI props, passes rules to useController, and displays the field error through Mantine’s error prop. The same pattern scales from a text input to a date picker, slider, select, or grouped control.
Controller lifecycle
Custom onChange and onBlur callbacks run alongside React Hook Form's handlers,
so blur still marks the field touched and runs mode: "onBlur" validation.
disabled is passed to the controller as well as the Mantine control: disabled
field values are omitted from submitted data, following React Hook Form semantics.
Use readOnly where supported if a non-editable value should still be submitted.
Install
pnpm add react-hook-form-mantine react-hook-form @mantine/core @mantine/dates dayjsThe published package is ESM (4.0.1). Its peer dependencies are:
| Package | Supported version |
| ----------------- | ----------------- |
| @mantine/core | ^9.0.0 |
| @mantine/dates | ^9.0.0 |
| react | ^19.0.0 |
| react-dom | ^19.0.0 |
| react-hook-form | ^7.43 |
What is covered
The package exports wrappers for Mantine text and password inputs, textarea, number and mask inputs, checkbox/radio/switch/chip groups, select/autocomplete/multi-select, color and JSON inputs, date/month/year/time pickers, sliders, rating, segmented control, tags, file and PIN inputs, and related groups. The barrel at src/index.ts is the complete export list.
Try the full form in example/src/App.tsx (also in Storybook under Examples / Full form), browse the deployed demo, or inspect the Storybook stories in src/**/*.stories.tsx.
Development
corepack enable
pnpm install --frozen-lockfile
pnpm typecheck
pnpm lint
pnpm format
pnpm test --run
pnpm buildpnpm format is the repository’s check command; pnpm format:fix writes formatting. CI runs formatting, linting, type checking, tests, and the library build on Node 24.
pnpm test runs two Vitest projects: unit (component tests in jsdom) and storybook, which renders every story in headless Chromium and fails on a broken render, a failing play function or .test(), or an accessibility violation. Run one with pnpm test:unit or pnpm test:storybook; the first run needs pnpm exec playwright install chromium.
Storybook
pnpm storybook opens the component workshop on port 6006; pnpm build-storybook produces the static site. GitHub Pages serves the gh-pages branch: main's Storybook at the root, and every same-repository pull request's at /pr-preview/pr-<number>/, linked from a comment on the pull request and removed when it closes.
- Every story is a real form. Components render in a form card with Reset and Submit. A Form addon panel (
.storybook/form-addon/) shows each field's value, dirty, touched and error state, the raw values and errors, and the submit result, with its own Reset and Submit.onChangeandonBlurarefn()spies, so their calls appear in the Actions panel. - Theme from the toolbar. Switch the Mantine color scheme, primary color and default radius. Stories can pin these with
globals, asExamples / Full form / Darkdoes. - Tests in the sidebar. Stories use CSF Next (
preview.meta/meta.story) and theStory.test()API, so each named test is listed under its story. The test widget runs interactions, accessibility checks and coverage in the browser, with watch mode. - Generated docs. Each component gets a docs page with what it wraps, an import snippet, links to Mantine and the source, and a props table, with react-hook-form props and events grouped separately.
- For coding agents. The dev server serves an MCP endpoint at
http://localhost:6006/mcp(@storybook/addon-mcp) with the component manifest and stories. - Filter by tag.
validationmarks stories with rules or a resolver;examplemarks full-form examples.
Storybook's docgen reads prop types through the TypeScript compiler API, which TypeScript 7 doesn't provide. .pnpmfile.cjs gives the docgen packages TypeScript 6 while the project compiles with 7.
Source map
| Path | Responsibility |
| ------------------ | ----------------------------------------------------------------------- |
| src/<Component>/ | Mantine wrapper, tests, and Storybook story for each control. |
| src/index.ts | Public export barrel. |
| example/ | Vite demo form exercising the wrappers together. |
| .storybook/ | Mantine provider, React Hook Form context, and Storybook configuration. |
| vitest.config.ts | Unit and Storybook test projects. |
| vite.config.ts | Library and declaration build configuration. |
Status and license
Version 4.0.1 is published from this repository through the release workflow. The package is licensed under the MIT License. Changes to Mantine or React Hook Form peer APIs should be checked against the supported ranges above.
