wizzard-stepper-react 1.3.1 → 1.5.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.cjs CHANGED
@@ -25,12 +25,20 @@ __export(index_exports, {
25
25
  LocalStorageAdapter: () => LocalStorageAdapter,
26
26
  MemoryAdapter: () => MemoryAdapter,
27
27
  WizardProvider: () => WizardProvider,
28
+ WizardStepRenderer: () => WizardStepRenderer,
29
+ WizardStore: () => WizardStore,
28
30
  YupAdapter: () => YupAdapter,
29
31
  ZodAdapter: () => ZodAdapter,
32
+ createWizardFactory: () => createWizardFactory,
30
33
  getByPath: () => getByPath,
31
34
  setByPath: () => setByPath,
32
35
  useWizard: () => useWizard,
33
- useWizardContext: () => useWizardContext
36
+ useWizardActions: () => useWizardActions,
37
+ useWizardContext: () => useWizardContext,
38
+ useWizardError: () => useWizardError,
39
+ useWizardSelector: () => useWizardSelector,
40
+ useWizardState: () => useWizardState,
41
+ useWizardValue: () => useWizardValue
34
42
  });
35
43
  module.exports = __toCommonJS(index_exports);
36
44
 
@@ -66,6 +74,9 @@ function getByPath(obj, path, defaultValue) {
66
74
  }
67
75
  function setByPath(obj, path, value) {
68
76
  if (!path) return value;
77
+ if (!path.includes(".") && !path.includes("[") && !path.includes("]")) {
78
+ return { ...obj, [path]: value };
79
+ }
69
80
  const keys = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
70
81
  const update = (current, index) => {
71
82
  if (index === keys.length) return value;
@@ -86,39 +97,93 @@ function setByPath(obj, path, value) {
86
97
 
87
98
  // src/context/WizardContext.tsx
88
99
  var import_jsx_runtime = require("react/jsx-runtime");
89
- var WizardContext = (0, import_react.createContext)(void 0);
100
+ var WizardStateContext = (0, import_react.createContext)(
101
+ void 0
102
+ );
103
+ var WizardActionsContext = (0, import_react.createContext)(
104
+ void 0
105
+ );
106
+ var WizardStore = class {
107
+ constructor(initialData) {
108
+ __publicField(this, "state");
109
+ __publicField(this, "listeners", /* @__PURE__ */ new Set());
110
+ __publicField(this, "getSnapshot", () => this.state);
111
+ __publicField(this, "subscribe", (listener) => {
112
+ this.listeners.add(listener);
113
+ return () => this.listeners.delete(listener);
114
+ });
115
+ this.state = { data: initialData, errors: {} };
116
+ }
117
+ update(newData) {
118
+ this.state = { ...this.state, data: newData };
119
+ this.notify();
120
+ }
121
+ updateErrors(newErrors) {
122
+ this.state = { ...this.state, errors: newErrors };
123
+ this.notify();
124
+ }
125
+ notify() {
126
+ this.listeners.forEach((l) => l());
127
+ }
128
+ };
90
129
  function WizardProvider({
91
130
  config,
92
131
  initialData,
132
+ initialStepId,
93
133
  children
94
134
  }) {
95
135
  const [currentStepId, setCurrentStepId] = (0, import_react.useState)("");
96
- const [wizardData, setWizardData] = (0, import_react.useState)(initialData || {});
97
136
  const [visitedSteps, setVisitedSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
98
137
  const [completedSteps, setCompletedSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
99
138
  const [errorSteps, setErrorSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
100
- const [allErrors, setAllErrors] = (0, import_react.useState)({});
139
+ const [, setAllErrorsState] = (0, import_react.useState)({});
101
140
  const [isLoading, setIsLoading] = (0, import_react.useState)(true);
141
+ const [isPending, startTransition] = (0, import_react.useTransition)();
142
+ const storeRef = (0, import_react.useRef)(new WizardStore(initialData || {}));
143
+ const [wizardData, setWizardData] = (0, import_react.useState)(initialData || {});
102
144
  const persistenceAdapter = (0, import_react.useMemo)(() => {
103
145
  return config.persistence?.adapter || new MemoryAdapter();
104
146
  }, [config.persistence?.adapter]);
105
147
  const persistenceMode = config.persistence?.mode || "onStepChange";
106
- const activeSteps = (0, import_react.useMemo)(() => {
107
- return config.steps.filter((step) => {
148
+ const [activeSteps, setActiveSteps] = (0, import_react.useState)(
149
+ () => config.steps.filter((s) => !s.condition || s.condition(wizardData))
150
+ );
151
+ (0, import_react.useEffect)(() => {
152
+ const nextActiveSteps = config.steps.filter((step) => {
108
153
  if (step.condition) {
109
154
  return step.condition(wizardData);
110
155
  }
111
156
  return true;
112
157
  });
113
- }, [config.steps, wizardData]);
158
+ const currentIds = activeSteps.map((s) => s.id).join(",");
159
+ const nextIds = nextActiveSteps.map((s) => s.id).join(",");
160
+ if (currentIds !== nextIds) {
161
+ setActiveSteps(nextActiveSteps);
162
+ }
163
+ }, [config.steps, wizardData, activeSteps]);
114
164
  (0, import_react.useEffect)(() => {
115
165
  if (!currentStepId && activeSteps.length > 0) {
116
- setCurrentStepId(activeSteps[0].id);
166
+ if (initialStepId) {
167
+ const target = activeSteps.find((s) => s.id === initialStepId);
168
+ if (target) {
169
+ setCurrentStepId(target.id);
170
+ } else {
171
+ setCurrentStepId(activeSteps[0].id);
172
+ }
173
+ } else {
174
+ setCurrentStepId(activeSteps[0].id);
175
+ }
117
176
  setIsLoading(false);
118
177
  }
119
- }, [activeSteps, currentStepId]);
120
- const currentStep = (0, import_react.useMemo)(() => activeSteps.find((s) => s.id === currentStepId) || null, [activeSteps, currentStepId]);
121
- const currentStepIndex = (0, import_react.useMemo)(() => activeSteps.findIndex((s) => s.id === currentStepId), [activeSteps, currentStepId]);
178
+ }, [activeSteps, currentStepId, initialStepId]);
179
+ const currentStep = (0, import_react.useMemo)(
180
+ () => activeSteps.find((s) => s.id === currentStepId) || null,
181
+ [activeSteps, currentStepId]
182
+ );
183
+ const currentStepIndex = (0, import_react.useMemo)(
184
+ () => activeSteps.findIndex((s) => s.id === currentStepId),
185
+ [activeSteps, currentStepId]
186
+ );
122
187
  const isFirstStep = currentStepIndex === 0;
123
188
  const isLastStep = currentStepIndex === activeSteps.length - 1;
124
189
  const META_KEY = "__wizzard_meta__";
@@ -138,103 +203,186 @@ function WizardProvider({
138
203
  }
139
204
  });
140
205
  if (Object.keys(loadedData).length > 0) {
141
- setWizardData((prev) => ({ ...prev, ...loadedData }));
206
+ setWizardData((prev) => {
207
+ const newData = { ...prev, ...loadedData };
208
+ storeRef.current.update(newData);
209
+ return newData;
210
+ });
142
211
  }
143
212
  setIsLoading(false);
144
213
  }, [config.steps, persistenceAdapter]);
145
214
  (0, import_react.useEffect)(() => {
146
215
  hydrate();
147
216
  }, [hydrate]);
148
- const saveData = (0, import_react.useCallback)((mode, stepId, data) => {
149
- if (mode === persistenceMode || mode === "manual") {
150
- persistenceAdapter.saveStep(stepId, data);
151
- }
152
- }, [persistenceAdapter, persistenceMode]);
153
- const setStepData = (0, import_react.useCallback)((stepId, data) => {
154
- setWizardData((prev) => {
155
- const newData = { ...prev, ...data };
217
+ const saveData = (0, import_react.useCallback)(
218
+ (mode, stepId, data) => {
219
+ const stepConfig = config.steps.find((s) => s.id === stepId);
220
+ const stepAdapter = stepConfig?.persistenceAdapter;
221
+ const adapterToUse = stepAdapter || persistenceAdapter;
222
+ if (mode === persistenceMode || mode === "manual") {
223
+ adapterToUse.saveStep(stepId, data);
224
+ }
225
+ },
226
+ [persistenceAdapter, persistenceMode, config.steps]
227
+ );
228
+ const validationTimeoutRef = (0, import_react.useRef)(
229
+ null
230
+ );
231
+ const validateStep = (0, import_react.useCallback)(
232
+ async (stepId, data) => {
233
+ const step = config.steps.find((s) => s.id === stepId);
234
+ if (!step || !step.validationAdapter) return true;
235
+ const result = await step.validationAdapter.validate(data);
236
+ if (!result.isValid) {
237
+ const newAllErrors = {
238
+ ...storeRef.current.getSnapshot().errors,
239
+ [stepId]: result.errors || {}
240
+ };
241
+ storeRef.current.updateErrors(newAllErrors);
242
+ setAllErrorsState(newAllErrors);
243
+ setErrorSteps((prev) => {
244
+ const next = new Set(prev);
245
+ next.add(stepId);
246
+ return next;
247
+ });
248
+ return false;
249
+ } else {
250
+ const newAllErrors = { ...storeRef.current.getSnapshot().errors };
251
+ delete newAllErrors[stepId];
252
+ storeRef.current.updateErrors(newAllErrors);
253
+ setAllErrorsState(newAllErrors);
254
+ setErrorSteps((prev) => {
255
+ const next = new Set(prev);
256
+ next.delete(stepId);
257
+ return next;
258
+ });
259
+ return true;
260
+ }
261
+ },
262
+ [config.steps]
263
+ );
264
+ const setStepData = (0, import_react.useCallback)(
265
+ (stepId, data) => {
266
+ const prevData = storeRef.current.getSnapshot().data;
267
+ const newData = { ...prevData, ...data };
268
+ storeRef.current.update(newData);
269
+ startTransition(() => {
270
+ setWizardData(newData);
271
+ });
156
272
  if (persistenceMode === "onChange") {
157
273
  saveData("onChange", stepId, newData);
158
274
  }
159
- return newData;
160
- });
161
- }, [persistenceMode, saveData]);
162
- const setData = (0, import_react.useCallback)((path, value2) => {
163
- setWizardData((prev) => {
164
- const newData = setByPath(prev, path, value2);
275
+ },
276
+ [persistenceMode, saveData]
277
+ );
278
+ const setData = (0, import_react.useCallback)(
279
+ (path, value, options) => {
280
+ const prevData = storeRef.current.getSnapshot().data;
281
+ const newData = setByPath(prevData, path, value);
282
+ storeRef.current.update(newData);
283
+ startTransition(() => {
284
+ setWizardData(newData);
285
+ });
286
+ if (options?.debounceValidation) {
287
+ if (validationTimeoutRef.current)
288
+ clearTimeout(validationTimeoutRef.current);
289
+ validationTimeoutRef.current = setTimeout(() => {
290
+ try {
291
+ validateStep(currentStepId, newData).catch((err) => {
292
+ console.error("[Wizard] Debounced validation failed:", err);
293
+ });
294
+ } catch (e) {
295
+ console.error("[Wizard] Error starting validation:", e);
296
+ }
297
+ }, options.debounceValidation);
298
+ } else {
299
+ validateStep(currentStepId, newData);
300
+ }
165
301
  if (persistenceMode === "onChange") {
166
302
  saveData("onChange", currentStepId, newData);
167
303
  }
168
- return newData;
169
- });
170
- }, [persistenceMode, saveData, currentStepId]);
171
- const getData = (0, import_react.useCallback)((path, defaultValue) => {
172
- return getByPath(wizardData, path, defaultValue);
173
- }, [wizardData]);
174
- const handleStepChange = (0, import_react.useCallback)((field, value2) => {
175
- if (!currentStepId) return;
176
- setData(field, value2);
177
- }, [setData, currentStepId]);
178
- const validateStep = (0, import_react.useCallback)(async (stepId) => {
179
- const step = config.steps.find((s) => s.id === stepId);
180
- if (!step) return true;
181
- if (!step.validationAdapter) return true;
182
- const result = await step.validationAdapter.validate(wizardData);
183
- if (!result.isValid) {
184
- setAllErrors((prev) => ({
185
- ...prev,
186
- [stepId]: result.errors || {}
187
- }));
188
- setErrorSteps((prev) => new Set(prev).add(stepId));
189
- return false;
190
- } else {
191
- setAllErrors((prev) => {
192
- const next = { ...prev };
193
- delete next[stepId];
194
- return next;
304
+ },
305
+ [persistenceMode, saveData, currentStepId, validateStep]
306
+ );
307
+ const updateData = (0, import_react.useCallback)(
308
+ (data, options) => {
309
+ const prevData = storeRef.current.getSnapshot().data;
310
+ const newData = options?.replace ? data : { ...prevData, ...data };
311
+ storeRef.current.update(newData);
312
+ startTransition(() => {
313
+ setWizardData(newData);
195
314
  });
196
- setErrorSteps((prev) => {
197
- const next = new Set(prev);
198
- next.delete(stepId);
199
- return next;
315
+ config.steps.forEach((step) => {
316
+ saveData("manual", step.id, newData);
200
317
  });
201
- return true;
202
- }
203
- }, [config.steps, wizardData]);
318
+ },
319
+ [saveData, config.steps]
320
+ );
321
+ const getData = (0, import_react.useCallback)((path, defaultValue) => {
322
+ return getByPath(storeRef.current.getSnapshot().data, path, defaultValue);
323
+ }, []);
324
+ const handleStepChange = (0, import_react.useCallback)(
325
+ (field, value) => {
326
+ if (!currentStepId) return;
327
+ setData(field, value);
328
+ },
329
+ [setData, currentStepId]
330
+ );
204
331
  const validateAll = (0, import_react.useCallback)(async () => {
205
332
  let isValid = true;
333
+ const currentData = storeRef.current.getSnapshot().data;
206
334
  for (const step of activeSteps) {
207
- const stepValid = await validateStep(step.id);
335
+ const stepValid = await validateStep(step.id, currentData);
208
336
  if (!stepValid) isValid = false;
209
337
  }
210
- return isValid;
338
+ const finalErrors = storeRef.current.getSnapshot().errors;
339
+ return { isValid, errors: finalErrors };
211
340
  }, [activeSteps, validateStep]);
212
- const goToStep = (0, import_react.useCallback)(async (stepId) => {
213
- const targetIndex = activeSteps.findIndex((s) => s.id === stepId);
214
- if (targetIndex === -1) return false;
215
- if (targetIndex > currentStepIndex) {
216
- const shouldValidate = currentStep?.autoValidate ?? config.autoValidate ?? true;
217
- if (shouldValidate) {
218
- const isValid = await validateStep(currentStepId);
219
- if (!isValid) return false;
341
+ const goToStep = (0, import_react.useCallback)(
342
+ async (stepId) => {
343
+ const targetIndex = activeSteps.findIndex((s) => s.id === stepId);
344
+ if (targetIndex === -1) return false;
345
+ const currentData = storeRef.current.getSnapshot().data;
346
+ if (targetIndex > currentStepIndex) {
347
+ const shouldValidate = currentStep?.autoValidate ?? config.autoValidate ?? true;
348
+ if (shouldValidate) {
349
+ const isValid = await validateStep(currentStepId, currentData);
350
+ if (!isValid) return false;
351
+ }
220
352
  }
221
- }
222
- if (persistenceMode === "onStepChange" && currentStep) {
223
- saveData("onStepChange", currentStepId, wizardData);
224
- }
225
- const nextVisited = new Set(visitedSteps).add(currentStepId);
226
- setVisitedSteps(nextVisited);
227
- setCurrentStepId(stepId);
228
- if (persistenceMode !== "manual") {
229
- persistenceAdapter.saveStep(META_KEY, {
230
- currentStepId: stepId,
231
- visited: Array.from(nextVisited),
232
- completed: Array.from(completedSteps)
233
- });
234
- }
235
- window.scrollTo(0, 0);
236
- return true;
237
- }, [activeSteps, currentStepId, currentStep, currentStepIndex, config.autoValidate, persistenceMode, saveData, wizardData, validateStep, visitedSteps, completedSteps, persistenceAdapter]);
353
+ if (persistenceMode === "onStepChange" && currentStep) {
354
+ saveData("onStepChange", currentStepId, currentData);
355
+ }
356
+ const nextVisited = new Set(visitedSteps).add(currentStepId);
357
+ setVisitedSteps(nextVisited);
358
+ setCurrentStepId(stepId);
359
+ if (persistenceMode !== "manual") {
360
+ persistenceAdapter.saveStep(META_KEY, {
361
+ currentStepId: stepId,
362
+ visited: Array.from(nextVisited),
363
+ completed: Array.from(completedSteps)
364
+ });
365
+ }
366
+ if (config.onStepChange) {
367
+ config.onStepChange(currentStepId, stepId, currentData);
368
+ }
369
+ window.scrollTo(0, 0);
370
+ return true;
371
+ },
372
+ [
373
+ activeSteps,
374
+ currentStepId,
375
+ currentStep,
376
+ currentStepIndex,
377
+ config.autoValidate,
378
+ persistenceMode,
379
+ saveData,
380
+ validateStep,
381
+ visitedSteps,
382
+ completedSteps,
383
+ persistenceAdapter
384
+ ]
385
+ );
238
386
  const goToNextStep = (0, import_react.useCallback)(async () => {
239
387
  if (isLastStep) return;
240
388
  const nextStep = activeSteps[currentStepIndex + 1];
@@ -248,12 +396,21 @@ function WizardProvider({
248
396
  currentStepId: nextStep.id,
249
397
  visited: Array.from(new Set(visitedSteps).add(currentStepId)),
250
398
  completed: Array.from(nextCompleted)
251
- // Updated completed steps
252
399
  });
253
400
  }
254
401
  }
255
402
  }
256
- }, [activeSteps, currentStepIndex, isLastStep, currentStepId, goToStep, visitedSteps, completedSteps, persistenceMode, persistenceAdapter]);
403
+ }, [
404
+ activeSteps,
405
+ currentStepIndex,
406
+ isLastStep,
407
+ currentStepId,
408
+ goToStep,
409
+ visitedSteps,
410
+ completedSteps,
411
+ persistenceMode,
412
+ persistenceAdapter
413
+ ]);
257
414
  const goToPrevStep = (0, import_react.useCallback)(() => {
258
415
  if (isFirstStep) return;
259
416
  const prevStep = activeSteps[currentStepIndex - 1];
@@ -261,45 +418,235 @@ function WizardProvider({
261
418
  goToStep(prevStep.id);
262
419
  }
263
420
  }, [activeSteps, currentStepIndex, isFirstStep, goToStep]);
264
- const value = {
265
- currentStep,
266
- currentStepIndex,
267
- isFirstStep,
268
- isLastStep,
269
- isLoading,
270
- activeSteps,
271
- wizardData,
272
- allErrors,
273
- visitedSteps,
274
- completedSteps,
275
- errorSteps,
276
- goToNextStep,
277
- goToPrevStep,
278
- goToStep,
279
- setStepData,
280
- handleStepChange,
281
- validateStep,
282
- validateAll,
283
- save: (0, import_react.useCallback)(() => saveData("manual", currentStepId, wizardData), [saveData, currentStepId, wizardData]),
284
- clearStorage: (0, import_react.useCallback)(() => persistenceAdapter.clear(), [persistenceAdapter]),
285
- setData,
286
- getData
287
- };
288
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WizardContext.Provider, { value, children });
421
+ const clearStorage = (0, import_react.useCallback)(
422
+ () => persistenceAdapter.clear(),
423
+ [persistenceAdapter]
424
+ );
425
+ const save = (0, import_react.useCallback)(
426
+ () => saveData("manual", currentStepId, storeRef.current.getSnapshot().data),
427
+ [saveData, currentStepId]
428
+ );
429
+ const stateValue = (0, import_react.useMemo)(
430
+ () => ({
431
+ currentStep,
432
+ currentStepIndex,
433
+ isFirstStep,
434
+ isLastStep,
435
+ isLoading,
436
+ isPending,
437
+ activeSteps,
438
+ visitedSteps,
439
+ completedSteps,
440
+ errorSteps,
441
+ store: storeRef.current
442
+ }),
443
+ [
444
+ currentStep,
445
+ currentStepIndex,
446
+ isFirstStep,
447
+ isLastStep,
448
+ isLoading,
449
+ isPending,
450
+ activeSteps,
451
+ visitedSteps,
452
+ completedSteps,
453
+ errorSteps
454
+ ]
455
+ );
456
+ const actionsValue = (0, import_react.useMemo)(
457
+ () => ({
458
+ goToNextStep,
459
+ goToPrevStep,
460
+ goToStep,
461
+ setStepData,
462
+ handleStepChange,
463
+ validateStep: (sid) => validateStep(sid, storeRef.current.getSnapshot().data),
464
+ validateAll,
465
+ save,
466
+ clearStorage,
467
+ setData,
468
+ updateData,
469
+ getData
470
+ }),
471
+ [
472
+ goToNextStep,
473
+ goToPrevStep,
474
+ goToStep,
475
+ setStepData,
476
+ handleStepChange,
477
+ validateStep,
478
+ validateAll,
479
+ save,
480
+ clearStorage,
481
+ setData,
482
+ updateData,
483
+ getData
484
+ ]
485
+ );
486
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WizardStateContext.Provider, { value: stateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WizardActionsContext.Provider, { value: actionsValue, children }) });
289
487
  }
290
- function useWizardContext() {
291
- const context = (0, import_react.useContext)(WizardContext);
488
+ function useWizardState() {
489
+ const context = (0, import_react.useContext)(WizardStateContext);
490
+ if (!context) {
491
+ throw new Error("useWizardState must be used within a WizardProvider");
492
+ }
493
+ return context;
494
+ }
495
+ function useWizardValue(path) {
496
+ const { store } = useWizardState();
497
+ const lastStateRef = (0, import_react.useRef)(null);
498
+ const lastValueRef = (0, import_react.useRef)(null);
499
+ const getSnapshot = (0, import_react.useCallback)(() => {
500
+ const fullState = store.getSnapshot();
501
+ const data = fullState.data;
502
+ if (data === lastStateRef.current) {
503
+ return lastValueRef.current;
504
+ }
505
+ const value = getByPath(data, path);
506
+ lastStateRef.current = data;
507
+ lastValueRef.current = value;
508
+ return value;
509
+ }, [store, path]);
510
+ return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
511
+ }
512
+ function useWizardError(path) {
513
+ const { store } = useWizardState();
514
+ const lastStateRef = (0, import_react.useRef)(null);
515
+ const lastValueRef = (0, import_react.useRef)(null);
516
+ const getSnapshot = (0, import_react.useCallback)(() => {
517
+ const fullState = store.getSnapshot();
518
+ const errors = fullState.errors;
519
+ if (errors === lastStateRef.current) {
520
+ return lastValueRef.current;
521
+ }
522
+ let foundError;
523
+ Object.values(errors).forEach((stepErrors) => {
524
+ const typedStepErrors = stepErrors;
525
+ if (typedStepErrors[path]) foundError = typedStepErrors[path];
526
+ });
527
+ lastStateRef.current = errors;
528
+ lastValueRef.current = foundError;
529
+ return foundError;
530
+ }, [store, path]);
531
+ return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
532
+ }
533
+ function useWizardSelector(selector) {
534
+ const { store } = useWizardState();
535
+ const lastStateRef = (0, import_react.useRef)(null);
536
+ const lastResultRef = (0, import_react.useRef)(null);
537
+ const getSnapshot = (0, import_react.useCallback)(() => {
538
+ const fullState = store.getSnapshot();
539
+ if (fullState === lastStateRef.current) {
540
+ return lastResultRef.current;
541
+ }
542
+ const result = selector(fullState.data);
543
+ lastStateRef.current = fullState;
544
+ lastResultRef.current = result;
545
+ return result;
546
+ }, [store, selector]);
547
+ return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
548
+ }
549
+ function useWizardActions() {
550
+ const context = (0, import_react.useContext)(WizardActionsContext);
292
551
  if (!context) {
293
- throw new Error("useWizardContext must be used within a WizardProvider");
552
+ throw new Error("useWizardActions must be used within a WizardProvider");
294
553
  }
295
554
  return context;
296
555
  }
556
+ function useWizardContext() {
557
+ const state = useWizardState();
558
+ const actions = useWizardActions();
559
+ const wizardData = useWizardSelector((s) => s);
560
+ const fullState = state.store.getSnapshot();
561
+ return (0, import_react.useMemo)(
562
+ () => ({
563
+ ...state,
564
+ ...actions,
565
+ wizardData,
566
+ allErrors: fullState.errors
567
+ }),
568
+ [state, actions, wizardData, fullState.errors]
569
+ );
570
+ }
571
+
572
+ // src/components/WizardStepRenderer.tsx
573
+ var import_react2 = require("react");
574
+ var import_jsx_runtime2 = require("react/jsx-runtime");
575
+ var WizardStepRenderer = ({
576
+ wrapper: Wrapper
577
+ }) => {
578
+ const { currentStep } = useWizardContext();
579
+ const StepComponent = (0, import_react2.useMemo)(() => {
580
+ if (!currentStep?.component) return null;
581
+ return currentStep.component;
582
+ }, [currentStep]);
583
+ if (!currentStep || !StepComponent) {
584
+ return null;
585
+ }
586
+ const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StepComponent, {});
587
+ if (Wrapper) {
588
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Wrapper, { children: content }, currentStep.id);
589
+ }
590
+ return content;
591
+ };
297
592
 
298
593
  // src/hooks/useWizard.ts
299
594
  var useWizard = () => {
300
595
  return useWizardContext();
301
596
  };
302
597
 
598
+ // src/factory.tsx
599
+ var import_jsx_runtime3 = require("react/jsx-runtime");
600
+ function createWizardFactory() {
601
+ const WizardProvider2 = ({
602
+ config,
603
+ initialData,
604
+ children
605
+ }) => {
606
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
607
+ WizardProvider,
608
+ {
609
+ config,
610
+ initialData,
611
+ children
612
+ }
613
+ );
614
+ };
615
+ const useWizard2 = () => {
616
+ return useWizard();
617
+ };
618
+ const useWizardContext2 = () => {
619
+ return useWizardContext();
620
+ };
621
+ const useWizardValue2 = (path) => {
622
+ return useWizardValue(path);
623
+ };
624
+ const useWizardSelector2 = (selector) => {
625
+ return useWizardSelector(selector);
626
+ };
627
+ const useWizardError2 = (path) => {
628
+ return useWizardError(path);
629
+ };
630
+ const useWizardActions2 = () => {
631
+ return useWizardActions();
632
+ };
633
+ const useWizardState2 = () => {
634
+ return useWizardState();
635
+ };
636
+ const createStep = (config) => config;
637
+ return {
638
+ WizardProvider: WizardProvider2,
639
+ useWizard: useWizard2,
640
+ useWizardContext: useWizardContext2,
641
+ useWizardValue: useWizardValue2,
642
+ useWizardSelector: useWizardSelector2,
643
+ useWizardError: useWizardError2,
644
+ useWizardActions: useWizardActions2,
645
+ useWizardState: useWizardState2,
646
+ createStep
647
+ };
648
+ }
649
+
303
650
  // src/adapters/persistence/LocalStorageAdapter.ts
304
651
  var LocalStorageAdapter = class {
305
652
  constructor(prefix = "wizard_") {
@@ -349,16 +696,17 @@ var ZodAdapter = class {
349
696
  return { isValid: true };
350
697
  }
351
698
  const errors = {};
352
- result.error.issues.forEach((err) => {
353
- const path = err.path.join(".");
354
- errors[path] = err.message;
355
- });
699
+ if (result.error) {
700
+ result.error.issues.forEach((err) => {
701
+ const path = err.path.join(".");
702
+ errors[path] = err.message;
703
+ });
704
+ }
356
705
  return { isValid: false, errors };
357
706
  }
358
707
  };
359
708
 
360
709
  // src/adapters/validation/YupAdapter.ts
361
- var import_yup = require("yup");
362
710
  var YupAdapter = class {
363
711
  constructor(schema) {
364
712
  __publicField(this, "schema");
@@ -369,9 +717,10 @@ var YupAdapter = class {
369
717
  await this.schema.validate(data, { abortEarly: false });
370
718
  return { isValid: true };
371
719
  } catch (err) {
372
- if (err instanceof import_yup.ValidationError) {
720
+ if (err && typeof err === "object" && "inner" in err) {
721
+ const yupError = err;
373
722
  const errors = {};
374
- err.inner.forEach((error) => {
723
+ yupError.inner.forEach((error) => {
375
724
  if (error.path) {
376
725
  errors[error.path] = error.message;
377
726
  }
@@ -387,11 +736,19 @@ var YupAdapter = class {
387
736
  LocalStorageAdapter,
388
737
  MemoryAdapter,
389
738
  WizardProvider,
739
+ WizardStepRenderer,
740
+ WizardStore,
390
741
  YupAdapter,
391
742
  ZodAdapter,
743
+ createWizardFactory,
392
744
  getByPath,
393
745
  setByPath,
394
746
  useWizard,
395
- useWizardContext
747
+ useWizardActions,
748
+ useWizardContext,
749
+ useWizardError,
750
+ useWizardSelector,
751
+ useWizardState,
752
+ useWizardValue
396
753
  });
397
754
  //# sourceMappingURL=index.cjs.map