rhf-stepper 0.2.4 → 1.0.0
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/README.md +202 -157
- package/dist/index.d.mts +18 -21
- package/dist/index.d.ts +18 -21
- package/dist/index.js +180 -274
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +180 -275
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A lightweight, headless multi-step form helper for [react-hook-form](https://react-hook-form.com). Build wizards, multi-step forms, and stepped workflows with automatic per-step validation. Bring your own UI — rhf-stepper handles the logic.
|
|
4
4
|
|
|
5
|
-
[Documentation](https://rhf-stepper-docs
|
|
5
|
+
[Documentation](https://rhf-stepper-docs.vercel.app/docs)
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -26,8 +26,8 @@ yarn add rhf-stepper
|
|
|
26
26
|
## Quick Start
|
|
27
27
|
|
|
28
28
|
```tsx
|
|
29
|
-
import { useForm } from 'react-hook-form'
|
|
30
|
-
import {
|
|
29
|
+
import { useForm, FormProvider } from 'react-hook-form'
|
|
30
|
+
import { Stepper, Step, Controller, useStepper } from 'rhf-stepper'
|
|
31
31
|
|
|
32
32
|
type FormValues = {
|
|
33
33
|
name: string
|
|
@@ -40,36 +40,40 @@ function MyMultiStepForm() {
|
|
|
40
40
|
const form = useForm<FormValues>()
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<
|
|
44
|
-
{(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
43
|
+
<FormProvider {...form}>
|
|
44
|
+
<form onSubmit={form.handleSubmit((data) => console.log(data))}>
|
|
45
|
+
<Stepper>
|
|
46
|
+
{({ activeStep }) => (
|
|
47
|
+
<>
|
|
48
|
+
<Step>
|
|
49
|
+
{activeStep === 0 && (
|
|
50
|
+
<>
|
|
51
|
+
<Controller name="name" render={({ field }) => <input {...field} placeholder="Name" />} />
|
|
52
|
+
<Controller name="email" render={({ field }) => <input {...field} placeholder="Email" />} />
|
|
53
|
+
</>
|
|
54
|
+
)}
|
|
55
|
+
</Step>
|
|
56
|
+
|
|
57
|
+
<Step>
|
|
58
|
+
{activeStep === 1 && (
|
|
59
|
+
<>
|
|
60
|
+
<Controller name="address" render={({ field }) => <input {...field} placeholder="Address" />} />
|
|
61
|
+
<Controller name="city" render={({ field }) => <input {...field} placeholder="City" />} />
|
|
62
|
+
</>
|
|
63
|
+
)}
|
|
64
|
+
</Step>
|
|
65
|
+
|
|
66
|
+
<StepNavigation />
|
|
67
|
+
</>
|
|
68
|
+
)}
|
|
69
|
+
</Stepper>
|
|
70
|
+
</form>
|
|
71
|
+
</FormProvider>
|
|
68
72
|
)
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
function StepNavigation() {
|
|
72
|
-
const { next, prev, isFirstStep, isLastStep } =
|
|
76
|
+
const { next, prev, isFirstStep, isLastStep } = useStepper()
|
|
73
77
|
|
|
74
78
|
return (
|
|
75
79
|
<div>
|
|
@@ -81,67 +85,63 @@ function StepNavigation() {
|
|
|
81
85
|
}
|
|
82
86
|
```
|
|
83
87
|
|
|
84
|
-
> **Important:** `<Step>`
|
|
88
|
+
> **Important:** Do not conditionally render `<Step>` based on `activeStep`. This would break step counting and cause `isLastStep`, `next()`, and other navigation to behave incorrectly. Always keep steps mounted and conditionally render only the children inside each step.
|
|
85
89
|
|
|
86
90
|
## API Reference
|
|
87
91
|
|
|
88
|
-
### `<
|
|
92
|
+
### `<Stepper>`
|
|
89
93
|
|
|
90
|
-
The root component that
|
|
94
|
+
The root component that manages step state and validation. Does **not** render a `<form>` element — you provide your own `<form>` and wrap with react-hook-form's `<FormProvider>`.
|
|
91
95
|
|
|
92
96
|
```tsx
|
|
93
|
-
<
|
|
94
|
-
form={form}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
>
|
|
98
|
-
|
|
99
|
-
</
|
|
97
|
+
<FormProvider {...form}>
|
|
98
|
+
<form onSubmit={form.handleSubmit(handleSubmit)}>
|
|
99
|
+
<Stepper stepValidationMode="forward">
|
|
100
|
+
{children}
|
|
101
|
+
</Stepper>
|
|
102
|
+
</form>
|
|
103
|
+
</FormProvider>
|
|
100
104
|
```
|
|
101
105
|
|
|
102
106
|
#### Props
|
|
103
107
|
|
|
104
108
|
| Prop | Type | Default | Description |
|
|
105
109
|
|------|------|---------|-------------|
|
|
106
|
-
| `form` | `UseFormReturn<T>` |
|
|
107
|
-
| `onSubmit` | `(values: T) => void` | *required* | Called with form values on valid submission |
|
|
110
|
+
| `form` | `UseFormReturn<T>` | - | The form instance from `useForm()`. Optional if wrapped in `<FormProvider>` |
|
|
108
111
|
| `stepValidationMode` | `'forward' \| 'all' \| 'none'` | `'forward'` | When to validate step fields (see below) |
|
|
109
112
|
| `children` | `ReactNode \| (context) => ReactNode` | *required* | Form content. Accepts a render function for context access |
|
|
110
|
-
| `ref` | `Ref<HTMLFormElement>` | - | Ref forwarded to the underlying `<form>` element |
|
|
111
|
-
|
|
112
|
-
All other props are passed through to the underlying `<form>` element (e.g., `className`, `id`).
|
|
113
113
|
|
|
114
114
|
#### Step Validation Modes
|
|
115
115
|
|
|
116
116
|
| Mode | Description |
|
|
117
117
|
|------|-------------|
|
|
118
|
-
| `'forward'` | Validates current step fields only when navigating forward (via `next()` or `
|
|
118
|
+
| `'forward'` | Validates current step fields only when navigating forward (via `next()` or `jumpTo` to a later step) |
|
|
119
119
|
| `'all'` | Validates current step fields on every navigation (forward and backward) |
|
|
120
120
|
| `'none'` | No automatic validation. Navigate freely between steps |
|
|
121
121
|
|
|
122
122
|
#### Render Function
|
|
123
123
|
|
|
124
|
-
When using a render function as children, you receive the full `
|
|
124
|
+
When using a render function as children, you receive the full `StepperContextValue`:
|
|
125
125
|
|
|
126
126
|
```tsx
|
|
127
|
-
<
|
|
128
|
-
{({
|
|
129
|
-
// render steps based on
|
|
127
|
+
<Stepper>
|
|
128
|
+
{({ activeStep, isFirstStep, isLastStep, next, prev }) => (
|
|
129
|
+
// render steps based on activeStep
|
|
130
130
|
)}
|
|
131
|
-
</
|
|
131
|
+
</Stepper>
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
---
|
|
135
135
|
|
|
136
136
|
### `<Step>`
|
|
137
137
|
|
|
138
|
-
Groups `<Controller>` fields into a logical step. Fields inside a `<Step>` are automatically registered and validated together. Each `<Step>` defines a step boundary
|
|
138
|
+
Groups `<Controller>` fields into a logical step. Fields inside a `<Step>` are automatically registered and validated together. Each `<Step>` defines a step boundary — conditionally render its children based on `activeStep` to control which step is visible.
|
|
139
139
|
|
|
140
|
-
> **Important:** `<Step>`
|
|
140
|
+
> **Important:** Do not conditionally render `<Step>` based on `activeStep`. This would break step counting and cause `isLastStep`, `next()`, and other navigation to behave incorrectly. Always keep steps mounted and conditionally render only the children inside each step. Steps **can** be conditionally rendered based on form values for dynamic forms (see [Dynamic Steps](#dynamic-steps)).
|
|
141
141
|
|
|
142
142
|
```tsx
|
|
143
143
|
<Step>
|
|
144
|
-
{
|
|
144
|
+
{activeStep === 0 && (
|
|
145
145
|
<>
|
|
146
146
|
<Controller name="firstName" render={({ field }) => <input {...field} />} />
|
|
147
147
|
<Controller name="lastName" render={({ field }) => <input {...field} />} />
|
|
@@ -150,23 +150,6 @@ Groups `<Controller>` fields into a logical step. Fields inside a `<Step>` are a
|
|
|
150
150
|
</Step>
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
Steps can be nested for sub-step grouping:
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
<Step>
|
|
157
|
-
<Step>
|
|
158
|
-
{currentStep === 0 && (
|
|
159
|
-
<Controller name="a" render={({ field }) => <input {...field} />} />
|
|
160
|
-
)}
|
|
161
|
-
</Step>
|
|
162
|
-
<Step>
|
|
163
|
-
{currentStep === 1 && (
|
|
164
|
-
<Controller name="b" render={({ field }) => <input {...field} />} />
|
|
165
|
-
)}
|
|
166
|
-
</Step>
|
|
167
|
-
</Step>
|
|
168
|
-
```
|
|
169
|
-
|
|
170
153
|
---
|
|
171
154
|
|
|
172
155
|
### `<Controller>`
|
|
@@ -188,43 +171,77 @@ A drop-in replacement for react-hook-form's `Controller`. It automatically regis
|
|
|
188
171
|
|
|
189
172
|
#### Props
|
|
190
173
|
|
|
191
|
-
Same as [react-hook-form's Controller](https://react-hook-form.com/docs/usecontroller/controller). The `control` prop is optional
|
|
174
|
+
Same as [react-hook-form's Controller](https://react-hook-form.com/docs/usecontroller/controller). The `control` prop is optional — it's automatically resolved from `<FormProvider>`.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### `useController()`
|
|
179
|
+
|
|
180
|
+
A hook alternative to `<Controller>`. Drop-in replacement for react-hook-form's `useController` that automatically registers the field with the nearest `<Step>`.
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { useController } from 'rhf-stepper'
|
|
184
|
+
|
|
185
|
+
function CustomInput({ name }: { name: string }) {
|
|
186
|
+
const { field, fieldState } = useController({ name, rules: { required: 'Required' } })
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<div>
|
|
190
|
+
<input {...field} />
|
|
191
|
+
{fieldState.error && <span>{fieldState.error.message}</span>}
|
|
192
|
+
</div>
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Props
|
|
198
|
+
|
|
199
|
+
Same as [react-hook-form's useController](https://react-hook-form.com/docs/usecontroller).
|
|
192
200
|
|
|
193
201
|
---
|
|
194
202
|
|
|
195
|
-
### `
|
|
203
|
+
### `useStepper()`
|
|
196
204
|
|
|
197
|
-
Hook to access the stepper state from any component inside `<
|
|
205
|
+
Hook to access the stepper state from any component inside `<Stepper>`.
|
|
198
206
|
|
|
199
207
|
```tsx
|
|
200
208
|
const {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
currentStepArr,
|
|
206
|
-
validatedFields,
|
|
209
|
+
activeStep,
|
|
210
|
+
jumpTo,
|
|
211
|
+
fields,
|
|
212
|
+
validSteps,
|
|
207
213
|
isFirstStep,
|
|
208
214
|
isLastStep,
|
|
209
215
|
next,
|
|
210
216
|
prev,
|
|
211
|
-
} =
|
|
217
|
+
} = useStepper<MyFormValues>()
|
|
212
218
|
```
|
|
213
219
|
|
|
214
|
-
#### Return Value (`
|
|
220
|
+
#### Return Value (`StepperContextValue<T>`)
|
|
215
221
|
|
|
216
222
|
| Property | Type | Description |
|
|
217
223
|
|----------|------|-------------|
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `currentStepArr` | `string[] \| null` | Field names registered in the current step |
|
|
223
|
-
| `validatedFields` | `string[]` | Field names that have been validated via step navigation |
|
|
224
|
+
| `activeStep` | `number` | Current step index (0-based) |
|
|
225
|
+
| `jumpTo` | `(step: number, onLeave?) => Promise<boolean>` | Navigate to a specific step. Validates before navigating (based on `stepValidationMode`). Returns `true` if navigation succeeded |
|
|
226
|
+
| `fields` | `string[] \| null` | Field names registered in the current step |
|
|
227
|
+
| `validSteps` | `number[]` | Step indices that have passed validation |
|
|
224
228
|
| `isFirstStep` | `boolean` | `true` if on the first step |
|
|
225
229
|
| `isLastStep` | `boolean` | `true` if on the last step |
|
|
226
|
-
| `next` | `() =>
|
|
227
|
-
| `prev` | `() =>
|
|
230
|
+
| `next` | `(onLeave?) => Promise<boolean>` | Navigate to the next step. Validates current step first. Returns `true` if navigation succeeded |
|
|
231
|
+
| `prev` | `(onLeave?) => Promise<boolean>` | Navigate to the previous step. Returns `true` if navigation succeeded |
|
|
232
|
+
|
|
233
|
+
#### `onLeave` Callback
|
|
234
|
+
|
|
235
|
+
`next`, `prev`, and `jumpTo` accept an optional `onLeave` callback that runs **after validation passes but before the step changes**. Use it for side effects like fetching data or auto-filling fields:
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
await next(async (values) => {
|
|
239
|
+
// values contains only the current step's fields
|
|
240
|
+
const res = await fetch(`/api/lookup?zip=${values.zipCode}`)
|
|
241
|
+
const data = await res.json()
|
|
242
|
+
form.setValue('city', data.city)
|
|
243
|
+
})
|
|
244
|
+
```
|
|
228
245
|
|
|
229
246
|
---
|
|
230
247
|
|
|
@@ -233,8 +250,8 @@ const {
|
|
|
233
250
|
### Basic Two-Step Form
|
|
234
251
|
|
|
235
252
|
```tsx
|
|
236
|
-
import { useForm } from 'react-hook-form'
|
|
237
|
-
import {
|
|
253
|
+
import { useForm, FormProvider } from 'react-hook-form'
|
|
254
|
+
import { Stepper, Step, Controller, useStepper } from 'rhf-stepper'
|
|
238
255
|
|
|
239
256
|
type SignupForm = {
|
|
240
257
|
email: string
|
|
@@ -247,62 +264,66 @@ function SignupWizard() {
|
|
|
247
264
|
const form = useForm<SignupForm>()
|
|
248
265
|
|
|
249
266
|
return (
|
|
250
|
-
<
|
|
251
|
-
{(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
267
|
+
<FormProvider {...form}>
|
|
268
|
+
<form onSubmit={form.handleSubmit((data) => console.log(data))}>
|
|
269
|
+
<Stepper>
|
|
270
|
+
{({ activeStep }) => (
|
|
271
|
+
<>
|
|
272
|
+
<Step>
|
|
273
|
+
{activeStep === 0 && (
|
|
274
|
+
<>
|
|
275
|
+
<Controller
|
|
276
|
+
name="email"
|
|
277
|
+
rules={{ required: 'Email is required' }}
|
|
278
|
+
render={({ field, fieldState }) => (
|
|
279
|
+
<div>
|
|
280
|
+
<input {...field} type="email" placeholder="Email" />
|
|
281
|
+
{fieldState.error && <p>{fieldState.error.message}</p>}
|
|
282
|
+
</div>
|
|
283
|
+
)}
|
|
284
|
+
/>
|
|
285
|
+
<Controller
|
|
286
|
+
name="password"
|
|
287
|
+
rules={{ required: 'Password is required', minLength: { value: 8, message: 'Min 8 characters' } }}
|
|
288
|
+
render={({ field, fieldState }) => (
|
|
289
|
+
<div>
|
|
290
|
+
<input {...field} type="password" placeholder="Password" />
|
|
291
|
+
{fieldState.error && <p>{fieldState.error.message}</p>}
|
|
292
|
+
</div>
|
|
293
|
+
)}
|
|
294
|
+
/>
|
|
295
|
+
</>
|
|
296
|
+
)}
|
|
297
|
+
</Step>
|
|
298
|
+
|
|
299
|
+
<Step>
|
|
300
|
+
{activeStep === 1 && (
|
|
301
|
+
<>
|
|
302
|
+
<Controller
|
|
303
|
+
name="firstName"
|
|
304
|
+
rules={{ required: 'First name is required' }}
|
|
305
|
+
render={({ field }) => <input {...field} placeholder="First Name" />}
|
|
306
|
+
/>
|
|
307
|
+
<Controller
|
|
308
|
+
name="lastName"
|
|
309
|
+
rules={{ required: 'Last name is required' }}
|
|
310
|
+
render={({ field }) => <input {...field} placeholder="Last Name" />}
|
|
311
|
+
/>
|
|
312
|
+
</>
|
|
313
|
+
)}
|
|
314
|
+
</Step>
|
|
315
|
+
|
|
316
|
+
<Navigation />
|
|
317
|
+
</>
|
|
318
|
+
)}
|
|
319
|
+
</Stepper>
|
|
320
|
+
</form>
|
|
321
|
+
</FormProvider>
|
|
301
322
|
)
|
|
302
323
|
}
|
|
303
324
|
|
|
304
325
|
function Navigation() {
|
|
305
|
-
const { next, prev, isFirstStep, isLastStep } =
|
|
326
|
+
const { next, prev, isFirstStep, isLastStep } = useStepper()
|
|
306
327
|
|
|
307
328
|
return (
|
|
308
329
|
<div>
|
|
@@ -318,13 +339,13 @@ function Navigation() {
|
|
|
318
339
|
|
|
319
340
|
```tsx
|
|
320
341
|
function StepIndicator() {
|
|
321
|
-
const {
|
|
342
|
+
const { activeStep, jumpTo } = useStepper()
|
|
322
343
|
|
|
323
344
|
return (
|
|
324
345
|
<nav>
|
|
325
|
-
<button type="button" onClick={() =>
|
|
326
|
-
<button type="button" onClick={() =>
|
|
327
|
-
<button type="button" onClick={() =>
|
|
346
|
+
<button type="button" onClick={() => jumpTo(0)}>Account</button>
|
|
347
|
+
<button type="button" onClick={() => jumpTo(1)}>Profile</button>
|
|
348
|
+
<button type="button" onClick={() => jumpTo(2)}>Review</button>
|
|
328
349
|
</nav>
|
|
329
350
|
)
|
|
330
351
|
}
|
|
@@ -333,18 +354,44 @@ function StepIndicator() {
|
|
|
333
354
|
### Skip Validation
|
|
334
355
|
|
|
335
356
|
```tsx
|
|
336
|
-
<
|
|
357
|
+
<Stepper stepValidationMode="none">
|
|
337
358
|
{/* Users can freely navigate between steps without validation */}
|
|
338
|
-
</
|
|
359
|
+
</Stepper>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Dynamic Steps
|
|
363
|
+
|
|
364
|
+
`<Step>` components can be conditionally rendered based on **form values** (not `activeStep`) for dynamic forms:
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
const needsShipping = useWatch({ control: form.control, name: 'needsShipping' })
|
|
368
|
+
|
|
369
|
+
<Stepper>
|
|
370
|
+
{({ activeStep }) => (
|
|
371
|
+
<>
|
|
372
|
+
<Step>{activeStep === 0 && <AccountFields />}</Step>
|
|
373
|
+
|
|
374
|
+
{needsShipping && (
|
|
375
|
+
<Step>{activeStep === 1 && <ShippingFields />}</Step>
|
|
376
|
+
)}
|
|
377
|
+
|
|
378
|
+
<Step>
|
|
379
|
+
{activeStep === (needsShipping ? 2 : 1) && <PaymentFields />}
|
|
380
|
+
</Step>
|
|
381
|
+
</>
|
|
382
|
+
)}
|
|
383
|
+
</Stepper>
|
|
339
384
|
```
|
|
340
385
|
|
|
341
386
|
### Accessing the Form Instance
|
|
342
387
|
|
|
343
|
-
`
|
|
388
|
+
Since `useStepper` only returns stepper state, use react-hook-form's `useFormContext` to access the form instance:
|
|
344
389
|
|
|
345
390
|
```tsx
|
|
391
|
+
import { useFormContext } from 'react-hook-form'
|
|
392
|
+
|
|
346
393
|
function ResetButton() {
|
|
347
|
-
const
|
|
394
|
+
const form = useFormContext<MyFormValues>()
|
|
348
395
|
|
|
349
396
|
return (
|
|
350
397
|
<button type="button" onClick={() => form.reset()}>
|
|
@@ -358,22 +405,20 @@ function ResetButton() {
|
|
|
358
405
|
|
|
359
406
|
```ts
|
|
360
407
|
import type {
|
|
361
|
-
|
|
362
|
-
|
|
408
|
+
StepperContextValue,
|
|
409
|
+
StepperProps,
|
|
363
410
|
ControllerProps,
|
|
364
411
|
ControllerRenderArgs,
|
|
365
|
-
StepTree,
|
|
366
412
|
StepValidationMode,
|
|
367
413
|
} from 'rhf-stepper'
|
|
368
414
|
```
|
|
369
415
|
|
|
370
416
|
| Type | Description |
|
|
371
417
|
|------|-------------|
|
|
372
|
-
| `
|
|
373
|
-
| `
|
|
418
|
+
| `StepperContextValue<T>` | Return type of `useStepper()` |
|
|
419
|
+
| `StepperProps<T>` | Props for the `<Stepper>` component |
|
|
374
420
|
| `ControllerProps<T, N>` | Props for the `<Controller>` component |
|
|
375
421
|
| `ControllerRenderArgs<T, N>` | Arguments passed to the Controller `render` function |
|
|
376
|
-
| `StepTree` | Recursive type representing the step structure (`string \| StepTree[]`) |
|
|
377
422
|
| `StepValidationMode` | `'all' \| 'forward' \| 'none'` |
|
|
378
423
|
|
|
379
424
|
## License
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ComponentProps } from 'react';
|
|
3
|
-
import { FieldValues, FieldPath, Controller as Controller$1, ControllerRenderProps, ControllerFieldState, UseFormStateReturn, UseFormReturn } from 'react-hook-form';
|
|
3
|
+
import { FieldValues, FieldPath, Controller as Controller$1, ControllerRenderProps, ControllerFieldState, UseFormStateReturn, UseControllerProps, UseControllerReturn, UseFormReturn } from 'react-hook-form';
|
|
4
4
|
|
|
5
5
|
type ControllerRenderArgs<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = {
|
|
6
6
|
field: ControllerRenderProps<TFieldValues, TName>;
|
|
@@ -8,36 +8,33 @@ type ControllerRenderArgs<TFieldValues extends FieldValues = FieldValues, TName
|
|
|
8
8
|
formState: UseFormStateReturn<TFieldValues>;
|
|
9
9
|
};
|
|
10
10
|
type ControllerProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = ComponentProps<typeof Controller$1<TFieldValues, TName>>;
|
|
11
|
-
declare function Controller<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ name,
|
|
11
|
+
declare function Controller<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ name, ...rest }: ControllerProps<TFieldValues, TName>): react_jsx_runtime.JSX.Element;
|
|
12
12
|
declare namespace Controller {
|
|
13
13
|
var displayName: string;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
declare function useController<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>(props: UseControllerProps<TFieldValues, TName>): UseControllerReturn<TFieldValues, TName>;
|
|
17
|
+
|
|
17
18
|
type StepValidationMode = 'all' | 'forward' | 'none';
|
|
19
|
+
type MaybePromise<T = void> = T | Promise<T>;
|
|
18
20
|
|
|
19
|
-
type
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
currentStepArr: string[] | null;
|
|
25
|
-
validatedFields: string[];
|
|
21
|
+
type StepperContextValue<TFieldValues extends FieldValues = FieldValues> = {
|
|
22
|
+
activeStep: number;
|
|
23
|
+
jumpTo: (step: number, onLeave?: (values: Partial<TFieldValues>) => MaybePromise<void>) => Promise<boolean>;
|
|
24
|
+
fields: string[] | null;
|
|
25
|
+
validSteps: number[];
|
|
26
26
|
isFirstStep: boolean;
|
|
27
27
|
isLastStep: boolean;
|
|
28
|
-
next: (
|
|
29
|
-
prev: (
|
|
28
|
+
next: (onLeave?: ((values: Partial<TFieldValues>) => MaybePromise<void>) | unknown) => Promise<boolean>;
|
|
29
|
+
prev: (onLeave?: ((values: Partial<TFieldValues>) => MaybePromise<void>) | unknown) => Promise<boolean>;
|
|
30
30
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
form: UseFormReturn<TFieldValues>;
|
|
34
|
-
onSubmit: (values: TFieldValues) => void;
|
|
31
|
+
interface StepperProps<TFieldValues extends FieldValues = FieldValues> {
|
|
32
|
+
form?: UseFormReturn<TFieldValues>;
|
|
35
33
|
stepValidationMode?: StepValidationMode;
|
|
36
|
-
children: React.ReactNode | ((context:
|
|
34
|
+
children: React.ReactNode | ((context: StepperContextValue<TFieldValues>) => React.ReactNode);
|
|
37
35
|
}
|
|
38
|
-
declare
|
|
39
|
-
|
|
40
|
-
}) => React.JSX.Element;
|
|
36
|
+
declare function Stepper<TFieldValues extends FieldValues = FieldValues>({ form: formProps, stepValidationMode, children }: StepperProps<TFieldValues>): react_jsx_runtime.JSX.Element;
|
|
37
|
+
declare function useStepper<TFieldValues extends FieldValues = FieldValues>(): StepperContextValue<TFieldValues>;
|
|
41
38
|
|
|
42
39
|
declare function Step({ children }: {
|
|
43
40
|
children: React.ReactNode;
|
|
@@ -46,4 +43,4 @@ declare namespace Step {
|
|
|
46
43
|
var displayName: string;
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
export { Controller, type ControllerProps, type ControllerRenderArgs,
|
|
46
|
+
export { Controller, type ControllerProps, type ControllerRenderArgs, Step, type StepValidationMode, Stepper, type StepperContextValue, type StepperProps, useController, useStepper };
|