wizzard-stepper-react 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +158 -431
- package/dist/index.cjs +1 -954
- package/dist/index.d.cts +309 -63
- package/dist/index.d.ts +309 -63
- package/dist/index.js +1 -921
- package/package.json +98 -93
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,954 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
-
|
|
22
|
-
// src/index.ts
|
|
23
|
-
var index_exports = {};
|
|
24
|
-
__export(index_exports, {
|
|
25
|
-
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
26
|
-
MemoryAdapter: () => MemoryAdapter,
|
|
27
|
-
WizardProvider: () => WizardProvider,
|
|
28
|
-
WizardStepRenderer: () => WizardStepRenderer,
|
|
29
|
-
WizardStore: () => WizardStore,
|
|
30
|
-
YupAdapter: () => YupAdapter,
|
|
31
|
-
ZodAdapter: () => ZodAdapter,
|
|
32
|
-
createWizardFactory: () => createWizardFactory,
|
|
33
|
-
getByPath: () => getByPath,
|
|
34
|
-
setByPath: () => setByPath,
|
|
35
|
-
shallowEqual: () => shallowEqual,
|
|
36
|
-
toPath: () => toPath,
|
|
37
|
-
useWizard: () => useWizard,
|
|
38
|
-
useWizardActions: () => useWizardActions,
|
|
39
|
-
useWizardContext: () => useWizardContext,
|
|
40
|
-
useWizardError: () => useWizardError,
|
|
41
|
-
useWizardSelector: () => useWizardSelector,
|
|
42
|
-
useWizardState: () => useWizardState,
|
|
43
|
-
useWizardValue: () => useWizardValue
|
|
44
|
-
});
|
|
45
|
-
module.exports = __toCommonJS(index_exports);
|
|
46
|
-
|
|
47
|
-
// src/context/WizardContext.tsx
|
|
48
|
-
var import_react = require("react");
|
|
49
|
-
|
|
50
|
-
// src/adapters/persistence/MemoryAdapter.ts
|
|
51
|
-
var MemoryAdapter = class {
|
|
52
|
-
constructor() {
|
|
53
|
-
__publicField(this, "storage", {});
|
|
54
|
-
}
|
|
55
|
-
saveStep(stepId, data) {
|
|
56
|
-
this.storage[stepId] = data;
|
|
57
|
-
}
|
|
58
|
-
getStep(stepId) {
|
|
59
|
-
return this.storage[stepId];
|
|
60
|
-
}
|
|
61
|
-
clear() {
|
|
62
|
-
this.storage = {};
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// src/utils/data.ts
|
|
67
|
-
var pathCache = /* @__PURE__ */ new Map();
|
|
68
|
-
function toPath(path) {
|
|
69
|
-
if (!path) return [];
|
|
70
|
-
if (pathCache.has(path)) {
|
|
71
|
-
return pathCache.get(path);
|
|
72
|
-
}
|
|
73
|
-
let keys;
|
|
74
|
-
if (path.includes("[")) {
|
|
75
|
-
keys = path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean);
|
|
76
|
-
} else {
|
|
77
|
-
keys = path.split(".").filter(Boolean);
|
|
78
|
-
}
|
|
79
|
-
pathCache.set(path, keys);
|
|
80
|
-
return keys;
|
|
81
|
-
}
|
|
82
|
-
function getByPath(obj, path, defaultValue) {
|
|
83
|
-
if (!path || obj === void 0 || obj === null) return defaultValue ?? obj;
|
|
84
|
-
if (!path.includes(".") && !path.includes("[")) {
|
|
85
|
-
const val = obj[path];
|
|
86
|
-
return val !== void 0 ? val : defaultValue;
|
|
87
|
-
}
|
|
88
|
-
const keys = toPath(path);
|
|
89
|
-
let result = obj;
|
|
90
|
-
for (let i = 0; i < keys.length; i++) {
|
|
91
|
-
if (result === void 0 || result === null) return defaultValue;
|
|
92
|
-
result = result[keys[i]];
|
|
93
|
-
}
|
|
94
|
-
return result !== void 0 ? result : defaultValue;
|
|
95
|
-
}
|
|
96
|
-
function setByPath(obj, path, value) {
|
|
97
|
-
if (!path) return value;
|
|
98
|
-
if (!path.includes(".") && !path.includes("[")) {
|
|
99
|
-
if (Array.isArray(obj)) {
|
|
100
|
-
const copy = [...obj];
|
|
101
|
-
copy[path] = value;
|
|
102
|
-
return copy;
|
|
103
|
-
}
|
|
104
|
-
return { ...obj, [path]: value };
|
|
105
|
-
}
|
|
106
|
-
const keys = toPath(path);
|
|
107
|
-
if (keys.length === 0) return value;
|
|
108
|
-
const root = Array.isArray(obj) ? [...obj] : { ...obj };
|
|
109
|
-
let current = root;
|
|
110
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
111
|
-
const key = keys[i];
|
|
112
|
-
const nextKey = keys[i + 1];
|
|
113
|
-
const existing = current[key];
|
|
114
|
-
let nextLevel;
|
|
115
|
-
if (existing && typeof existing === "object") {
|
|
116
|
-
nextLevel = Array.isArray(existing) ? [...existing] : { ...existing };
|
|
117
|
-
} else {
|
|
118
|
-
const isNumeric = /^\d+$/.test(nextKey);
|
|
119
|
-
nextLevel = isNumeric ? [] : {};
|
|
120
|
-
}
|
|
121
|
-
current[key] = nextLevel;
|
|
122
|
-
current = nextLevel;
|
|
123
|
-
}
|
|
124
|
-
const lastKey = keys[keys.length - 1];
|
|
125
|
-
current[lastKey] = value;
|
|
126
|
-
return root;
|
|
127
|
-
}
|
|
128
|
-
function shallowEqual(a, b) {
|
|
129
|
-
if (Object.is(a, b)) return true;
|
|
130
|
-
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const keysA = Object.keys(a);
|
|
134
|
-
const keysB = Object.keys(b);
|
|
135
|
-
if (keysA.length !== keysB.length) return false;
|
|
136
|
-
for (let i = 0; i < keysA.length; i++) {
|
|
137
|
-
const key = keysA[i];
|
|
138
|
-
if (!Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key])) {
|
|
139
|
-
return false;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// src/context/WizardContext.tsx
|
|
146
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
147
|
-
var WizardStateContext = (0, import_react.createContext)(
|
|
148
|
-
void 0
|
|
149
|
-
);
|
|
150
|
-
var WizardActionsContext = (0, import_react.createContext)(
|
|
151
|
-
void 0
|
|
152
|
-
);
|
|
153
|
-
var WizardStore = class {
|
|
154
|
-
constructor(initialData) {
|
|
155
|
-
__publicField(this, "state");
|
|
156
|
-
__publicField(this, "listeners", /* @__PURE__ */ new Set());
|
|
157
|
-
__publicField(this, "errorsMap", /* @__PURE__ */ new Map());
|
|
158
|
-
__publicField(this, "subscribe", (listener) => {
|
|
159
|
-
this.listeners.add(listener);
|
|
160
|
-
return () => this.listeners.delete(listener);
|
|
161
|
-
});
|
|
162
|
-
this.state = {
|
|
163
|
-
data: initialData,
|
|
164
|
-
errors: {}
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
getSnapshot() {
|
|
168
|
-
return this.state;
|
|
169
|
-
}
|
|
170
|
-
update(newData) {
|
|
171
|
-
this.state = { ...this.state, data: newData };
|
|
172
|
-
this.notify();
|
|
173
|
-
}
|
|
174
|
-
// Sync internal Map to external Object (for backward compat)
|
|
175
|
-
syncErrors() {
|
|
176
|
-
const newErrorsObj = {};
|
|
177
|
-
for (const [stepId, fieldErrors] of this.errorsMap.entries()) {
|
|
178
|
-
if (fieldErrors.size > 0) {
|
|
179
|
-
newErrorsObj[stepId] = Object.fromEntries(fieldErrors);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
this.state = { ...this.state, errors: newErrorsObj };
|
|
183
|
-
this.notify();
|
|
184
|
-
}
|
|
185
|
-
// Update from Object (Legacy/State setter)
|
|
186
|
-
updateErrors(newErrors) {
|
|
187
|
-
this.errorsMap.clear();
|
|
188
|
-
for (const [stepId, fieldErrors] of Object.entries(newErrors)) {
|
|
189
|
-
const stepMap = /* @__PURE__ */ new Map();
|
|
190
|
-
for (const [field, msg] of Object.entries(fieldErrors)) {
|
|
191
|
-
stepMap.set(field, msg);
|
|
192
|
-
}
|
|
193
|
-
if (stepMap.size > 0) this.errorsMap.set(stepId, stepMap);
|
|
194
|
-
}
|
|
195
|
-
this.state = { ...this.state, errors: newErrors };
|
|
196
|
-
this.notify();
|
|
197
|
-
}
|
|
198
|
-
// Optimize: Update Step Errors directly (O(1) Map updated, then Sync)
|
|
199
|
-
setStepErrors(stepId, errors) {
|
|
200
|
-
if (!errors || Object.keys(errors).length === 0) {
|
|
201
|
-
if (this.errorsMap.has(stepId)) {
|
|
202
|
-
this.errorsMap.delete(stepId);
|
|
203
|
-
this.syncErrors();
|
|
204
|
-
return true;
|
|
205
|
-
}
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
const stepMap = /* @__PURE__ */ new Map();
|
|
209
|
-
for (const [field, msg] of Object.entries(errors)) {
|
|
210
|
-
stepMap.set(field, msg);
|
|
211
|
-
}
|
|
212
|
-
this.errorsMap.set(stepId, stepMap);
|
|
213
|
-
this.syncErrors();
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
// Fast Delete (O(1))
|
|
217
|
-
deleteError(stepId, path) {
|
|
218
|
-
const stepErrors = this.errorsMap.get(stepId);
|
|
219
|
-
if (!stepErrors) return false;
|
|
220
|
-
if (stepErrors.has(path)) {
|
|
221
|
-
stepErrors.delete(path);
|
|
222
|
-
if (stepErrors.size === 0) {
|
|
223
|
-
this.errorsMap.delete(stepId);
|
|
224
|
-
}
|
|
225
|
-
this.syncErrors();
|
|
226
|
-
return true;
|
|
227
|
-
}
|
|
228
|
-
return false;
|
|
229
|
-
}
|
|
230
|
-
notify() {
|
|
231
|
-
this.listeners.forEach((l) => l());
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
function WizardProvider({
|
|
235
|
-
config,
|
|
236
|
-
initialData,
|
|
237
|
-
initialStepId,
|
|
238
|
-
children
|
|
239
|
-
}) {
|
|
240
|
-
const [currentStepId, setCurrentStepId] = (0, import_react.useState)("");
|
|
241
|
-
const currentStepIdRef = (0, import_react.useRef)(currentStepId);
|
|
242
|
-
(0, import_react.useEffect)(() => {
|
|
243
|
-
currentStepIdRef.current = currentStepId;
|
|
244
|
-
}, [currentStepId]);
|
|
245
|
-
const [visitedSteps, setVisitedSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
246
|
-
const [completedSteps, setCompletedSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
247
|
-
const [errorSteps, setErrorSteps] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
248
|
-
const [, setAllErrorsState] = (0, import_react.useState)({});
|
|
249
|
-
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
250
|
-
const [isPending, startTransition] = (0, import_react.useTransition)();
|
|
251
|
-
const storeRef = (0, import_react.useRef)(new WizardStore(initialData || {}));
|
|
252
|
-
const persistenceAdapter = (0, import_react.useMemo)(() => {
|
|
253
|
-
return config.persistence?.adapter || new MemoryAdapter();
|
|
254
|
-
}, [config.persistence?.adapter]);
|
|
255
|
-
const persistenceMode = config.persistence?.mode || "onStepChange";
|
|
256
|
-
const stepsMap = (0, import_react.useMemo)(() => {
|
|
257
|
-
const map = /* @__PURE__ */ new Map();
|
|
258
|
-
config.steps.forEach((step) => map.set(step.id, step));
|
|
259
|
-
return map;
|
|
260
|
-
}, [config.steps]);
|
|
261
|
-
const lastActiveStepsRef = (0, import_react.useRef)([]);
|
|
262
|
-
const activeSteps = (0, import_react.useSyncExternalStore)(
|
|
263
|
-
storeRef.current.subscribe,
|
|
264
|
-
(0, import_react.useCallback)(() => {
|
|
265
|
-
const currentData = storeRef.current.getSnapshot().data;
|
|
266
|
-
const nextActiveSteps = config.steps.filter((step) => {
|
|
267
|
-
if (step.condition) {
|
|
268
|
-
return step.condition(currentData);
|
|
269
|
-
}
|
|
270
|
-
return true;
|
|
271
|
-
});
|
|
272
|
-
const prevIds = lastActiveStepsRef.current.map((s) => s.id).join(".");
|
|
273
|
-
const nextIds = nextActiveSteps.map((s) => s.id).join(".");
|
|
274
|
-
if (prevIds === nextIds && lastActiveStepsRef.current.length > 0) {
|
|
275
|
-
return lastActiveStepsRef.current;
|
|
276
|
-
}
|
|
277
|
-
lastActiveStepsRef.current = nextActiveSteps;
|
|
278
|
-
return nextActiveSteps;
|
|
279
|
-
}, [config.steps])
|
|
280
|
-
);
|
|
281
|
-
const activeStepsIndexMap = (0, import_react.useMemo)(() => {
|
|
282
|
-
const map = /* @__PURE__ */ new Map();
|
|
283
|
-
activeSteps.forEach((s, i) => map.set(s.id, i));
|
|
284
|
-
return map;
|
|
285
|
-
}, [activeSteps]);
|
|
286
|
-
(0, import_react.useEffect)(() => {
|
|
287
|
-
if (!currentStepId && activeSteps.length > 0) {
|
|
288
|
-
if (initialStepId) {
|
|
289
|
-
const target = activeSteps.find((s) => s.id === initialStepId);
|
|
290
|
-
if (target) {
|
|
291
|
-
setCurrentStepId(target.id);
|
|
292
|
-
} else {
|
|
293
|
-
setCurrentStepId(activeSteps[0].id);
|
|
294
|
-
}
|
|
295
|
-
} else {
|
|
296
|
-
setCurrentStepId(activeSteps[0].id);
|
|
297
|
-
}
|
|
298
|
-
setIsLoading(false);
|
|
299
|
-
}
|
|
300
|
-
}, [activeSteps, currentStepId, initialStepId]);
|
|
301
|
-
const stateRef = (0, import_react.useRef)({
|
|
302
|
-
config,
|
|
303
|
-
stepsMap,
|
|
304
|
-
activeSteps,
|
|
305
|
-
activeStepsIndexMap,
|
|
306
|
-
visitedSteps,
|
|
307
|
-
completedSteps,
|
|
308
|
-
persistenceMode,
|
|
309
|
-
persistenceAdapter,
|
|
310
|
-
currentStepId
|
|
311
|
-
});
|
|
312
|
-
stateRef.current = {
|
|
313
|
-
config,
|
|
314
|
-
stepsMap,
|
|
315
|
-
activeSteps,
|
|
316
|
-
activeStepsIndexMap,
|
|
317
|
-
visitedSteps,
|
|
318
|
-
completedSteps,
|
|
319
|
-
persistenceMode,
|
|
320
|
-
persistenceAdapter,
|
|
321
|
-
currentStepId
|
|
322
|
-
};
|
|
323
|
-
const currentStep = (0, import_react.useMemo)(
|
|
324
|
-
() => stepsMap.get(currentStepId) || null,
|
|
325
|
-
[stepsMap, currentStepId]
|
|
326
|
-
);
|
|
327
|
-
const currentStepIndex = (0, import_react.useMemo)(
|
|
328
|
-
() => activeStepsIndexMap.get(currentStepId) ?? -1,
|
|
329
|
-
[activeStepsIndexMap, currentStepId]
|
|
330
|
-
);
|
|
331
|
-
const isFirstStep = currentStepIndex === 0;
|
|
332
|
-
const isLastStep = currentStepIndex === activeSteps.length - 1;
|
|
333
|
-
const META_KEY = "__wizzard_meta__";
|
|
334
|
-
const hydrate = (0, import_react.useCallback)(() => {
|
|
335
|
-
setIsLoading(true);
|
|
336
|
-
const { persistenceAdapter: persistenceAdapter2, config: config2 } = stateRef.current;
|
|
337
|
-
const metaFn = persistenceAdapter2.getStep(META_KEY);
|
|
338
|
-
if (metaFn) {
|
|
339
|
-
if (metaFn.currentStepId) setCurrentStepId(metaFn.currentStepId);
|
|
340
|
-
if (metaFn.visited) setVisitedSteps(new Set(metaFn.visited));
|
|
341
|
-
if (metaFn.completed) setCompletedSteps(new Set(metaFn.completed));
|
|
342
|
-
}
|
|
343
|
-
const loadedData = {};
|
|
344
|
-
config2.steps.forEach((step) => {
|
|
345
|
-
const stepData = persistenceAdapter2.getStep(step.id);
|
|
346
|
-
if (stepData) {
|
|
347
|
-
Object.assign(loadedData, stepData);
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
if (Object.keys(loadedData).length > 0) {
|
|
351
|
-
const currentData = storeRef.current.getSnapshot().data;
|
|
352
|
-
const newData = { ...currentData, ...loadedData };
|
|
353
|
-
storeRef.current.update(newData);
|
|
354
|
-
}
|
|
355
|
-
setIsLoading(false);
|
|
356
|
-
}, []);
|
|
357
|
-
(0, import_react.useEffect)(() => {
|
|
358
|
-
hydrate();
|
|
359
|
-
}, [hydrate]);
|
|
360
|
-
const saveData = (0, import_react.useCallback)(
|
|
361
|
-
(mode, stepId, data) => {
|
|
362
|
-
const { stepsMap: stepsMap2, persistenceAdapter: persistenceAdapter2, persistenceMode: globalMode } = stateRef.current;
|
|
363
|
-
const stepConfig = stepsMap2.get(stepId);
|
|
364
|
-
const stepAdapter = stepConfig?.persistenceAdapter;
|
|
365
|
-
const stepMode = stepConfig?.persistenceMode;
|
|
366
|
-
const adapterToUse = stepAdapter || persistenceAdapter2;
|
|
367
|
-
const modeToUse = stepMode || globalMode;
|
|
368
|
-
if (mode === modeToUse || mode === "manual") {
|
|
369
|
-
adapterToUse.saveStep(stepId, data);
|
|
370
|
-
}
|
|
371
|
-
},
|
|
372
|
-
[]
|
|
373
|
-
);
|
|
374
|
-
const validationTimeoutRef = (0, import_react.useRef)(
|
|
375
|
-
null
|
|
376
|
-
);
|
|
377
|
-
const validateStep = (0, import_react.useCallback)(
|
|
378
|
-
async (stepId, data) => {
|
|
379
|
-
const { stepsMap: stepsMap2 } = stateRef.current;
|
|
380
|
-
const step = stepsMap2.get(stepId);
|
|
381
|
-
if (!step || !step.validationAdapter) {
|
|
382
|
-
return true;
|
|
383
|
-
}
|
|
384
|
-
const result = await step.validationAdapter.validate(data);
|
|
385
|
-
if (result.isValid) {
|
|
386
|
-
const changed = storeRef.current.setStepErrors(stepId, null);
|
|
387
|
-
if (changed) {
|
|
388
|
-
setAllErrorsState(storeRef.current.getSnapshot().errors);
|
|
389
|
-
setErrorSteps((prev) => {
|
|
390
|
-
const next = new Set(prev);
|
|
391
|
-
next.delete(stepId);
|
|
392
|
-
return next;
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return true;
|
|
396
|
-
} else {
|
|
397
|
-
storeRef.current.setStepErrors(stepId, result.errors || null);
|
|
398
|
-
setAllErrorsState(storeRef.current.getSnapshot().errors);
|
|
399
|
-
setErrorSteps((prev) => {
|
|
400
|
-
const next = new Set(prev);
|
|
401
|
-
next.add(stepId);
|
|
402
|
-
return next;
|
|
403
|
-
});
|
|
404
|
-
return false;
|
|
405
|
-
}
|
|
406
|
-
},
|
|
407
|
-
[]
|
|
408
|
-
);
|
|
409
|
-
const setStepData = (0, import_react.useCallback)(
|
|
410
|
-
(stepId, data) => {
|
|
411
|
-
const { persistenceMode: persistenceMode2 } = stateRef.current;
|
|
412
|
-
const prevData = storeRef.current.getSnapshot().data;
|
|
413
|
-
const newData = { ...prevData, ...data };
|
|
414
|
-
storeRef.current.update(newData);
|
|
415
|
-
const stepConfig = stateRef.current.stepsMap.get(stepId);
|
|
416
|
-
const effectiveMode = stepConfig?.persistenceMode || persistenceMode2;
|
|
417
|
-
if (effectiveMode === "onChange") {
|
|
418
|
-
saveData("onChange", stepId, newData);
|
|
419
|
-
}
|
|
420
|
-
},
|
|
421
|
-
[saveData]
|
|
422
|
-
);
|
|
423
|
-
const setData = (0, import_react.useCallback)(
|
|
424
|
-
(path, value, options) => {
|
|
425
|
-
const { persistenceMode: persistenceMode2, stepsMap: stepsMap2 } = stateRef.current;
|
|
426
|
-
const prevData = storeRef.current.getSnapshot().data;
|
|
427
|
-
const currentValue = getByPath(prevData, path);
|
|
428
|
-
if (currentValue === value) return;
|
|
429
|
-
const newData = setByPath(prevData, path, value);
|
|
430
|
-
storeRef.current.update(newData);
|
|
431
|
-
const activeStepId = stateRef.current.currentStepId;
|
|
432
|
-
const stepConfig = stepsMap2.get(activeStepId);
|
|
433
|
-
if (activeStepId) {
|
|
434
|
-
const wasDeleted = storeRef.current.deleteError(activeStepId, path);
|
|
435
|
-
if (wasDeleted) {
|
|
436
|
-
if (!storeRef.current.errorsMap.has(activeStepId)) {
|
|
437
|
-
setErrorSteps((prev) => {
|
|
438
|
-
const next = new Set(prev);
|
|
439
|
-
next.delete(activeStepId);
|
|
440
|
-
return next;
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
if (activeStepId && storeRef.current.getSnapshot().errors[activeStepId]) {
|
|
446
|
-
startTransition(() => {
|
|
447
|
-
setAllErrorsState(storeRef.current.getSnapshot().errors);
|
|
448
|
-
});
|
|
449
|
-
}
|
|
450
|
-
const { config: config2 } = stateRef.current;
|
|
451
|
-
const mode = stepConfig?.validationMode ?? config2.validationMode ?? "onStepChange";
|
|
452
|
-
if (mode === "onChange") {
|
|
453
|
-
if (options?.debounceValidation) {
|
|
454
|
-
if (validationTimeoutRef.current)
|
|
455
|
-
clearTimeout(validationTimeoutRef.current);
|
|
456
|
-
validationTimeoutRef.current = setTimeout(() => {
|
|
457
|
-
try {
|
|
458
|
-
if (activeStepId) {
|
|
459
|
-
validateStep(activeStepId, newData).catch((err) => {
|
|
460
|
-
console.error("[Wizard] Debounced validation failed:", err);
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
} catch (e) {
|
|
464
|
-
console.error("[Wizard] Error starting validation:", e);
|
|
465
|
-
}
|
|
466
|
-
}, options.debounceValidation);
|
|
467
|
-
} else {
|
|
468
|
-
if (activeStepId) validateStep(activeStepId, newData);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
const effectivePersistenceMode = stepConfig?.persistenceMode ?? persistenceMode2;
|
|
472
|
-
if (effectivePersistenceMode === "onChange" && activeStepId) {
|
|
473
|
-
saveData("onChange", activeStepId, newData);
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
[saveData, validateStep]
|
|
477
|
-
);
|
|
478
|
-
const updateData = (0, import_react.useCallback)(
|
|
479
|
-
(data, options) => {
|
|
480
|
-
const { config: config2 } = stateRef.current;
|
|
481
|
-
const prevData = storeRef.current.getSnapshot().data;
|
|
482
|
-
const newData = options?.replace ? data : { ...prevData, ...data };
|
|
483
|
-
storeRef.current.update(newData);
|
|
484
|
-
if (options?.persist) {
|
|
485
|
-
config2.steps.forEach((step) => {
|
|
486
|
-
saveData("manual", step.id, newData);
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
},
|
|
490
|
-
[saveData]
|
|
491
|
-
);
|
|
492
|
-
const getData = (0, import_react.useCallback)((path, defaultValue) => {
|
|
493
|
-
return getByPath(storeRef.current.getSnapshot().data, path, defaultValue);
|
|
494
|
-
}, []);
|
|
495
|
-
const handleStepChange = (0, import_react.useCallback)(
|
|
496
|
-
(field, value) => {
|
|
497
|
-
const { currentStepId: currentStepId2 } = stateRef.current;
|
|
498
|
-
if (!currentStepId2) return;
|
|
499
|
-
setData(field, value);
|
|
500
|
-
},
|
|
501
|
-
[setData]
|
|
502
|
-
);
|
|
503
|
-
const validateAll = (0, import_react.useCallback)(async () => {
|
|
504
|
-
const { activeSteps: activeSteps2 } = stateRef.current;
|
|
505
|
-
const currentData = storeRef.current.getSnapshot().data;
|
|
506
|
-
const validationResults = await Promise.all(
|
|
507
|
-
activeSteps2.map((step) => validateStep(step.id, currentData))
|
|
508
|
-
);
|
|
509
|
-
const isValid = validationResults.every(Boolean);
|
|
510
|
-
const finalErrors = storeRef.current.getSnapshot().errors;
|
|
511
|
-
return { isValid, errors: finalErrors };
|
|
512
|
-
}, [validateStep]);
|
|
513
|
-
const goToStep = (0, import_react.useCallback)(
|
|
514
|
-
async (stepId) => {
|
|
515
|
-
const {
|
|
516
|
-
activeStepsIndexMap: activeStepsIndexMap2,
|
|
517
|
-
currentStepId: currentStepId2,
|
|
518
|
-
config: config2,
|
|
519
|
-
persistenceMode: persistenceMode2,
|
|
520
|
-
visitedSteps: visitedSteps2,
|
|
521
|
-
completedSteps: completedSteps2,
|
|
522
|
-
persistenceAdapter: persistenceAdapter2,
|
|
523
|
-
stepsMap: stepsMap2
|
|
524
|
-
} = stateRef.current;
|
|
525
|
-
const targetIndex = activeStepsIndexMap2.get(stepId) ?? -1;
|
|
526
|
-
if (targetIndex === -1) return false;
|
|
527
|
-
const currentData = storeRef.current.getSnapshot().data;
|
|
528
|
-
const currentStepIndex2 = activeStepsIndexMap2.get(currentStepId2) ?? -1;
|
|
529
|
-
const currentStep2 = stepsMap2.get(currentStepId2);
|
|
530
|
-
if (targetIndex > currentStepIndex2) {
|
|
531
|
-
const shouldValidate = currentStep2?.autoValidate ?? config2.autoValidate ?? false;
|
|
532
|
-
if (shouldValidate && currentStepId2) {
|
|
533
|
-
const isValid = await validateStep(currentStepId2, currentData);
|
|
534
|
-
if (!isValid) return false;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
if (currentStep2 && currentStepId2) {
|
|
538
|
-
const effectivePersistenceMode = currentStep2.persistenceMode ?? persistenceMode2;
|
|
539
|
-
if (effectivePersistenceMode === "onStepChange") {
|
|
540
|
-
saveData("onStepChange", currentStepId2, currentData);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
const nextVisited = new Set(visitedSteps2);
|
|
544
|
-
if (currentStepId2) nextVisited.add(currentStepId2);
|
|
545
|
-
setVisitedSteps(nextVisited);
|
|
546
|
-
setCurrentStepId(stepId);
|
|
547
|
-
if (persistenceMode2 !== "manual") {
|
|
548
|
-
persistenceAdapter2.saveStep(META_KEY, {
|
|
549
|
-
currentStepId: stepId,
|
|
550
|
-
visited: Array.from(nextVisited),
|
|
551
|
-
completed: Array.from(completedSteps2)
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
if (config2.onStepChange) {
|
|
555
|
-
config2.onStepChange(currentStepId2 || null, stepId, currentData);
|
|
556
|
-
}
|
|
557
|
-
window.scrollTo(0, 0);
|
|
558
|
-
return true;
|
|
559
|
-
},
|
|
560
|
-
[saveData, validateStep]
|
|
561
|
-
);
|
|
562
|
-
const goToNextStep = (0, import_react.useCallback)(async () => {
|
|
563
|
-
const { activeSteps: activeSteps2, activeStepsIndexMap: activeStepsIndexMap2, currentStepId: currentStepId2, completedSteps: completedSteps2, persistenceMode: persistenceMode2 } = stateRef.current;
|
|
564
|
-
const currentStepIndex2 = activeStepsIndexMap2.get(currentStepId2) ?? -1;
|
|
565
|
-
if (currentStepIndex2 === -1 || currentStepIndex2 === activeSteps2.length - 1) return;
|
|
566
|
-
const nextStep = activeSteps2[currentStepIndex2 + 1];
|
|
567
|
-
if (nextStep) {
|
|
568
|
-
const success = await goToStep(nextStep.id);
|
|
569
|
-
if (success) {
|
|
570
|
-
const nextCompleted = new Set(completedSteps2).add(currentStepId2);
|
|
571
|
-
setCompletedSteps(nextCompleted);
|
|
572
|
-
if (persistenceMode2 !== "manual") {
|
|
573
|
-
persistenceAdapter.saveStep(META_KEY, {
|
|
574
|
-
currentStepId: nextStep.id,
|
|
575
|
-
visited: Array.from(new Set(visitedSteps).add(currentStepId2)),
|
|
576
|
-
completed: Array.from(nextCompleted)
|
|
577
|
-
});
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
}, [goToStep]);
|
|
582
|
-
const goToPrevStep = (0, import_react.useCallback)(() => {
|
|
583
|
-
const { activeSteps: activeSteps2, activeStepsIndexMap: activeStepsIndexMap2, currentStepId: currentStepId2 } = stateRef.current;
|
|
584
|
-
const currentStepIndex2 = activeStepsIndexMap2.get(currentStepId2) ?? -1;
|
|
585
|
-
if (currentStepIndex2 <= 0) return;
|
|
586
|
-
const prevStep = activeSteps2[currentStepIndex2 - 1];
|
|
587
|
-
if (prevStep) {
|
|
588
|
-
goToStep(prevStep.id);
|
|
589
|
-
}
|
|
590
|
-
}, [goToStep]);
|
|
591
|
-
const clearStorage = (0, import_react.useCallback)(() => {
|
|
592
|
-
stateRef.current.persistenceAdapter.clear();
|
|
593
|
-
}, []);
|
|
594
|
-
const save = (0, import_react.useCallback)(
|
|
595
|
-
(stepIds) => {
|
|
596
|
-
const { config: config2, currentStepId: currentStepId2 } = stateRef.current;
|
|
597
|
-
const data = storeRef.current.getSnapshot().data;
|
|
598
|
-
if (stepIds === true) {
|
|
599
|
-
config2.steps.forEach((step) => {
|
|
600
|
-
saveData("manual", step.id, data);
|
|
601
|
-
});
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
if (!stepIds) {
|
|
605
|
-
if (currentStepId2) {
|
|
606
|
-
saveData("manual", currentStepId2, data);
|
|
607
|
-
}
|
|
608
|
-
return;
|
|
609
|
-
}
|
|
610
|
-
const ids = Array.isArray(stepIds) ? stepIds : [stepIds];
|
|
611
|
-
ids.forEach((id) => {
|
|
612
|
-
saveData("manual", id, data);
|
|
613
|
-
});
|
|
614
|
-
},
|
|
615
|
-
[saveData]
|
|
616
|
-
);
|
|
617
|
-
const stateValue = (0, import_react.useMemo)(
|
|
618
|
-
() => ({
|
|
619
|
-
currentStep,
|
|
620
|
-
currentStepIndex,
|
|
621
|
-
isFirstStep,
|
|
622
|
-
isLastStep,
|
|
623
|
-
isLoading,
|
|
624
|
-
isPending,
|
|
625
|
-
activeSteps,
|
|
626
|
-
visitedSteps,
|
|
627
|
-
completedSteps,
|
|
628
|
-
errorSteps,
|
|
629
|
-
store: storeRef.current
|
|
630
|
-
}),
|
|
631
|
-
[
|
|
632
|
-
currentStep,
|
|
633
|
-
currentStepIndex,
|
|
634
|
-
isFirstStep,
|
|
635
|
-
isLastStep,
|
|
636
|
-
isLoading,
|
|
637
|
-
isPending,
|
|
638
|
-
activeSteps,
|
|
639
|
-
visitedSteps,
|
|
640
|
-
completedSteps,
|
|
641
|
-
errorSteps
|
|
642
|
-
]
|
|
643
|
-
);
|
|
644
|
-
const actionsValue = (0, import_react.useMemo)(
|
|
645
|
-
() => ({
|
|
646
|
-
goToNextStep,
|
|
647
|
-
goToPrevStep,
|
|
648
|
-
goToStep,
|
|
649
|
-
setStepData,
|
|
650
|
-
handleStepChange,
|
|
651
|
-
validateStep: (sid) => validateStep(sid, storeRef.current.getSnapshot().data),
|
|
652
|
-
validateAll,
|
|
653
|
-
save,
|
|
654
|
-
clearStorage,
|
|
655
|
-
setData,
|
|
656
|
-
updateData,
|
|
657
|
-
getData
|
|
658
|
-
}),
|
|
659
|
-
[
|
|
660
|
-
goToNextStep,
|
|
661
|
-
goToPrevStep,
|
|
662
|
-
goToStep,
|
|
663
|
-
setStepData,
|
|
664
|
-
handleStepChange,
|
|
665
|
-
validateStep,
|
|
666
|
-
validateAll,
|
|
667
|
-
save,
|
|
668
|
-
clearStorage,
|
|
669
|
-
setData,
|
|
670
|
-
updateData,
|
|
671
|
-
getData
|
|
672
|
-
]
|
|
673
|
-
);
|
|
674
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WizardStateContext.Provider, { value: stateValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WizardActionsContext.Provider, { value: actionsValue, children }) });
|
|
675
|
-
}
|
|
676
|
-
function useWizardState() {
|
|
677
|
-
const context = (0, import_react.useContext)(WizardStateContext);
|
|
678
|
-
if (!context) {
|
|
679
|
-
throw new Error("useWizardState must be used within a WizardProvider");
|
|
680
|
-
}
|
|
681
|
-
return context;
|
|
682
|
-
}
|
|
683
|
-
function useWizardValue(path, options) {
|
|
684
|
-
const { store } = useWizardState();
|
|
685
|
-
const lastStateRef = (0, import_react.useRef)(null);
|
|
686
|
-
const lastValueRef = (0, import_react.useRef)(null);
|
|
687
|
-
const isEqual = options?.isEqual || Object.is;
|
|
688
|
-
const getSnapshot = (0, import_react.useCallback)(() => {
|
|
689
|
-
const fullState = store.getSnapshot();
|
|
690
|
-
const data = fullState.data;
|
|
691
|
-
if (data === lastStateRef.current) {
|
|
692
|
-
return lastValueRef.current;
|
|
693
|
-
}
|
|
694
|
-
const value = getByPath(data, path);
|
|
695
|
-
if (lastValueRef.current !== void 0 && isEqual(lastValueRef.current, value)) {
|
|
696
|
-
lastStateRef.current = data;
|
|
697
|
-
return lastValueRef.current;
|
|
698
|
-
}
|
|
699
|
-
lastStateRef.current = data;
|
|
700
|
-
lastValueRef.current = value;
|
|
701
|
-
return value;
|
|
702
|
-
}, [store, path, isEqual]);
|
|
703
|
-
return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
|
|
704
|
-
}
|
|
705
|
-
function useWizardError(path) {
|
|
706
|
-
const { store } = useWizardState();
|
|
707
|
-
const lastStateRef = (0, import_react.useRef)(null);
|
|
708
|
-
const lastValueRef = (0, import_react.useRef)(null);
|
|
709
|
-
const getSnapshot = (0, import_react.useCallback)(() => {
|
|
710
|
-
const fullState = store.getSnapshot();
|
|
711
|
-
const errors = fullState.errors;
|
|
712
|
-
if (errors === lastStateRef.current) {
|
|
713
|
-
return lastValueRef.current;
|
|
714
|
-
}
|
|
715
|
-
let foundError;
|
|
716
|
-
Object.values(errors).forEach((stepErrors) => {
|
|
717
|
-
const typedStepErrors = stepErrors;
|
|
718
|
-
if (typedStepErrors[path]) foundError = typedStepErrors[path];
|
|
719
|
-
});
|
|
720
|
-
lastStateRef.current = errors;
|
|
721
|
-
lastValueRef.current = foundError;
|
|
722
|
-
return foundError;
|
|
723
|
-
}, [store, path]);
|
|
724
|
-
return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
|
|
725
|
-
}
|
|
726
|
-
function useWizardSelector(selector, options) {
|
|
727
|
-
const { store } = useWizardState();
|
|
728
|
-
const lastStateRef = (0, import_react.useRef)(null);
|
|
729
|
-
const lastResultRef = (0, import_react.useRef)(null);
|
|
730
|
-
const isEqual = options?.isEqual || Object.is;
|
|
731
|
-
const getSnapshot = (0, import_react.useCallback)(() => {
|
|
732
|
-
const fullState = store.getSnapshot();
|
|
733
|
-
if (fullState === lastStateRef.current) {
|
|
734
|
-
return lastResultRef.current;
|
|
735
|
-
}
|
|
736
|
-
const result = selector(fullState.data);
|
|
737
|
-
if (lastResultRef.current !== null && isEqual(lastResultRef.current, result)) {
|
|
738
|
-
lastStateRef.current = fullState;
|
|
739
|
-
return lastResultRef.current;
|
|
740
|
-
}
|
|
741
|
-
lastStateRef.current = fullState;
|
|
742
|
-
lastResultRef.current = result;
|
|
743
|
-
return result;
|
|
744
|
-
}, [store, selector, isEqual]);
|
|
745
|
-
return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot);
|
|
746
|
-
}
|
|
747
|
-
function useWizardActions() {
|
|
748
|
-
const context = (0, import_react.useContext)(WizardActionsContext);
|
|
749
|
-
if (!context) {
|
|
750
|
-
throw new Error("useWizardActions must be used within a WizardProvider");
|
|
751
|
-
}
|
|
752
|
-
return context;
|
|
753
|
-
}
|
|
754
|
-
function useWizardContext() {
|
|
755
|
-
const state = useWizardState();
|
|
756
|
-
const actions = useWizardActions();
|
|
757
|
-
const wizardData = useWizardSelector((s) => s);
|
|
758
|
-
const allErrors = (0, import_react.useSyncExternalStore)(state.store.subscribe, () => state.store.getSnapshot().errors);
|
|
759
|
-
return (0, import_react.useMemo)(
|
|
760
|
-
() => ({
|
|
761
|
-
...state,
|
|
762
|
-
...actions,
|
|
763
|
-
wizardData,
|
|
764
|
-
allErrors
|
|
765
|
-
}),
|
|
766
|
-
[state, actions, wizardData, allErrors]
|
|
767
|
-
);
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
// src/components/WizardStepRenderer.tsx
|
|
771
|
-
var import_react2 = require("react");
|
|
772
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
773
|
-
var WizardStepRenderer = ({
|
|
774
|
-
wrapper: Wrapper
|
|
775
|
-
}) => {
|
|
776
|
-
const { currentStep } = useWizardContext();
|
|
777
|
-
const StepComponent = (0, import_react2.useMemo)(() => {
|
|
778
|
-
if (!currentStep?.component) return null;
|
|
779
|
-
return currentStep.component;
|
|
780
|
-
}, [currentStep]);
|
|
781
|
-
if (!currentStep || !StepComponent) {
|
|
782
|
-
return null;
|
|
783
|
-
}
|
|
784
|
-
const content = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StepComponent, {});
|
|
785
|
-
if (Wrapper) {
|
|
786
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Wrapper, { children: content }, currentStep.id);
|
|
787
|
-
}
|
|
788
|
-
return content;
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
// src/hooks/useWizard.ts
|
|
792
|
-
var useWizard = () => {
|
|
793
|
-
return useWizardContext();
|
|
794
|
-
};
|
|
795
|
-
|
|
796
|
-
// src/factory.tsx
|
|
797
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
798
|
-
function createWizardFactory() {
|
|
799
|
-
const WizardProvider2 = ({
|
|
800
|
-
config,
|
|
801
|
-
initialData,
|
|
802
|
-
children
|
|
803
|
-
}) => {
|
|
804
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
805
|
-
WizardProvider,
|
|
806
|
-
{
|
|
807
|
-
config,
|
|
808
|
-
initialData,
|
|
809
|
-
children
|
|
810
|
-
}
|
|
811
|
-
);
|
|
812
|
-
};
|
|
813
|
-
const useWizard2 = () => {
|
|
814
|
-
return useWizard();
|
|
815
|
-
};
|
|
816
|
-
const useWizardContext2 = () => {
|
|
817
|
-
return useWizardContext();
|
|
818
|
-
};
|
|
819
|
-
const useWizardValue2 = (path, options) => {
|
|
820
|
-
return useWizardValue(path, options);
|
|
821
|
-
};
|
|
822
|
-
const useWizardSelector2 = (selector, options) => {
|
|
823
|
-
return useWizardSelector(selector, options);
|
|
824
|
-
};
|
|
825
|
-
const useWizardError2 = (path) => {
|
|
826
|
-
return useWizardError(path);
|
|
827
|
-
};
|
|
828
|
-
const useWizardActions2 = () => {
|
|
829
|
-
return useWizardActions();
|
|
830
|
-
};
|
|
831
|
-
const useWizardState2 = () => {
|
|
832
|
-
return useWizardState();
|
|
833
|
-
};
|
|
834
|
-
const createStep = (config) => config;
|
|
835
|
-
return {
|
|
836
|
-
WizardProvider: WizardProvider2,
|
|
837
|
-
useWizard: useWizard2,
|
|
838
|
-
useWizardContext: useWizardContext2,
|
|
839
|
-
useWizardValue: useWizardValue2,
|
|
840
|
-
useWizardSelector: useWizardSelector2,
|
|
841
|
-
useWizardError: useWizardError2,
|
|
842
|
-
useWizardActions: useWizardActions2,
|
|
843
|
-
useWizardState: useWizardState2,
|
|
844
|
-
createStep
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
// src/adapters/persistence/LocalStorageAdapter.ts
|
|
849
|
-
var LocalStorageAdapter = class {
|
|
850
|
-
constructor(prefix = "wizard_") {
|
|
851
|
-
__publicField(this, "prefix");
|
|
852
|
-
this.prefix = prefix;
|
|
853
|
-
}
|
|
854
|
-
getKey(stepId) {
|
|
855
|
-
return `${this.prefix}${stepId}`;
|
|
856
|
-
}
|
|
857
|
-
saveStep(stepId, data) {
|
|
858
|
-
if (typeof window === "undefined") return;
|
|
859
|
-
try {
|
|
860
|
-
localStorage.setItem(this.getKey(stepId), JSON.stringify(data));
|
|
861
|
-
} catch (error) {
|
|
862
|
-
console.warn("LocalStorageAdapter: Failed to save step", error);
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
getStep(stepId) {
|
|
866
|
-
if (typeof window === "undefined") return void 0;
|
|
867
|
-
try {
|
|
868
|
-
const item = localStorage.getItem(this.getKey(stepId));
|
|
869
|
-
return item ? JSON.parse(item) : void 0;
|
|
870
|
-
} catch (error) {
|
|
871
|
-
console.warn("LocalStorageAdapter: Failed to get step", error);
|
|
872
|
-
return void 0;
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
clear() {
|
|
876
|
-
if (typeof window === "undefined") return;
|
|
877
|
-
Object.keys(localStorage).forEach((key) => {
|
|
878
|
-
if (key.startsWith(this.prefix)) {
|
|
879
|
-
localStorage.removeItem(key);
|
|
880
|
-
}
|
|
881
|
-
});
|
|
882
|
-
}
|
|
883
|
-
};
|
|
884
|
-
|
|
885
|
-
// src/adapters/validation/ZodAdapter.ts
|
|
886
|
-
var ZodAdapter = class {
|
|
887
|
-
constructor(schema) {
|
|
888
|
-
__publicField(this, "schema");
|
|
889
|
-
this.schema = schema;
|
|
890
|
-
}
|
|
891
|
-
async validate(data) {
|
|
892
|
-
const result = await this.schema.safeParseAsync(data);
|
|
893
|
-
if (result.success) {
|
|
894
|
-
return { isValid: true };
|
|
895
|
-
}
|
|
896
|
-
const errors = {};
|
|
897
|
-
if (result.error) {
|
|
898
|
-
result.error.issues.forEach((err) => {
|
|
899
|
-
const path = err.path.join(".");
|
|
900
|
-
errors[path] = err.message;
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
return { isValid: false, errors };
|
|
904
|
-
}
|
|
905
|
-
};
|
|
906
|
-
|
|
907
|
-
// src/adapters/validation/YupAdapter.ts
|
|
908
|
-
var YupAdapter = class {
|
|
909
|
-
constructor(schema) {
|
|
910
|
-
__publicField(this, "schema");
|
|
911
|
-
this.schema = schema;
|
|
912
|
-
}
|
|
913
|
-
async validate(data) {
|
|
914
|
-
try {
|
|
915
|
-
await this.schema.validate(data, { abortEarly: false });
|
|
916
|
-
return { isValid: true };
|
|
917
|
-
} catch (err) {
|
|
918
|
-
if (err && typeof err === "object" && "inner" in err) {
|
|
919
|
-
const yupError = err;
|
|
920
|
-
const errors = {};
|
|
921
|
-
yupError.inner.forEach((error) => {
|
|
922
|
-
if (error.path) {
|
|
923
|
-
errors[error.path] = error.message;
|
|
924
|
-
}
|
|
925
|
-
});
|
|
926
|
-
return { isValid: false, errors };
|
|
927
|
-
}
|
|
928
|
-
throw err;
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
};
|
|
932
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
933
|
-
0 && (module.exports = {
|
|
934
|
-
LocalStorageAdapter,
|
|
935
|
-
MemoryAdapter,
|
|
936
|
-
WizardProvider,
|
|
937
|
-
WizardStepRenderer,
|
|
938
|
-
WizardStore,
|
|
939
|
-
YupAdapter,
|
|
940
|
-
ZodAdapter,
|
|
941
|
-
createWizardFactory,
|
|
942
|
-
getByPath,
|
|
943
|
-
setByPath,
|
|
944
|
-
shallowEqual,
|
|
945
|
-
toPath,
|
|
946
|
-
useWizard,
|
|
947
|
-
useWizardActions,
|
|
948
|
-
useWizardContext,
|
|
949
|
-
useWizardError,
|
|
950
|
-
useWizardSelector,
|
|
951
|
-
useWizardState,
|
|
952
|
-
useWizardValue
|
|
953
|
-
});
|
|
954
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
"use strict";var q=Object.defineProperty;var De=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Ve=Object.prototype.hasOwnProperty;var Be=(a,e,t)=>e in a?q(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var Le=(a,e)=>{for(var t in e)q(a,t,{get:e[t],enumerable:!0})},Ne=(a,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Oe(e))!Ve.call(a,s)&&s!==t&&q(a,s,{get:()=>e[s],enumerable:!(i=De(e,s))||i.enumerable});return a};var Fe=a=>Ne(q({},"__esModule",{value:!0}),a);var I=(a,e,t)=>Be(a,typeof e!="symbol"?e+"":e,t);var Ye={};Le(Ye,{LocalStorageAdapter:()=>pe,MemoryAdapter:()=>N,WizardDevTools:()=>Re,WizardProvider:()=>ie,WizardStepRenderer:()=>ze,YupAdapter:()=>ue,ZodAdapter:()=>le,createWizardFactory:()=>We,devToolsMiddleware:()=>Pe,getByPath:()=>C,loggerMiddleware:()=>Ae,setByPath:()=>V,shallowEqual:()=>je,toPath:()=>ne,useWizard:()=>ce,useWizardActions:()=>X,useWizardContext:()=>P,useWizardError:()=>de,useWizardSelector:()=>F,useWizardState:()=>J,useWizardValue:()=>oe});module.exports=Fe(Ye);var d=require("react");var ae=new Map;function ne(a){if(!a)return[];if(ae.has(a))return ae.get(a);let e;return a.includes("[")?e=a.replace(/\[(\d+)\]/g,".$1").split(".").filter(Boolean):e=a.split(".").filter(Boolean),ae.set(a,e),e}function C(a,e,t){if(!e||a===void 0||a===null)return t??a;if(!e.includes(".")&&!e.includes("[")){let l=a[e];return l!==void 0?l:t}let i=ne(e),s=a;for(let l=0;l<i.length;l++){if(s==null)return t;s=s[i[l]]}return s!==void 0?s:t}function V(a,e,t){if(!e)return t;if(!e.includes(".")&&!e.includes("[")){if(Array.isArray(a)){let u=[...a];return u[e]=t,u}return{...a,[e]:t}}let i=ne(e);if(i.length===0)return t;let s=Array.isArray(a)?[...a]:{...a},l=s;for(let u=0;u<i.length-1;u++){let h=i[u],x=i[u+1],S=l[h],m;S&&typeof S=="object"?m=Array.isArray(S)?[...S]:{...S}:m=/^\d+$/.test(x)?[]:{},l[h]=m,l=m}let r=i[i.length-1];return l[r]=t,s}function je(a,e){if(Object.is(a,e))return!0;if(typeof a!="object"||a===null||typeof e!="object"||e===null)return!1;let t=Object.keys(a),i=Object.keys(e);if(t.length!==i.length)return!1;for(let s=0;s<t.length;s++){let l=t[s];if(!Object.prototype.hasOwnProperty.call(e,l)||!Object.is(a[l],e[l]))return!1}return!0}var K=class{constructor(e,t=[]){I(this,"initialData");I(this,"dirtyFields",new Set);I(this,"state");I(this,"listeners",new Set);I(this,"actionListeners",new Set);I(this,"errorsMap",new Map);I(this,"middlewareChain");I(this,"getSnapshot",()=>this.state);I(this,"subscribe",e=>(this.listeners.add(e),()=>this.listeners.delete(e)));this.initialData=JSON.parse(JSON.stringify(e)),this.state={data:e,errors:{},isDirty:!1,dirtyFields:this.dirtyFields,visitedSteps:new Set,completedSteps:new Set,errorSteps:new Set,currentStep:null,currentStepId:"",currentStepIndex:0,isFirstStep:!0,isLastStep:!1,isLoading:!0,isPending:!1,isBusy:!1,activeSteps:[],history:[],busySteps:new Set,progress:0,activeStepsCount:0,breadcrumbs:[],config:{}},this.middlewareChain=this.setupMiddlewares(t)}subscribeToActions(e){return this.actionListeners.add(e),()=>this.actionListeners.delete(e)}notifyActions(e){this.actionListeners.forEach(t=>t(e))}setupMiddlewares(e){let t={getState:()=>this.state.data,getSnapshot:()=>this.getSnapshot(),dispatch:s=>this.dispatch(s)};return e.map(s=>s(t)).reduceRight((s,l)=>l(s),this.internalDispatch.bind(this))}dispatch(e){this.middlewareChain(e)}internalDispatch(e){switch(this.notifyActions(e),e.type){case"INIT":this.initialData=JSON.parse(JSON.stringify(e.payload.data));let t=e.payload.config.steps.filter(i=>!i.condition);this.state={...this.state,data:e.payload.data,config:e.payload.config,activeSteps:t,activeStepsCount:t.length},this.notify();break;case"SET_CURRENT_STEP_ID":this.state={...this.state,currentStepId:e.payload.stepId},this.notify();break;case"SET_HISTORY":this.state={...this.state,history:e.payload.history},this.notify();break;case"SET_ACTIVE_STEPS":this.state={...this.state,activeSteps:e.payload.steps,activeStepsCount:e.payload.steps.length},this.notify();break;case"SET_DATA":this.updateDataByPath(e.payload.path,e.payload.value,e.payload.options);break;case"UPDATE_DATA":this.updateBulkData(e.payload.data,e.payload.options);break;case"GO_TO_STEP":break;case"VALIDATE_START":break;case"VALIDATE_END":break;case"SET_STEP_ERRORS":this.setStepErrors(e.payload.stepId,e.payload.errors);break;case"RESET":this.setInitialData(e.payload.data);break;case"SET_ERROR_STEPS":this.state={...this.state,errorSteps:e.payload.steps};break}this.syncDerivedState(),this.notify()}updateDataByPath(e,t,i){let s=V(this.state.data,e,t);s!==this.state.data&&this.update(s,e)}updateBulkData(e,t){let i;t?.replace?i=e:(i=JSON.parse(JSON.stringify(this.state.data)),Object.assign(i,e)),this.update(i,Object.keys(e))}update(e,t){t&&(Array.isArray(t)?t:[t]).forEach(s=>{let l=C(this.initialData,s),r=C(e,s);JSON.stringify(l)!==JSON.stringify(r)?this.dirtyFields.add(s):this.dirtyFields.delete(s)}),this.state={...this.state,data:e,isDirty:this.dirtyFields.size>0,dirtyFields:new Set(this.dirtyFields)},this.notify()}updateMeta(e){this.state={...this.state,...e},this.syncDerivedState(),this.notify()}syncDerivedState(){let{activeSteps:e,currentStepId:t,visitedSteps:i,completedSteps:s,errorSteps:l}=this.state,r=Math.max(0,e.findIndex(x=>x.id===t)),u=e[r]||null,h=e.map(x=>{let S="upcoming";return x.id===t?S="current":l.has(x.id)?S="error":s.has(x.id)?S="completed":i.has(x.id)&&(S="visited"),{id:x.id,label:x.label,status:S}});this.state={...this.state,currentStep:u,currentStepIndex:r,isFirstStep:r===0,isLastStep:e.length>0&&r===e.length-1,progress:e.length>0?Math.round((r+1)/e.length*100):0,breadcrumbs:h}}setInitialData(e){this.initialData=JSON.parse(JSON.stringify(e)),this.dirtyFields.clear(),this.state={...this.state,data:e,isDirty:!1,dirtyFields:new Set},this.notify()}syncErrors(){let e={};for(let[t,i]of this.errorsMap.entries())i.size>0&&(e[t]=Object.fromEntries(i));this.state={...this.state,errors:e},this.notify()}updateErrors(e){this.errorsMap.clear();for(let[t,i]of Object.entries(e)){let s=new Map;for(let[l,r]of Object.entries(i))s.set(l,r);s.size>0&&this.errorsMap.set(t,s)}this.state={...this.state,errors:e},this.notify()}setStepErrors(e,t){if(!t||Object.keys(t).length===0)return this.errorsMap.has(e)?(this.errorsMap.delete(e),this.syncErrors(),!0):!1;let i=new Map;for(let[s,l]of Object.entries(t))i.set(s,l);return this.errorsMap.set(e,i),this.syncErrors(),!0}deleteError(e,t){let i=this.errorsMap.get(e);return i&&i.has(t)?(i.delete(t),i.size===0&&this.errorsMap.delete(e),this.syncErrors(),!0):!1}notify(){this.listeners.forEach(e=>e())}};var N=class{constructor(){I(this,"storage",{})}saveStep(e,t){this.storage[e]=t}getStep(e){return this.storage[e]}clear(){this.storage={}}};var $=require("react/jsx-runtime"),be=(0,d.createContext)(void 0),Ee=(0,d.createContext)(void 0),j=(0,d.createContext)(void 0);function ie({config:a,initialData:e,initialStepId:t,children:i}){let[s,l]=(0,d.useState)(a),r=(0,d.useRef)(new K(e||{},a.middlewares)),u=(0,d.useRef)(!1),h=(0,d.useMemo)(()=>s.persistence?.adapter||new N,[s.persistence?.adapter]),x=s.persistence?.mode||"onStepChange",S="__wizzard_meta__",m=(0,d.useSyncExternalStore)(n=>r.current.subscribe(n),()=>r.current.getSnapshot()),{activeSteps:b,currentStepId:H,history:Se,visitedSteps:fe,completedSteps:ye,data:ge,errors:{}}=m,M=(0,d.useMemo)(()=>{let n=new Map;return s.steps.forEach(p=>n.set(p.id,p)),n},[s.steps]);(0,d.useEffect)(()=>{l(a)},[a]);let he=(0,d.useMemo)(()=>{let n=new Map;return b.forEach((p,o)=>n.set(p.id,o)),n},[b]),W=(0,d.useRef)({config:s,stepsMap:M,activeSteps:b,activeStepsIndexMap:he,visitedSteps:fe,completedSteps:ye,persistenceMode:x,persistenceAdapter:h,currentStepId:H,history:Se});(0,d.useEffect)(()=>{W.current={config:s,stepsMap:M,activeSteps:b,activeStepsIndexMap:he,visitedSteps:fe,completedSteps:ye,persistenceMode:x,persistenceAdapter:h,currentStepId:H,history:Se}});let D=(0,d.useCallback)((n,p)=>{s.analytics?.onEvent(n,p)},[s.analytics]),z=(0,d.useCallback)((n,p,o)=>{let{stepsMap:y,persistenceAdapter:f,persistenceMode:g}=W.current,E=y.get(p),v=E?.persistenceAdapter||f,T=E?.persistenceMode||g;(n===T||n==="manual")&&v.saveStep(p,o)},[]),_=(0,d.useCallback)(async n=>{r.current.updateMeta({isBusy:!0});try{return(await Promise.all(s.steps.map(async o=>{if(!o.condition)return{step:o,ok:!0};let y=new Set(r.current.getSnapshot().busySteps);y.add(o.id),r.current.updateMeta({busySteps:y,isBusy:!0});try{let f=o.condition(n||{},r.current.getSnapshot()),g=f instanceof Promise?await f:f;return{step:o,ok:g}}catch(f){return console.error(`[Wizard] Condition failed for ${o.id}:`,f),{step:o,ok:!1}}finally{let f=r.current.getSnapshot(),g=new Set(f.busySteps);g.delete(o.id),r.current.updateMeta({busySteps:g,isBusy:g.size>0})}}))).filter(o=>o.ok).map(o=>o.step)}finally{r.current.getSnapshot().busySteps.size===0&&r.current.updateMeta({isBusy:!1})}},[s.steps]),w=(0,d.useCallback)(async(n,p)=>{let o=M.get(n);if(!o||!o.validationAdapter)return!0;r.current.dispatch({type:"VALIDATE_START",payload:{stepId:n}});let y=new Set(r.current.getSnapshot().busySteps);y.add(n),r.current.updateMeta({busySteps:y,isBusy:!0});try{let f=await o.validationAdapter.validate(p);if(f.isValid){r.current.setStepErrors(n,null);let g=new Set(r.current.getSnapshot().errorSteps);return g.delete(n),r.current.dispatch({type:"SET_ERROR_STEPS",payload:{steps:g}}),!0}else{r.current.setStepErrors(n,f.errors||null),D("validation_error",{stepId:n,errors:f.errors,timestamp:Date.now()});let g=new Set(r.current.getSnapshot().errorSteps);return g.add(n),r.current.dispatch({type:"SET_ERROR_STEPS",payload:{steps:g}}),!1}}finally{let f=new Set(r.current.getSnapshot().busySteps);f.delete(n),r.current.updateMeta({busySteps:f,isBusy:f.size>0}),r.current.dispatch({type:"VALIDATE_END",payload:{stepId:n,result:{isValid:!0}}})}},[M,D]),O=(0,d.useCallback)(async(n,p)=>{let{currentStepId:o,config:y,persistenceMode:f,persistenceAdapter:g,stepsMap:E}=W.current,v=r.current.getSnapshot().data,T=y.steps,R=T.findIndex(A=>A.id===o),L=T.findIndex(A=>A.id===n);if(L>R&&o){let A=E.get(o);if((A?.autoValidate??y.autoValidate??!!A?.validationAdapter)&&!await w(o,v))return!1}r.current.updateMeta({isBusy:!0});try{if(!(p||await _(v)).find(se=>se.id===n))return!1;let U=E.get(o);if(U?.beforeLeave){let se=r.current.getSnapshot(),Me=L>R?"next":"prev";if(await U.beforeLeave(v,Me,se)===!1)return!1}o&&(U?.persistenceMode||f)==="onStepChange"&&z("onStepChange",o,v);let te=r.current.getSnapshot(),re=new Set(te.visitedSteps);o&&re.add(o),r.current.dispatch({type:"SET_VISITED_STEPS",payload:{steps:re}}),r.current.dispatch({type:"SET_CURRENT_STEP_ID",payload:{stepId:n}});let ve=[...te.history,n];return r.current.dispatch({type:"SET_HISTORY",payload:{history:ve}}),f!=="manual"&&g.saveStep(S,{currentStepId:n,visited:Array.from(re),completed:Array.from(te.completedSteps),history:ve}),y.onStepChange&&y.onStepChange(o||null,n,v),D("step_change",{from:o||null,to:n,timestamp:Date.now()}),window.scrollTo(0,0),!0}finally{r.current.updateMeta({isBusy:!1})}},[_,w,z,D]),Te=(0,d.useCallback)(async()=>{let{currentStepId:n}=W.current;if(!n)return;let p=r.current.getSnapshot().data,o=M.get(n);if((o?.autoValidate??s.autoValidate??!!o?.validationAdapter)&&!await w(n,p))return;let f=await _(p),g=f.findIndex(E=>E.id===n);if(g!==-1&&g<f.length-1){let E=f[g+1].id;if(await O(E,f)){let T=new Set(r.current.getSnapshot().completedSteps);T.add(n),r.current.dispatch({type:"SET_COMPLETED_STEPS",payload:{steps:T}})}}},[O,_,w,M]),me=(0,d.useCallback)(()=>{let{currentStepId:n,activeSteps:p,activeStepsIndexMap:o}=W.current,y=o.get(n)??-1;y>0&&O(p[y-1].id)},[O]),ee=(0,d.useCallback)((n,p,o)=>{let{persistenceMode:y,stepsMap:f,currentStepId:g}=W.current,E=r.current.getSnapshot().data;if(C(E,n)===p)return;let v=V(E,n,p);if(s.steps.forEach(T=>{if(T.dependsOn?.some(R=>n===R||n.startsWith(R+"."))){let R=new Set(r.current.getSnapshot().completedSteps);R.delete(T.id)&&r.current.dispatch({type:"SET_COMPLETED_STEPS",payload:{steps:R}});let L=new Set(r.current.getSnapshot().visitedSteps);L.delete(T.id)&&r.current.dispatch({type:"SET_VISITED_STEPS",payload:{steps:L}}),T.clearData&&(typeof T.clearData=="function"?v={...v,...T.clearData(v)}:(Array.isArray(T.clearData)?T.clearData:[T.clearData]).forEach(A=>{v=V(v,A,void 0)}))}}),r.current.dispatch({type:"SET_DATA",payload:{path:n,value:p,options:o}}),g){r.current.deleteError(g,n);let T=f.get(g);(T?.validationMode||s.validationMode||"onStepChange")==="onChange"&&w(g,v),(T?.persistenceMode||y)==="onChange"&&z("onChange",g,v)}},[s,w,z]),Ie=(0,d.useCallback)((n,p)=>{let o=r.current.getSnapshot().data,y=p?.replace?n:{...o,...n};r.current.update(y,Object.keys(n)),p?.persist&&s.steps.forEach(f=>z("manual",f.id,y))},[s.steps,z]),xe=(0,d.useCallback)(()=>{if(r.current.setInitialData(e||{}),r.current.update(e||{}),r.current.updateErrors({}),r.current.dispatch({type:"SET_VISITED_STEPS",payload:{steps:new Set}}),r.current.dispatch({type:"SET_COMPLETED_STEPS",payload:{steps:new Set}}),r.current.dispatch({type:"SET_ERROR_STEPS",payload:{steps:new Set}}),b.length>0){let n=b[0].id;r.current.dispatch({type:"SET_CURRENT_STEP_ID",payload:{stepId:n}}),r.current.dispatch({type:"SET_HISTORY",payload:{history:[n]}})}else r.current.dispatch({type:"SET_CURRENT_STEP_ID",payload:{stepId:""}}),r.current.dispatch({type:"SET_HISTORY",payload:{history:[]}});h.clear(),D("wizard_reset",{data:e})},[e,b,h,D]),Ce=(0,d.useMemo)(()=>({...m,config:s}),[m,s]),_e=(0,d.useMemo)(()=>({goToNextStep:Te,goToPrevStep:me,goToStep:O,setStepData:(n,p)=>{let o={...r.current.getSnapshot().data,...p};r.current.update(o,Object.keys(p))},handleStepChange:(n,p)=>{W.current.currentStepId&&ee(n,p)},validateStep:n=>w(n,r.current.getSnapshot().data),validateAll:async()=>{r.current.updateMeta({isBusy:!0});let n=r.current.getSnapshot().data,p=await _(n),o=await Promise.all(p.map(y=>w(y.id,n)));return r.current.updateMeta({isBusy:!1}),{isValid:o.every(Boolean),errors:r.current.getSnapshot().errors}},save:n=>{let p=r.current.getSnapshot().data;n===!0?s.steps.forEach(o=>z("manual",o.id,p)):n?(Array.isArray(n)?n:[n]).forEach(o=>z("manual",o,p)):W.current.currentStepId&&z("manual",W.current.currentStepId,p)},clearStorage:()=>h.clear(),reset:xe,setData:ee,updateData:Ie,getData:(n,p)=>C(r.current.getSnapshot().data,n,p),updateConfig:n=>l(p=>({...p,...n}))}),[Te,me,O,w,xe,ee,Ie,h,s.steps,z]);return(0,d.useEffect)(()=>{u.current?r.current.updateMeta({config:s}):(r.current.dispatch({type:"INIT",payload:{data:e||{},config:s}}),u.current=!0)},[e,s]),(0,d.useEffect)(()=>{let n=!0;return(async()=>{let o=await _(ge);n&&r.current.dispatch({type:"SET_ACTIVE_STEPS",payload:{steps:o}})})(),()=>{n=!1}},[ge,_]),(0,d.useEffect)(()=>{let n=h.getStep(S);n&&(n.currentStepId&&r.current.dispatch({type:"SET_CURRENT_STEP_ID",payload:{stepId:n.currentStepId}}),n.visited&&r.current.dispatch({type:"SET_VISITED_STEPS",payload:{steps:new Set(n.visited)}}),n.completed&&r.current.dispatch({type:"SET_COMPLETED_STEPS",payload:{steps:new Set(n.completed)}}),n.history&&r.current.dispatch({type:"SET_HISTORY",payload:{history:n.history}}));let p=r.current.getSnapshot(),o=p.activeSteps;if(!H&&o.length>0){let y=t&&o.some(f=>f.id===t)?t:o[0].id;r.current.dispatch({type:"SET_CURRENT_STEP_ID",payload:{stepId:y}}),p.history.length===0&&r.current.dispatch({type:"SET_HISTORY",payload:{history:[y]}}),r.current.updateMeta({isLoading:!1})}},[b,t,H,h]),(0,$.jsx)(j.Provider,{value:r.current,children:(0,$.jsx)(be.Provider,{value:Ce,children:(0,$.jsx)(Ee.Provider,{value:_e,children:i})})})}function J(){let a=(0,d.useContext)(be);if(!a)throw new Error("useWizardState must be used within a WizardProvider");return a}function oe(a,e){let t=(0,d.useContext)(j);if(!t)throw new Error("useWizardValue must be used within a WizardProvider");let i=(0,d.useRef)(null),s=(0,d.useRef)(null),l=(0,d.useCallback)(()=>{let r=t.getSnapshot().data;if(r===i.current)return s.current;let u=C(r,a);return s.current!==void 0&&(e?.isEqual||Object.is)(s.current,u)?(i.current=r,s.current):(i.current=r,s.current=u,u)},[t,a,e?.isEqual]);return(0,d.useSyncExternalStore)(t.subscribe,l)}function de(a){let e=(0,d.useContext)(j);if(!e)throw new Error("useWizardError must be used within a WizardProvider");let t=(0,d.useCallback)(()=>{let i=e.getSnapshot().errors;for(let[s,l]of Object.entries(i)){let r=l;if(r[a])return r[a];if(a.startsWith(s+".")&&r[s])return r[s];let u=a.split(".").pop();if(u&&r[u])return r[u]}},[e,a]);return(0,d.useSyncExternalStore)(e.subscribe,t)}function F(a,e){let t=(0,d.useContext)(j);if(!t)throw new Error("useWizardSelector must be used within a WizardProvider");let i=(0,d.useRef)(null),s=(0,d.useRef)(null),l=(0,d.useCallback)(()=>{let r=t.getSnapshot();if(r===i.current)return s.current;let u=a(r);return s.current!==null&&(e?.isEqual||Object.is)(s.current,u)?(i.current=r,s.current):(i.current=r,s.current=u,u)},[t,a,e?.isEqual]);return(0,d.useSyncExternalStore)(t.subscribe,l)}function X(){let a=(0,d.useContext)(Ee);if(!a)throw new Error("useWizardActions must be used within a WizardProvider");return a}function P(){let a=J(),e=X(),t=(0,d.useContext)(j),i=F(h=>h.data),s=F(h=>h.errors),{data:l,errors:r,...u}=a;return(0,d.useMemo)(()=>({...u,...e,wizardData:i,allErrors:s,data:i,errors:s,store:t}),[u,e,i,s,t])}var G=require("react");var Z=require("react/jsx-runtime"),ze=({wrapper:a,fallback:e=null})=>{let{currentStep:t}=P(),i=(0,G.useMemo)(()=>t?.component?t.component:null,[t]);if(!t||!i)return null;let s=(0,Z.jsx)(G.Suspense,{fallback:e,children:(0,Z.jsx)(i,{})});return a?(0,Z.jsx)(a,{children:s},t.id):s};var ce=()=>P();var we=require("react/jsx-runtime");function We(){return{WizardProvider:({config:S,initialData:m,children:b})=>(0,we.jsx)(ie,{config:S,initialData:m,children:b}),useWizard:()=>ce(),useWizardContext:()=>P(),useWizardValue:(S,m)=>oe(S,m),useWizardSelector:(S,m)=>F(S,m),useWizardError:S=>de(S),useWizardActions:()=>X(),useWizardState:()=>J(),useBreadcrumbs:()=>J().breadcrumbs,createStep:S=>S}}var pe=class{constructor(e="wizard_"){I(this,"prefix");this.prefix=e}getKey(e){return`${this.prefix}${e}`}saveStep(e,t){if(!(typeof window>"u"))try{localStorage.setItem(this.getKey(e),JSON.stringify(t))}catch(i){console.warn("LocalStorageAdapter: Failed to save step",i)}}getStep(e){if(!(typeof window>"u"))try{let t=localStorage.getItem(this.getKey(e));return t?JSON.parse(t):void 0}catch(t){console.warn("LocalStorageAdapter: Failed to get step",t);return}}clear(){typeof window>"u"||Object.keys(localStorage).forEach(e=>{e.startsWith(this.prefix)&&localStorage.removeItem(e)})}};var le=class{constructor(e){I(this,"schema");this.schema=e}async validate(e){let t=await this.schema.safeParseAsync(e);if(t.success)return{isValid:!0};let i={};return t.error&&t.error.issues.forEach(s=>{let l=s.path.join(".");i[l]=s.message}),{isValid:!1,errors:i}}};var ue=class{constructor(e){I(this,"schema");this.schema=e}async validate(e){try{return await this.schema.validate(e,{abortEarly:!1}),{isValid:!0}}catch(t){if(t&&typeof t=="object"&&"inner"in t){let i=t,s={};return i.inner.forEach(l=>{l.path&&(s[l.path]=l.message)}),{isValid:!1,errors:s}}throw t}}};var Ae=a=>e=>t=>{console.group(`Wizard Action: ${t.type}`),console.log("Action payload:",t.payload),console.log("State before:",a.getSnapshot());let i=e(t);return console.log("State after:",a.getSnapshot()),console.groupEnd(),i};var Pe=a=>{if(typeof window>"u"||!window.__REDUX_DEVTOOLS_EXTENSION__)return t=>i=>t(i);let e=window.__REDUX_DEVTOOLS_EXTENSION__.connect({name:"Wizard Stepper React"});return e.init(a.getSnapshot()),t=>i=>{let s=t(i);return e.send(i,a.getSnapshot()),s}};var k=require("react");var c=require("react/jsx-runtime");function Re(){let[a,e]=(0,k.useState)(!1),[t,i]=(0,k.useState)("state"),{wizardData:s,allErrors:l,store:r,...u}=P(),[h,x]=(0,k.useState)([]);return(0,k.useEffect)(()=>r?r.subscribeToActions(m=>{x(b=>[{timestamp:Date.now(),action:m,state:r.getSnapshot()},...b].slice(0,50))}):void 0,[r]),a?(0,c.jsxs)("div",{style:{position:"fixed",bottom:"20px",right:"20px",width:"400px",height:"500px",backgroundColor:"rgba(15, 23, 42, 0.9)",backdropFilter:"blur(12px)",borderRadius:"16px",border:"1px solid rgba(255, 255, 255, 0.1)",boxShadow:"0 10px 40px rgba(0,0,0,0.5)",zIndex:9999,display:"flex",flexDirection:"column",color:"#e2e8f0",fontFamily:"Inter, sans-serif",overflow:"hidden"},children:[(0,c.jsxs)("div",{style:{padding:"12px 16px",borderBottom:"1px solid rgba(255, 255, 255, 0.1)",display:"flex",justifyContent:"space-between",alignItems:"center",background:"rgba(255, 255, 255, 0.03)"},children:[(0,c.jsx)("span",{style:{fontWeight:600,fontSize:"14px"},children:"Wizard DevTools"}),(0,c.jsx)("button",{onClick:()=>e(!1),style:{background:"none",border:"none",color:"#94a3b8",cursor:"pointer",fontSize:"18px"},children:"\xD7"})]}),(0,c.jsx)("div",{style:{display:"flex",borderBottom:"1px solid rgba(255, 255, 255, 0.1)",background:"rgba(255, 255, 255, 0.02)"},children:["state","actions","errors"].map(S=>(0,c.jsx)("button",{onClick:()=>i(S),style:{flex:1,padding:"10px",background:t===S?"rgba(37, 99, 235, 0.2)":"none",border:"none",color:t===S?"#60a5fa":"#94a3b8",borderBottom:t===S?"2px solid #3b82f6":"none",cursor:"pointer",fontSize:"12px",textTransform:"capitalize",fontWeight:t===S?600:400},children:S},S))}),(0,c.jsxs)("div",{style:{flex:1,overflowY:"auto",padding:"16px",fontSize:"12px"},children:[t==="state"&&(0,c.jsxs)("div",{children:[(0,c.jsxs)(Q,{title:"Navigation",children:[(0,c.jsx)(B,{label:"Current Step",value:u.currentStepId}),(0,c.jsx)(B,{label:"Index",value:u.currentStepIndex}),(0,c.jsx)(B,{label:"Progress",value:`${u.progress}%`}),(0,c.jsx)(B,{label:"Total Steps",value:u.activeStepsCount}),(0,c.jsx)(B,{label:"Is Loading",value:String(u.isLoading)}),(0,c.jsx)(B,{label:"Is Busy",value:String(u.isBusy)})]}),(0,c.jsx)(Q,{title:"History",children:(0,c.jsx)("div",{style:{color:"#94a3b8"},children:u.history.join(" \u2192 ")||"Empty"})}),(0,c.jsx)(Q,{title:"Data",children:(0,c.jsx)(Y,{data:s})}),(0,c.jsx)(Q,{title:"Meta",children:(0,c.jsx)(Y,{data:{visited:Array.from(u.visitedSteps),completed:Array.from(u.completedSteps),busy:Array.from(u.busySteps)}})})]}),t==="errors"&&(0,c.jsx)("div",{children:Object.keys(l).length===0?(0,c.jsx)("div",{style:{color:"#94a3b8",textAlign:"center",marginTop:"20px"},children:"No active errors"}):(0,c.jsx)(Y,{data:l})}),t==="actions"&&(0,c.jsx)("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:h.length===0?(0,c.jsx)("div",{style:{color:"#94a3b8",textAlign:"center",marginTop:"20px"},children:"No actions recorded yet"}):h.map((S,m)=>(0,c.jsx)(Je,{log:S},S.timestamp+m))})]}),(0,c.jsxs)("div",{style:{padding:"8px 16px",fontSize:"10px",color:"#64748b",borderTop:"1px solid rgba(255, 255, 255, 0.1)",background:"rgba(255, 255, 255, 0.02)",display:"flex",justifyContent:"space-between"},children:[(0,c.jsxs)("span",{children:["v",globalThis.process?.env?.VERSION||"2.0.0"]}),(0,c.jsx)("span",{children:"Strict Mode: Active"})]})]}):(0,c.jsx)("button",{onClick:()=>e(!0),style:{position:"fixed",bottom:"20px",right:"20px",zIndex:9999,padding:"10px 15px",borderRadius:"50px",background:"rgba(37, 99, 235, 0.9)",color:"white",border:"none",boxShadow:"0 4px 15px rgba(0,0,0,0.2)",cursor:"pointer",fontWeight:"bold",fontSize:"12px",backdropFilter:"blur(5px)"},children:"Wizard DevTools"})}var Je=({log:a})=>{let[e,t]=(0,k.useState)(!1),i=new Date(a.timestamp).toLocaleTimeString();return(0,c.jsxs)("div",{style:{background:"rgba(255, 255, 255, 0.05)",borderRadius:"8px",overflow:"hidden",border:"1px solid rgba(255, 255, 255, 0.05)"},children:[(0,c.jsxs)("div",{onClick:()=>t(!e),style:{padding:"8px 12px",display:"flex",justifyContent:"space-between",cursor:"pointer",alignItems:"center"},children:[(0,c.jsxs)("div",{style:{display:"flex",gap:"8px",alignItems:"center"},children:[(0,c.jsx)("span",{style:{color:"#64748b",fontSize:"10px"},children:i}),(0,c.jsx)("span",{style:{color:"#60a5fa",fontWeight:600},children:a.action.type})]}),(0,c.jsx)("span",{style:{color:"#475569",transform:e?"rotate(180deg)":"none",transition:"transform 0.2s"},children:"\u25BE"})]}),e&&(0,c.jsxs)("div",{style:{padding:"0 12px 12px 12px",borderTop:"1px solid rgba(255, 255, 255, 0.05)"},children:[(0,c.jsxs)("div",{style:{marginTop:"8px"},children:[(0,c.jsx)("div",{style:{color:"#94a3b8",marginBottom:"4px",fontSize:"10px"},children:"Payload:"}),(0,c.jsx)(Y,{data:a.action.payload})]}),(0,c.jsxs)("div",{style:{marginTop:"8px"},children:[(0,c.jsx)("div",{style:{color:"#94a3b8",marginBottom:"4px",fontSize:"10px"},children:"State after:"}),(0,c.jsx)(Y,{data:a.state})]})]})]})},Q=({title:a,children:e})=>(0,c.jsxs)("div",{style:{marginBottom:"20px"},children:[(0,c.jsx)("h4",{style:{margin:"0 0 8px 0",color:"#3b82f6",fontSize:"11px",textTransform:"uppercase",letterSpacing:"0.05em"},children:a}),e]}),B=({label:a,value:e})=>(0,c.jsxs)("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:"4px"},children:[(0,c.jsxs)("span",{style:{color:"#94a3b8"},children:[a,":"]}),(0,c.jsx)("span",{style:{color:"#f8fafc",fontWeight:500},children:e})]}),Y=({data:a})=>(0,c.jsx)("pre",{style:{background:"rgba(0, 0, 0, 0.3)",padding:"10px",borderRadius:"8px",overflowX:"auto",color:"#60a5fa",border:"1px solid rgba(255, 255, 255, 0.05)",margin:0},children:JSON.stringify(a,(t,i)=>i instanceof Set?Array.from(i):i,2)});0&&(module.exports={LocalStorageAdapter,MemoryAdapter,WizardDevTools,WizardProvider,WizardStepRenderer,YupAdapter,ZodAdapter,createWizardFactory,devToolsMiddleware,getByPath,loggerMiddleware,setByPath,shallowEqual,toPath,useWizard,useWizardActions,useWizardContext,useWizardError,useWizardSelector,useWizardState,useWizardValue});
|