@beignet/react-hook-form 0.0.24 → 0.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @beignet/react-hook-form
2
2
 
3
+ ## 0.0.26
4
+
5
+ ### Patch Changes
6
+
7
+ - 104302c: Refresh package-shipped TanStack Intent skills and add package skills for Drizzle database providers, Better Auth, React Hook Form, and React uploads.
8
+
9
+ ## 0.0.25
10
+
3
11
  ## 0.0.24
4
12
 
5
13
  ## 0.0.23
package/README.md CHANGED
@@ -18,6 +18,14 @@ npm install @beignet/react-hook-form @beignet/core react-hook-form @hookform/res
18
18
 
19
19
  This package requires TypeScript 5.0 or higher for proper type inference.
20
20
 
21
+ ## Agent skills
22
+
23
+ This package ships a TanStack Intent skill for coding agents:
24
+ `@beignet/react-hook-form#forms`. Load it when adding contract-backed forms,
25
+ React Hook Form setup, Standard Schema resolver behavior, `rootFormError`,
26
+ React Query mutations, transforming body schemas, feature component
27
+ boundaries, or field/server error mapping in a Beignet app.
28
+
21
29
  ## Usage
22
30
 
23
31
  ### Basic form
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beignet/react-hook-form",
3
- "version": "0.0.24",
3
+ "version": "0.0.26",
4
4
  "type": "module",
5
5
  "description": "React Hook Form integration for Beignet with Standard Schema support",
6
6
  "main": "./dist/index.js",
@@ -17,6 +17,7 @@
17
17
  "!src/**/*.test.ts",
18
18
  "!src/**/*.test.tsx",
19
19
  "!src/**/*.test-d.ts",
20
+ "skills",
20
21
  "README.md",
21
22
  "CHANGELOG.md"
22
23
  ],
@@ -34,7 +35,8 @@
34
35
  "api",
35
36
  "typescript",
36
37
  "react-hook-form",
37
- "standard-schema"
38
+ "standard-schema",
39
+ "tanstack-intent"
38
40
  ],
39
41
  "license": "MIT",
40
42
  "repository": {
@@ -0,0 +1,143 @@
1
+ ---
2
+ name: forms
3
+ description: "Build Beignet React Hook Form integration with @beignet/react-hook-form: createReactHookForm, contract body schemas, formOptions, useForm, Standard Schema resolver behavior, rootFormError, React Query mutations, transforming schemas, feature component boundaries, field/server error mapping, and client/server import fixes. Use when adding or debugging forms in a Beignet React app."
4
+ ---
5
+
6
+ # Beignet React Hook Form
7
+
8
+ Use this skill when working in a Beignet React app that depends on
9
+ `@beignet/react-hook-form`. Read the nearest feature component, feature
10
+ schemas/contracts, root `client/` helpers, and existing form patterns before
11
+ adding a new form.
12
+
13
+ ## Setup
14
+
15
+ Create the adapter once in root `client/` or reuse the app's existing helper.
16
+
17
+ ```ts
18
+ import { createReactHookForm } from "@beignet/react-hook-form";
19
+
20
+ export const rhf = createReactHookForm();
21
+ ```
22
+
23
+ Feature forms should import contracts, schemas, feature client helpers, React
24
+ Hook Form, React Query, and UI components only. They must not import use cases,
25
+ routes, providers, infra adapters, `server/`, or `app-context.ts`.
26
+
27
+ ## Contract Requirements
28
+
29
+ React Hook Form binds to the contract body schema. If a contract has no
30
+ `.body(...)`, `rhf(contract)` throws because there are no form fields or body
31
+ validation to infer.
32
+
33
+ Keep shared form DTOs in `features/<feature>/schemas.ts`, then reuse them from
34
+ contracts, use cases, tests, and components.
35
+
36
+ ## Form Pattern
37
+
38
+ ```tsx
39
+ "use client";
40
+
41
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
42
+ import { rootFormError } from "@beignet/react-hook-form";
43
+ import { rhf } from "@/client/forms";
44
+ import { createTodo } from "@/features/todos/contracts";
45
+ import {
46
+ createTodoMutationOptions,
47
+ invalidateTodos,
48
+ } from "@/features/todos/client/queries";
49
+
50
+ const createTodoForm = rhf(createTodo);
51
+
52
+ export function CreateTodoForm() {
53
+ const queryClient = useQueryClient();
54
+ const form = createTodoForm.useForm({
55
+ defaultValues: { title: "" },
56
+ });
57
+
58
+ const mutation = useMutation({
59
+ ...createTodoMutationOptions(),
60
+ onSuccess: () => {
61
+ form.reset();
62
+ invalidateTodos(queryClient);
63
+ },
64
+ onError: (error) => {
65
+ form.setError(
66
+ "root",
67
+ rootFormError(error, "Could not create the todo."),
68
+ );
69
+ },
70
+ });
71
+
72
+ return (
73
+ <form
74
+ onSubmit={form.handleSubmit((values) => {
75
+ form.clearErrors("root");
76
+ mutation.mutate({ body: values });
77
+ })}
78
+ >
79
+ {/* fields */}
80
+ </form>
81
+ );
82
+ }
83
+ ```
84
+
85
+ Use `formOptions(...)` when a component or wrapper wants options without
86
+ calling the hook directly.
87
+
88
+ ## Input And Output Types
89
+
90
+ React Hook Form field state uses the schema input type. `handleSubmit` receives
91
+ the schema output type after validation, coercion, defaults, and transforms.
92
+
93
+ For plain, defaulted, or coerced schemas, submitting `values` as the contract
94
+ body usually works. If a schema transform changes a field's type so the parsed
95
+ output no longer matches the contract body input, send raw field values from
96
+ `form.getValues()` after validation instead of `values`.
97
+
98
+ ## Error Mapping
99
+
100
+ Use `rootFormError(error, fallback, overrides?)` for mutation or endpoint
101
+ failures when the server error belongs at the form level.
102
+
103
+ ```ts
104
+ form.setError(
105
+ "root",
106
+ rootFormError(error, "Could not update profile.", {
107
+ HANDLE_UNAVAILABLE: "That handle is already taken.",
108
+ }),
109
+ );
110
+ ```
111
+
112
+ Map a server error to a field only when the server response identifies a
113
+ specific field and the field exists in the body schema. Keep route-owned error
114
+ codes declared on the contract with `.errors(...)`.
115
+
116
+ ## Gotchas
117
+
118
+ - `rhf(contract)` only understands the request body. Path params, query
119
+ params, headers, tenant IDs, and auth-derived values belong in mutation
120
+ variables or app context, not form fields.
121
+ - Contracts without `.body(...)` are not form contracts.
122
+ - `handleSubmit` returns parsed schema output. For transforms that change field
123
+ types, submit `form.getValues()` after validation when the contract client
124
+ expects body input.
125
+ - Keep the root form helper in `client/forms.ts` unless the app already uses a
126
+ different local convention.
127
+ - Do not import use cases or server modules to reuse validation. Move shared
128
+ validation to `features/<feature>/schemas.ts`.
129
+
130
+ ## Validation
131
+
132
+ Leave the generated Standard Schema resolver enabled by default. Use
133
+ `resolverEnabled: false` only for deliberate partial or multi-step flows, and
134
+ keep final validation in use cases.
135
+
136
+ After form changes, run from the app root:
137
+
138
+ ```bash
139
+ beignet lint
140
+ beignet doctor --strict
141
+ bun run typecheck
142
+ bun run test
143
+ ```