rhf-stepper 0.1.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/dist/index.d.mts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +342 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +337 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +52 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ComponentProps } from 'react';
|
|
3
|
+
import { FieldValues, FieldPath, Controller as Controller$1, ControllerRenderProps, ControllerFieldState, UseFormStateReturn, UseFormReturn } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
type ControllerRenderArgs<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = {
|
|
6
|
+
field: ControllerRenderProps<TFieldValues, TName>;
|
|
7
|
+
fieldState: ControllerFieldState;
|
|
8
|
+
formState: UseFormStateReturn<TFieldValues>;
|
|
9
|
+
};
|
|
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, control, ...rest }: ControllerProps<TFieldValues, TName>): react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare namespace Controller {
|
|
13
|
+
var displayName: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type StepTree = StepTree[] | string;
|
|
17
|
+
type StepValidationMode = 'all' | 'forward' | 'none';
|
|
18
|
+
|
|
19
|
+
type FormContextValue<TFieldValues extends FieldValues = FieldValues> = {
|
|
20
|
+
form: UseFormReturn<TFieldValues, any, any>;
|
|
21
|
+
step?: number;
|
|
22
|
+
currentStep: number | number[] | null;
|
|
23
|
+
setCurrentStep: (step: number | number[]) => Promise<void>;
|
|
24
|
+
currentStepNode: StepTree | undefined;
|
|
25
|
+
currentStepArr: string[] | null;
|
|
26
|
+
validatedFields: string[];
|
|
27
|
+
isFirstStep: boolean;
|
|
28
|
+
isLastStep: boolean;
|
|
29
|
+
registrationKey: number;
|
|
30
|
+
next: () => void;
|
|
31
|
+
prev: () => void;
|
|
32
|
+
rebuildSteps: () => void;
|
|
33
|
+
registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void;
|
|
34
|
+
changeStepAtIndex: (elements: StepTree, index: number) => void;
|
|
35
|
+
};
|
|
36
|
+
declare function useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues>;
|
|
37
|
+
interface FormProps<TFieldValues extends FieldValues = FieldValues> extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'children'> {
|
|
38
|
+
form: UseFormReturn<TFieldValues, any, any>;
|
|
39
|
+
onSubmit: (values: TFieldValues) => void;
|
|
40
|
+
stepValidationMode?: StepValidationMode;
|
|
41
|
+
children: React.ReactNode | ((context: FormContextValue<TFieldValues>) => React.ReactNode);
|
|
42
|
+
}
|
|
43
|
+
declare const Form: <TFieldValues extends FieldValues = FieldValues>(props: FormProps<TFieldValues> & {
|
|
44
|
+
ref?: React.Ref<HTMLFormElement>;
|
|
45
|
+
}) => React.JSX.Element;
|
|
46
|
+
|
|
47
|
+
declare function Step({ children }: {
|
|
48
|
+
children: React.ReactNode;
|
|
49
|
+
}): react_jsx_runtime.JSX.Element;
|
|
50
|
+
declare namespace Step {
|
|
51
|
+
var displayName: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { Controller, type ControllerProps, type ControllerRenderArgs, Form, type FormContextValue, type FormProps, Step, type StepTree, type StepValidationMode, useFormContext };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ComponentProps } from 'react';
|
|
3
|
+
import { FieldValues, FieldPath, Controller as Controller$1, ControllerRenderProps, ControllerFieldState, UseFormStateReturn, UseFormReturn } from 'react-hook-form';
|
|
4
|
+
|
|
5
|
+
type ControllerRenderArgs<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = {
|
|
6
|
+
field: ControllerRenderProps<TFieldValues, TName>;
|
|
7
|
+
fieldState: ControllerFieldState;
|
|
8
|
+
formState: UseFormStateReturn<TFieldValues>;
|
|
9
|
+
};
|
|
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, control, ...rest }: ControllerProps<TFieldValues, TName>): react_jsx_runtime.JSX.Element;
|
|
12
|
+
declare namespace Controller {
|
|
13
|
+
var displayName: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type StepTree = StepTree[] | string;
|
|
17
|
+
type StepValidationMode = 'all' | 'forward' | 'none';
|
|
18
|
+
|
|
19
|
+
type FormContextValue<TFieldValues extends FieldValues = FieldValues> = {
|
|
20
|
+
form: UseFormReturn<TFieldValues, any, any>;
|
|
21
|
+
step?: number;
|
|
22
|
+
currentStep: number | number[] | null;
|
|
23
|
+
setCurrentStep: (step: number | number[]) => Promise<void>;
|
|
24
|
+
currentStepNode: StepTree | undefined;
|
|
25
|
+
currentStepArr: string[] | null;
|
|
26
|
+
validatedFields: string[];
|
|
27
|
+
isFirstStep: boolean;
|
|
28
|
+
isLastStep: boolean;
|
|
29
|
+
registrationKey: number;
|
|
30
|
+
next: () => void;
|
|
31
|
+
prev: () => void;
|
|
32
|
+
rebuildSteps: () => void;
|
|
33
|
+
registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void;
|
|
34
|
+
changeStepAtIndex: (elements: StepTree, index: number) => void;
|
|
35
|
+
};
|
|
36
|
+
declare function useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues>;
|
|
37
|
+
interface FormProps<TFieldValues extends FieldValues = FieldValues> extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'children'> {
|
|
38
|
+
form: UseFormReturn<TFieldValues, any, any>;
|
|
39
|
+
onSubmit: (values: TFieldValues) => void;
|
|
40
|
+
stepValidationMode?: StepValidationMode;
|
|
41
|
+
children: React.ReactNode | ((context: FormContextValue<TFieldValues>) => React.ReactNode);
|
|
42
|
+
}
|
|
43
|
+
declare const Form: <TFieldValues extends FieldValues = FieldValues>(props: FormProps<TFieldValues> & {
|
|
44
|
+
ref?: React.Ref<HTMLFormElement>;
|
|
45
|
+
}) => React.JSX.Element;
|
|
46
|
+
|
|
47
|
+
declare function Step({ children }: {
|
|
48
|
+
children: React.ReactNode;
|
|
49
|
+
}): react_jsx_runtime.JSX.Element;
|
|
50
|
+
declare namespace Step {
|
|
51
|
+
var displayName: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { Controller, type ControllerProps, type ControllerRenderArgs, Form, type FormContextValue, type FormProps, Step, type StepTree, type StepValidationMode, useFormContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var reactHookForm = require('react-hook-form');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/controller.tsx
|
|
8
|
+
var StepContext = react.createContext(null);
|
|
9
|
+
function useStep() {
|
|
10
|
+
return react.useContext(StepContext);
|
|
11
|
+
}
|
|
12
|
+
function Step({ children }) {
|
|
13
|
+
const stepContext = useStep();
|
|
14
|
+
const formContext = useFormContext();
|
|
15
|
+
const {
|
|
16
|
+
registerStep: registerStepFromParent,
|
|
17
|
+
step: stepFromParent,
|
|
18
|
+
rebuildSteps: rebuildStepsFromParent,
|
|
19
|
+
changeStepAtIndex: changeStepAtIndexFromParent,
|
|
20
|
+
registrationKey: registrationKeyFromParent
|
|
21
|
+
} = stepContext != null ? stepContext : formContext;
|
|
22
|
+
const stepRef = react.useRef(void 0);
|
|
23
|
+
const [steps, setSteps] = react.useState([]);
|
|
24
|
+
const [registrationKey, setRegistrationKey] = react.useState(0);
|
|
25
|
+
const changeStepAtIndex = react.useCallback((steps2, index) => {
|
|
26
|
+
setSteps((prevSteps) => {
|
|
27
|
+
const newSteps = [...prevSteps];
|
|
28
|
+
newSteps[index] = steps2;
|
|
29
|
+
return newSteps;
|
|
30
|
+
});
|
|
31
|
+
}, []);
|
|
32
|
+
react.useEffect(() => {
|
|
33
|
+
if (steps.length > 0) {
|
|
34
|
+
if (stepRef.current !== void 0) {
|
|
35
|
+
changeStepAtIndexFromParent(steps, stepRef.current);
|
|
36
|
+
} else {
|
|
37
|
+
registerStepFromParent(steps, stepRef);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, [registrationKeyFromParent, steps]);
|
|
41
|
+
react.useEffect(() => {
|
|
42
|
+
if (stepFromParent !== void 0) {
|
|
43
|
+
rebuildStepsFromParent();
|
|
44
|
+
}
|
|
45
|
+
return () => {
|
|
46
|
+
rebuildStepsFromParent();
|
|
47
|
+
};
|
|
48
|
+
}, []);
|
|
49
|
+
const registerField = react.useCallback(
|
|
50
|
+
(elements) => {
|
|
51
|
+
setSteps((prevSteps) => {
|
|
52
|
+
return [...prevSteps, ...elements];
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
[steps]
|
|
56
|
+
);
|
|
57
|
+
const registerStep = react.useCallback(
|
|
58
|
+
(elements, stepRef2, step) => {
|
|
59
|
+
setSteps((prevSteps) => {
|
|
60
|
+
const stepNumber = step != null ? step : prevSteps.length;
|
|
61
|
+
stepRef2.current = stepNumber;
|
|
62
|
+
const newSteps = [...prevSteps];
|
|
63
|
+
newSteps.splice(stepNumber, 0, elements);
|
|
64
|
+
return newSteps;
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
[steps]
|
|
68
|
+
);
|
|
69
|
+
const rebuildSteps = react.useCallback(() => {
|
|
70
|
+
setSteps([]);
|
|
71
|
+
setRegistrationKey((prev) => prev + 1);
|
|
72
|
+
}, []);
|
|
73
|
+
const contextValue = react.useMemo(
|
|
74
|
+
() => ({
|
|
75
|
+
// eslint-disable-next-line react-hooks/refs
|
|
76
|
+
step: stepRef.current,
|
|
77
|
+
registrationKey,
|
|
78
|
+
changeStepAtIndex,
|
|
79
|
+
registerField,
|
|
80
|
+
registerStep,
|
|
81
|
+
rebuildSteps
|
|
82
|
+
}),
|
|
83
|
+
[registrationKey, changeStepAtIndex, registerField, registerStep, rebuildSteps]
|
|
84
|
+
);
|
|
85
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StepContext.Provider, { value: contextValue, children });
|
|
86
|
+
}
|
|
87
|
+
Step.displayName = "Step";
|
|
88
|
+
function comparePaths(a, b) {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
91
|
+
const ai = (_a = a[i]) != null ? _a : -1;
|
|
92
|
+
const bi = (_b = b[i]) != null ? _b : -1;
|
|
93
|
+
if (ai !== bi) return ai - bi;
|
|
94
|
+
}
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
function getNodeAtPath(tree, path) {
|
|
98
|
+
let current = tree;
|
|
99
|
+
for (const index of path) {
|
|
100
|
+
if (!Array.isArray(current) || index >= current.length) return void 0;
|
|
101
|
+
current = current[index];
|
|
102
|
+
}
|
|
103
|
+
return current;
|
|
104
|
+
}
|
|
105
|
+
function isLeafParent(node) {
|
|
106
|
+
return Array.isArray(node) && node.length > 0 && node.every((child) => typeof child === "string");
|
|
107
|
+
}
|
|
108
|
+
function getFirstLeafParentPath(tree, path) {
|
|
109
|
+
const node = getNodeAtPath(tree, path);
|
|
110
|
+
if (node === void 0) return null;
|
|
111
|
+
if (isLeafParent(node)) return path;
|
|
112
|
+
if (Array.isArray(node) && node.length > 0) {
|
|
113
|
+
for (let i = 0; i < node.length; i++) {
|
|
114
|
+
const found = getFirstLeafParentPath(tree, [...path, i]);
|
|
115
|
+
if (found) return found;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
function getLastLeafParentPath(tree, path) {
|
|
121
|
+
const node = getNodeAtPath(tree, path);
|
|
122
|
+
if (node === void 0) return null;
|
|
123
|
+
if (isLeafParent(node)) return path;
|
|
124
|
+
if (Array.isArray(node) && node.length > 0) {
|
|
125
|
+
for (let i = node.length - 1; i >= 0; i--) {
|
|
126
|
+
const found = getLastLeafParentPath(tree, [...path, i]);
|
|
127
|
+
if (found) return found;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
function getPrevLeafParentPath(tree, path) {
|
|
133
|
+
const current = [...path];
|
|
134
|
+
while (current.length > 0) {
|
|
135
|
+
const lastIndex = current[current.length - 1];
|
|
136
|
+
const parentPath = current.slice(0, -1);
|
|
137
|
+
const parent = getNodeAtPath(tree, parentPath);
|
|
138
|
+
if (Array.isArray(parent)) {
|
|
139
|
+
for (let i = lastIndex - 1; i >= 0; i--) {
|
|
140
|
+
const found = getLastLeafParentPath(tree, [...parentPath, i]);
|
|
141
|
+
if (found) return found;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
current.pop();
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function getNextLeafParentPath(tree, path) {
|
|
149
|
+
const current = [...path];
|
|
150
|
+
while (current.length > 0) {
|
|
151
|
+
const lastIndex = current[current.length - 1];
|
|
152
|
+
const parentPath = current.slice(0, -1);
|
|
153
|
+
const parent = getNodeAtPath(tree, parentPath);
|
|
154
|
+
if (Array.isArray(parent)) {
|
|
155
|
+
for (let i = lastIndex + 1; i < parent.length; i++) {
|
|
156
|
+
const found = getFirstLeafParentPath(tree, [...parentPath, i]);
|
|
157
|
+
if (found) return found;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
current.pop();
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
var FormContext = react.createContext(null);
|
|
165
|
+
function useFormContext() {
|
|
166
|
+
const context = react.useContext(FormContext);
|
|
167
|
+
if (!context) {
|
|
168
|
+
throw new Error("useFormContext must be used within a <Form>");
|
|
169
|
+
}
|
|
170
|
+
return context;
|
|
171
|
+
}
|
|
172
|
+
function FormInner({ form, onSubmit, stepValidationMode = "forward", children, ...props }, ref) {
|
|
173
|
+
const [steps, setSteps] = react.useState([]);
|
|
174
|
+
const [currentStep, setCurrentStep] = react.useState(null);
|
|
175
|
+
const [validatedFields, setValidatedFields] = react.useState([]);
|
|
176
|
+
const [registrationKey, setRegistrationKey] = react.useState(0);
|
|
177
|
+
const stepRef = react.useRef(void 0);
|
|
178
|
+
const _currentStep = react.useMemo(() => {
|
|
179
|
+
if (!currentStep) return null;
|
|
180
|
+
const sliced = currentStep.slice(1);
|
|
181
|
+
return sliced.length === 1 ? sliced[0] : sliced;
|
|
182
|
+
}, [currentStep]);
|
|
183
|
+
const currentStepNode = react.useMemo(
|
|
184
|
+
() => currentStep ? getNodeAtPath(steps, currentStep) : void 0,
|
|
185
|
+
[steps, currentStep]
|
|
186
|
+
);
|
|
187
|
+
const currentStepArr = react.useMemo(() => {
|
|
188
|
+
if (!currentStepNode) return null;
|
|
189
|
+
return isLeafParent(currentStepNode) ? currentStepNode : null;
|
|
190
|
+
}, [currentStepNode]);
|
|
191
|
+
const _setCurrentStep = react.useCallback(
|
|
192
|
+
async (step) => {
|
|
193
|
+
const path = typeof step === "number" ? [0, step] : [0, ...step];
|
|
194
|
+
if (currentStep && currentStepArr && stepValidationMode !== "none") {
|
|
195
|
+
const isForward = comparePaths(path, currentStep) > 0;
|
|
196
|
+
const shouldValidate = stepValidationMode === "all" || stepValidationMode === "forward" && isForward;
|
|
197
|
+
if (shouldValidate) {
|
|
198
|
+
const isValid = await form.trigger(currentStepArr);
|
|
199
|
+
if (!isValid) {
|
|
200
|
+
setValidatedFields((prev2) => prev2.filter((field) => !currentStepArr.includes(field)));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
setValidatedFields((prev2) => [.../* @__PURE__ */ new Set([...prev2, ...currentStepArr])]);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
setCurrentStep(path);
|
|
207
|
+
},
|
|
208
|
+
[currentStep, currentStepArr, form, stepValidationMode]
|
|
209
|
+
);
|
|
210
|
+
const isFirstStep = react.useMemo(
|
|
211
|
+
() => currentStep ? getPrevLeafParentPath(steps, currentStep) === null : true,
|
|
212
|
+
[steps, currentStep]
|
|
213
|
+
);
|
|
214
|
+
const isLastStep = react.useMemo(
|
|
215
|
+
() => currentStep ? getNextLeafParentPath(steps, currentStep) === null : true,
|
|
216
|
+
[steps, currentStep]
|
|
217
|
+
);
|
|
218
|
+
const next = react.useCallback(async () => {
|
|
219
|
+
if (!currentStep) return;
|
|
220
|
+
const nextPath = getNextLeafParentPath(steps, currentStep);
|
|
221
|
+
if (currentStepArr && stepValidationMode !== "none") {
|
|
222
|
+
const isValid = await form.trigger(currentStepArr);
|
|
223
|
+
if (!isValid) {
|
|
224
|
+
setValidatedFields((prev2) => prev2.filter((field) => !currentStepArr.includes(field)));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
setValidatedFields((prev2) => [.../* @__PURE__ */ new Set([...prev2, ...currentStepArr])]);
|
|
228
|
+
}
|
|
229
|
+
if (nextPath) {
|
|
230
|
+
setCurrentStep(nextPath);
|
|
231
|
+
}
|
|
232
|
+
}, [steps, currentStep, currentStepArr, form, stepValidationMode]);
|
|
233
|
+
const prev = react.useCallback(() => {
|
|
234
|
+
if (!currentStep) return;
|
|
235
|
+
const prevPath = getPrevLeafParentPath(steps, currentStep);
|
|
236
|
+
if (prevPath) {
|
|
237
|
+
setCurrentStep(prevPath);
|
|
238
|
+
}
|
|
239
|
+
}, [steps, currentStep]);
|
|
240
|
+
const registerStep = react.useCallback(
|
|
241
|
+
(elements, stepRef2, step) => {
|
|
242
|
+
setSteps((prevSteps) => {
|
|
243
|
+
const stepNumber = step != null ? step : Array.isArray(prevSteps) ? prevSteps.length : 0;
|
|
244
|
+
stepRef2.current = stepNumber;
|
|
245
|
+
const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps];
|
|
246
|
+
newSteps.splice(stepNumber, 0, elements);
|
|
247
|
+
if (currentStep === null) {
|
|
248
|
+
const firstLeafParent = getFirstLeafParentPath(newSteps, [0]);
|
|
249
|
+
if (firstLeafParent) {
|
|
250
|
+
setCurrentStep(firstLeafParent);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return newSteps;
|
|
254
|
+
});
|
|
255
|
+
},
|
|
256
|
+
[currentStep]
|
|
257
|
+
);
|
|
258
|
+
const rebuildSteps = react.useCallback(() => {
|
|
259
|
+
setSteps([]);
|
|
260
|
+
setRegistrationKey((prev2) => prev2 + 1);
|
|
261
|
+
}, []);
|
|
262
|
+
const changeStepAtIndex = react.useCallback((steps2, index) => {
|
|
263
|
+
setSteps((prevSteps) => {
|
|
264
|
+
const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps];
|
|
265
|
+
newSteps[index] = steps2;
|
|
266
|
+
return newSteps;
|
|
267
|
+
});
|
|
268
|
+
}, []);
|
|
269
|
+
const contextValue = react.useMemo(
|
|
270
|
+
() => ({
|
|
271
|
+
// eslint-disable-next-line react-hooks/refs
|
|
272
|
+
step: stepRef.current,
|
|
273
|
+
currentStep: _currentStep,
|
|
274
|
+
setCurrentStep: _setCurrentStep,
|
|
275
|
+
currentStepNode,
|
|
276
|
+
currentStepArr,
|
|
277
|
+
validatedFields,
|
|
278
|
+
isFirstStep,
|
|
279
|
+
isLastStep,
|
|
280
|
+
form,
|
|
281
|
+
registrationKey,
|
|
282
|
+
next,
|
|
283
|
+
prev,
|
|
284
|
+
rebuildSteps,
|
|
285
|
+
registerStep,
|
|
286
|
+
changeStepAtIndex
|
|
287
|
+
}),
|
|
288
|
+
[
|
|
289
|
+
form,
|
|
290
|
+
_currentStep,
|
|
291
|
+
_setCurrentStep,
|
|
292
|
+
currentStepNode,
|
|
293
|
+
currentStepArr,
|
|
294
|
+
validatedFields,
|
|
295
|
+
isFirstStep,
|
|
296
|
+
isLastStep,
|
|
297
|
+
registrationKey,
|
|
298
|
+
next,
|
|
299
|
+
prev,
|
|
300
|
+
rebuildSteps,
|
|
301
|
+
registerStep,
|
|
302
|
+
changeStepAtIndex
|
|
303
|
+
]
|
|
304
|
+
);
|
|
305
|
+
const resolvedChildren = (
|
|
306
|
+
// eslint-disable-next-line react-hooks/refs
|
|
307
|
+
typeof children === "function" ? children(contextValue) : children
|
|
308
|
+
);
|
|
309
|
+
return (
|
|
310
|
+
// eslint-disable-next-line react-hooks/refs
|
|
311
|
+
/* @__PURE__ */ jsxRuntime.jsx(FormContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("form", { ref, onSubmit: form.handleSubmit(onSubmit), ...props, children: /* @__PURE__ */ jsxRuntime.jsx(Step, { children: resolvedChildren }) }) })
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
var Form = react.forwardRef(FormInner);
|
|
315
|
+
Form.displayName = "Form";
|
|
316
|
+
function Controller({ name, control, ...rest }) {
|
|
317
|
+
const formContext = useFormContext();
|
|
318
|
+
const stepContext = useStep();
|
|
319
|
+
const resolvedControl = control != null ? control : formContext.form.control;
|
|
320
|
+
react.useEffect(() => {
|
|
321
|
+
if (stepContext) {
|
|
322
|
+
stepContext.registerField([name]);
|
|
323
|
+
}
|
|
324
|
+
}, [stepContext == null ? void 0 : stepContext.registrationKey]);
|
|
325
|
+
react.useEffect(() => {
|
|
326
|
+
if ((stepContext == null ? void 0 : stepContext.step) !== void 0) {
|
|
327
|
+
stepContext == null ? void 0 : stepContext.rebuildSteps();
|
|
328
|
+
}
|
|
329
|
+
return () => {
|
|
330
|
+
stepContext == null ? void 0 : stepContext.rebuildSteps();
|
|
331
|
+
};
|
|
332
|
+
}, []);
|
|
333
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.Controller, { name, control: resolvedControl, ...rest });
|
|
334
|
+
}
|
|
335
|
+
Controller.displayName = "Controller";
|
|
336
|
+
|
|
337
|
+
exports.Controller = Controller;
|
|
338
|
+
exports.Form = Form;
|
|
339
|
+
exports.Step = Step;
|
|
340
|
+
exports.useFormContext = useFormContext;
|
|
341
|
+
//# sourceMappingURL=index.js.map
|
|
342
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/step.tsx","../src/form.tsx","../src/controller.tsx"],"names":["createContext","useContext","useRef","useState","useCallback","steps","useEffect","stepRef","useMemo","prev","jsx","forwardRef","RHFController"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { useFormContext } from './form'\nimport { type StepTree } from './types'\n\ntype StepContextValue = {\n step?: number\n registrationKey: number\n registerField: (elements: StepTree) => void\n registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void\n rebuildSteps: () => void\n changeStepAtIndex: (steps: StepTree, index: number) => void\n}\n\nconst StepContext = createContext<StepContextValue | null>(null)\n\nfunction useStep(): StepContextValue | null {\n return useContext(StepContext)\n}\n\nfunction Step({ children }: { children: React.ReactNode }) {\n const stepContext = useStep()\n const formContext = useFormContext()\n\n const {\n registerStep: registerStepFromParent,\n step: stepFromParent,\n rebuildSteps: rebuildStepsFromParent,\n changeStepAtIndex: changeStepAtIndexFromParent,\n registrationKey: registrationKeyFromParent,\n } = stepContext ?? formContext\n const stepRef = useRef<number | undefined>(undefined)\n const [steps, setSteps] = useState<StepTree>([])\n const [registrationKey, setRegistrationKey] = useState(0)\n\n const changeStepAtIndex = useCallback((steps: StepTree, index: number): void => {\n setSteps((prevSteps) => {\n const newSteps = [...prevSteps]\n newSteps[index] = steps\n return newSteps\n })\n }, [])\n\n useEffect(() => {\n if (steps.length > 0) {\n if (stepRef.current !== undefined) {\n changeStepAtIndexFromParent(steps, stepRef.current)\n } else {\n registerStepFromParent(steps, stepRef)\n }\n }\n }, [registrationKeyFromParent, steps])\n\n useEffect(() => {\n if (stepFromParent !== undefined) {\n rebuildStepsFromParent()\n }\n return () => {\n rebuildStepsFromParent()\n }\n }, [])\n\n const registerField = useCallback(\n (elements: StepTree): void => {\n setSteps((prevSteps) => {\n return [...prevSteps, ...elements]\n })\n },\n [steps],\n )\n\n const registerStep = useCallback(\n (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number): void => {\n setSteps((prevSteps: StepTree) => {\n const stepNumber = step ?? prevSteps.length\n stepRef.current = stepNumber\n const newSteps = [...prevSteps]\n newSteps.splice(stepNumber, 0, elements)\n return newSteps\n })\n },\n [steps],\n )\n\n const rebuildSteps = useCallback(() => {\n setSteps([])\n setRegistrationKey((prev) => prev + 1)\n }, [])\n\n const contextValue = useMemo<StepContextValue>(\n () => ({\n // eslint-disable-next-line react-hooks/refs\n step: stepRef.current,\n registrationKey,\n changeStepAtIndex,\n registerField,\n registerStep,\n rebuildSteps,\n }),\n [registrationKey, changeStepAtIndex, registerField, registerStep, rebuildSteps],\n )\n\n // eslint-disable-next-line react-hooks/refs\n return <StepContext.Provider value={contextValue}>{children}</StepContext.Provider>\n}\n\nStep.displayName = 'Step'\n\nexport { Step, useStep }\nexport type { StepContextValue }\n","import { createContext, forwardRef, useCallback, useContext, useMemo, useRef, useState } from 'react'\nimport { type FieldValues, Path, type UseFormReturn } from 'react-hook-form'\n\nimport { Step } from './step'\nimport { type StepTree, type StepValidationMode } from './types'\n\nfunction comparePaths(a: number[], b: number[]): number {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const ai = a[i] ?? -1\n const bi = b[i] ?? -1\n if (ai !== bi) return ai - bi\n }\n return 0\n}\n\nfunction getNodeAtPath(tree: StepTree, path: number[]): StepTree | undefined {\n let current: StepTree = tree\n for (const index of path) {\n if (!Array.isArray(current) || index >= current.length) return undefined\n current = current[index]\n }\n return current\n}\n\nfunction isLeafParent(node: StepTree): node is string[] {\n return Array.isArray(node) && node.length > 0 && node.every((child) => typeof child === 'string')\n}\n\nfunction getFirstLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const node = getNodeAtPath(tree, path)\n if (node === undefined) return null\n if (isLeafParent(node)) return path\n if (Array.isArray(node) && node.length > 0) {\n for (let i = 0; i < node.length; i++) {\n const found = getFirstLeafParentPath(tree, [...path, i])\n if (found) return found\n }\n }\n return null\n}\n\nfunction getLastLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const node = getNodeAtPath(tree, path)\n if (node === undefined) return null\n if (isLeafParent(node)) return path\n if (Array.isArray(node) && node.length > 0) {\n for (let i = node.length - 1; i >= 0; i--) {\n const found = getLastLeafParentPath(tree, [...path, i])\n if (found) return found\n }\n }\n return null\n}\n\nfunction getPrevLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const current = [...path]\n while (current.length > 0) {\n const lastIndex = current[current.length - 1]\n const parentPath = current.slice(0, -1)\n const parent = getNodeAtPath(tree, parentPath)\n\n if (Array.isArray(parent)) {\n for (let i = lastIndex - 1; i >= 0; i--) {\n const found = getLastLeafParentPath(tree, [...parentPath, i])\n if (found) return found\n }\n }\n\n current.pop()\n }\n\n return null\n}\n\nfunction getNextLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const current = [...path]\n while (current.length > 0) {\n const lastIndex = current[current.length - 1]\n const parentPath = current.slice(0, -1)\n const parent = getNodeAtPath(tree, parentPath)\n\n if (Array.isArray(parent)) {\n for (let i = lastIndex + 1; i < parent.length; i++) {\n const found = getFirstLeafParentPath(tree, [...parentPath, i])\n if (found) return found\n }\n }\n\n current.pop()\n }\n\n return null\n}\n\ntype FormContextValue<TFieldValues extends FieldValues = FieldValues> = {\n form: UseFormReturn<TFieldValues, any, any>\n step?: number\n currentStep: number | number[] | null\n setCurrentStep: (step: number | number[]) => Promise<void>\n currentStepNode: StepTree | undefined\n currentStepArr: string[] | null\n validatedFields: string[]\n isFirstStep: boolean\n isLastStep: boolean\n registrationKey: number\n next: () => void\n prev: () => void\n rebuildSteps: () => void\n registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void\n changeStepAtIndex: (elements: StepTree, index: number) => void\n}\n\nconst FormContext = createContext<FormContextValue | null>(null)\n\nfunction useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues> {\n const context = useContext(FormContext)\n if (!context) {\n throw new Error('useFormContext must be used within a <Form>')\n }\n return context as unknown as FormContextValue<TFieldValues>\n}\n\ninterface FormProps<TFieldValues extends FieldValues = FieldValues>\n extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'children'> {\n form: UseFormReturn<TFieldValues, any, any>\n onSubmit: (values: TFieldValues) => void\n stepValidationMode?: StepValidationMode\n children: React.ReactNode | ((context: FormContextValue<TFieldValues>) => React.ReactNode)\n}\n\nfunction FormInner<TFieldValues extends FieldValues = FieldValues>(\n { form, onSubmit, stepValidationMode = 'forward', children, ...props }: FormProps<TFieldValues>,\n ref: React.Ref<HTMLFormElement>,\n) {\n const [steps, setSteps] = useState<StepTree>([])\n const [currentStep, setCurrentStep] = useState<number[] | null>(null)\n const [validatedFields, setValidatedFields] = useState<string[]>([])\n const [registrationKey, setRegistrationKey] = useState(0)\n\n const stepRef = useRef<number | undefined>(undefined)\n\n const _currentStep = useMemo<number | number[] | null>(() => {\n if (!currentStep) return null\n const sliced = currentStep.slice(1)\n return sliced.length === 1 ? sliced[0] : sliced\n }, [currentStep])\n\n const currentStepNode = useMemo(\n () => (currentStep ? getNodeAtPath(steps, currentStep) : undefined),\n [steps, currentStep],\n )\n\n const currentStepArr = useMemo<string[] | null>(() => {\n if (!currentStepNode) return null\n return isLeafParent(currentStepNode) ? currentStepNode : null\n }, [currentStepNode])\n\n const _setCurrentStep = useCallback(\n async (step: number | number[]) => {\n const path = typeof step === 'number' ? [0, step] : [0, ...step]\n if (currentStep && currentStepArr && stepValidationMode !== 'none') {\n const isForward = comparePaths(path, currentStep) > 0\n const shouldValidate = stepValidationMode === 'all' || (stepValidationMode === 'forward' && isForward)\n if (shouldValidate) {\n const isValid = await form.trigger(currentStepArr as Path<TFieldValues>[])\n if (!isValid) {\n setValidatedFields((prev) => prev.filter((field) => !currentStepArr.includes(field)))\n return\n }\n setValidatedFields((prev) => [...new Set([...prev, ...currentStepArr])])\n }\n }\n setCurrentStep(path)\n },\n [currentStep, currentStepArr, form, stepValidationMode],\n )\n\n const isFirstStep = useMemo(\n () => (currentStep ? getPrevLeafParentPath(steps, currentStep) === null : true),\n [steps, currentStep],\n )\n\n const isLastStep = useMemo(\n () => (currentStep ? getNextLeafParentPath(steps, currentStep) === null : true),\n [steps, currentStep],\n )\n\n const next = useCallback(async () => {\n if (!currentStep) return\n const nextPath = getNextLeafParentPath(steps, currentStep)\n if (currentStepArr && stepValidationMode !== 'none') {\n const isValid = await form.trigger(currentStepArr as Path<TFieldValues>[])\n if (!isValid) {\n setValidatedFields((prev) => prev.filter((field) => !currentStepArr.includes(field)))\n return\n }\n setValidatedFields((prev) => [...new Set([...prev, ...currentStepArr])])\n }\n if (nextPath) {\n setCurrentStep(nextPath)\n }\n }, [steps, currentStep, currentStepArr, form, stepValidationMode])\n\n const prev = useCallback(() => {\n if (!currentStep) return\n const prevPath = getPrevLeafParentPath(steps, currentStep)\n if (prevPath) {\n setCurrentStep(prevPath)\n }\n }, [steps, currentStep])\n\n const registerStep = useCallback(\n (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number): void => {\n setSteps((prevSteps: StepTree) => {\n const stepNumber = step ?? (Array.isArray(prevSteps) ? prevSteps.length : 0)\n stepRef.current = stepNumber\n const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps]\n newSteps.splice(stepNumber, 0, elements)\n\n if (currentStep === null) {\n const firstLeafParent = getFirstLeafParentPath(newSteps, [0])\n if (firstLeafParent) {\n setCurrentStep(firstLeafParent)\n }\n }\n\n return newSteps\n })\n },\n [currentStep],\n )\n\n const rebuildSteps = useCallback(() => {\n setSteps([])\n setRegistrationKey((prev) => prev + 1)\n }, [])\n\n const changeStepAtIndex = useCallback((steps: StepTree, index: number): void => {\n setSteps((prevSteps) => {\n const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps]\n newSteps[index] = steps\n return newSteps\n })\n }, [])\n\n const contextValue = useMemo<FormContextValue>(\n () => ({\n // eslint-disable-next-line react-hooks/refs\n step: stepRef.current,\n currentStep: _currentStep,\n setCurrentStep: _setCurrentStep,\n currentStepNode,\n currentStepArr,\n validatedFields,\n isFirstStep,\n isLastStep,\n form: form as unknown as UseFormReturn<FieldValues, any, any>,\n registrationKey,\n next,\n prev,\n rebuildSteps,\n registerStep,\n changeStepAtIndex,\n }),\n [\n form,\n _currentStep,\n _setCurrentStep,\n currentStepNode,\n currentStepArr,\n validatedFields,\n isFirstStep,\n isLastStep,\n registrationKey,\n next,\n prev,\n rebuildSteps,\n registerStep,\n changeStepAtIndex,\n ],\n )\n\n const resolvedChildren =\n // eslint-disable-next-line react-hooks/refs\n typeof children === 'function' ? children(contextValue as unknown as FormContextValue<TFieldValues>) : children\n\n return (\n // eslint-disable-next-line react-hooks/refs\n <FormContext.Provider value={contextValue}>\n <form ref={ref} onSubmit={form.handleSubmit(onSubmit)} {...props}>\n <Step>{resolvedChildren}</Step>\n </form>\n </FormContext.Provider>\n )\n}\n\nconst Form = forwardRef(FormInner) as <TFieldValues extends FieldValues = FieldValues>(\n props: FormProps<TFieldValues> & { ref?: React.Ref<HTMLFormElement> },\n) => React.JSX.Element\n\n;(Form as React.NamedExoticComponent & { displayName?: string }).displayName = 'Form'\n\nexport { Form, useFormContext }\nexport type { FormContextValue, FormProps }\n","import { ComponentProps, useEffect } from 'react'\nimport {\n type Control,\n Controller as RHFController,\n type ControllerFieldState,\n type ControllerRenderProps,\n type FieldPath,\n type FieldValues,\n type UseFormStateReturn,\n} from 'react-hook-form'\n\nimport { useFormContext } from './form'\nimport { useStep } from './step'\n\ntype ControllerRenderArgs<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n field: ControllerRenderProps<TFieldValues, TName>\n fieldState: ControllerFieldState\n formState: UseFormStateReturn<TFieldValues>\n}\n\ntype ControllerProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = ComponentProps<typeof RHFController<TFieldValues, TName>>\n\nfunction Controller<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({ name, control, ...rest }: ControllerProps<TFieldValues, TName>) {\n const formContext = useFormContext<TFieldValues>()\n const stepContext = useStep()\n const resolvedControl = control ?? (formContext.form.control as unknown as Control<TFieldValues>)\n\n useEffect(() => {\n if (stepContext) {\n stepContext.registerField([name as string])\n }\n }, [stepContext?.registrationKey])\n\n useEffect(() => {\n if (stepContext?.step !== undefined) {\n stepContext?.rebuildSteps()\n }\n return () => {\n stepContext?.rebuildSteps()\n }\n }, [])\n\n return <RHFController name={name} control={resolvedControl} {...rest} />\n}\n\nController.displayName = 'Controller'\n\nexport { Controller }\nexport type { ControllerProps, ControllerRenderArgs }\n"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { createContext, forwardRef, useState, useRef, useMemo, useCallback, useEffect, useContext } from 'react';
|
|
2
|
+
import { Controller as Controller$1 } from 'react-hook-form';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/controller.tsx
|
|
6
|
+
var StepContext = createContext(null);
|
|
7
|
+
function useStep() {
|
|
8
|
+
return useContext(StepContext);
|
|
9
|
+
}
|
|
10
|
+
function Step({ children }) {
|
|
11
|
+
const stepContext = useStep();
|
|
12
|
+
const formContext = useFormContext();
|
|
13
|
+
const {
|
|
14
|
+
registerStep: registerStepFromParent,
|
|
15
|
+
step: stepFromParent,
|
|
16
|
+
rebuildSteps: rebuildStepsFromParent,
|
|
17
|
+
changeStepAtIndex: changeStepAtIndexFromParent,
|
|
18
|
+
registrationKey: registrationKeyFromParent
|
|
19
|
+
} = stepContext != null ? stepContext : formContext;
|
|
20
|
+
const stepRef = useRef(void 0);
|
|
21
|
+
const [steps, setSteps] = useState([]);
|
|
22
|
+
const [registrationKey, setRegistrationKey] = useState(0);
|
|
23
|
+
const changeStepAtIndex = useCallback((steps2, index) => {
|
|
24
|
+
setSteps((prevSteps) => {
|
|
25
|
+
const newSteps = [...prevSteps];
|
|
26
|
+
newSteps[index] = steps2;
|
|
27
|
+
return newSteps;
|
|
28
|
+
});
|
|
29
|
+
}, []);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (steps.length > 0) {
|
|
32
|
+
if (stepRef.current !== void 0) {
|
|
33
|
+
changeStepAtIndexFromParent(steps, stepRef.current);
|
|
34
|
+
} else {
|
|
35
|
+
registerStepFromParent(steps, stepRef);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}, [registrationKeyFromParent, steps]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (stepFromParent !== void 0) {
|
|
41
|
+
rebuildStepsFromParent();
|
|
42
|
+
}
|
|
43
|
+
return () => {
|
|
44
|
+
rebuildStepsFromParent();
|
|
45
|
+
};
|
|
46
|
+
}, []);
|
|
47
|
+
const registerField = useCallback(
|
|
48
|
+
(elements) => {
|
|
49
|
+
setSteps((prevSteps) => {
|
|
50
|
+
return [...prevSteps, ...elements];
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
[steps]
|
|
54
|
+
);
|
|
55
|
+
const registerStep = useCallback(
|
|
56
|
+
(elements, stepRef2, step) => {
|
|
57
|
+
setSteps((prevSteps) => {
|
|
58
|
+
const stepNumber = step != null ? step : prevSteps.length;
|
|
59
|
+
stepRef2.current = stepNumber;
|
|
60
|
+
const newSteps = [...prevSteps];
|
|
61
|
+
newSteps.splice(stepNumber, 0, elements);
|
|
62
|
+
return newSteps;
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
[steps]
|
|
66
|
+
);
|
|
67
|
+
const rebuildSteps = useCallback(() => {
|
|
68
|
+
setSteps([]);
|
|
69
|
+
setRegistrationKey((prev) => prev + 1);
|
|
70
|
+
}, []);
|
|
71
|
+
const contextValue = useMemo(
|
|
72
|
+
() => ({
|
|
73
|
+
// eslint-disable-next-line react-hooks/refs
|
|
74
|
+
step: stepRef.current,
|
|
75
|
+
registrationKey,
|
|
76
|
+
changeStepAtIndex,
|
|
77
|
+
registerField,
|
|
78
|
+
registerStep,
|
|
79
|
+
rebuildSteps
|
|
80
|
+
}),
|
|
81
|
+
[registrationKey, changeStepAtIndex, registerField, registerStep, rebuildSteps]
|
|
82
|
+
);
|
|
83
|
+
return /* @__PURE__ */ jsx(StepContext.Provider, { value: contextValue, children });
|
|
84
|
+
}
|
|
85
|
+
Step.displayName = "Step";
|
|
86
|
+
function comparePaths(a, b) {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
89
|
+
const ai = (_a = a[i]) != null ? _a : -1;
|
|
90
|
+
const bi = (_b = b[i]) != null ? _b : -1;
|
|
91
|
+
if (ai !== bi) return ai - bi;
|
|
92
|
+
}
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
function getNodeAtPath(tree, path) {
|
|
96
|
+
let current = tree;
|
|
97
|
+
for (const index of path) {
|
|
98
|
+
if (!Array.isArray(current) || index >= current.length) return void 0;
|
|
99
|
+
current = current[index];
|
|
100
|
+
}
|
|
101
|
+
return current;
|
|
102
|
+
}
|
|
103
|
+
function isLeafParent(node) {
|
|
104
|
+
return Array.isArray(node) && node.length > 0 && node.every((child) => typeof child === "string");
|
|
105
|
+
}
|
|
106
|
+
function getFirstLeafParentPath(tree, path) {
|
|
107
|
+
const node = getNodeAtPath(tree, path);
|
|
108
|
+
if (node === void 0) return null;
|
|
109
|
+
if (isLeafParent(node)) return path;
|
|
110
|
+
if (Array.isArray(node) && node.length > 0) {
|
|
111
|
+
for (let i = 0; i < node.length; i++) {
|
|
112
|
+
const found = getFirstLeafParentPath(tree, [...path, i]);
|
|
113
|
+
if (found) return found;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
function getLastLeafParentPath(tree, path) {
|
|
119
|
+
const node = getNodeAtPath(tree, path);
|
|
120
|
+
if (node === void 0) return null;
|
|
121
|
+
if (isLeafParent(node)) return path;
|
|
122
|
+
if (Array.isArray(node) && node.length > 0) {
|
|
123
|
+
for (let i = node.length - 1; i >= 0; i--) {
|
|
124
|
+
const found = getLastLeafParentPath(tree, [...path, i]);
|
|
125
|
+
if (found) return found;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function getPrevLeafParentPath(tree, path) {
|
|
131
|
+
const current = [...path];
|
|
132
|
+
while (current.length > 0) {
|
|
133
|
+
const lastIndex = current[current.length - 1];
|
|
134
|
+
const parentPath = current.slice(0, -1);
|
|
135
|
+
const parent = getNodeAtPath(tree, parentPath);
|
|
136
|
+
if (Array.isArray(parent)) {
|
|
137
|
+
for (let i = lastIndex - 1; i >= 0; i--) {
|
|
138
|
+
const found = getLastLeafParentPath(tree, [...parentPath, i]);
|
|
139
|
+
if (found) return found;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
current.pop();
|
|
143
|
+
}
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
function getNextLeafParentPath(tree, path) {
|
|
147
|
+
const current = [...path];
|
|
148
|
+
while (current.length > 0) {
|
|
149
|
+
const lastIndex = current[current.length - 1];
|
|
150
|
+
const parentPath = current.slice(0, -1);
|
|
151
|
+
const parent = getNodeAtPath(tree, parentPath);
|
|
152
|
+
if (Array.isArray(parent)) {
|
|
153
|
+
for (let i = lastIndex + 1; i < parent.length; i++) {
|
|
154
|
+
const found = getFirstLeafParentPath(tree, [...parentPath, i]);
|
|
155
|
+
if (found) return found;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
current.pop();
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
var FormContext = createContext(null);
|
|
163
|
+
function useFormContext() {
|
|
164
|
+
const context = useContext(FormContext);
|
|
165
|
+
if (!context) {
|
|
166
|
+
throw new Error("useFormContext must be used within a <Form>");
|
|
167
|
+
}
|
|
168
|
+
return context;
|
|
169
|
+
}
|
|
170
|
+
function FormInner({ form, onSubmit, stepValidationMode = "forward", children, ...props }, ref) {
|
|
171
|
+
const [steps, setSteps] = useState([]);
|
|
172
|
+
const [currentStep, setCurrentStep] = useState(null);
|
|
173
|
+
const [validatedFields, setValidatedFields] = useState([]);
|
|
174
|
+
const [registrationKey, setRegistrationKey] = useState(0);
|
|
175
|
+
const stepRef = useRef(void 0);
|
|
176
|
+
const _currentStep = useMemo(() => {
|
|
177
|
+
if (!currentStep) return null;
|
|
178
|
+
const sliced = currentStep.slice(1);
|
|
179
|
+
return sliced.length === 1 ? sliced[0] : sliced;
|
|
180
|
+
}, [currentStep]);
|
|
181
|
+
const currentStepNode = useMemo(
|
|
182
|
+
() => currentStep ? getNodeAtPath(steps, currentStep) : void 0,
|
|
183
|
+
[steps, currentStep]
|
|
184
|
+
);
|
|
185
|
+
const currentStepArr = useMemo(() => {
|
|
186
|
+
if (!currentStepNode) return null;
|
|
187
|
+
return isLeafParent(currentStepNode) ? currentStepNode : null;
|
|
188
|
+
}, [currentStepNode]);
|
|
189
|
+
const _setCurrentStep = useCallback(
|
|
190
|
+
async (step) => {
|
|
191
|
+
const path = typeof step === "number" ? [0, step] : [0, ...step];
|
|
192
|
+
if (currentStep && currentStepArr && stepValidationMode !== "none") {
|
|
193
|
+
const isForward = comparePaths(path, currentStep) > 0;
|
|
194
|
+
const shouldValidate = stepValidationMode === "all" || stepValidationMode === "forward" && isForward;
|
|
195
|
+
if (shouldValidate) {
|
|
196
|
+
const isValid = await form.trigger(currentStepArr);
|
|
197
|
+
if (!isValid) {
|
|
198
|
+
setValidatedFields((prev2) => prev2.filter((field) => !currentStepArr.includes(field)));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
setValidatedFields((prev2) => [.../* @__PURE__ */ new Set([...prev2, ...currentStepArr])]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
setCurrentStep(path);
|
|
205
|
+
},
|
|
206
|
+
[currentStep, currentStepArr, form, stepValidationMode]
|
|
207
|
+
);
|
|
208
|
+
const isFirstStep = useMemo(
|
|
209
|
+
() => currentStep ? getPrevLeafParentPath(steps, currentStep) === null : true,
|
|
210
|
+
[steps, currentStep]
|
|
211
|
+
);
|
|
212
|
+
const isLastStep = useMemo(
|
|
213
|
+
() => currentStep ? getNextLeafParentPath(steps, currentStep) === null : true,
|
|
214
|
+
[steps, currentStep]
|
|
215
|
+
);
|
|
216
|
+
const next = useCallback(async () => {
|
|
217
|
+
if (!currentStep) return;
|
|
218
|
+
const nextPath = getNextLeafParentPath(steps, currentStep);
|
|
219
|
+
if (currentStepArr && stepValidationMode !== "none") {
|
|
220
|
+
const isValid = await form.trigger(currentStepArr);
|
|
221
|
+
if (!isValid) {
|
|
222
|
+
setValidatedFields((prev2) => prev2.filter((field) => !currentStepArr.includes(field)));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
setValidatedFields((prev2) => [.../* @__PURE__ */ new Set([...prev2, ...currentStepArr])]);
|
|
226
|
+
}
|
|
227
|
+
if (nextPath) {
|
|
228
|
+
setCurrentStep(nextPath);
|
|
229
|
+
}
|
|
230
|
+
}, [steps, currentStep, currentStepArr, form, stepValidationMode]);
|
|
231
|
+
const prev = useCallback(() => {
|
|
232
|
+
if (!currentStep) return;
|
|
233
|
+
const prevPath = getPrevLeafParentPath(steps, currentStep);
|
|
234
|
+
if (prevPath) {
|
|
235
|
+
setCurrentStep(prevPath);
|
|
236
|
+
}
|
|
237
|
+
}, [steps, currentStep]);
|
|
238
|
+
const registerStep = useCallback(
|
|
239
|
+
(elements, stepRef2, step) => {
|
|
240
|
+
setSteps((prevSteps) => {
|
|
241
|
+
const stepNumber = step != null ? step : Array.isArray(prevSteps) ? prevSteps.length : 0;
|
|
242
|
+
stepRef2.current = stepNumber;
|
|
243
|
+
const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps];
|
|
244
|
+
newSteps.splice(stepNumber, 0, elements);
|
|
245
|
+
if (currentStep === null) {
|
|
246
|
+
const firstLeafParent = getFirstLeafParentPath(newSteps, [0]);
|
|
247
|
+
if (firstLeafParent) {
|
|
248
|
+
setCurrentStep(firstLeafParent);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return newSteps;
|
|
252
|
+
});
|
|
253
|
+
},
|
|
254
|
+
[currentStep]
|
|
255
|
+
);
|
|
256
|
+
const rebuildSteps = useCallback(() => {
|
|
257
|
+
setSteps([]);
|
|
258
|
+
setRegistrationKey((prev2) => prev2 + 1);
|
|
259
|
+
}, []);
|
|
260
|
+
const changeStepAtIndex = useCallback((steps2, index) => {
|
|
261
|
+
setSteps((prevSteps) => {
|
|
262
|
+
const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps];
|
|
263
|
+
newSteps[index] = steps2;
|
|
264
|
+
return newSteps;
|
|
265
|
+
});
|
|
266
|
+
}, []);
|
|
267
|
+
const contextValue = useMemo(
|
|
268
|
+
() => ({
|
|
269
|
+
// eslint-disable-next-line react-hooks/refs
|
|
270
|
+
step: stepRef.current,
|
|
271
|
+
currentStep: _currentStep,
|
|
272
|
+
setCurrentStep: _setCurrentStep,
|
|
273
|
+
currentStepNode,
|
|
274
|
+
currentStepArr,
|
|
275
|
+
validatedFields,
|
|
276
|
+
isFirstStep,
|
|
277
|
+
isLastStep,
|
|
278
|
+
form,
|
|
279
|
+
registrationKey,
|
|
280
|
+
next,
|
|
281
|
+
prev,
|
|
282
|
+
rebuildSteps,
|
|
283
|
+
registerStep,
|
|
284
|
+
changeStepAtIndex
|
|
285
|
+
}),
|
|
286
|
+
[
|
|
287
|
+
form,
|
|
288
|
+
_currentStep,
|
|
289
|
+
_setCurrentStep,
|
|
290
|
+
currentStepNode,
|
|
291
|
+
currentStepArr,
|
|
292
|
+
validatedFields,
|
|
293
|
+
isFirstStep,
|
|
294
|
+
isLastStep,
|
|
295
|
+
registrationKey,
|
|
296
|
+
next,
|
|
297
|
+
prev,
|
|
298
|
+
rebuildSteps,
|
|
299
|
+
registerStep,
|
|
300
|
+
changeStepAtIndex
|
|
301
|
+
]
|
|
302
|
+
);
|
|
303
|
+
const resolvedChildren = (
|
|
304
|
+
// eslint-disable-next-line react-hooks/refs
|
|
305
|
+
typeof children === "function" ? children(contextValue) : children
|
|
306
|
+
);
|
|
307
|
+
return (
|
|
308
|
+
// eslint-disable-next-line react-hooks/refs
|
|
309
|
+
/* @__PURE__ */ jsx(FormContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx("form", { ref, onSubmit: form.handleSubmit(onSubmit), ...props, children: /* @__PURE__ */ jsx(Step, { children: resolvedChildren }) }) })
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
var Form = forwardRef(FormInner);
|
|
313
|
+
Form.displayName = "Form";
|
|
314
|
+
function Controller({ name, control, ...rest }) {
|
|
315
|
+
const formContext = useFormContext();
|
|
316
|
+
const stepContext = useStep();
|
|
317
|
+
const resolvedControl = control != null ? control : formContext.form.control;
|
|
318
|
+
useEffect(() => {
|
|
319
|
+
if (stepContext) {
|
|
320
|
+
stepContext.registerField([name]);
|
|
321
|
+
}
|
|
322
|
+
}, [stepContext == null ? void 0 : stepContext.registrationKey]);
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
if ((stepContext == null ? void 0 : stepContext.step) !== void 0) {
|
|
325
|
+
stepContext == null ? void 0 : stepContext.rebuildSteps();
|
|
326
|
+
}
|
|
327
|
+
return () => {
|
|
328
|
+
stepContext == null ? void 0 : stepContext.rebuildSteps();
|
|
329
|
+
};
|
|
330
|
+
}, []);
|
|
331
|
+
return /* @__PURE__ */ jsx(Controller$1, { name, control: resolvedControl, ...rest });
|
|
332
|
+
}
|
|
333
|
+
Controller.displayName = "Controller";
|
|
334
|
+
|
|
335
|
+
export { Controller, Form, Step, useFormContext };
|
|
336
|
+
//# sourceMappingURL=index.mjs.map
|
|
337
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/step.tsx","../src/form.tsx","../src/controller.tsx"],"names":["steps","stepRef","createContext","useContext","useState","useRef","useMemo","useCallback","prev","jsx","useEffect","RHFController"],"mappings":"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","file":"index.mjs","sourcesContent":["import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'\n\nimport { useFormContext } from './form'\nimport { type StepTree } from './types'\n\ntype StepContextValue = {\n step?: number\n registrationKey: number\n registerField: (elements: StepTree) => void\n registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void\n rebuildSteps: () => void\n changeStepAtIndex: (steps: StepTree, index: number) => void\n}\n\nconst StepContext = createContext<StepContextValue | null>(null)\n\nfunction useStep(): StepContextValue | null {\n return useContext(StepContext)\n}\n\nfunction Step({ children }: { children: React.ReactNode }) {\n const stepContext = useStep()\n const formContext = useFormContext()\n\n const {\n registerStep: registerStepFromParent,\n step: stepFromParent,\n rebuildSteps: rebuildStepsFromParent,\n changeStepAtIndex: changeStepAtIndexFromParent,\n registrationKey: registrationKeyFromParent,\n } = stepContext ?? formContext\n const stepRef = useRef<number | undefined>(undefined)\n const [steps, setSteps] = useState<StepTree>([])\n const [registrationKey, setRegistrationKey] = useState(0)\n\n const changeStepAtIndex = useCallback((steps: StepTree, index: number): void => {\n setSteps((prevSteps) => {\n const newSteps = [...prevSteps]\n newSteps[index] = steps\n return newSteps\n })\n }, [])\n\n useEffect(() => {\n if (steps.length > 0) {\n if (stepRef.current !== undefined) {\n changeStepAtIndexFromParent(steps, stepRef.current)\n } else {\n registerStepFromParent(steps, stepRef)\n }\n }\n }, [registrationKeyFromParent, steps])\n\n useEffect(() => {\n if (stepFromParent !== undefined) {\n rebuildStepsFromParent()\n }\n return () => {\n rebuildStepsFromParent()\n }\n }, [])\n\n const registerField = useCallback(\n (elements: StepTree): void => {\n setSteps((prevSteps) => {\n return [...prevSteps, ...elements]\n })\n },\n [steps],\n )\n\n const registerStep = useCallback(\n (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number): void => {\n setSteps((prevSteps: StepTree) => {\n const stepNumber = step ?? prevSteps.length\n stepRef.current = stepNumber\n const newSteps = [...prevSteps]\n newSteps.splice(stepNumber, 0, elements)\n return newSteps\n })\n },\n [steps],\n )\n\n const rebuildSteps = useCallback(() => {\n setSteps([])\n setRegistrationKey((prev) => prev + 1)\n }, [])\n\n const contextValue = useMemo<StepContextValue>(\n () => ({\n // eslint-disable-next-line react-hooks/refs\n step: stepRef.current,\n registrationKey,\n changeStepAtIndex,\n registerField,\n registerStep,\n rebuildSteps,\n }),\n [registrationKey, changeStepAtIndex, registerField, registerStep, rebuildSteps],\n )\n\n // eslint-disable-next-line react-hooks/refs\n return <StepContext.Provider value={contextValue}>{children}</StepContext.Provider>\n}\n\nStep.displayName = 'Step'\n\nexport { Step, useStep }\nexport type { StepContextValue }\n","import { createContext, forwardRef, useCallback, useContext, useMemo, useRef, useState } from 'react'\nimport { type FieldValues, Path, type UseFormReturn } from 'react-hook-form'\n\nimport { Step } from './step'\nimport { type StepTree, type StepValidationMode } from './types'\n\nfunction comparePaths(a: number[], b: number[]): number {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const ai = a[i] ?? -1\n const bi = b[i] ?? -1\n if (ai !== bi) return ai - bi\n }\n return 0\n}\n\nfunction getNodeAtPath(tree: StepTree, path: number[]): StepTree | undefined {\n let current: StepTree = tree\n for (const index of path) {\n if (!Array.isArray(current) || index >= current.length) return undefined\n current = current[index]\n }\n return current\n}\n\nfunction isLeafParent(node: StepTree): node is string[] {\n return Array.isArray(node) && node.length > 0 && node.every((child) => typeof child === 'string')\n}\n\nfunction getFirstLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const node = getNodeAtPath(tree, path)\n if (node === undefined) return null\n if (isLeafParent(node)) return path\n if (Array.isArray(node) && node.length > 0) {\n for (let i = 0; i < node.length; i++) {\n const found = getFirstLeafParentPath(tree, [...path, i])\n if (found) return found\n }\n }\n return null\n}\n\nfunction getLastLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const node = getNodeAtPath(tree, path)\n if (node === undefined) return null\n if (isLeafParent(node)) return path\n if (Array.isArray(node) && node.length > 0) {\n for (let i = node.length - 1; i >= 0; i--) {\n const found = getLastLeafParentPath(tree, [...path, i])\n if (found) return found\n }\n }\n return null\n}\n\nfunction getPrevLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const current = [...path]\n while (current.length > 0) {\n const lastIndex = current[current.length - 1]\n const parentPath = current.slice(0, -1)\n const parent = getNodeAtPath(tree, parentPath)\n\n if (Array.isArray(parent)) {\n for (let i = lastIndex - 1; i >= 0; i--) {\n const found = getLastLeafParentPath(tree, [...parentPath, i])\n if (found) return found\n }\n }\n\n current.pop()\n }\n\n return null\n}\n\nfunction getNextLeafParentPath(tree: StepTree, path: number[]): number[] | null {\n const current = [...path]\n while (current.length > 0) {\n const lastIndex = current[current.length - 1]\n const parentPath = current.slice(0, -1)\n const parent = getNodeAtPath(tree, parentPath)\n\n if (Array.isArray(parent)) {\n for (let i = lastIndex + 1; i < parent.length; i++) {\n const found = getFirstLeafParentPath(tree, [...parentPath, i])\n if (found) return found\n }\n }\n\n current.pop()\n }\n\n return null\n}\n\ntype FormContextValue<TFieldValues extends FieldValues = FieldValues> = {\n form: UseFormReturn<TFieldValues, any, any>\n step?: number\n currentStep: number | number[] | null\n setCurrentStep: (step: number | number[]) => Promise<void>\n currentStepNode: StepTree | undefined\n currentStepArr: string[] | null\n validatedFields: string[]\n isFirstStep: boolean\n isLastStep: boolean\n registrationKey: number\n next: () => void\n prev: () => void\n rebuildSteps: () => void\n registerStep: (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number) => void\n changeStepAtIndex: (elements: StepTree, index: number) => void\n}\n\nconst FormContext = createContext<FormContextValue | null>(null)\n\nfunction useFormContext<TFieldValues extends FieldValues = FieldValues>(): FormContextValue<TFieldValues> {\n const context = useContext(FormContext)\n if (!context) {\n throw new Error('useFormContext must be used within a <Form>')\n }\n return context as unknown as FormContextValue<TFieldValues>\n}\n\ninterface FormProps<TFieldValues extends FieldValues = FieldValues>\n extends Omit<React.ComponentProps<'form'>, 'onSubmit' | 'children'> {\n form: UseFormReturn<TFieldValues, any, any>\n onSubmit: (values: TFieldValues) => void\n stepValidationMode?: StepValidationMode\n children: React.ReactNode | ((context: FormContextValue<TFieldValues>) => React.ReactNode)\n}\n\nfunction FormInner<TFieldValues extends FieldValues = FieldValues>(\n { form, onSubmit, stepValidationMode = 'forward', children, ...props }: FormProps<TFieldValues>,\n ref: React.Ref<HTMLFormElement>,\n) {\n const [steps, setSteps] = useState<StepTree>([])\n const [currentStep, setCurrentStep] = useState<number[] | null>(null)\n const [validatedFields, setValidatedFields] = useState<string[]>([])\n const [registrationKey, setRegistrationKey] = useState(0)\n\n const stepRef = useRef<number | undefined>(undefined)\n\n const _currentStep = useMemo<number | number[] | null>(() => {\n if (!currentStep) return null\n const sliced = currentStep.slice(1)\n return sliced.length === 1 ? sliced[0] : sliced\n }, [currentStep])\n\n const currentStepNode = useMemo(\n () => (currentStep ? getNodeAtPath(steps, currentStep) : undefined),\n [steps, currentStep],\n )\n\n const currentStepArr = useMemo<string[] | null>(() => {\n if (!currentStepNode) return null\n return isLeafParent(currentStepNode) ? currentStepNode : null\n }, [currentStepNode])\n\n const _setCurrentStep = useCallback(\n async (step: number | number[]) => {\n const path = typeof step === 'number' ? [0, step] : [0, ...step]\n if (currentStep && currentStepArr && stepValidationMode !== 'none') {\n const isForward = comparePaths(path, currentStep) > 0\n const shouldValidate = stepValidationMode === 'all' || (stepValidationMode === 'forward' && isForward)\n if (shouldValidate) {\n const isValid = await form.trigger(currentStepArr as Path<TFieldValues>[])\n if (!isValid) {\n setValidatedFields((prev) => prev.filter((field) => !currentStepArr.includes(field)))\n return\n }\n setValidatedFields((prev) => [...new Set([...prev, ...currentStepArr])])\n }\n }\n setCurrentStep(path)\n },\n [currentStep, currentStepArr, form, stepValidationMode],\n )\n\n const isFirstStep = useMemo(\n () => (currentStep ? getPrevLeafParentPath(steps, currentStep) === null : true),\n [steps, currentStep],\n )\n\n const isLastStep = useMemo(\n () => (currentStep ? getNextLeafParentPath(steps, currentStep) === null : true),\n [steps, currentStep],\n )\n\n const next = useCallback(async () => {\n if (!currentStep) return\n const nextPath = getNextLeafParentPath(steps, currentStep)\n if (currentStepArr && stepValidationMode !== 'none') {\n const isValid = await form.trigger(currentStepArr as Path<TFieldValues>[])\n if (!isValid) {\n setValidatedFields((prev) => prev.filter((field) => !currentStepArr.includes(field)))\n return\n }\n setValidatedFields((prev) => [...new Set([...prev, ...currentStepArr])])\n }\n if (nextPath) {\n setCurrentStep(nextPath)\n }\n }, [steps, currentStep, currentStepArr, form, stepValidationMode])\n\n const prev = useCallback(() => {\n if (!currentStep) return\n const prevPath = getPrevLeafParentPath(steps, currentStep)\n if (prevPath) {\n setCurrentStep(prevPath)\n }\n }, [steps, currentStep])\n\n const registerStep = useCallback(\n (elements: StepTree, stepRef: React.RefObject<number | undefined>, step?: number): void => {\n setSteps((prevSteps: StepTree) => {\n const stepNumber = step ?? (Array.isArray(prevSteps) ? prevSteps.length : 0)\n stepRef.current = stepNumber\n const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps]\n newSteps.splice(stepNumber, 0, elements)\n\n if (currentStep === null) {\n const firstLeafParent = getFirstLeafParentPath(newSteps, [0])\n if (firstLeafParent) {\n setCurrentStep(firstLeafParent)\n }\n }\n\n return newSteps\n })\n },\n [currentStep],\n )\n\n const rebuildSteps = useCallback(() => {\n setSteps([])\n setRegistrationKey((prev) => prev + 1)\n }, [])\n\n const changeStepAtIndex = useCallback((steps: StepTree, index: number): void => {\n setSteps((prevSteps) => {\n const newSteps = Array.isArray(prevSteps) ? [...prevSteps] : [prevSteps]\n newSteps[index] = steps\n return newSteps\n })\n }, [])\n\n const contextValue = useMemo<FormContextValue>(\n () => ({\n // eslint-disable-next-line react-hooks/refs\n step: stepRef.current,\n currentStep: _currentStep,\n setCurrentStep: _setCurrentStep,\n currentStepNode,\n currentStepArr,\n validatedFields,\n isFirstStep,\n isLastStep,\n form: form as unknown as UseFormReturn<FieldValues, any, any>,\n registrationKey,\n next,\n prev,\n rebuildSteps,\n registerStep,\n changeStepAtIndex,\n }),\n [\n form,\n _currentStep,\n _setCurrentStep,\n currentStepNode,\n currentStepArr,\n validatedFields,\n isFirstStep,\n isLastStep,\n registrationKey,\n next,\n prev,\n rebuildSteps,\n registerStep,\n changeStepAtIndex,\n ],\n )\n\n const resolvedChildren =\n // eslint-disable-next-line react-hooks/refs\n typeof children === 'function' ? children(contextValue as unknown as FormContextValue<TFieldValues>) : children\n\n return (\n // eslint-disable-next-line react-hooks/refs\n <FormContext.Provider value={contextValue}>\n <form ref={ref} onSubmit={form.handleSubmit(onSubmit)} {...props}>\n <Step>{resolvedChildren}</Step>\n </form>\n </FormContext.Provider>\n )\n}\n\nconst Form = forwardRef(FormInner) as <TFieldValues extends FieldValues = FieldValues>(\n props: FormProps<TFieldValues> & { ref?: React.Ref<HTMLFormElement> },\n) => React.JSX.Element\n\n;(Form as React.NamedExoticComponent & { displayName?: string }).displayName = 'Form'\n\nexport { Form, useFormContext }\nexport type { FormContextValue, FormProps }\n","import { ComponentProps, useEffect } from 'react'\nimport {\n type Control,\n Controller as RHFController,\n type ControllerFieldState,\n type ControllerRenderProps,\n type FieldPath,\n type FieldValues,\n type UseFormStateReturn,\n} from 'react-hook-form'\n\nimport { useFormContext } from './form'\nimport { useStep } from './step'\n\ntype ControllerRenderArgs<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n field: ControllerRenderProps<TFieldValues, TName>\n fieldState: ControllerFieldState\n formState: UseFormStateReturn<TFieldValues>\n}\n\ntype ControllerProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = ComponentProps<typeof RHFController<TFieldValues, TName>>\n\nfunction Controller<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({ name, control, ...rest }: ControllerProps<TFieldValues, TName>) {\n const formContext = useFormContext<TFieldValues>()\n const stepContext = useStep()\n const resolvedControl = control ?? (formContext.form.control as unknown as Control<TFieldValues>)\n\n useEffect(() => {\n if (stepContext) {\n stepContext.registerField([name as string])\n }\n }, [stepContext?.registrationKey])\n\n useEffect(() => {\n if (stepContext?.step !== undefined) {\n stepContext?.rebuildSteps()\n }\n return () => {\n stepContext?.rebuildSteps()\n }\n }, [])\n\n return <RHFController name={name} control={resolvedControl} {...rest} />\n}\n\nController.displayName = 'Controller'\n\nexport { Controller }\nexport type { ControllerProps, ControllerRenderArgs }\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rhf-stepper",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A multi-step form helper for react-hook-form",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
27
|
+
"lint": "eslint src/",
|
|
28
|
+
"typecheck": "tsc --noEmit"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"react",
|
|
32
|
+
"react-hook-form",
|
|
33
|
+
"stepper",
|
|
34
|
+
"multi-step-form",
|
|
35
|
+
"wizard",
|
|
36
|
+
"form"
|
|
37
|
+
],
|
|
38
|
+
"author": "",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=17.0.0",
|
|
42
|
+
"react-hook-form": ">=7.0.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/react": "^19.2.14",
|
|
46
|
+
"react": "^19.2.4",
|
|
47
|
+
"react-hook-form": "^7.71.1",
|
|
48
|
+
"tsup": "^8.5.1",
|
|
49
|
+
"typescript": "^5.9.3"
|
|
50
|
+
},
|
|
51
|
+
"packageManager": "pnpm@10.28.0"
|
|
52
|
+
}
|