react-wizard-engine 0.1.6 → 0.1.8

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.js CHANGED
@@ -1,2189 +1,2 @@
1
1
  "use client";
2
- import {
3
- WizardComponentsProvider,
4
- WizardEngineContext,
5
- WizardError,
6
- WizardInitializationError,
7
- WizardNavigationError,
8
- WizardResolverError,
9
- cn,
10
- useWizard,
11
- useWizardComponents
12
- } from "./chunk-NDYZHURP.js";
13
-
14
- // src/enums/wizard-event-type.enum.ts
15
- var WizardEventType = /* @__PURE__ */ ((WizardEventType2) => {
16
- WizardEventType2["Complete"] = "complete";
17
- WizardEventType2["Exit"] = "exit";
18
- WizardEventType2["NavigationCancelled"] = "navigation_cancelled";
19
- WizardEventType2["NavigationEnd"] = "navigation_end";
20
- WizardEventType2["NavigationError"] = "navigation_error";
21
- WizardEventType2["NavigationIgnored"] = "navigation_ignored";
22
- WizardEventType2["NavigationStart"] = "navigation_start";
23
- WizardEventType2["ResolveEnd"] = "resolve_end";
24
- WizardEventType2["ResolveStart"] = "resolve_start";
25
- WizardEventType2["ScrollEnd"] = "scroll_end";
26
- WizardEventType2["ScrollStart"] = "scroll_start";
27
- WizardEventType2["StepHide"] = "step_hide";
28
- WizardEventType2["StepShow"] = "step_show";
29
- return WizardEventType2;
30
- })(WizardEventType || {});
31
-
32
- // src/core/utils/general/last.ts
33
- var last = (arr) => arr[arr.length - 1];
34
-
35
- // src/core/utils/general/to-array.ts
36
- var toArray = (arr) => Array.isArray(arr) ? arr : [arr];
37
-
38
- // src/core/utils/state/get-step-id.ts
39
- var getStepId = (stepState) => {
40
- const branchesId = stepState.branches.join(",");
41
- return `${stepState.htmlIndex}:${branchesId}.${stepState.categoryId}.${stepState.id}`;
42
- };
43
- var getStepStateId = (stepState) => {
44
- return `${+stepState.isShow}${+stepState.isCompleted}${+stepState.isSkipped}${+stepState.isActive}`;
45
- };
46
-
47
- // src/core/utils/state/get-shape-id.ts
48
- var getShapeId = (state, prefix = "") => {
49
- const id = state.map(getStepId).join("|");
50
- return prefix !== "" && prefix !== void 0 ? `@${prefix}@${id}` : id;
51
- };
52
-
53
- // src/core/utils/state/get-state-id.ts
54
- var getStateId = (state, prefix = "") => {
55
- const id = state.map(getStepStateId).join("|");
56
- return prefix ? `@${prefix}@${id}` : id;
57
- };
58
-
59
- // src/core/builders/build-tree-state.ts
60
- function buildWizardBranchState(id, categories) {
61
- const shownCategories = [];
62
- const activeCategories = [];
63
- const completedCategories = [];
64
- const skippedCategories = [];
65
- const passedCategories = [];
66
- for (const category of categories) {
67
- if (category.isActive) activeCategories.push(category);
68
- if (category.isShow) shownCategories.push(category);
69
- if (category.isCompleted) completedCategories.push(category);
70
- if (category.isSkipped) skippedCategories.push(category);
71
- if (category.isPassed) passedCategories.push(category);
72
- }
73
- const activeCategory = activeCategories[0] ?? shownCategories[0];
74
- const getShownCategoryIndex = (category) => shownCategories.indexOf(category);
75
- const activeCategoryIndex = getShownCategoryIndex(activeCategory);
76
- const firstCategory = shownCategories[0];
77
- const lastCategory = last(shownCategories);
78
- const prevCategory = activeCategoryIndex > 0 ? shownCategories[activeCategoryIndex - 1] ?? null : null;
79
- const nextCategory = activeCategoryIndex >= 0 ? shownCategories[activeCategoryIndex + 1] ?? null : null;
80
- const getShownCategories = (fromIndex, toIndex) => shownCategories.slice(fromIndex, toIndex + 1);
81
- return {
82
- activeCategories,
83
- activeCategory,
84
- activeCategoryIndex,
85
- categories: [...categories],
86
- completedCategories,
87
- firstCategory,
88
- getShownCategories,
89
- getShownCategoryIndex,
90
- id,
91
- lastCategory,
92
- nextCategory,
93
- passedCategories,
94
- prevCategory,
95
- shownCategories,
96
- skippedCategories
97
- };
98
- }
99
- function buildWizardCategoryState(id, htmlIndex, steps) {
100
- const branches = steps[0]?.branches ?? [];
101
- const shownSteps = [];
102
- const activeSteps = [];
103
- const completedSteps = [];
104
- const skippedSteps = [];
105
- const passedSteps = [];
106
- for (const step of steps) {
107
- if (step.isActive) activeSteps.push(step);
108
- if (step.isShow) shownSteps.push(step);
109
- if (step.isSkipped) skippedSteps.push(step);
110
- if (step.isCompleted) completedSteps.push(step);
111
- if (step.isSkipped || step.isCompleted) passedSteps.push(step);
112
- }
113
- const isActive = activeSteps.length > 0;
114
- const isShow = shownSteps.length > 0;
115
- const skippedAt = shownSteps.findIndex((step) => step.isSkipped);
116
- const isSkipped = skippedAt !== -1;
117
- const completedShownSteps = shownSteps.filter((step) => step.isCompleted || step.isSkipped);
118
- const isCompleted = completedShownSteps.length === shownSteps.length && shownSteps.length > 0;
119
- const isPassed = isCompleted || isSkipped;
120
- const lastActiveStep = last(activeSteps);
121
- const activeStepIndex = lastActiveStep ? shownSteps.indexOf(lastActiveStep) : -1;
122
- const firstStep = shownSteps[0];
123
- const lastStep = last(shownSteps);
124
- const firstActiveStep = activeSteps[0];
125
- const prevStep = activeStepIndex > 0 ? shownSteps[activeStepIndex - 1] ?? null : null;
126
- const nextStep = activeStepIndex >= 0 ? shownSteps[activeStepIndex + 1] ?? null : null;
127
- return {
128
- activeStepIndex,
129
- activeSteps,
130
- branches: [...branches],
131
- completedSteps,
132
- firstActiveStep,
133
- firstStep,
134
- htmlIndex,
135
- id,
136
- isActive,
137
- isCompleted,
138
- isPassed,
139
- isShow,
140
- isSkipped,
141
- lastActiveStep,
142
- lastStep,
143
- nextStep,
144
- passedSteps,
145
- prevStep,
146
- shownSteps,
147
- skippedAt,
148
- skippedSteps,
149
- steps: [...steps]
150
- };
151
- }
152
- function buildWizardTreeState(state, activeBranchId) {
153
- const stepMap = {};
154
- const categoryOrder = [];
155
- const stepsByCategory = {};
156
- for (const step of state) {
157
- stepMap[step.id] = step;
158
- if (!stepsByCategory[step.categoryId]) {
159
- categoryOrder.push(step.categoryId);
160
- stepsByCategory[step.categoryId] = [];
161
- }
162
- stepsByCategory[step.categoryId].push(step);
163
- }
164
- const categoryMap = {};
165
- const categoriesByBranch = {};
166
- for (const [index, categoryId] of categoryOrder.entries()) {
167
- const categoryState = buildWizardCategoryState(
168
- categoryId,
169
- index,
170
- stepsByCategory[categoryId]
171
- );
172
- categoryMap[categoryId] = categoryState;
173
- for (const branchId of categoryState.branches) {
174
- (categoriesByBranch[branchId] ??= []).push(categoryState);
175
- }
176
- }
177
- const branchMap = {};
178
- const branches = [];
179
- for (const branchId of Object.keys(categoriesByBranch)) {
180
- const branchState = buildWizardBranchState(branchId, categoriesByBranch[branchId]);
181
- branchMap[branchId] = branchState;
182
- branches.push(branchState);
183
- }
184
- const activeBranch = pickActiveBranch(branches, branchMap, activeBranchId);
185
- const activeCategory = activeBranch.activeCategory;
186
- const activeSteps = activeCategory.activeSteps;
187
- const lastActiveStep = last(activeSteps);
188
- return {
189
- activeBranch,
190
- activeCategory,
191
- activeSteps,
192
- branches,
193
- branchMap,
194
- categoryMap,
195
- id: getStateId(state),
196
- lastActiveStep,
197
- state: [...state],
198
- stepMap
199
- };
200
- }
201
- function pickActiveBranch(branches, branchMap, activeBranchId) {
202
- if (branches.length === 1) {
203
- return branches[0];
204
- }
205
- const activeBranches = branches.filter((branch) => branch.activeCategories.length > 0);
206
- if (activeBranches.length === 1) {
207
- return activeBranches[0];
208
- }
209
- if (activeBranchId && branchMap[activeBranchId]) {
210
- return branchMap[activeBranchId];
211
- }
212
- return activeBranches[0] ?? branches[0];
213
- }
214
-
215
- // src/core/builders/wizard-default.const.ts
216
- var wizardDefaultState = {
217
- isActive: false,
218
- isCompleted: false,
219
- isShow: true,
220
- isSkipped: false
221
- };
222
- var wizardDefaultBranch = "main";
223
-
224
- // src/core/rules/wizard-rule.ts
225
- var WizardRule = class {
226
- };
227
-
228
- // src/core/rules/wizard-active-step.rule.ts
229
- var WizardActiveStepRule = class extends WizardRule {
230
- verify({ lastActiveStep }) {
231
- if (!lastActiveStep) {
232
- throw new WizardError("[WizardActiveStepRule]: There are no available active step in tree state.");
233
- }
234
- }
235
- };
236
-
237
- // src/core/rules/wizard-passed-prev-categories.rule.ts
238
- var WizardPassedPrevCategoriesRule = class extends WizardRule {
239
- verify({ activeBranch, activeCategory }) {
240
- const prevCategories = activeBranch.shownCategories.slice(0, activeBranch.activeCategoryIndex);
241
- const hasUnpassedPrevCategories = prevCategories.some((prevCategory) => !prevCategory.isPassed);
242
- if (hasUnpassedPrevCategories) {
243
- const prevCategoryNames = prevCategories.map((prevCategory) => prevCategory.id).join(",");
244
- throw new WizardError(
245
- `[WizardPassedPrevCategoriesRule]: Active category "${activeCategory.id}" has neither completed nor skipped prev categories. Please, skip or complete categories: "${prevCategoryNames}".`
246
- );
247
- }
248
- }
249
- };
250
-
251
- // src/core/rules/wizard-passed-prev-steps.rule.ts
252
- var WizardPassedPrevStepsRule = class extends WizardRule {
253
- verify({ activeCategory }) {
254
- const prevSteps = activeCategory.shownSteps.slice(0, activeCategory.activeStepIndex);
255
- const prevUnpassedSteps = prevSteps.filter((prevStep) => !prevStep.isCompleted && !prevStep.isSkipped);
256
- if (prevUnpassedSteps.length) {
257
- const prevStepNames = prevUnpassedSteps.map((prevStep) => prevStep.id).join(",");
258
- throw new WizardError(
259
- `[WizardPassedPrevStepsRule]: Last active step "${activeCategory.lastActiveStep.id}" has not completed steps before. Please, complete or hide steps: "${prevStepNames}".`
260
- );
261
- }
262
- }
263
- };
264
-
265
- // src/core/rules/wizard-shown-active-category.rule.ts
266
- var WizardShownActiveCategoryRule = class extends WizardRule {
267
- verify({ activeCategory }) {
268
- if (!activeCategory.isShow) {
269
- throw new WizardError(
270
- `[WizardShownActiveCategoryRule]: Active category is hidden. Please, show category "${activeCategory.id}" to be able to activate it.`
271
- );
272
- }
273
- }
274
- };
275
-
276
- // src/core/rules/wizard-single-active-category.rule.ts
277
- var WizardSingleActiveCategoryRule = class extends WizardRule {
278
- verify({ activeBranch }) {
279
- if (activeBranch.activeCategories.length > 1) {
280
- const activeCategoryNames = activeBranch.activeCategories.map((c) => c.id).join(",");
281
- throw new WizardError(
282
- `[WizardSingleActiveCategoryRule]: There are 2 active categories at the same time: ${activeCategoryNames}.`
283
- );
284
- }
285
- }
286
- };
287
-
288
- // src/core/rules/wizard-rules.ts
289
- var wizardRules = [
290
- new WizardActiveStepRule(),
291
- new WizardSingleActiveCategoryRule(),
292
- new WizardShownActiveCategoryRule(),
293
- new WizardPassedPrevStepsRule(),
294
- new WizardPassedPrevCategoriesRule()
295
- ];
296
-
297
- // src/core/state/wizard-tree.state.ts
298
- var WizardCompleteTreeState = class {
299
- constructor(originTree) {
300
- this.originTree = originTree;
301
- }
302
- originTree;
303
- state = "complete";
304
- };
305
- var WizardExitTreeState = class {
306
- constructor(originTree) {
307
- this.originTree = originTree;
308
- }
309
- originTree;
310
- state = "exit";
311
- };
312
-
313
- // src/core/state/project-to-tree.ts
314
- var projectToTree = (target) => target instanceof WizardExitTreeState || target instanceof WizardCompleteTreeState ? target.originTree : target;
315
-
316
- // src/core/builders/wizard-tree-state.builder.ts
317
- var WizardTreeStateBuilder = class _WizardTreeStateBuilder {
318
- branch;
319
- state;
320
- constructor(treeState, branch) {
321
- this.state = treeState.state.map((step) => ({ ...step }));
322
- this.branch = branch ?? treeState.activeBranch.id;
323
- }
324
- static validate(tree) {
325
- wizardRules.forEach((rule) => rule.verify(tree));
326
- return tree;
327
- }
328
- /** Activate completed steps + the next step after the last completed one. */
329
- activateCategory(categoryId) {
330
- const shown = this.getCategoryStepStates(categoryId).filter((s) => s.isShow);
331
- for (let i = 0; i < shown.length; i++) {
332
- const step = shown[i];
333
- const prev = shown[i - 1];
334
- step.isActive = step.isCompleted || (prev?.isCompleted ?? true);
335
- }
336
- return this;
337
- }
338
- /** Activate first shown step of a category; deactivate the rest. */
339
- activateFirstStep(categoryId) {
340
- const shown = this.getCategoryStepStates(categoryId).filter((step) => step.isShow);
341
- if (shown.length === 0) return this;
342
- shown[0].isActive = true;
343
- for (let i = 1; i < shown.length; i++) {
344
- shown[i].isActive = false;
345
- }
346
- return this;
347
- }
348
- // ================
349
- // Step actions
350
- // ================
351
- activateStep(step) {
352
- this.getStepState(step).isActive = true;
353
- return this;
354
- }
355
- build() {
356
- const tree = buildWizardTreeState(this.state, this.branch);
357
- _WizardTreeStateBuilder.validate(tree);
358
- return Object.freeze(tree);
359
- }
360
- /** Build a terminal complete tree (skips rule validation since the tree is sealed). */
361
- buildComplete() {
362
- const tree = buildWizardTreeState(this.state, this.branch);
363
- return Object.freeze(new WizardCompleteTreeState(tree));
364
- }
365
- /** Build a terminal exit tree (skips rule validation since the tree is sealed). */
366
- buildExit() {
367
- const tree = buildWizardTreeState(this.state, this.branch);
368
- return Object.freeze(new WizardExitTreeState(tree));
369
- }
370
- completeCategory(categoryId) {
371
- this.getCategoryStepStates(categoryId).forEach((step) => step.isCompleted = true);
372
- return this;
373
- }
374
- // ================
375
- // Category actions
376
- // ================
377
- completeStep(step) {
378
- this.getStepState(step).isCompleted = true;
379
- return this;
380
- }
381
- deactivateCategory(categoryId) {
382
- this.getCategoryStepStates(categoryId).forEach((step) => step.isActive = false);
383
- return this;
384
- }
385
- deactivateStep(step) {
386
- this.getStepState(step).isActive = false;
387
- return this;
388
- }
389
- getCategoryStepStates(categoryId) {
390
- return this.state.filter((step) => step.categoryId === categoryId);
391
- }
392
- /** Reset every step in the tree to `wizardDefaultState`. */
393
- getResetTree() {
394
- this.state.forEach((step) => Object.assign(step, wizardDefaultState));
395
- const firstStep = this.state[0];
396
- if (firstStep) {
397
- firstStep.isActive = true;
398
- }
399
- return Object.freeze(buildWizardTreeState(this.state, this.branch));
400
- }
401
- getStepState(step) {
402
- const found = this.state.find((s) => s.id === step);
403
- if (!found) {
404
- throw new Error(`[WizardTreeStateBuilder] Unknown step "${step}"`);
405
- }
406
- return found;
407
- }
408
- hideCategory(categoryId) {
409
- this.getCategoryStepStates(categoryId).forEach((step) => step.isShow = false);
410
- return this;
411
- }
412
- hideStep(step) {
413
- this.getStepState(step).isShow = false;
414
- return this;
415
- }
416
- /** Reset category steps from `from` index onward; deactivate all but first. */
417
- resetCategory(categoryId, from = 0) {
418
- const slice = this.getCategoryStepStates(categoryId).slice(from);
419
- slice.forEach((step, index) => {
420
- step.isActive = step.isActive && index === 0;
421
- step.isCompleted = false;
422
- });
423
- return this;
424
- }
425
- showCategory(categoryId) {
426
- this.getCategoryStepStates(categoryId).forEach((step) => step.isShow = true);
427
- return this;
428
- }
429
- // ================
430
- // Build / reset
431
- // ================
432
- showStep(step) {
433
- this.getStepState(step).isShow = true;
434
- return this;
435
- }
436
- skipCategory(categoryId) {
437
- this.getCategoryStepStates(categoryId).forEach((step) => step.isSkipped = true);
438
- return this;
439
- }
440
- skipCategoryUncompleted(categoryId) {
441
- this.getCategoryStepStates(categoryId).filter((step) => !step.isCompleted).forEach((step) => step.isSkipped = true);
442
- return this;
443
- }
444
- uncompleteStep(step) {
445
- this.getStepState(step).isCompleted = false;
446
- return this;
447
- }
448
- unskipCategory(categoryId) {
449
- this.getCategoryStepStates(categoryId).forEach((step) => step.isSkipped = false);
450
- return this;
451
- }
452
- };
453
-
454
- // src/core/compose-wizard-providers.ts
455
- function composeWizardProviders(...mods) {
456
- const props = {
457
- config: {},
458
- initializers: [],
459
- listeners: [],
460
- strategies: {}
461
- };
462
- for (const mod of mods) {
463
- mod(props);
464
- }
465
- return props;
466
- }
467
- var withConfig = (options) => (props) => {
468
- props.config = { ...props.config, ...options };
469
- };
470
- var withInitializer = (initializer) => (props) => {
471
- props.initializers.push(initializer);
472
- };
473
- var withListener = (listener) => (props) => {
474
- props.listeners.push(listener);
475
- };
476
- var withScrollStrategy = (strategy) => (props) => {
477
- props.strategies.scroll = strategy;
478
- };
479
- var withScrollContainer = (container) => (props) => {
480
- props.scrollContainer = container;
481
- };
482
- var withProgressStrategy = (strategy) => (props) => {
483
- props.strategies.progress = strategy;
484
- };
485
- var withVisibilityStrategy = (strategy) => (props) => {
486
- props.strategies.visibility = strategy;
487
- };
488
-
489
- // src/core/events/wizard-events.ts
490
- var WizardEvent = class {
491
- /** @param navigation - Specific navigation data associated with event */
492
- constructor(navigation) {
493
- this.navigation = navigation;
494
- }
495
- navigation;
496
- };
497
- var WizardCompleteEvent = class extends WizardEvent {
498
- constructor(navigation) {
499
- super(navigation);
500
- this.navigation = navigation;
501
- }
502
- navigation;
503
- type = "complete" /* Complete */;
504
- };
505
- var WizardExitEvent = class extends WizardEvent {
506
- type = "exit" /* Exit */;
507
- };
508
- var WizardNavigationCancelledEvent = class extends WizardEvent {
509
- constructor(navigation, reason) {
510
- super(navigation);
511
- this.navigation = navigation;
512
- this.reason = reason;
513
- }
514
- navigation;
515
- reason;
516
- type = "navigation_cancelled" /* NavigationCancelled */;
517
- };
518
- var WizardNavigationEndEvent = class extends WizardEvent {
519
- constructor(navigation) {
520
- super(navigation);
521
- this.navigation = navigation;
522
- }
523
- navigation;
524
- type = "navigation_end" /* NavigationEnd */;
525
- };
526
- var WizardNavigationErrorEvent = class extends WizardEvent {
527
- constructor(navigation) {
528
- super(navigation);
529
- this.navigation = navigation;
530
- }
531
- navigation;
532
- type = "navigation_error" /* NavigationError */;
533
- };
534
- var WizardNavigationIgnoredEvent = class extends WizardEvent {
535
- constructor(navigation, reason) {
536
- super(navigation);
537
- this.navigation = navigation;
538
- this.reason = reason;
539
- }
540
- navigation;
541
- reason;
542
- type = "navigation_ignored" /* NavigationIgnored */;
543
- };
544
- var WizardNavigationStartEvent = class extends WizardEvent {
545
- constructor(navigation) {
546
- super(navigation);
547
- this.navigation = navigation;
548
- }
549
- navigation;
550
- type = "navigation_start" /* NavigationStart */;
551
- };
552
- var WizardResolveEndEvent = class extends WizardEvent {
553
- constructor(navigation) {
554
- super(navigation);
555
- this.navigation = navigation;
556
- }
557
- navigation;
558
- type = "resolve_end" /* ResolveEnd */;
559
- };
560
- var WizardResolveStartEvent = class extends WizardEvent {
561
- constructor(navigation) {
562
- super(navigation);
563
- this.navigation = navigation;
564
- }
565
- navigation;
566
- type = "resolve_start" /* ResolveStart */;
567
- };
568
- var WizardScrollEndEvent = class extends WizardEvent {
569
- constructor(navigation) {
570
- super(navigation);
571
- this.navigation = navigation;
572
- }
573
- navigation;
574
- type = "scroll_end" /* ScrollEnd */;
575
- };
576
- var WizardScrollStartEvent = class extends WizardEvent {
577
- constructor(navigation) {
578
- super(navigation);
579
- this.navigation = navigation;
580
- }
581
- navigation;
582
- type = "scroll_start" /* ScrollStart */;
583
- };
584
- var WizardStepHideEvent = class extends WizardEvent {
585
- constructor(navigation) {
586
- super(navigation);
587
- this.navigation = navigation;
588
- }
589
- navigation;
590
- type = "step_hide" /* StepHide */;
591
- };
592
- var WizardStepShowEvent = class extends WizardEvent {
593
- constructor(navigation) {
594
- super(navigation);
595
- this.navigation = navigation;
596
- }
597
- navigation;
598
- type = "step_show" /* StepShow */;
599
- };
600
-
601
- // src/core/initializers/wizard-initializer.ts
602
- var WizardInitializer = class {
603
- };
604
-
605
- // src/core/initializers/wizard-default.initializer.ts
606
- var WizardDefaultInitializer = class extends WizardInitializer {
607
- getState(tree) {
608
- const builder = new WizardTreeStateBuilder(tree);
609
- if (tree.activeSteps.length > 0) {
610
- return builder.build();
611
- }
612
- const firstUnpassed = tree.activeBranch.shownCategories.find((category) => !category.isPassed) ?? tree.activeCategory;
613
- return builder.activateCategory(firstUnpassed.id).build();
614
- }
615
- };
616
-
617
- // src/core/listeners/wizard-listener.ts
618
- var WizardListener = class {
619
- onDestroy(_tree) {
620
- return;
621
- }
622
- onEvent(_event) {
623
- return;
624
- }
625
- onInit(_tree) {
626
- return;
627
- }
628
- onTreeChange(_tree) {
629
- return;
630
- }
631
- };
632
-
633
- // src/core/navigation/initializer-service.ts
634
- var WizardInitializerService = class {
635
- constructor(wizardLog, wizardInitializers) {
636
- this.wizardLog = wizardLog;
637
- this.wizardInitializers = wizardInitializers;
638
- }
639
- wizardLog;
640
- wizardInitializers;
641
- async getInitialState(state, activeBranch) {
642
- const htmlTree = buildWizardTreeState(state, activeBranch);
643
- this.wizardLog.trace("HTML tree", htmlTree);
644
- try {
645
- this.validateHtmlTree(htmlTree);
646
- this.validateActiveBranch(htmlTree, activeBranch);
647
- let tree = htmlTree;
648
- for (const initializer of this.wizardInitializers) {
649
- tree = await initializer.getState(tree, htmlTree);
650
- this.wizardLog.trace("Initializer", initializer, tree);
651
- }
652
- return tree;
653
- } catch (e) {
654
- this.wizardLog.error(e);
655
- return htmlTree;
656
- }
657
- }
658
- validateActiveBranch(htmlTree, activeBranch) {
659
- if (!activeBranch) return;
660
- if (!htmlTree.branchMap[activeBranch]) {
661
- const branchIds = htmlTree.branches.map((branch) => branch.id).join(",");
662
- throw new WizardError(
663
- `[WizardInitializerService02]: There is no branch with id "${activeBranch}". List of available branches: ${branchIds}.`
664
- );
665
- }
666
- }
667
- validateHtmlTree(htmlTree) {
668
- const seen = /* @__PURE__ */ new Set();
669
- const duplicates = [];
670
- for (const s of htmlTree.state) {
671
- if (seen.has(s.id)) duplicates.push(s.id);
672
- else seen.add(s.id);
673
- }
674
- if (duplicates.length > 0) {
675
- throw new WizardInitializationError(
676
- `[WizardInitializerService01]: There are steps with the same ID: ${duplicates.join(",")}.`
677
- );
678
- }
679
- }
680
- };
681
-
682
- // src/core/navigation/typed-emitter.ts
683
- var TypedEmitter = class {
684
- map = /* @__PURE__ */ new Map();
685
- dispose() {
686
- this.map.clear();
687
- }
688
- emit(event) {
689
- const specific = this.map.get(event.type);
690
- if (specific) {
691
- for (const handler of [...specific]) handler(event);
692
- }
693
- const wildcard = this.map.get("*");
694
- if (wildcard) {
695
- for (const handler of [...wildcard]) handler(event);
696
- }
697
- }
698
- on(type, handler) {
699
- let set = this.map.get(type);
700
- if (!set) {
701
- set = /* @__PURE__ */ new Set();
702
- this.map.set(type, set);
703
- }
704
- set.add(handler);
705
- return () => {
706
- set.delete(handler);
707
- };
708
- }
709
- };
710
-
711
- // src/core/navigation/wizard-navigation.ts
712
- var WizardNavigation = class _WizardNavigation {
713
- constructor(from, to) {
714
- this.from = from;
715
- this.to = to;
716
- const toTree = projectToTree(to);
717
- this.id = `${from.id}=>${toTree.id}`;
718
- this.direction = _WizardNavigation.getDirection(from, toTree);
719
- this.isSkipping = _WizardNavigation.isSkipping(from, toTree, this.direction);
720
- this.isCategoryChanging = _WizardNavigation.isCategoryChanging(from, toTree);
721
- this.isScrollChanging = _WizardNavigation.isScrollChanging(from, toTree);
722
- this.isExit = to instanceof WizardExitTreeState;
723
- this.isComplete = to instanceof WizardCompleteTreeState;
724
- }
725
- from;
726
- to;
727
- direction;
728
- id;
729
- isCategoryChanging;
730
- isComplete;
731
- isExit;
732
- isScrollChanging;
733
- isSkipping;
734
- static getDirection(from, to) {
735
- if (_WizardNavigation.isCategoryChanging(from, to)) {
736
- return from.activeCategory.htmlIndex > to.activeCategory.htmlIndex ? "back" : "next";
737
- }
738
- if (from.activeCategory.activeStepIndex === to.activeCategory.activeStepIndex) {
739
- return to.activeCategory.id === to.activeBranch.firstCategory.id ? "back" : "next";
740
- }
741
- return from.activeCategory.activeStepIndex > to.activeCategory.activeStepIndex ? "back" : "next";
742
- }
743
- static isCategoryChanging(from, to) {
744
- return from.activeCategory.id !== to.activeCategory.id;
745
- }
746
- static isScrollChanging(from, to) {
747
- const isSamePosition = from.activeCategory.activeStepIndex === to.activeCategory.activeStepIndex;
748
- const isSameStep = from.activeCategory.lastActiveStep.id === to.activeCategory.lastActiveStep.id;
749
- return !isSameStep || !isSamePosition;
750
- }
751
- /**
752
- * Navigation counted as skipped when Category "A" was "active" and not "skipped" before transition
753
- * and became "inactive" and "skipped" after transition.
754
- */
755
- static isSkipping(from, to, direction = _WizardNavigation.getDirection(from, to)) {
756
- if (direction === "back") {
757
- return false;
758
- }
759
- const isPrevCategoryAlreadySkipped = from.activeCategory.isSkipped;
760
- const isPrevCategorySkipped = to.categoryMap[from.activeCategory.id].isSkipped;
761
- return !isPrevCategoryAlreadySkipped && isPrevCategorySkipped;
762
- }
763
- };
764
-
765
- // src/core/navigation/navigation-service.ts
766
- var WizardNavigationService = class {
767
- constructor(wizardStore, wizardConfig, wizardStateService, wizardScrollStrategy) {
768
- this.wizardStore = wizardStore;
769
- this.wizardConfig = wizardConfig;
770
- this.wizardStateService = wizardStateService;
771
- this.wizardScrollStrategy = wizardScrollStrategy;
772
- }
773
- wizardStore;
774
- wizardConfig;
775
- wizardStateService;
776
- wizardScrollStrategy;
777
- get isNavigating() {
778
- return !!this.inFlight;
779
- }
780
- disposed = false;
781
- emitter = new TypedEmitter();
782
- inFlight = null;
783
- prevSuccessId = null;
784
- async completeWizard() {
785
- const tree = this.wizardStore.getTreeSnapshot();
786
- const to = new WizardCompleteTreeState(tree);
787
- return this.navigate(to);
788
- }
789
- dispose() {
790
- this.disposed = true;
791
- if (this.inFlight) {
792
- this.inFlight.abort.abort();
793
- this.inFlight = null;
794
- }
795
- this.emitter.dispose();
796
- }
797
- async exitWizard() {
798
- try {
799
- const tree = this.wizardStore.getTreeSnapshot();
800
- const to = new WizardExitTreeState(tree);
801
- return this.navigate(to);
802
- } catch {
803
- this.emitter.emit(new WizardExitEvent());
804
- return true;
805
- }
806
- }
807
- async hideCategory(categoryId) {
808
- const to = this.wizardStateService.hideCategory(categoryId);
809
- return this.hide(this.projectTree(to));
810
- }
811
- async hideStep(step) {
812
- const tree = this.wizardStore.getTreeSnapshot();
813
- const to = toArray(step).reduce((acc, id) => {
814
- const accTree = this.projectTree(acc);
815
- return this.wizardStateService.hideStep(id, accTree);
816
- }, tree);
817
- return this.hide(this.projectTree(to));
818
- }
819
- async navigate(to) {
820
- if (this.disposed) return false;
821
- const fromTree = this.wizardStore.getTreeSnapshot();
822
- const navigation = new WizardNavigation(fromTree, to);
823
- if (navigation.id === this.prevSuccessId && !navigation.isExit && !navigation.isComplete) {
824
- this.emitter.emit(new WizardNavigationIgnoredEvent(navigation, "same_navigation"));
825
- return false;
826
- }
827
- if (this.inFlight) {
828
- const prior = this.inFlight;
829
- prior.abort.abort();
830
- this.inFlight = null;
831
- this.emitter.emit(new WizardNavigationCancelledEvent(prior.navigation, "new_navigation"));
832
- }
833
- const abort = new AbortController();
834
- this.inFlight = { abort, navigation };
835
- try {
836
- this.emitter.emit(new WizardNavigationStartEvent(navigation));
837
- this.emitter.emit(new WizardResolveStartEvent(navigation));
838
- try {
839
- await this.runResolverChain(navigation, abort.signal);
840
- } catch (e) {
841
- if (this.isAbortReason(e, abort.signal)) {
842
- return false;
843
- }
844
- if (e instanceof WizardResolverError) {
845
- this.emitter.emit(new WizardNavigationCancelledEvent(navigation, "resolver"));
846
- return false;
847
- }
848
- this.emitter.emit(new WizardNavigationErrorEvent(navigation));
849
- console.error(e);
850
- throw e;
851
- }
852
- if (abort.signal.aborted) return false;
853
- this.emitter.emit(new WizardResolveEndEvent(navigation));
854
- this.commitTree(navigation, to);
855
- this.emitVisibilityFlips(navigation, fromTree, to);
856
- this.emitter.emit(new WizardNavigationEndEvent(navigation));
857
- if (navigation.isExit) this.emitter.emit(new WizardExitEvent(navigation));
858
- if (navigation.isComplete) this.emitter.emit(new WizardCompleteEvent(navigation));
859
- if (!navigation.isExit && !navigation.isComplete && navigation.isScrollChanging) {
860
- this.emitter.emit(new WizardScrollStartEvent(navigation));
861
- await this.wizardScrollStrategy.onNavigate(navigation);
862
- this.emitter.emit(new WizardScrollEndEvent(navigation));
863
- }
864
- this.prevSuccessId = navigation.id;
865
- return true;
866
- } finally {
867
- if (this.inFlight && this.inFlight.navigation === navigation) {
868
- this.inFlight = null;
869
- }
870
- }
871
- }
872
- on(type, handler) {
873
- return this.emitter.on(type, handler);
874
- }
875
- async showCategory(categoryId) {
876
- const to = this.wizardStateService.showCategory(categoryId);
877
- return this.show(to);
878
- }
879
- async showStep(step) {
880
- const tree = this.wizardStore.getTreeSnapshot();
881
- const to = toArray(step).reduce(
882
- (acc, id) => this.wizardStateService.showStep(id, acc),
883
- tree
884
- );
885
- return this.show(to);
886
- }
887
- // --- internals ---
888
- commitTree(navigation, to) {
889
- if (navigation.isExit || navigation.isComplete) {
890
- const tree = this.projectTree(to);
891
- this.wizardStore.setState(tree);
892
- return;
893
- }
894
- this.wizardStore.setState(to);
895
- }
896
- emitVisibilityFlips(navigation, from, to) {
897
- const toTree = this.projectTree(to);
898
- for (const stepId of Object.keys(from.stepMap)) {
899
- const before = from.stepMap[stepId];
900
- const after = toTree.stepMap[stepId];
901
- if (!before || !after) continue;
902
- if (before.isShow === after.isShow) continue;
903
- if (after.isShow) {
904
- this.emitter.emit(new WizardStepShowEvent(navigation));
905
- } else {
906
- this.emitter.emit(new WizardStepHideEvent(navigation));
907
- }
908
- }
909
- }
910
- async hide(to) {
911
- const fromTree = this.wizardStore.getTreeSnapshot();
912
- const navigation = new WizardNavigation(fromTree, to);
913
- this.wizardStore.setState(to);
914
- this.emitter.emit(new WizardStepHideEvent(navigation));
915
- if (navigation.isScrollChanging) {
916
- await this.wizardScrollStrategy.onToggle(navigation);
917
- }
918
- return true;
919
- }
920
- async invokeResolver(resolver, navigation, signal) {
921
- if (!resolver) return;
922
- if (signal.aborted) throw new DOMException("aborted", "AbortError");
923
- const abortPromise = new Promise((_, reject) => {
924
- const onAbort = () => reject(new DOMException("aborted", "AbortError"));
925
- if (signal.aborted) {
926
- onAbort();
927
- } else {
928
- signal.addEventListener("abort", onAbort, { once: true });
929
- }
930
- });
931
- const result = await Promise.race([Promise.resolve(resolver(navigation)), abortPromise]);
932
- if (signal.aborted) throw new DOMException("aborted", "AbortError");
933
- if (!result) {
934
- throw new WizardResolverError(`Resolver rejected navigation ${navigation.id}`);
935
- }
936
- }
937
- isAbortReason(error, signal) {
938
- if (!signal.aborted) return false;
939
- if (error instanceof DOMException && error.name === "AbortError") return true;
940
- return false;
941
- }
942
- projectTree(to) {
943
- if (to instanceof WizardExitTreeState || to instanceof WizardCompleteTreeState) {
944
- return to.originTree;
945
- }
946
- return to;
947
- }
948
- async runResolverChain(navigation, signal) {
949
- const config = this.wizardConfig.getOptions();
950
- if (navigation.direction === "next" && navigation.isCategoryChanging && !navigation.isSkipping) {
951
- await this.invokeResolver(config.resolveCategoryComplete, navigation, signal);
952
- }
953
- if (navigation.isCategoryChanging) {
954
- await this.invokeResolver(config.resolveCategoryChange, navigation, signal);
955
- }
956
- if (navigation.isCategoryChanging) {
957
- await this.invokeResolver(config.resolveCategoryEnter, navigation, signal);
958
- }
959
- await this.invokeResolver(config.resolveStepChange, navigation, signal);
960
- }
961
- async show(to) {
962
- const fromTree = this.wizardStore.getTreeSnapshot();
963
- const toTree = this.projectTree(to);
964
- const navigation = new WizardNavigation(fromTree, toTree);
965
- this.wizardStore.setState(toTree);
966
- this.emitter.emit(new WizardStepShowEvent(navigation));
967
- if (navigation.isScrollChanging) {
968
- await this.wizardScrollStrategy.onToggle(navigation);
969
- }
970
- return true;
971
- }
972
- };
973
-
974
- // src/core/navigation/state-service.ts
975
- var WizardStateService = class {
976
- constructor(wizardStore, wizardConfig) {
977
- this.wizardStore = wizardStore;
978
- this.wizardConfig = wizardConfig;
979
- }
980
- wizardStore;
981
- wizardConfig;
982
- completeCategory(category, tree = this.currentTree()) {
983
- const { activeBranch } = tree;
984
- const { activeCategory, nextCategory } = activeBranch;
985
- const builder = new WizardTreeStateBuilder(tree);
986
- builder.completeCategory(category);
987
- if (activeCategory.id === category && nextCategory) {
988
- return builder.deactivateCategory(category).activateCategory(nextCategory.id).build();
989
- }
990
- if (activeCategory.id === category && !nextCategory) {
991
- return builder.buildComplete();
992
- }
993
- return builder.build();
994
- }
995
- goToCategory(categoryId, tree = this.currentTree()) {
996
- const { activeBranch, activeCategory, branchMap, categoryMap } = tree;
997
- const builder = new WizardTreeStateBuilder(tree);
998
- const toCategory = categoryMap[categoryId];
999
- const toCategoryFirstBranch = branchMap[toCategory.branches[0]];
1000
- const toCategoryBranch = toCategory.branches.includes(activeBranch.id) ? activeBranch : toCategoryFirstBranch;
1001
- const toCategoryIndex = toCategoryBranch.getShownCategoryIndex(toCategory);
1002
- const activeCategoryIndex = toCategoryBranch.getShownCategoryIndex(activeCategory);
1003
- if (activeBranch !== toCategoryBranch && toCategoryIndex > activeCategoryIndex) {
1004
- throw new WizardError(
1005
- `[State02]: Trying to switch to category "${categoryId}" in different branch "${toCategoryBranch.id}" from current active branch "${activeBranch.id}", but new category has uncompleted prev category in new branch.`
1006
- );
1007
- }
1008
- if (toCategoryIndex > activeCategoryIndex) {
1009
- activeBranch.getShownCategories(activeCategoryIndex, toCategoryIndex - 1).forEach((mid) => builder.skipCategoryUncompleted(mid.id));
1010
- }
1011
- if (this.wizardConfig.getOptions().isBackResetCompleted && toCategoryIndex < activeCategoryIndex) {
1012
- activeBranch.getShownCategories(toCategoryIndex + 1, activeCategoryIndex).forEach((mid) => builder.resetCategory(mid.id));
1013
- }
1014
- builder.deactivateCategory(activeCategory.id);
1015
- if (this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange) {
1016
- return builder.activateFirstStep(categoryId).build();
1017
- }
1018
- return builder.activateCategory(categoryId).build();
1019
- }
1020
- hideCategory(categoryId, tree = this.currentTree()) {
1021
- const { activeBranch, activeCategory } = tree;
1022
- const projected = activeCategory.id === categoryId ? this.projectShownCategory(categoryId, tree) : tree;
1023
- const builder = new WizardTreeStateBuilder(projected, activeBranch.id);
1024
- return builder.hideCategory(categoryId).build();
1025
- }
1026
- hideStep(step, tree = this.currentTree()) {
1027
- const { activeBranch, lastActiveStep } = tree;
1028
- const projected = lastActiveStep.id === step ? this.projectShownStep(step, tree) : tree;
1029
- const builder = new WizardTreeStateBuilder(projected, activeBranch.id);
1030
- return builder.hideStep(step).deactivateStep(step).build();
1031
- }
1032
- next(branch, tree = this.currentTree()) {
1033
- const { activeBranch, branchMap } = tree;
1034
- const nextBranch = branch ? branchMap[branch] : activeBranch;
1035
- const builder = new WizardTreeStateBuilder(tree, branch ?? activeBranch.id);
1036
- const activeCategory = nextBranch.activeCategory;
1037
- const activeStep = activeCategory.lastActiveStep;
1038
- const nextCategory = nextBranch.nextCategory;
1039
- const nextStep = activeCategory.nextStep;
1040
- if (activeBranch.activeCategory !== nextBranch.activeCategory) {
1041
- throw new WizardError(
1042
- `[State01]: In order to move to the "${branch}" branch, you need to have common category between 2 branches`
1043
- );
1044
- }
1045
- builder.unskipCategory(activeCategory.id).completeStep(activeStep.id);
1046
- if (nextStep) {
1047
- return builder.activateStep(nextStep.id).build();
1048
- }
1049
- if (nextCategory) {
1050
- builder.deactivateCategory(activeCategory.id);
1051
- if (this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange) {
1052
- return builder.activateFirstStep(nextCategory.id).build();
1053
- }
1054
- return builder.activateCategory(nextCategory.id).build();
1055
- }
1056
- return builder.buildComplete();
1057
- }
1058
- nextCategory(branch, tree = this.currentTree()) {
1059
- const { activeBranch, branchMap } = tree;
1060
- const nextBranch = branch ? branchMap[branch] : activeBranch;
1061
- const builder = new WizardTreeStateBuilder(tree, branch ?? activeBranch.id);
1062
- const activeCategory = nextBranch.activeCategory;
1063
- const activeStep = activeCategory.lastActiveStep;
1064
- const nextCategory = nextBranch.nextCategory;
1065
- if (activeBranch.activeCategory !== nextBranch.activeCategory) {
1066
- throw new WizardError(
1067
- `[State01]: In order to move to the "${branch}" branch, you need to have common category between 2 branches`
1068
- );
1069
- }
1070
- builder.deactivateCategory(activeCategory.id).completeStep(activeStep.id);
1071
- if (nextCategory) {
1072
- builder.skipCategoryUncompleted(activeCategory.id);
1073
- if (this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange) {
1074
- return builder.activateFirstStep(nextCategory.id).build();
1075
- }
1076
- return builder.activateCategory(nextCategory.id).build();
1077
- }
1078
- return builder.buildComplete();
1079
- }
1080
- prev(tree = this.currentTree()) {
1081
- const { activeBranch } = tree;
1082
- const builder = new WizardTreeStateBuilder(tree);
1083
- const activeCategory = activeBranch.activeCategory;
1084
- const activeStep = activeCategory.lastActiveStep;
1085
- const prevCategory = activeBranch.prevCategory;
1086
- const prevStep = activeCategory.prevStep;
1087
- if (this.wizardConfig.getOptions().isBackResetCompleted) {
1088
- builder.uncompleteStep(activeStep.id);
1089
- }
1090
- if (prevStep) {
1091
- return builder.deactivateStep(activeStep.id).build();
1092
- }
1093
- if (prevCategory) {
1094
- return builder.deactivateCategory(activeCategory.id).activateCategory(prevCategory.id).build();
1095
- }
1096
- return builder.buildExit();
1097
- }
1098
- prevCategory(tree = this.currentTree()) {
1099
- const { activeBranch } = tree;
1100
- const builder = new WizardTreeStateBuilder(tree);
1101
- const activeCategory = activeBranch.activeCategory;
1102
- const prevCategory = activeBranch.prevCategory;
1103
- if (prevCategory && this.wizardConfig.getOptions().isBackResetCompleted) {
1104
- builder.resetCategory(activeCategory.id);
1105
- }
1106
- if (prevCategory) {
1107
- return builder.deactivateCategory(activeCategory.id).activateCategory(prevCategory.id).build();
1108
- }
1109
- return builder.buildExit();
1110
- }
1111
- resetCategory(category, from = 0, tree = this.currentTree()) {
1112
- const { activeCategory } = tree;
1113
- const builder = new WizardTreeStateBuilder(tree);
1114
- builder.resetCategory(category, from);
1115
- if (activeCategory.id === category) {
1116
- return builder.activateStep(activeCategory.firstStep.id).build();
1117
- }
1118
- return builder.build();
1119
- }
1120
- resetTree(tree = this.currentTree()) {
1121
- const reset = new WizardTreeStateBuilder(tree).getResetTree();
1122
- return new WizardTreeStateBuilder(reset, tree.activeBranch.id).activateStep(reset.activeCategory.firstStep.id).build();
1123
- }
1124
- showCategory(categoryId, tree = this.currentTree()) {
1125
- const { activeBranch } = tree;
1126
- const builder = new WizardTreeStateBuilder(tree);
1127
- const activeCategoryIndex = activeBranch.categories.indexOf(activeBranch.activeCategory);
1128
- const categoryIndex = activeBranch.categories.findIndex((category) => category.id === categoryId);
1129
- const isBeforeActiveCategory = activeCategoryIndex > categoryIndex;
1130
- builder.showCategory(categoryId);
1131
- if (isBeforeActiveCategory) builder.skipCategory(categoryId);
1132
- return builder.build();
1133
- }
1134
- showStep(step, tree = this.currentTree()) {
1135
- const { activeCategory, lastActiveStep, stepMap } = tree;
1136
- const builder = new WizardTreeStateBuilder(tree);
1137
- const stepState = stepMap[step];
1138
- const isInActiveCategory = activeCategory.steps.some((s) => s.id === step);
1139
- const isBeforeLastActiveStep = lastActiveStep.htmlIndex > stepState.htmlIndex;
1140
- builder.showStep(step);
1141
- if (isBeforeLastActiveStep) builder.completeStep(step);
1142
- if (isInActiveCategory && isBeforeLastActiveStep) builder.activateStep(step);
1143
- return builder.build();
1144
- }
1145
- skipCategory(category, tree = this.currentTree()) {
1146
- const { activeBranch } = tree;
1147
- const { activeCategory, nextCategory } = activeBranch;
1148
- const builder = new WizardTreeStateBuilder(tree);
1149
- builder.skipCategory(category);
1150
- if (activeCategory.id === category && nextCategory) {
1151
- return builder.deactivateCategory(category).activateCategory(nextCategory.id).build();
1152
- }
1153
- if (activeCategory.id === category && !nextCategory) {
1154
- return builder.buildComplete();
1155
- }
1156
- return builder.build();
1157
- }
1158
- currentTree() {
1159
- return this.wizardStore.getTreeSnapshot();
1160
- }
1161
- projectShownCategory(categoryId, tree) {
1162
- const { activeBranch } = tree;
1163
- const result = categoryId === activeBranch.firstCategory.id ? this.nextCategory(null, tree) : this.prevCategory(tree);
1164
- return result;
1165
- }
1166
- projectShownStep(step, tree) {
1167
- const { activeBranch, activeCategory, stepMap } = tree;
1168
- const stepState = stepMap[step];
1169
- const isFirstCategory = stepState.categoryId === activeBranch.firstCategory.id;
1170
- const isFirstStep = step === activeCategory.firstStep.id;
1171
- const result = isFirstCategory && isFirstStep ? this.next(null, tree) : this.prev(tree);
1172
- return result;
1173
- }
1174
- };
1175
-
1176
- // src/core/strategies/progress/wizard-progress.strategy.ts
1177
- var WizardProgressStrategy = class {
1178
- };
1179
-
1180
- // src/core/strategies/progress/wizard-active-progress.strategy.ts
1181
- var WizardActiveProgressStrategy = class extends WizardProgressStrategy {
1182
- getProgress(tree) {
1183
- const { activeCategory, categoryMap } = tree;
1184
- const progress = {};
1185
- for (const category of Object.keys(categoryMap)) {
1186
- const categoryState = categoryMap[category];
1187
- if (categoryState.htmlIndex !== activeCategory.htmlIndex) {
1188
- progress[category] = categoryState.htmlIndex < activeCategory.htmlIndex ? 100 : 0;
1189
- continue;
1190
- }
1191
- progress[category] = categoryState.shownSteps.length > 0 ? (categoryState.activeSteps.length - 1) * 100 / categoryState.shownSteps.length : 0;
1192
- }
1193
- return progress;
1194
- }
1195
- };
1196
-
1197
- // src/core/strategies/scroll/wizard-scroll.strategy.ts
1198
- var WizardScrollStrategy = class {
1199
- // Thin re-export so subclasses keep the existing call site.
1200
- static projectToTree = projectToTree;
1201
- container;
1202
- /** Called when toggling step/category visibility (instant scroll by default). */
1203
- onToggle(navigation) {
1204
- const tree = projectToTree(navigation.to);
1205
- if (!tree) return Promise.resolve(false);
1206
- const isFirstStepOfCategory = tree.lastActiveStep?.id === tree.activeCategory.firstStep?.id;
1207
- return scrollToStep(isFirstStepOfCategory ? null : tree.lastActiveStep?.id, "auto", this.container);
1208
- }
1209
- /**
1210
- * Imperative scroll-to-top of the configured container (or window). Useful
1211
- * for surfacing top-of-page state — e.g. an error banner — after a failed
1212
- * submit, without re-running the navigation pipeline.
1213
- */
1214
- scrollToTop(behavior = "smooth") {
1215
- return scrollToStep(null, behavior, this.container);
1216
- }
1217
- setContainer(container) {
1218
- this.container = container;
1219
- }
1220
- };
1221
- function scrollToStep(stepId, behavior, container) {
1222
- if (typeof document === "undefined") return Promise.resolve(false);
1223
- const reducedMotion = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : false;
1224
- const effectiveBehavior = reducedMotion ? "auto" : behavior;
1225
- if (!stepId) {
1226
- const containerEl = resolveScrollContainer(container);
1227
- if (containerEl) {
1228
- containerEl.scrollTo({ behavior: effectiveBehavior, top: 0 });
1229
- } else if (typeof window !== "undefined") {
1230
- window.scrollTo({ behavior: effectiveBehavior, top: 0 });
1231
- }
1232
- return Promise.resolve(true);
1233
- }
1234
- const element = document.getElementById(stepId);
1235
- if (!element) return Promise.resolve(false);
1236
- element.scrollIntoView({ behavior: effectiveBehavior, block: "start" });
1237
- return Promise.resolve(true);
1238
- }
1239
- function resolveScrollContainer(c) {
1240
- if (!c) return null;
1241
- if (typeof c === "function") return c();
1242
- if ("current" in c) return c.current;
1243
- return c;
1244
- }
1245
-
1246
- // src/core/strategies/scroll/wizard-smooth-scroll.strategy.ts
1247
- var WizardSmoothScrollStrategy = class extends WizardScrollStrategy {
1248
- constructor(wizardConfig) {
1249
- super();
1250
- this.wizardConfig = wizardConfig;
1251
- }
1252
- wizardConfig;
1253
- onNavigate(navigation) {
1254
- const tree = WizardScrollStrategy.projectToTree(navigation.to);
1255
- if (!tree) return Promise.resolve(false);
1256
- const isFirstStepOfCategory = tree.lastActiveStep?.id === tree.activeCategory.firstStep?.id;
1257
- const stepId = isFirstStepOfCategory ? null : tree.lastActiveStep?.id;
1258
- const useInstant = navigation.isCategoryChanging || (this.wizardConfig?.isMobile ?? false);
1259
- return scrollToStep(stepId, useInstant ? "auto" : "smooth", this.container);
1260
- }
1261
- };
1262
-
1263
- // src/core/strategies/visibility/wizard-visibility.strategy.ts
1264
- var WizardVisibilityStrategy = class {
1265
- };
1266
-
1267
- // src/core/strategies/visibility/wizard-default-visibility.strategy.ts
1268
- var WizardDefaultVisibilityStrategy = class extends WizardVisibilityStrategy {
1269
- constructor(wizardConfig) {
1270
- super();
1271
- this.wizardConfig = wizardConfig;
1272
- }
1273
- wizardConfig;
1274
- isStepVisible(step, tree) {
1275
- const isShowStep = step.isActive && step.isShow;
1276
- const isLastActiveStep = step.id === tree.lastActiveStep?.id;
1277
- return this.wizardConfig.isMobile ? isShowStep && isLastActiveStep : isShowStep;
1278
- }
1279
- };
1280
-
1281
- // src/core/strategies/visibility/wizard-last-active-visibility.strategy.ts
1282
- var WizardLastActiveVisibilityStrategy = class extends WizardVisibilityStrategy {
1283
- isStepVisible(step, tree) {
1284
- const isShowStep = step.isActive && step.isShow;
1285
- const isLastActiveStep = step.id === tree.lastActiveStep?.id;
1286
- return isShowStep && isLastActiveStep;
1287
- }
1288
- };
1289
-
1290
- // src/core/wizard-default.config.ts
1291
- var passResolver = () => true;
1292
- var wizardDefaultConfig = {
1293
- backBtnClass: "",
1294
- backBtnText: "Back",
1295
- doneDotText: "Finish",
1296
- enableTracing: "none",
1297
- finishText: "Finish",
1298
- headerI18n: null,
1299
- isActiveCategoryClickReset: true,
1300
- isBackResetCompleted: true,
1301
- isDoneDot: false,
1302
- isShowFirstStepOnCategoryChange: false,
1303
- isShowWizardHeader: true,
1304
- isShowWizardHeaderSteps: true,
1305
- nextBtnClass: "",
1306
- nextBtnText: "Next",
1307
- nextCategoryText: "Continue",
1308
- resolveCategoryChange: passResolver,
1309
- resolveCategoryComplete: passResolver,
1310
- resolveCategoryEnter: passResolver,
1311
- resolveStepChange: passResolver,
1312
- silenceErrors: false,
1313
- stickyHeader: true
1314
- };
1315
-
1316
- // src/core/wizard-config.ts
1317
- var WizardConfig = class {
1318
- /**
1319
- * Whether the wizard is rendering on a mobile viewport. Used by the default
1320
- * visibility and scroll strategies. The React adapter (Phase 15) updates this
1321
- * via a media-query subscription; in plain Node (tests/SSR), it stays `false`.
1322
- */
1323
- isMobile = false;
1324
- get options() {
1325
- return this.current;
1326
- }
1327
- current;
1328
- disposed = false;
1329
- listeners = /* @__PURE__ */ new Set();
1330
- notifyScheduled = false;
1331
- constructor(overrides = {}) {
1332
- this.current = { ...wizardDefaultConfig, ...overrides };
1333
- }
1334
- dispose() {
1335
- this.disposed = true;
1336
- this.listeners.clear();
1337
- }
1338
- getOptions() {
1339
- return this.current;
1340
- }
1341
- setOptions(options) {
1342
- if (this.disposed) return this;
1343
- let changed = false;
1344
- for (const k of Object.keys(options)) {
1345
- if (!Object.is(options[k], this.current[k])) {
1346
- changed = true;
1347
- break;
1348
- }
1349
- }
1350
- if (!changed) return this;
1351
- this.current = { ...this.current, ...options };
1352
- this.scheduleNotify();
1353
- return this;
1354
- }
1355
- subscribe(listener) {
1356
- if (this.disposed) return () => {
1357
- };
1358
- this.listeners.add(listener);
1359
- return () => {
1360
- this.listeners.delete(listener);
1361
- };
1362
- }
1363
- scheduleNotify() {
1364
- if (this.notifyScheduled) return;
1365
- this.notifyScheduled = true;
1366
- queueMicrotask(() => {
1367
- this.notifyScheduled = false;
1368
- if (this.disposed) return;
1369
- const snapshot = this.current;
1370
- for (const listener of [...this.listeners]) {
1371
- listener(snapshot);
1372
- }
1373
- });
1374
- }
1375
- };
1376
-
1377
- // src/core/wizard-log.ts
1378
- var WizardLog = class {
1379
- constructor(wizardConfig) {
1380
- this.wizardConfig = wizardConfig;
1381
- }
1382
- wizardConfig;
1383
- error(e) {
1384
- if (!(e instanceof WizardError)) {
1385
- console.error(e);
1386
- return;
1387
- }
1388
- if (this.wizardConfig.getOptions().silenceErrors) {
1389
- return;
1390
- }
1391
- console.error(e);
1392
- }
1393
- trace(...args) {
1394
- if (this.wizardConfig.getOptions().enableTracing !== "none") {
1395
- console.log(...args);
1396
- }
1397
- }
1398
- };
1399
-
1400
- // src/core/wizard-store.ts
1401
- var WizardStore = class {
1402
- constructor(storagePrefix) {
1403
- this.storagePrefix = storagePrefix;
1404
- this.initOnce = new Promise((resolve) => {
1405
- this.resolveInitOnce = resolve;
1406
- });
1407
- }
1408
- storagePrefix;
1409
- initOnce;
1410
- get shapeId() {
1411
- return this._shapeId ?? "";
1412
- }
1413
- _shapeId = null;
1414
- current = null;
1415
- disposed = false;
1416
- initialTree = null;
1417
- listeners = /* @__PURE__ */ new Set();
1418
- resolveInitOnce;
1419
- dispose() {
1420
- this.disposed = true;
1421
- this.listeners.clear();
1422
- }
1423
- getTreeSnapshot() {
1424
- if (!this.current) {
1425
- throw new WizardInitializationError("[WizardStore] getTreeSnapshot called before init");
1426
- }
1427
- return this.current;
1428
- }
1429
- init(initialTree) {
1430
- if (this.disposed) return;
1431
- if (this.initialTree) {
1432
- console.warn("[WizardStore] init() called more than once; ignoring subsequent call.");
1433
- return;
1434
- }
1435
- this.initialTree = initialTree;
1436
- this._shapeId = getShapeId(initialTree.state, this.storagePrefix);
1437
- this.setState(initialTree);
1438
- this.resolveInitOnce(initialTree);
1439
- }
1440
- setState(tree) {
1441
- if (this.disposed) return;
1442
- if (!this.initialTree) {
1443
- throw new WizardInitializationError("[WizardStore] setState called before init");
1444
- }
1445
- if (this.current === tree) return;
1446
- this.current = tree;
1447
- for (const listener of [...this.listeners]) {
1448
- listener();
1449
- }
1450
- }
1451
- subscribe = (listener) => {
1452
- this.listeners.add(listener);
1453
- return () => {
1454
- this.listeners.delete(listener);
1455
- };
1456
- };
1457
- };
1458
-
1459
- // src/core/wizard-engine.ts
1460
- var WizardEngine = class {
1461
- get configOptions() {
1462
- return this.config.options;
1463
- }
1464
- get isInitialized() {
1465
- return this.initialized;
1466
- }
1467
- get lastActiveStep() {
1468
- return this.tree.lastActiveStep;
1469
- }
1470
- get progress() {
1471
- return this.progressStrategy.getProgress(this.tree);
1472
- }
1473
- get shapeId() {
1474
- return this.store.shapeId;
1475
- }
1476
- get steps() {
1477
- return this.tree.stepMap;
1478
- }
1479
- get tree() {
1480
- return this.store.getTreeSnapshot();
1481
- }
1482
- committed = false;
1483
- // commitRegistration() entered
1484
- config;
1485
- disposed = false;
1486
- initialBranch;
1487
- initialized = false;
1488
- // store.init() ran successfully
1489
- initialState;
1490
- initService;
1491
- listeners;
1492
- log;
1493
- // ------------- snapshots -------------
1494
- navService;
1495
- pendingPostInitTasks = [];
1496
- progressStrategy;
1497
- scrollStrategy;
1498
- stateService;
1499
- store;
1500
- visibilityStrategy;
1501
- constructor(options) {
1502
- this.config = new WizardConfig(options.config ?? {});
1503
- const storagePrefix = options.config?.storagePrefix ?? void 0;
1504
- this.store = new WizardStore(storagePrefix);
1505
- this.log = new WizardLog(this.config);
1506
- this.scrollStrategy = options.strategies?.scroll ?? new WizardSmoothScrollStrategy(this.config);
1507
- if (options.scrollContainer !== void 0) {
1508
- this.scrollStrategy.setContainer(options.scrollContainer);
1509
- }
1510
- this.visibilityStrategy = options.strategies?.visibility ?? new WizardDefaultVisibilityStrategy(this.config);
1511
- this.progressStrategy = options.strategies?.progress ?? new WizardActiveProgressStrategy();
1512
- this.stateService = new WizardStateService(this.store, this.config);
1513
- this.navService = new WizardNavigationService(
1514
- this.store,
1515
- this.config,
1516
- this.stateService,
1517
- this.scrollStrategy
1518
- );
1519
- const initializers = options.initializers ?? [new WizardDefaultInitializer()];
1520
- this.initService = new WizardInitializerService(this.log, initializers);
1521
- this.listeners = options.listeners ?? [];
1522
- this.initialState = options.state;
1523
- this.initialBranch = options.activeBranch;
1524
- }
1525
- // ------------- React adapter wiring -------------
1526
- back() {
1527
- return this.runOrQueue(() => this.navService.navigate(this.stateService.prev()));
1528
- }
1529
- backCategory() {
1530
- return this.runOrQueue(() => this.navService.navigate(this.stateService.prevCategory()));
1531
- }
1532
- async commitRegistration() {
1533
- if (this.disposed) return;
1534
- if (this.committed) return;
1535
- this.committed = true;
1536
- const tree = await this.initService.getInitialState(this.initialState, this.initialBranch);
1537
- if (this.disposed) {
1538
- for (const task of this.pendingPostInitTasks.splice(0)) task.resolve(false);
1539
- return;
1540
- }
1541
- this.store.init(tree);
1542
- this.initialized = true;
1543
- for (const listener of this.listeners) {
1544
- try {
1545
- listener.onInit(tree);
1546
- } catch (e) {
1547
- this.log.error(e);
1548
- }
1549
- }
1550
- this.store.subscribe(() => {
1551
- const current = this.store.getTreeSnapshot();
1552
- for (const listener of this.listeners) {
1553
- try {
1554
- listener.onTreeChange(current);
1555
- } catch (e) {
1556
- this.log.error(e);
1557
- }
1558
- }
1559
- });
1560
- this.navService.on("*", (event) => {
1561
- for (const listener of this.listeners) {
1562
- try {
1563
- listener.onEvent(event);
1564
- } catch (e) {
1565
- this.log.error(e);
1566
- }
1567
- }
1568
- });
1569
- for (const task of this.pendingPostInitTasks.splice(0)) {
1570
- task.run();
1571
- }
1572
- }
1573
- // ------------- bootstrap -------------
1574
- completeWizard() {
1575
- return this.runOrQueue(() => this.navService.completeWizard());
1576
- }
1577
- // ------------- imperative API -------------
1578
- dispose() {
1579
- if (this.disposed) return;
1580
- this.disposed = true;
1581
- for (const task of this.pendingPostInitTasks.splice(0)) task.resolve(false);
1582
- const lastTree = this.initialized ? this.store.getTreeSnapshot() : null;
1583
- for (const listener of this.listeners) {
1584
- try {
1585
- listener.onDestroy(lastTree);
1586
- } catch (e) {
1587
- this.log.error(e);
1588
- }
1589
- }
1590
- this.navService.dispose();
1591
- this.store.dispose();
1592
- this.config.dispose();
1593
- }
1594
- exitWizard() {
1595
- return this.runOrQueue(() => this.navService.exitWizard());
1596
- }
1597
- getTreeSnapshot = () => this.store.getTreeSnapshot();
1598
- go(tree) {
1599
- return this.runOrQueue(() => this.navService.navigate(tree));
1600
- }
1601
- goToCategory(category) {
1602
- return this.runOrQueue(() => this.navService.navigate(this.stateService.goToCategory(category)));
1603
- }
1604
- hideCategory(category) {
1605
- return this.runOrQueue(() => this.navService.hideCategory(category));
1606
- }
1607
- hideStep(step) {
1608
- return this.runOrQueue(() => this.navService.hideStep(step));
1609
- }
1610
- isStepVisible(stepId) {
1611
- const tree = this.store.getTreeSnapshot();
1612
- const step = tree.stepMap[stepId];
1613
- if (!step) return false;
1614
- return this.visibilityStrategy.isStepVisible(step, tree);
1615
- }
1616
- next(branch) {
1617
- return this.runOrQueue(() => this.navService.navigate(this.stateService.next(branch ?? null)));
1618
- }
1619
- nextCategory(branch) {
1620
- return this.runOrQueue(() => this.navService.navigate(this.stateService.nextCategory(branch ?? null)));
1621
- }
1622
- on(type, handler) {
1623
- return this.navService.on(type, handler);
1624
- }
1625
- resetActiveCategory(from = 0) {
1626
- return this.runOrQueue(
1627
- () => this.navService.navigate(this.stateService.resetCategory(this.tree.activeCategory.id, from))
1628
- );
1629
- }
1630
- resetCategory(category, from = 0) {
1631
- return this.runOrQueue(() => this.navService.navigate(this.stateService.resetCategory(category, from)));
1632
- }
1633
- resetWizard() {
1634
- return this.runOrQueue(() => this.navService.navigate(this.stateService.resetTree()));
1635
- }
1636
- scrollToTop(behavior = "smooth") {
1637
- return this.scrollStrategy.scrollToTop(behavior);
1638
- }
1639
- showCategory(category) {
1640
- return this.runOrQueue(() => this.navService.showCategory(category));
1641
- }
1642
- showStep(step) {
1643
- return this.runOrQueue(() => this.navService.showStep(step));
1644
- }
1645
- skipActiveCategory() {
1646
- return this.runOrQueue(
1647
- () => this.navService.navigate(this.stateService.skipCategory(this.tree.activeCategory.id))
1648
- );
1649
- }
1650
- skipCategory(category) {
1651
- return this.runOrQueue(
1652
- () => this.navService.navigate(this.stateService.skipCategory(category ?? this.tree.activeCategory.id))
1653
- );
1654
- }
1655
- subscribe = (listener) => this.store.subscribe(listener);
1656
- toggleCategory(category, show) {
1657
- return show ? this.showCategory(category) : this.hideCategory(category);
1658
- }
1659
- // ------------- lifecycle -------------
1660
- toggleStep(step, show) {
1661
- return show ? this.showStep(step) : this.hideStep(step);
1662
- }
1663
- // ------------- internal -------------
1664
- runOrQueue(action) {
1665
- if (this.disposed) {
1666
- return Promise.resolve(false);
1667
- }
1668
- if (!this.initialized) {
1669
- return new Promise((resolve, reject) => {
1670
- this.pendingPostInitTasks.push({
1671
- resolve,
1672
- run: () => {
1673
- action().then(resolve, reject);
1674
- }
1675
- });
1676
- });
1677
- }
1678
- return action();
1679
- }
1680
- };
1681
-
1682
- // src/enums/wizard-category-direction.enum.ts
1683
- var WizardCategoryDirection = /* @__PURE__ */ ((WizardCategoryDirection2) => {
1684
- WizardCategoryDirection2["Backward"] = "backward";
1685
- WizardCategoryDirection2["Forward"] = "forward";
1686
- return WizardCategoryDirection2;
1687
- })(WizardCategoryDirection || {});
1688
-
1689
- // src/react/components/wizard-action-button.tsx
1690
- import { Slot } from "@radix-ui/react-slot";
1691
- import { jsx } from "react/jsx-runtime";
1692
- function WizardActionButton(props) {
1693
- const { Button } = useWizardComponents();
1694
- if (props.asChild) {
1695
- return /* @__PURE__ */ jsx(Slot, { className: props.className, onClick: props.onClick, children: props.children });
1696
- }
1697
- return /* @__PURE__ */ jsx(Button, { className: props.className, onClick: props.onClick, type: "button", variant: props.variant, children: props.children ?? props.defaultLabel });
1698
- }
1699
-
1700
- // src/react/components/wizard-back.tsx
1701
- import { jsx as jsx2 } from "react/jsx-runtime";
1702
- function WizardBack(props) {
1703
- const wizard = useWizard();
1704
- return /* @__PURE__ */ jsx2(
1705
- WizardActionButton,
1706
- {
1707
- asChild: props.asChild,
1708
- className: props.className,
1709
- defaultLabel: wizard.configOptions.backBtnText ?? "Back",
1710
- onClick: () => void wizard.back(),
1711
- variant: "ghost",
1712
- children: props.children
1713
- }
1714
- );
1715
- }
1716
-
1717
- // src/react/components/wizard-category.tsx
1718
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
1719
- function WizardCategory(props) {
1720
- const wizard = useWizard();
1721
- if (wizard.tree.activeCategory.id !== props.categoryId) return null;
1722
- return /* @__PURE__ */ jsx3(Fragment, { children: props.children });
1723
- }
1724
-
1725
- // src/react/components/wizard-stepper-dot.tsx
1726
- import { CheckIcon } from "lucide-react";
1727
- import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1728
- function WizardStepperDot(props) {
1729
- const { clickable = false, isLast = false, label, onClick, progress, state } = props;
1730
- const isInteractive = clickable && !!onClick;
1731
- return /* @__PURE__ */ jsxs("li", { className: "relative flex flex-1 items-center", "data-state": state, children: [
1732
- /* @__PURE__ */ jsx4(
1733
- "button",
1734
- {
1735
- "aria-current": state === "active" ? "step" : void 0,
1736
- "aria-label": label ?? state,
1737
- className: cn(
1738
- "relative flex size-3 shrink-0 items-center justify-center rounded-full border-2 transition-colors",
1739
- state === "pending" && "border-border bg-background",
1740
- state === "active" && "border-success-text bg-success-text ring-2 ring-success-border/40 ring-offset-2 ring-offset-background",
1741
- state === "completed" && "border-success-border bg-success-text",
1742
- state === "skipped" && "border-border bg-background opacity-60",
1743
- isInteractive && "cursor-pointer hover:bg-success-bg",
1744
- !isInteractive && "cursor-default"
1745
- ),
1746
- disabled: !isInteractive,
1747
- onClick: isInteractive ? onClick : void 0,
1748
- type: "button",
1749
- children: state === "completed" && /* @__PURE__ */ jsx4(CheckIcon, { className: "size-2 text-background" })
1750
- }
1751
- ),
1752
- !isLast && /* @__PURE__ */ jsx4("span", { "aria-hidden": true, className: "relative ml-1 mr-1 h-px flex-1 bg-border", children: /* @__PURE__ */ jsx4(
1753
- "span",
1754
- {
1755
- className: "absolute inset-y-0 left-0 bg-success-border transition-[width]",
1756
- style: { width: `${Math.max(0, Math.min(100, progress))}%` }
1757
- }
1758
- ) }),
1759
- label && /* @__PURE__ */ jsx4(
1760
- "span",
1761
- {
1762
- className: cn(
1763
- "absolute -top-6 left-0 -translate-x-[calc(50%-0.375rem)] text-sm font-semibold whitespace-nowrap",
1764
- state === "active" && "text-success-text",
1765
- state !== "active" && "text-muted-foreground"
1766
- ),
1767
- children: label
1768
- }
1769
- )
1770
- ] });
1771
- }
1772
-
1773
- // src/react/components/wizard-stepper.tsx
1774
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1775
- function WizardStepper(props) {
1776
- const { canAccessCategory, categories, doneDot, headerI18n, onCategoryClick, progress } = props;
1777
- const lastIdx = categories.length - 1;
1778
- return /* @__PURE__ */ jsxs2("ol", { "aria-label": "Wizard progress", className: "relative flex flex-1 items-center pt-6", children: [
1779
- categories.map((category, idx) => {
1780
- const isLast = idx === lastIdx && !doneDot;
1781
- const clickable = canAccessCategory?.(category) ?? false;
1782
- return /* @__PURE__ */ jsx5(
1783
- WizardStepperDot,
1784
- {
1785
- clickable,
1786
- isLast,
1787
- label: headerI18n?.[category.id],
1788
- onClick: onCategoryClick ? () => onCategoryClick(category) : void 0,
1789
- progress: progress[category.id] ?? 0,
1790
- state: getDotState(category, progress[category.id] ?? 0)
1791
- },
1792
- category.id
1793
- );
1794
- }),
1795
- doneDot && /* @__PURE__ */ jsx5(WizardStepperDot, { isLast: true, label: doneDot.text, progress: 0, state: "pending" })
1796
- ] });
1797
- }
1798
- function getDotState(category, progress) {
1799
- if (category.isActive) return "active";
1800
- if (progress >= 100) return "completed";
1801
- if (category.isSkipped) return "skipped";
1802
- return "pending";
1803
- }
1804
-
1805
- // src/react/components/wizard-header.tsx
1806
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
1807
- function WizardHeader() {
1808
- const wizard = useWizard();
1809
- const tree = wizard.tree;
1810
- const config = wizard.configOptions;
1811
- if (!config.isShowWizardHeader) return null;
1812
- const oneCategory = tree.activeBranch.shownCategories.length === 1 && !config.isDoneDot;
1813
- const stepHeaderEnabled = true;
1814
- const showSteps = config.isShowWizardHeaderSteps && stepHeaderEnabled && !oneCategory;
1815
- const canAccessCategory = (category) => {
1816
- if (config.isBackResetCompleted) return false;
1817
- if (category.isCompleted) return true;
1818
- const idx = tree.activeBranch.shownCategories.indexOf(category);
1819
- return !!tree.activeBranch.shownCategories[idx - 1]?.isCompleted;
1820
- };
1821
- const onCategoryClick = (category) => {
1822
- if (config.isBackResetCompleted) return;
1823
- const isCategoryStart = category.activeSteps.length === 1;
1824
- if (config.isActiveCategoryClickReset && category.isActive && !isCategoryStart) {
1825
- void wizard.resetCategory(category.id);
1826
- return;
1827
- }
1828
- if (!category.isActive && category.isCompleted) {
1829
- void wizard.goToCategory(category.id);
1830
- return;
1831
- }
1832
- if (!category.isActive && canAccessCategory(category)) {
1833
- void wizard.goToCategory(category.id);
1834
- }
1835
- };
1836
- return /* @__PURE__ */ jsxs3(
1837
- "header",
1838
- {
1839
- className: cn(
1840
- "relative mb-8 flex items-center gap-4 border-b border-border bg-background px-4 py-3",
1841
- config.stickyHeader && "sticky top-0 z-10"
1842
- ),
1843
- children: [
1844
- /* @__PURE__ */ jsx6(WizardBack, {}),
1845
- showSteps && /* @__PURE__ */ jsx6(
1846
- WizardStepper,
1847
- {
1848
- canAccessCategory,
1849
- categories: tree.activeBranch.shownCategories,
1850
- doneDot: config.isDoneDot ? { text: config.doneDotText } : void 0,
1851
- headerI18n: config.headerI18n,
1852
- onCategoryClick,
1853
- progress: wizard.progress
1854
- }
1855
- )
1856
- ]
1857
- }
1858
- );
1859
- }
1860
-
1861
- // src/react/components/wizard-next.tsx
1862
- import { jsx as jsx7 } from "react/jsx-runtime";
1863
- function WizardNext(props) {
1864
- const wizard = useWizard();
1865
- const defaultLabel = !props.asChild && props.children === void 0 ? getNextLabel(wizard) : "";
1866
- return /* @__PURE__ */ jsx7(
1867
- WizardActionButton,
1868
- {
1869
- asChild: props.asChild,
1870
- className: props.className,
1871
- defaultLabel,
1872
- onClick: () => void wizard.next(),
1873
- children: props.children
1874
- }
1875
- );
1876
- }
1877
- function getNextLabel(wizard) {
1878
- const config = wizard.configOptions;
1879
- const tree = wizard.tree;
1880
- const activeStep = tree.lastActiveStep;
1881
- const category = tree.categoryMap[activeStep.categoryId];
1882
- const isLastStep = category.lastStep.id === activeStep.id;
1883
- const isLastCategory = tree.activeBranch.lastCategory.id === category.id;
1884
- if (!isLastStep) return config.nextBtnText;
1885
- return isLastCategory ? config.finishText : config.nextCategoryText;
1886
- }
1887
-
1888
- // src/react/components/wizard-rail.tsx
1889
- import { CheckIcon as CheckIcon2 } from "lucide-react";
1890
-
1891
- // src/react/hooks/use-wizard-categories-view.ts
1892
- var EMPTY_SUB_STEPS = [];
1893
- function useWizardCategoriesView() {
1894
- const wizard = useWizard();
1895
- return wizard.tree.activeBranch.shownCategories.map((category) => projectCategory(category));
1896
- }
1897
- function getCategoryState(category) {
1898
- if (category.isActive) return "active";
1899
- if (category.isCompleted) return "completed";
1900
- if (category.isSkipped) return "skipped";
1901
- return "pending";
1902
- }
1903
- function projectCategory(category) {
1904
- const shown = category.shownSteps;
1905
- const subSteps = shown.length > 1 ? shown.slice().sort((a, b) => a.htmlIndex - b.htmlIndex).map((step) => ({ id: step.id, isActive: step.isActive })) : EMPTY_SUB_STEPS;
1906
- return {
1907
- id: category.id,
1908
- isActive: category.isActive,
1909
- state: getCategoryState(category),
1910
- subSteps
1911
- };
1912
- }
1913
-
1914
- // src/react/components/wizard-rail.tsx
1915
- import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1916
- function WizardRail(props) {
1917
- const { canAccessCategory, className, headerI18n, subStepLabels } = props;
1918
- const wizard = useWizard();
1919
- const view = useWizardCategoriesView();
1920
- const labels = headerI18n ?? wizard.configOptions.headerI18n;
1921
- const isClickable = (category) => canAccessCategory?.(category) ?? defaultClickable(category.state);
1922
- return /* @__PURE__ */ jsx8("nav", { "aria-label": "Wizard steps", className: cn("flex flex-col gap-1", className), children: /* @__PURE__ */ jsx8("ol", { className: "relative flex flex-col gap-1", children: view.map((category, idx) => {
1923
- const label = labels?.[category.id] ?? String(category.id);
1924
- const clickable = isClickable(category);
1925
- const isLast = idx === view.length - 1;
1926
- const isPassed = category.state === "completed" || category.state === "skipped";
1927
- return /* @__PURE__ */ jsxs4("li", { className: "relative", children: [
1928
- !isLast && /* @__PURE__ */ jsx8(
1929
- "span",
1930
- {
1931
- "aria-hidden": true,
1932
- className: cn(
1933
- "pointer-events-none absolute top-7 -bottom-2 left-5 w-px -translate-x-1/2 transition-colors duration-200",
1934
- isPassed ? "bg-success-border" : "bg-border"
1935
- )
1936
- }
1937
- ),
1938
- /* @__PURE__ */ jsxs4(
1939
- "button",
1940
- {
1941
- "aria-current": category.isActive ? "step" : void 0,
1942
- className: cn(
1943
- "group flex w-full items-center gap-3 rounded-md px-3 py-2 text-left text-sm font-medium transition-[color,background-color,transform] duration-200 ease-(--ease-out-strong)",
1944
- category.state === "active" && "bg-success-bg/60 text-success-text",
1945
- category.state === "completed" && "text-foreground",
1946
- category.state === "skipped" && "text-muted-foreground opacity-70",
1947
- category.state === "pending" && "text-muted-foreground",
1948
- clickable ? "cursor-pointer hover:bg-foreground/[0.06] motion-safe:active:scale-[0.97]" : "cursor-default"
1949
- ),
1950
- "data-state": category.state,
1951
- disabled: !clickable,
1952
- onClick: () => {
1953
- void wizard.goToCategory(category.id);
1954
- },
1955
- type: "button",
1956
- children: [
1957
- /* @__PURE__ */ jsx8(RailDot, { state: category.state }),
1958
- /* @__PURE__ */ jsx8("span", { children: label })
1959
- ]
1960
- }
1961
- ),
1962
- category.isActive && category.subSteps.length > 0 && /* @__PURE__ */ jsx8("ol", { className: "mt-1 ml-7 flex flex-col gap-1 border-l border-border pl-3", children: category.subSteps.map((step) => /* @__PURE__ */ jsx8(
1963
- "li",
1964
- {
1965
- "aria-current": step.isActive ? "step" : void 0,
1966
- className: cn(
1967
- "rounded px-2 py-1 text-sm",
1968
- step.isActive ? "text-success-text font-medium" : "text-muted-foreground"
1969
- ),
1970
- children: subStepLabels?.[step.id] ?? String(step.id)
1971
- },
1972
- step.id
1973
- )) })
1974
- ] }, category.id);
1975
- }) }) });
1976
- }
1977
- function defaultClickable(state) {
1978
- return state !== "pending";
1979
- }
1980
- function RailDot({ state }) {
1981
- return /* @__PURE__ */ jsx8(
1982
- "span",
1983
- {
1984
- "aria-hidden": true,
1985
- className: cn(
1986
- "flex size-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors",
1987
- state === "pending" && "border-border bg-background",
1988
- state === "active" && "border-success-border bg-success-bg",
1989
- state === "completed" && "border-success-border bg-success-text",
1990
- state === "skipped" && "border-border bg-background opacity-60"
1991
- ),
1992
- children: state === "completed" && /* @__PURE__ */ jsx8(CheckIcon2, { className: "size-2.5 text-background motion-safe:animate-in motion-safe:fade-in motion-safe:zoom-in-75 motion-safe:duration-200" })
1993
- }
1994
- );
1995
- }
1996
-
1997
- // src/react/components/wizard-step.tsx
1998
- import { useCallback, useContext, useSyncExternalStore } from "react";
1999
- import { jsx as jsx9 } from "react/jsx-runtime";
2000
- function WizardStep(props) {
2001
- const engine = useContext(WizardEngineContext);
2002
- if (!engine) {
2003
- throw new WizardError("WizardStep must be used inside <WizardProvider>");
2004
- }
2005
- const getSnapshot = useCallback(() => engine.isStepVisible(props.id), [engine, props.id]);
2006
- const isVisible = useSyncExternalStore(engine.subscribe, getSnapshot, getSnapshot);
2007
- if (!isVisible) return null;
2008
- return /* @__PURE__ */ jsx9(
2009
- "div",
2010
- {
2011
- className: "motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-1 motion-safe:duration-300 motion-safe:ease-(--ease-out-strong)",
2012
- id: props.id,
2013
- children: props.children
2014
- }
2015
- );
2016
- }
2017
-
2018
- // src/react/provider.tsx
2019
- import { useEffect, useState } from "react";
2020
- import { jsx as jsx10 } from "react/jsx-runtime";
2021
- function WizardProvider(props) {
2022
- const { activeBranch, children, config, initializers, listeners, scrollContainer, state, strategies } = props;
2023
- const [bootOptions] = useState(() => ({
2024
- activeBranch,
2025
- config,
2026
- initializers,
2027
- listeners,
2028
- scrollContainer,
2029
- state,
2030
- strategies
2031
- }));
2032
- const [engine, setEngine] = useState(null);
2033
- useEffect(() => {
2034
- const newEngine = new WizardEngine(bootOptions);
2035
- let cancelled = false;
2036
- newEngine.commitRegistration().then(() => {
2037
- if (!cancelled) setEngine(newEngine);
2038
- });
2039
- return () => {
2040
- cancelled = true;
2041
- newEngine.dispose();
2042
- setEngine((prev) => prev === newEngine ? null : prev);
2043
- };
2044
- }, [bootOptions]);
2045
- if (!engine) {
2046
- return null;
2047
- }
2048
- return /* @__PURE__ */ jsx10(WizardEngineContext.Provider, { value: engine, children });
2049
- }
2050
-
2051
- // src/react/use-wizard-engine-ref.ts
2052
- import { useEffect as useEffect2, useRef } from "react";
2053
- function useWizardEngineRef() {
2054
- return useRef(null);
2055
- }
2056
- function WizardEngineRefCapture({
2057
- engineRef
2058
- }) {
2059
- const wizard = useWizard();
2060
- useEffect2(() => {
2061
- engineRef.current = wizard;
2062
- return () => {
2063
- engineRef.current = null;
2064
- };
2065
- }, [engineRef, wizard]);
2066
- return null;
2067
- }
2068
-
2069
- // src/react/use-wizard-event.ts
2070
- import { useContext as useContext2, useEffect as useEffect3, useRef as useRef2 } from "react";
2071
- function useWizardEvent(type, handler) {
2072
- const engine = useContext2(WizardEngineContext);
2073
- if (!engine) {
2074
- throw new WizardError("useWizardEvent must be used inside <WizardProvider>");
2075
- }
2076
- const handlerRef = useRef2(handler);
2077
- useEffect3(() => {
2078
- handlerRef.current = handler;
2079
- });
2080
- useEffect3(() => {
2081
- return engine.on(type, (event) => handlerRef.current(event));
2082
- }, [engine, type]);
2083
- }
2084
-
2085
- // src/react/use-wizard-step.ts
2086
- import { useCallback as useCallback2, useContext as useContext3, useRef as useRef3, useSyncExternalStore as useSyncExternalStore2 } from "react";
2087
- function useWizardStep(stepId) {
2088
- const engine = useContext3(WizardEngineContext);
2089
- if (!engine) {
2090
- throw new WizardError("useWizardStep must be used inside <WizardProvider>");
2091
- }
2092
- const lastRef = useRef3(null);
2093
- const getSnapshot = useCallback2(() => {
2094
- const tree = engine.getTreeSnapshot();
2095
- const next = tree.stepMap[stepId] ?? null;
2096
- const prev = lastRef.current;
2097
- if (prev !== null && next !== null && prev.isActive === next.isActive && prev.isShow === next.isShow && prev.isCompleted === next.isCompleted && prev.isSkipped === next.isSkipped) {
2098
- return prev;
2099
- }
2100
- lastRef.current = next;
2101
- return next;
2102
- }, [engine, stepId]);
2103
- return useSyncExternalStore2(engine.subscribe, getSnapshot, getSnapshot);
2104
- }
2105
- export {
2106
- TypedEmitter,
2107
- WizardActiveProgressStrategy,
2108
- WizardActiveStepRule,
2109
- WizardBack,
2110
- WizardCategory,
2111
- WizardCategoryDirection,
2112
- WizardCompleteEvent,
2113
- WizardCompleteTreeState,
2114
- WizardComponentsProvider,
2115
- WizardConfig,
2116
- WizardDefaultInitializer,
2117
- WizardDefaultVisibilityStrategy,
2118
- WizardEngine,
2119
- WizardEngineContext,
2120
- WizardEngineRefCapture,
2121
- WizardError,
2122
- WizardEvent,
2123
- WizardEventType,
2124
- WizardExitEvent,
2125
- WizardExitTreeState,
2126
- WizardHeader,
2127
- WizardInitializationError,
2128
- WizardInitializer,
2129
- WizardInitializerService,
2130
- WizardLastActiveVisibilityStrategy,
2131
- WizardListener,
2132
- WizardLog,
2133
- WizardNavigation,
2134
- WizardNavigationCancelledEvent,
2135
- WizardNavigationEndEvent,
2136
- WizardNavigationError,
2137
- WizardNavigationErrorEvent,
2138
- WizardNavigationIgnoredEvent,
2139
- WizardNavigationService,
2140
- WizardNavigationStartEvent,
2141
- WizardNext,
2142
- WizardPassedPrevCategoriesRule,
2143
- WizardPassedPrevStepsRule,
2144
- WizardProgressStrategy,
2145
- WizardProvider,
2146
- WizardRail,
2147
- WizardResolveEndEvent,
2148
- WizardResolveStartEvent,
2149
- WizardResolverError,
2150
- WizardRule,
2151
- WizardScrollEndEvent,
2152
- WizardScrollStartEvent,
2153
- WizardScrollStrategy,
2154
- WizardShownActiveCategoryRule,
2155
- WizardSingleActiveCategoryRule,
2156
- WizardSmoothScrollStrategy,
2157
- WizardStateService,
2158
- WizardStep,
2159
- WizardStepHideEvent,
2160
- WizardStepShowEvent,
2161
- WizardStepper,
2162
- WizardStepperDot,
2163
- WizardStore,
2164
- WizardTreeStateBuilder,
2165
- WizardVisibilityStrategy,
2166
- buildWizardBranchState,
2167
- buildWizardCategoryState,
2168
- buildWizardTreeState,
2169
- composeWizardProviders,
2170
- scrollToStep,
2171
- useWizard,
2172
- useWizardCategoriesView,
2173
- useWizardComponents,
2174
- useWizardEngineRef,
2175
- useWizardEvent,
2176
- useWizardStep,
2177
- withConfig,
2178
- withInitializer,
2179
- withListener,
2180
- withProgressStrategy,
2181
- withScrollContainer,
2182
- withScrollStrategy,
2183
- withVisibilityStrategy,
2184
- wizardDefaultBranch,
2185
- wizardDefaultConfig,
2186
- wizardDefaultState,
2187
- wizardRules
2188
- };
2189
- //# sourceMappingURL=index.js.map
2
+ import{a as l,b as P,c as Qt,d as me,e as Ye,f as ze,g as B,h as m,i as x}from"./chunk-RBC55LQI.js";var Ie=(p=>(p.Complete="complete",p.Exit="exit",p.NavigationCancelled="navigation_cancelled",p.NavigationEnd="navigation_end",p.NavigationError="navigation_error",p.NavigationIgnored="navigation_ignored",p.NavigationStart="navigation_start",p.ResolveEnd="resolve_end",p.ResolveStart="resolve_start",p.ScrollEnd="scroll_end",p.ScrollStart="scroll_start",p.StepHide="step_hide",p.StepShow="step_show",p))(Ie||{});var A=i=>i[i.length-1];var ve=i=>Array.isArray(i)?i:[i];var we=i=>{let e=i.branches.join(",");return`${i.htmlIndex}:${e}.${i.categoryId}.${i.id}`},Te=i=>`${+i.isShow}${+i.isCompleted}${+i.isSkipped}${+i.isActive}`;var Re=(i,e="")=>{let t=i.map(we).join("|");return e!==""&&e!==void 0?`@${e}@${t}`:t};var ke=(i,e="")=>{let t=i.map(Te).join("|");return e?`@${e}@${t}`:t};function Ee(i,e){let t=[],r=[],a=[],n=[],o=[];for(let g of e)g.isActive&&r.push(g),g.isShow&&t.push(g),g.isCompleted&&a.push(g),g.isSkipped&&n.push(g),g.isPassed&&o.push(g);let d=r[0]??t[0],c=g=>t.indexOf(g),s=c(d),S=t[0],y=A(t),h=s>0?t[s-1]??null:null,p=s>=0?t[s+1]??null:null,C=(g,T)=>t.slice(g,T+1);return{activeCategories:r,activeCategory:d,activeCategoryIndex:s,categories:[...e],completedCategories:a,firstCategory:S,getShownCategories:C,getShownCategoryIndex:c,id:i,lastCategory:y,nextCategory:p,passedCategories:o,prevCategory:h,shownCategories:t,skippedCategories:n}}function Pe(i,e,t){let r=t[0]?.branches??[],a=[],n=[],o=[],d=[],c=[];for(let f of t)f.isActive&&n.push(f),f.isShow&&a.push(f),f.isSkipped&&d.push(f),f.isCompleted&&o.push(f),(f.isSkipped||f.isCompleted)&&c.push(f);let s=n.length>0,S=a.length>0,y=a.findIndex(f=>f.isSkipped),h=y!==-1,C=a.filter(f=>f.isCompleted||f.isSkipped).length===a.length&&a.length>0,g=C||h,T=A(n),E=T?a.indexOf(T):-1,Qe=a[0],_e=A(a),Ue=n[0],qe=E>0?a[E-1]??null:null,Ke=E>=0?a[E+1]??null:null;return{activeStepIndex:E,activeSteps:n,branches:[...r],completedSteps:o,firstActiveStep:Ue,firstStep:Qe,htmlIndex:e,id:i,isActive:s,isCompleted:C,isPassed:g,isShow:S,isSkipped:h,lastActiveStep:T,lastStep:_e,nextStep:Ke,passedSteps:c,prevStep:qe,shownSteps:a,skippedAt:y,skippedSteps:d,steps:[...t]}}function w(i,e){let t={},r=[],a={};for(let p of i)t[p.id]=p,a[p.categoryId]||(r.push(p.categoryId),a[p.categoryId]=[]),a[p.categoryId].push(p);let n={},o={};for(let[p,C]of r.entries()){let g=Pe(C,p,a[C]);n[C]=g;for(let T of g.branches)(o[T]??=[]).push(g)}let d={},c=[];for(let p of Object.keys(o)){let C=Ee(p,o[p]);d[p]=C,c.push(C)}let s=Ge(c,d,e),S=s.activeCategory,y=S.activeSteps,h=A(y);return{activeBranch:s,activeCategory:S,activeSteps:y,branches:c,branchMap:d,categoryMap:n,id:ke(i),lastActiveStep:h,state:[...i],stepMap:t}}function Ge(i,e,t){if(i.length===1)return i[0];let r=i.filter(a=>a.activeCategories.length>0);return r.length===1?r[0]:t&&e[t]?e[t]:r[0]??i[0]}var We={isActive:!1,isCompleted:!1,isShow:!0,isSkipped:!1},Je="main";var v=class{};var Y=class extends v{verify({lastActiveStep:e}){if(!e)throw new l("[WizardActiveStepRule]: There are no available active step in tree state.")}};var G=class extends v{verify({activeBranch:e,activeCategory:t}){let r=e.shownCategories.slice(0,e.activeCategoryIndex);if(r.some(n=>!n.isPassed)){let n=r.map(o=>o.id).join(",");throw new l(`[WizardPassedPrevCategoriesRule]: Active category "${t.id}" has neither completed nor skipped prev categories. Please, skip or complete categories: "${n}".`)}}};var J=class extends v{verify({activeCategory:e}){let r=e.shownSteps.slice(0,e.activeStepIndex).filter(a=>!a.isCompleted&&!a.isSkipped);if(r.length){let a=r.map(n=>n.id).join(",");throw new l(`[WizardPassedPrevStepsRule]: Last active step "${e.lastActiveStep.id}" has not completed steps before. Please, complete or hide steps: "${a}".`)}}};var X=class extends v{verify({activeCategory:e}){if(!e.isShow)throw new l(`[WizardShownActiveCategoryRule]: Active category is hidden. Please, show category "${e.id}" to be able to activate it.`)}};var Z=class extends v{verify({activeBranch:e}){if(e.activeCategories.length>1){let t=e.activeCategories.map(r=>r.id).join(",");throw new l(`[WizardSingleActiveCategoryRule]: There are 2 active categories at the same time: ${t}.`)}}};var Ae=[new Y,new Z,new X,new J,new G];var W=class{constructor(e){this.originTree=e}originTree;state="complete"},b=class{constructor(e){this.originTree=e}originTree;state="exit"};var N=i=>i instanceof b||i instanceof W?i.originTree:i;var u=class i{branch;state;constructor(e,t){this.state=e.state.map(r=>({...r})),this.branch=t??e.activeBranch.id}static validate(e){return Ae.forEach(t=>t.verify(e)),e}activateCategory(e){let t=this.getCategoryStepStates(e).filter(r=>r.isShow);for(let r=0;r<t.length;r++){let a=t[r],n=t[r-1];a.isActive=a.isCompleted||(n?.isCompleted??!0)}return this}activateFirstStep(e){let t=this.getCategoryStepStates(e).filter(r=>r.isShow);if(t.length===0)return this;t[0].isActive=!0;for(let r=1;r<t.length;r++)t[r].isActive=!1;return this}activateStep(e){return this.getStepState(e).isActive=!0,this}build(){let e=w(this.state,this.branch);return i.validate(e),Object.freeze(e)}buildComplete(){let e=w(this.state,this.branch);return Object.freeze(new W(e))}buildExit(){let e=w(this.state,this.branch);return Object.freeze(new b(e))}completeCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isCompleted=!0),this}completeStep(e){return this.getStepState(e).isCompleted=!0,this}deactivateCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isActive=!1),this}deactivateStep(e){return this.getStepState(e).isActive=!1,this}getCategoryStepStates(e){return this.state.filter(t=>t.categoryId===e)}getResetTree(){this.state.forEach(t=>Object.assign(t,We));let e=this.state[0];return e&&(e.isActive=!0),Object.freeze(w(this.state,this.branch))}getStepState(e){let t=this.state.find(r=>r.id===e);if(!t)throw new Error(`[WizardTreeStateBuilder] Unknown step "${e}"`);return t}hideCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isShow=!1),this}hideStep(e){return this.getStepState(e).isShow=!1,this}resetCategory(e,t=0){return this.getCategoryStepStates(e).slice(t).forEach((a,n)=>{a.isActive=a.isActive&&n===0,a.isCompleted=!1}),this}showCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isShow=!0),this}showStep(e){return this.getStepState(e).isShow=!0,this}skipCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isSkipped=!0),this}skipCategoryUncompleted(e){return this.getCategoryStepStates(e).filter(t=>!t.isCompleted).forEach(t=>t.isSkipped=!0),this}uncompleteStep(e){return this.getStepState(e).isCompleted=!1,this}unskipCategory(e){return this.getCategoryStepStates(e).forEach(t=>t.isSkipped=!1),this}};function Xe(...i){let e={config:{},initializers:[],listeners:[],strategies:{}};for(let t of i)t(e);return e}var Ze=i=>e=>{e.config={...e.config,...i}},et=i=>e=>{e.initializers.push(i)},tt=i=>e=>{e.listeners.push(i)},rt=i=>e=>{e.strategies.scroll=i},it=i=>e=>{e.scrollContainer=i},at=i=>e=>{e.strategies.progress=i},nt=i=>e=>{e.strategies.visibility=i};var z=class{constructor(e){this.navigation=e}navigation},ee=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="complete"},O=class extends z{type="exit"},L=class extends z{constructor(t,r){super(t);this.navigation=t;this.reason=r}navigation;reason;type="navigation_cancelled"},te=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="navigation_end"},re=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="navigation_error"},ie=class extends z{constructor(t,r){super(t);this.navigation=t;this.reason=r}navigation;reason;type="navigation_ignored"},ae=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="navigation_start"},ne=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="resolve_end"},oe=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="resolve_start"},se=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="scroll_end"},de=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="scroll_start"},M=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="step_hide"},D=class extends z{constructor(t){super(t);this.navigation=t}navigation;type="step_show"};var ce=class{};var pe=class extends ce{getState(e){let t=new u(e);if(e.activeSteps.length>0)return t.build();let r=e.activeBranch.shownCategories.find(a=>!a.isPassed)??e.activeCategory;return t.activateCategory(r.id).build()}};var Ne=class{onDestroy(e){}onEvent(e){}onInit(e){}onTreeChange(e){}};var V=class{constructor(e,t){this.wizardLog=e;this.wizardInitializers=t}wizardLog;wizardInitializers;async getInitialState(e,t){let r=w(e,t);this.wizardLog.trace("HTML tree",r);try{this.validateHtmlTree(r),this.validateActiveBranch(r,t);let a=r;for(let n of this.wizardInitializers)a=await n.getState(a,r),this.wizardLog.trace("Initializer",n,a);return a}catch(a){return this.wizardLog.error(a),r}}validateActiveBranch(e,t){if(t&&!e.branchMap[t]){let r=e.branches.map(a=>a.id).join(",");throw new l(`[WizardInitializerService02]: There is no branch with id "${t}". List of available branches: ${r}.`)}}validateHtmlTree(e){let t=new Set,r=[];for(let a of e.state)t.has(a.id)?r.push(a.id):t.add(a.id);if(r.length>0)throw new P(`[WizardInitializerService01]: There are steps with the same ID: ${r.join(",")}.`)}};var j=class{map=new Map;dispose(){this.map.clear()}emit(e){let t=this.map.get(e.type);if(t)for(let a of[...t])a(e);let r=this.map.get("*");if(r)for(let a of[...r])a(e)}on(e,t){let r=this.map.get(e);return r||(r=new Set,this.map.set(e,r)),r.add(t),()=>{r.delete(t)}}};var R=class i{constructor(e,t){this.from=e;this.to=t;let r=N(t);this.id=`${e.id}=>${r.id}`,this.direction=i.getDirection(e,r),this.isSkipping=i.isSkipping(e,r,this.direction),this.isCategoryChanging=i.isCategoryChanging(e,r),this.isScrollChanging=i.isScrollChanging(e,r),this.isExit=t instanceof b,this.isComplete=t instanceof W}from;to;direction;id;isCategoryChanging;isComplete;isExit;isScrollChanging;isSkipping;static getDirection(e,t){return i.isCategoryChanging(e,t)?e.activeCategory.htmlIndex>t.activeCategory.htmlIndex?"back":"next":e.activeCategory.activeStepIndex===t.activeCategory.activeStepIndex?t.activeCategory.id===t.activeBranch.firstCategory.id?"back":"next":e.activeCategory.activeStepIndex>t.activeCategory.activeStepIndex?"back":"next"}static isCategoryChanging(e,t){return e.activeCategory.id!==t.activeCategory.id}static isScrollChanging(e,t){let r=e.activeCategory.activeStepIndex===t.activeCategory.activeStepIndex;return!(e.activeCategory.lastActiveStep.id===t.activeCategory.lastActiveStep.id)||!r}static isSkipping(e,t,r=i.getDirection(e,t)){if(r==="back")return!1;let a=e.activeCategory.isSkipped,n=t.categoryMap[e.activeCategory.id].isSkipped;return!a&&n}};var F=class{constructor(e,t,r,a){this.wizardStore=e;this.wizardConfig=t;this.wizardStateService=r;this.wizardScrollStrategy=a}wizardStore;wizardConfig;wizardStateService;wizardScrollStrategy;get isNavigating(){return!!this.inFlight}disposed=!1;emitter=new j;inFlight=null;prevSuccessId=null;async completeWizard(){let e=this.wizardStore.getTreeSnapshot(),t=new W(e);return this.navigate(t)}dispose(){this.disposed=!0,this.inFlight&&(this.inFlight.abort.abort(),this.inFlight=null),this.emitter.dispose()}async exitWizard(){try{let e=this.wizardStore.getTreeSnapshot(),t=new b(e);return this.navigate(t)}catch{return this.emitter.emit(new O),!0}}async hideCategory(e){let t=this.wizardStateService.hideCategory(e);return this.hide(this.projectTree(t))}async hideStep(e){let t=this.wizardStore.getTreeSnapshot(),r=ve(e).reduce((a,n)=>{let o=this.projectTree(a);return this.wizardStateService.hideStep(n,o)},t);return this.hide(this.projectTree(r))}async navigate(e){if(this.disposed)return!1;let t=this.wizardStore.getTreeSnapshot(),r=new R(t,e);if(r.id===this.prevSuccessId&&!r.isExit&&!r.isComplete)return this.emitter.emit(new ie(r,"same_navigation")),!1;if(this.inFlight){let n=this.inFlight;n.abort.abort(),this.inFlight=null,this.emitter.emit(new L(n.navigation,"new_navigation"))}let a=new AbortController;this.inFlight={abort:a,navigation:r};try{this.emitter.emit(new ae(r)),this.emitter.emit(new oe(r));try{await this.runResolverChain(r,a.signal)}catch(n){if(this.isAbortReason(n,a.signal))return!1;if(n instanceof me)return this.emitter.emit(new L(r,"resolver")),!1;throw this.emitter.emit(new re(r)),console.error(n),n}return a.signal.aborted?!1:(this.emitter.emit(new ne(r)),this.commitTree(r,e),this.emitVisibilityFlips(r,t,e),this.emitter.emit(new te(r)),r.isExit&&this.emitter.emit(new O(r)),r.isComplete&&this.emitter.emit(new ee(r)),!r.isExit&&!r.isComplete&&r.isScrollChanging&&(this.emitter.emit(new de(r)),await this.wizardScrollStrategy.onNavigate(r),this.emitter.emit(new se(r))),this.prevSuccessId=r.id,!0)}finally{this.inFlight&&this.inFlight.navigation===r&&(this.inFlight=null)}}on(e,t){return this.emitter.on(e,t)}async showCategory(e){let t=this.wizardStateService.showCategory(e);return this.show(t)}async showStep(e){let t=this.wizardStore.getTreeSnapshot(),r=ve(e).reduce((a,n)=>this.wizardStateService.showStep(n,a),t);return this.show(r)}commitTree(e,t){if(e.isExit||e.isComplete){let r=this.projectTree(t);this.wizardStore.setState(r);return}this.wizardStore.setState(t)}emitVisibilityFlips(e,t,r){let a=this.projectTree(r);for(let n of Object.keys(t.stepMap)){let o=t.stepMap[n],d=a.stepMap[n];!o||!d||o.isShow!==d.isShow&&(d.isShow?this.emitter.emit(new D(e)):this.emitter.emit(new M(e)))}}async hide(e){let t=this.wizardStore.getTreeSnapshot(),r=new R(t,e);return this.wizardStore.setState(e),this.emitter.emit(new M(r)),r.isScrollChanging&&await this.wizardScrollStrategy.onToggle(r),!0}async invokeResolver(e,t,r){if(!e)return;if(r.aborted)throw new DOMException("aborted","AbortError");let a=new Promise((o,d)=>{let c=()=>d(new DOMException("aborted","AbortError"));r.aborted?c():r.addEventListener("abort",c,{once:!0})}),n=await Promise.race([Promise.resolve(e(t)),a]);if(r.aborted)throw new DOMException("aborted","AbortError");if(!n)throw new me(`Resolver rejected navigation ${t.id}`)}isAbortReason(e,t){return t.aborted?e instanceof DOMException&&e.name==="AbortError":!1}projectTree(e){return e instanceof b||e instanceof W?e.originTree:e}async runResolverChain(e,t){let r=this.wizardConfig.getOptions();e.direction==="next"&&e.isCategoryChanging&&!e.isSkipping&&await this.invokeResolver(r.resolveCategoryComplete,e,t),e.isCategoryChanging&&await this.invokeResolver(r.resolveCategoryChange,e,t),e.isCategoryChanging&&await this.invokeResolver(r.resolveCategoryEnter,e,t),await this.invokeResolver(r.resolveStepChange,e,t)}async show(e){let t=this.wizardStore.getTreeSnapshot(),r=this.projectTree(e),a=new R(t,r);return this.wizardStore.setState(r),this.emitter.emit(new D(a)),a.isScrollChanging&&await this.wizardScrollStrategy.onToggle(a),!0}};var $=class{constructor(e,t){this.wizardStore=e;this.wizardConfig=t}wizardStore;wizardConfig;completeCategory(e,t=this.currentTree()){let{activeBranch:r}=t,{activeCategory:a,nextCategory:n}=r,o=new u(t);return o.completeCategory(e),a.id===e&&n?o.deactivateCategory(e).activateCategory(n.id).build():a.id===e&&!n?o.buildComplete():o.build()}goToCategory(e,t=this.currentTree()){let{activeBranch:r,activeCategory:a,branchMap:n,categoryMap:o}=t,d=new u(t),c=o[e],s=n[c.branches[0]],S=c.branches.includes(r.id)?r:s,y=S.getShownCategoryIndex(c),h=S.getShownCategoryIndex(a);if(r!==S&&y>h)throw new l(`[State02]: Trying to switch to category "${e}" in different branch "${S.id}" from current active branch "${r.id}", but new category has uncompleted prev category in new branch.`);return y>h&&r.getShownCategories(h,y-1).forEach(p=>d.skipCategoryUncompleted(p.id)),this.wizardConfig.getOptions().isBackResetCompleted&&y<h&&r.getShownCategories(y+1,h).forEach(p=>d.resetCategory(p.id)),d.deactivateCategory(a.id),this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange?d.activateFirstStep(e).build():d.activateCategory(e).build()}hideCategory(e,t=this.currentTree()){let{activeBranch:r,activeCategory:a}=t,n=a.id===e?this.projectShownCategory(e,t):t;return new u(n,r.id).hideCategory(e).build()}hideStep(e,t=this.currentTree()){let{activeBranch:r,lastActiveStep:a}=t,n=a.id===e?this.projectShownStep(e,t):t;return new u(n,r.id).hideStep(e).deactivateStep(e).build()}next(e,t=this.currentTree()){let{activeBranch:r,branchMap:a}=t,n=e?a[e]:r,o=new u(t,e??r.id),d=n.activeCategory,c=d.lastActiveStep,s=n.nextCategory,S=d.nextStep;if(r.activeCategory!==n.activeCategory)throw new l(`[State01]: In order to move to the "${e}" branch, you need to have common category between 2 branches`);return o.unskipCategory(d.id).completeStep(c.id),S?o.activateStep(S.id).build():s?(o.deactivateCategory(d.id),this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange?o.activateFirstStep(s.id).build():o.activateCategory(s.id).build()):o.buildComplete()}nextCategory(e,t=this.currentTree()){let{activeBranch:r,branchMap:a}=t,n=e?a[e]:r,o=new u(t,e??r.id),d=n.activeCategory,c=d.lastActiveStep,s=n.nextCategory;if(r.activeCategory!==n.activeCategory)throw new l(`[State01]: In order to move to the "${e}" branch, you need to have common category between 2 branches`);return o.deactivateCategory(d.id).completeStep(c.id),s?(o.skipCategoryUncompleted(d.id),this.wizardConfig.getOptions().isShowFirstStepOnCategoryChange?o.activateFirstStep(s.id).build():o.activateCategory(s.id).build()):o.buildComplete()}prev(e=this.currentTree()){let{activeBranch:t}=e,r=new u(e),a=t.activeCategory,n=a.lastActiveStep,o=t.prevCategory,d=a.prevStep;return this.wizardConfig.getOptions().isBackResetCompleted&&r.uncompleteStep(n.id),d?r.deactivateStep(n.id).build():o?r.deactivateCategory(a.id).activateCategory(o.id).build():r.buildExit()}prevCategory(e=this.currentTree()){let{activeBranch:t}=e,r=new u(e),a=t.activeCategory,n=t.prevCategory;return n&&this.wizardConfig.getOptions().isBackResetCompleted&&r.resetCategory(a.id),n?r.deactivateCategory(a.id).activateCategory(n.id).build():r.buildExit()}resetCategory(e,t=0,r=this.currentTree()){let{activeCategory:a}=r,n=new u(r);return n.resetCategory(e,t),a.id===e?n.activateStep(a.firstStep.id).build():n.build()}resetTree(e=this.currentTree()){let t=new u(e).getResetTree();return new u(t,e.activeBranch.id).activateStep(t.activeCategory.firstStep.id).build()}showCategory(e,t=this.currentTree()){let{activeBranch:r}=t,a=new u(t),n=r.categories.indexOf(r.activeCategory),o=r.categories.findIndex(c=>c.id===e),d=n>o;return a.showCategory(e),d&&a.skipCategory(e),a.build()}showStep(e,t=this.currentTree()){let{activeCategory:r,lastActiveStep:a,stepMap:n}=t,o=new u(t),d=n[e],c=r.steps.some(S=>S.id===e),s=a.htmlIndex>d.htmlIndex;return o.showStep(e),s&&o.completeStep(e),c&&s&&o.activateStep(e),o.build()}skipCategory(e,t=this.currentTree()){let{activeBranch:r}=t,{activeCategory:a,nextCategory:n}=r,o=new u(t);return o.skipCategory(e),a.id===e&&n?o.deactivateCategory(e).activateCategory(n.id).build():a.id===e&&!n?o.buildComplete():o.build()}currentTree(){return this.wizardStore.getTreeSnapshot()}projectShownCategory(e,t){let{activeBranch:r}=t;return e===r.firstCategory.id?this.nextCategory(null,t):this.prevCategory(t)}projectShownStep(e,t){let{activeBranch:r,activeCategory:a,stepMap:n}=t,d=n[e].categoryId===r.firstCategory.id,c=e===a.firstStep.id;return d&&c?this.next(null,t):this.prev(t)}};var ge=class{};var le=class extends ge{getProgress(e){let{activeCategory:t,categoryMap:r}=e,a={};for(let n of Object.keys(r)){let o=r[n];if(o.htmlIndex!==t.htmlIndex){a[n]=o.htmlIndex<t.htmlIndex?100:0;continue}a[n]=o.shownSteps.length>0?(o.activeSteps.length-1)*100/o.shownSteps.length:0}return a}};var H=class{static projectToTree=N;container;onToggle(e){let t=N(e.to);if(!t)return Promise.resolve(!1);let r=t.lastActiveStep?.id===t.activeCategory.firstStep?.id;return Se(r?null:t.lastActiveStep?.id,"auto",this.container)}scrollToTop(e="smooth"){return Se(null,e,this.container)}setContainer(e){this.container=e}};function Se(i,e,t){if(typeof document>"u")return Promise.resolve(!1);let a=(typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia("(prefers-reduced-motion: reduce)").matches:!1)?"auto":e;if(!i){let o=ot(t);return o?o.scrollTo({behavior:a,top:0}):typeof window<"u"&&window.scrollTo({behavior:a,top:0}),Promise.resolve(!0)}let n=document.getElementById(i);return n?(n.scrollIntoView({behavior:a,block:"start"}),Promise.resolve(!0)):Promise.resolve(!1)}function ot(i){return i?typeof i=="function"?i():"current"in i?i.current:i:null}var ye=class extends H{constructor(t){super();this.wizardConfig=t}wizardConfig;onNavigate(t){let r=H.projectToTree(t.to);if(!r)return Promise.resolve(!1);let n=r.lastActiveStep?.id===r.activeCategory.firstStep?.id?null:r.lastActiveStep?.id,o=t.isCategoryChanging||(this.wizardConfig?.isMobile??!1);return Se(n,o?"auto":"smooth",this.container)}};var k=class{};var he=class extends k{constructor(t){super();this.wizardConfig=t}wizardConfig;isStepVisible(t,r){let a=t.isActive&&t.isShow,n=t.id===r.lastActiveStep?.id;return this.wizardConfig.isMobile?a&&n:a}};var Oe=class extends k{isStepVisible(e,t){let r=e.isActive&&e.isShow,a=e.id===t.lastActiveStep?.id;return r&&a}};var ue=()=>!0,be={backBtnClass:"",backBtnText:"Back",doneDotText:"Finish",enableTracing:"none",finishText:"Finish",headerI18n:null,isActiveCategoryClickReset:!0,isBackResetCompleted:!0,isDoneDot:!1,isShowFirstStepOnCategoryChange:!1,isShowWizardHeader:!0,isShowWizardHeaderSteps:!0,nextBtnClass:"",nextBtnText:"Next",nextCategoryText:"Continue",resolveCategoryChange:ue,resolveCategoryComplete:ue,resolveCategoryEnter:ue,resolveStepChange:ue,silenceErrors:!1,stickyHeader:!0};var Q=class{isMobile=!1;get options(){return this.current}current;disposed=!1;listeners=new Set;notifyScheduled=!1;constructor(e={}){this.current={...be,...e}}dispose(){this.disposed=!0,this.listeners.clear()}getOptions(){return this.current}setOptions(e){if(this.disposed)return this;let t=!1;for(let r of Object.keys(e))if(!Object.is(e[r],this.current[r])){t=!0;break}return t?(this.current={...this.current,...e},this.scheduleNotify(),this):this}subscribe(e){return this.disposed?()=>{}:(this.listeners.add(e),()=>{this.listeners.delete(e)})}scheduleNotify(){this.notifyScheduled||(this.notifyScheduled=!0,queueMicrotask(()=>{if(this.notifyScheduled=!1,this.disposed)return;let e=this.current;for(let t of[...this.listeners])t(e)}))}};var _=class{constructor(e){this.wizardConfig=e}wizardConfig;error(e){if(!(e instanceof l)){console.error(e);return}this.wizardConfig.getOptions().silenceErrors||console.error(e)}trace(...e){this.wizardConfig.getOptions().enableTracing!=="none"&&console.log(...e)}};var U=class{constructor(e){this.storagePrefix=e;this.initOnce=new Promise(t=>{this.resolveInitOnce=t})}storagePrefix;initOnce;get shapeId(){return this._shapeId??""}_shapeId=null;current=null;disposed=!1;initialTree=null;listeners=new Set;resolveInitOnce;dispose(){this.disposed=!0,this.listeners.clear()}getTreeSnapshot(){if(!this.current)throw new P("[WizardStore] getTreeSnapshot called before init");return this.current}init(e){if(!this.disposed){if(this.initialTree){console.warn("[WizardStore] init() called more than once; ignoring subsequent call.");return}this.initialTree=e,this._shapeId=Re(e.state,this.storagePrefix),this.setState(e),this.resolveInitOnce(e)}}setState(e){if(!this.disposed){if(!this.initialTree)throw new P("[WizardStore] setState called before init");if(this.current!==e){this.current=e;for(let t of[...this.listeners])t()}}}subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)})};var q=class{get configOptions(){return this.config.options}get isInitialized(){return this.initialized}get lastActiveStep(){return this.tree.lastActiveStep}get progress(){return this.progressStrategy.getProgress(this.tree)}get shapeId(){return this.store.shapeId}get steps(){return this.tree.stepMap}get tree(){return this.store.getTreeSnapshot()}committed=!1;config;disposed=!1;initialBranch;initialized=!1;initialState;initService;listeners;log;navService;pendingPostInitTasks=[];progressStrategy;scrollStrategy;stateService;store;visibilityStrategy;constructor(e){this.config=new Q(e.config??{});let t=e.config?.storagePrefix??void 0;this.store=new U(t),this.log=new _(this.config),this.scrollStrategy=e.strategies?.scroll??new ye(this.config),e.scrollContainer!==void 0&&this.scrollStrategy.setContainer(e.scrollContainer),this.visibilityStrategy=e.strategies?.visibility??new he(this.config),this.progressStrategy=e.strategies?.progress??new le,this.stateService=new $(this.store,this.config),this.navService=new F(this.store,this.config,this.stateService,this.scrollStrategy);let r=e.initializers??[new pe];this.initService=new V(this.log,r),this.listeners=e.listeners??[],this.initialState=e.state,this.initialBranch=e.activeBranch}back(){return this.runOrQueue(()=>this.navService.navigate(this.stateService.prev()))}backCategory(){return this.runOrQueue(()=>this.navService.navigate(this.stateService.prevCategory()))}async commitRegistration(){if(this.disposed||this.committed)return;this.committed=!0;let e=await this.initService.getInitialState(this.initialState,this.initialBranch);if(this.disposed){for(let t of this.pendingPostInitTasks.splice(0))t.resolve(!1);return}this.store.init(e),this.initialized=!0;for(let t of this.listeners)try{t.onInit(e)}catch(r){this.log.error(r)}this.store.subscribe(()=>{let t=this.store.getTreeSnapshot();for(let r of this.listeners)try{r.onTreeChange(t)}catch(a){this.log.error(a)}}),this.navService.on("*",t=>{for(let r of this.listeners)try{r.onEvent(t)}catch(a){this.log.error(a)}});for(let t of this.pendingPostInitTasks.splice(0))t.run()}completeWizard(){return this.runOrQueue(()=>this.navService.completeWizard())}dispose(){if(this.disposed)return;this.disposed=!0;for(let t of this.pendingPostInitTasks.splice(0))t.resolve(!1);let e=this.initialized?this.store.getTreeSnapshot():null;for(let t of this.listeners)try{t.onDestroy(e)}catch(r){this.log.error(r)}this.navService.dispose(),this.store.dispose(),this.config.dispose()}exitWizard(){return this.runOrQueue(()=>this.navService.exitWizard())}getTreeSnapshot=()=>this.store.getTreeSnapshot();go(e){return this.runOrQueue(()=>this.navService.navigate(e))}goToCategory(e){return this.runOrQueue(()=>this.navService.navigate(this.stateService.goToCategory(e)))}hideCategory(e){return this.runOrQueue(()=>this.navService.hideCategory(e))}hideStep(e){return this.runOrQueue(()=>this.navService.hideStep(e))}isStepVisible(e){let t=this.store.getTreeSnapshot(),r=t.stepMap[e];return r?this.visibilityStrategy.isStepVisible(r,t):!1}next(e){return this.runOrQueue(()=>this.navService.navigate(this.stateService.next(e??null)))}nextCategory(e){return this.runOrQueue(()=>this.navService.navigate(this.stateService.nextCategory(e??null)))}on(e,t){return this.navService.on(e,t)}resetActiveCategory(e=0){return this.runOrQueue(()=>this.navService.navigate(this.stateService.resetCategory(this.tree.activeCategory.id,e)))}resetCategory(e,t=0){return this.runOrQueue(()=>this.navService.navigate(this.stateService.resetCategory(e,t)))}resetWizard(){return this.runOrQueue(()=>this.navService.navigate(this.stateService.resetTree()))}scrollToTop(e="smooth"){return this.scrollStrategy.scrollToTop(e)}showCategory(e){return this.runOrQueue(()=>this.navService.showCategory(e))}showStep(e){return this.runOrQueue(()=>this.navService.showStep(e))}skipActiveCategory(){return this.runOrQueue(()=>this.navService.navigate(this.stateService.skipCategory(this.tree.activeCategory.id)))}skipCategory(e){return this.runOrQueue(()=>this.navService.navigate(this.stateService.skipCategory(e??this.tree.activeCategory.id)))}subscribe=e=>this.store.subscribe(e);toggleCategory(e,t){return t?this.showCategory(e):this.hideCategory(e)}toggleStep(e,t){return t?this.showStep(e):this.hideStep(e)}runOrQueue(e){return this.disposed?Promise.resolve(!1):this.initialized?e():new Promise((t,r)=>{this.pendingPostInitTasks.push({resolve:t,run:()=>{e().then(t,r)}})})}};var Le=(t=>(t.Backward="backward",t.Forward="forward",t))(Le||{});import{Slot as st}from"@radix-ui/react-slot";import{jsx as Me}from"react/jsx-runtime";function Ce(i){let{Button:e}=ze();return i.asChild?Me(st,{className:i.className,onClick:i.onClick,children:i.children}):Me(e,{className:i.className,onClick:i.onClick,type:"button",variant:i.variant,children:i.children??i.defaultLabel})}import{jsx as dt}from"react/jsx-runtime";function De(i){let e=m();return dt(Ce,{asChild:i.asChild,className:i.className,defaultLabel:e.configOptions.backBtnText??"Back",onClick:()=>{e.back()},variant:"outline",children:i.children})}import{Fragment as ct,jsx as pt}from"react/jsx-runtime";function ji(i){return m().tree.activeCategory.id!==i.categoryId?null:pt(ct,{children:i.children})}import{CheckIcon as gt}from"lucide-react";import{jsx as K,jsxs as lt}from"react/jsx-runtime";function fe(i){let{clickable:e=!1,isLast:t=!1,label:r,onClick:a,progress:n,state:o}=i,d=e&&!!a;return lt("li",{className:"relative flex flex-1 items-center","data-state":o,children:[K("button",{"aria-current":o==="active"?"step":void 0,"aria-label":r??o,className:x("relative flex size-3 shrink-0 items-center justify-center rounded-full border-2 transition-colors",o==="pending"&&"border-border bg-background",o==="active"&&"border-success-text bg-success-text ring-2 ring-success-border/40 ring-offset-2 ring-offset-background",o==="completed"&&"border-success-border bg-success-text",o==="skipped"&&"border-border bg-background opacity-60",d&&"cursor-pointer hover:bg-success-bg",!d&&"cursor-default"),disabled:!d,onClick:d?a:void 0,type:"button",children:o==="completed"&&K(gt,{className:"size-2 text-background"})}),!t&&K("span",{"aria-hidden":!0,className:"relative ml-1 mr-1 h-px flex-1 bg-border",children:K("span",{className:"absolute inset-y-0 left-0 bg-success-border transition-[width]",style:{width:`${Math.max(0,Math.min(100,n))}%`}})}),r&&K("span",{className:x("absolute -top-6 left-0 -translate-x-[calc(50%-0.375rem)] text-sm font-semibold whitespace-nowrap",o==="active"&&"text-success-text",o!=="active"&&"text-muted-foreground"),children:r})]})}import{jsx as Ve,jsxs as yt}from"react/jsx-runtime";function xe(i){let{canAccessCategory:e,categories:t,doneDot:r,headerI18n:a,onCategoryClick:n,progress:o}=i,d=t.length-1;return yt("ol",{"aria-label":"Wizard progress",className:"relative flex flex-1 items-center pt-6",children:[t.map((c,s)=>{let S=s===d&&!r,y=e?.(c)??!1;return Ve(fe,{clickable:y,isLast:S,label:a?.[c.id],onClick:n?()=>n(c):void 0,progress:o[c.id]??0,state:St(c,o[c.id]??0)},c.id)}),r&&Ve(fe,{isLast:!0,label:r.text,progress:0,state:"pending"})]})}function St(i,e){return i.isActive?"active":e>=100?"completed":i.isSkipped?"skipped":"pending"}import{jsx as je,jsxs as ht}from"react/jsx-runtime";function ea(){let i=m(),e=i.tree,t=i.configOptions;if(!t.isShowWizardHeader)return null;let r=e.activeBranch.shownCategories.length===1&&!t.isDoneDot,n=t.isShowWizardHeaderSteps&&!0&&!r,o=c=>{if(t.isBackResetCompleted)return!1;if(c.isCompleted)return!0;let s=e.activeBranch.shownCategories.indexOf(c);return!!e.activeBranch.shownCategories[s-1]?.isCompleted},d=c=>{if(t.isBackResetCompleted)return;let s=c.activeSteps.length===1;if(t.isActiveCategoryClickReset&&c.isActive&&!s){i.resetCategory(c.id);return}if(!c.isActive&&c.isCompleted){i.goToCategory(c.id);return}!c.isActive&&o(c)&&i.goToCategory(c.id)};return ht("header",{className:x("relative mb-8 flex items-center gap-4 border-b border-border bg-background px-4 py-3",t.stickyHeader&&"sticky top-0 z-10"),children:[je(De,{}),n&&je(xe,{canAccessCategory:o,categories:e.activeBranch.shownCategories,doneDot:t.isDoneDot?{text:t.doneDotText}:void 0,headerI18n:t.headerI18n,onCategoryClick:d,progress:i.progress})]})}import{jsx as Ct}from"react/jsx-runtime";function na(i){let e=m(),t=!i.asChild&&i.children===void 0?ut(e):"";return Ct(Ce,{asChild:i.asChild,className:i.className,defaultLabel:t,onClick:()=>{e.next()},children:i.children})}function ut(i){let e=i.configOptions,t=i.tree,r=t.lastActiveStep,a=t.categoryMap[r.categoryId],n=a.lastStep.id===r.id,o=t.activeBranch.lastCategory.id===a.id;return n?o?e.finishText:e.nextCategoryText:e.nextBtnText}import{CheckIcon as vt}from"lucide-react";var ft=[];function Be(){return m().tree.activeBranch.shownCategories.map(e=>zt(e))}function mt(i){return i.isActive?"active":i.isCompleted?"completed":i.isSkipped?"skipped":"pending"}function zt(i){let e=i.shownSteps,t=e.length>1?e.slice().sort((r,a)=>r.htmlIndex-a.htmlIndex).map(r=>({id:r.id,isActive:r.isActive})):ft;return{id:i.id,isActive:i.isActive,state:mt(i),subSteps:t}}import{jsx as I,jsxs as Fe}from"react/jsx-runtime";function Wt(i){let{canAccessCategory:e,className:t,headerI18n:r,subStepLabels:a}=i,n=m(),o=Be(),d=r??n.configOptions.headerI18n,c=s=>e?.(s)??bt(s.state);return I("nav",{"aria-label":"Wizard steps",className:x("flex flex-col gap-1",t),children:I("ol",{className:"relative flex flex-col gap-1",children:o.map((s,S)=>{let y=d?.[s.id]??String(s.id),h=c(s),p=S===o.length-1,C=s.state==="completed"||s.state==="skipped";return Fe("li",{className:"relative",children:[!p&&I("span",{"aria-hidden":!0,className:x("pointer-events-none absolute top-7 -bottom-2 left-5 w-px -translate-x-1/2 transition-colors duration-200",C?"bg-success-border":"bg-border")}),Fe("button",{"aria-current":s.isActive?"step":void 0,className:x("group flex w-full items-center gap-3 rounded-md px-3 py-2 text-left text-sm font-medium transition-[color,background-color,transform] duration-200 ease-(--ease-out-strong)",s.state==="active"&&"bg-success-bg/60 text-success-text",s.state==="completed"&&"text-foreground",s.state==="skipped"&&"text-muted-foreground opacity-70",s.state==="pending"&&"text-muted-foreground",h?"cursor-pointer hover:bg-foreground/[0.06] motion-safe:active:scale-[0.97]":"cursor-default"),"data-state":s.state,disabled:!h,onClick:()=>{n.goToCategory(s.id)},type:"button",children:[I(xt,{state:s.state}),I("span",{children:y})]}),s.isActive&&s.subSteps.length>0&&I("ol",{className:"mt-1 ml-7 flex flex-col gap-1 border-l border-border pl-3",children:s.subSteps.map(g=>I("li",{"aria-current":g.isActive?"step":void 0,className:x("rounded px-2 py-1 text-sm",g.isActive?"text-success-text font-medium":"text-muted-foreground"),children:a?.[g.id]??String(g.id)},g.id))})]},s.id)})})})}function bt(i){return i!=="pending"}function xt({state:i}){return I("span",{"aria-hidden":!0,className:x("flex size-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors",i==="pending"&&"border-border bg-background",i==="active"&&"border-success-border bg-success-bg",i==="completed"&&"border-success-border bg-success-text",i==="skipped"&&"border-border bg-background opacity-60"),children:i==="completed"&&I(vt,{className:"size-2.5 text-background motion-safe:animate-in motion-safe:fade-in motion-safe:zoom-in-75 motion-safe:duration-200"})})}import{useCallback as Bt,useContext as It,useSyncExternalStore as wt}from"react";import{jsx as Tt}from"react/jsx-runtime";function ma(i){let e=It(B);if(!e)throw new l("WizardStep must be used inside <WizardProvider>");let t=Bt(()=>e.isStepVisible(i.id),[e,i.id]);return wt(e.subscribe,t,t)?Tt("div",{className:"motion-safe:animate-in motion-safe:fade-in motion-safe:slide-in-from-bottom-1 motion-safe:duration-300 motion-safe:ease-(--ease-out-strong)",id:i.id,children:i.children}):null}import{useEffect as Rt,useState as $e}from"react";import{jsx as Et}from"react/jsx-runtime";function kt(i){let{activeBranch:e,children:t,config:r,initializers:a,listeners:n,scrollContainer:o,state:d,strategies:c}=i,[s]=$e(()=>({activeBranch:e,config:r,initializers:a,listeners:n,scrollContainer:o,state:d,strategies:c})),[S,y]=$e(null);return Rt(()=>{let h=new q(s),p=!1;return h.commitRegistration().then(()=>{p||y(h)}),()=>{p=!0,h.dispose(),y(C=>C===h?null:C)}},[s]),S?Et(B.Provider,{value:S,children:t}):null}import{useEffect as Pt,useRef as At}from"react";function Nt(){return At(null)}function Ot({engineRef:i}){let e=m();return Pt(()=>(i.current=e,()=>{i.current=null}),[i,e]),null}import{useContext as Lt,useEffect as He,useRef as Mt}from"react";function Dt(i,e){let t=Lt(B);if(!t)throw new l("useWizardEvent must be used inside <WizardProvider>");let r=Mt(e);He(()=>{r.current=e}),He(()=>t.on(i,a=>r.current(a)),[t,i])}import{useCallback as Vt,useContext as jt,useRef as Ft,useSyncExternalStore as $t}from"react";function Ht(i){let e=jt(B);if(!e)throw new l("useWizardStep must be used inside <WizardProvider>");let t=Ft(null),r=Vt(()=>{let n=e.getTreeSnapshot().stepMap[i]??null,o=t.current;return o!==null&&n!==null&&o.isActive===n.isActive&&o.isShow===n.isShow&&o.isCompleted===n.isCompleted&&o.isSkipped===n.isSkipped?o:(t.current=n,n)},[e,i]);return $t(e.subscribe,r,r)}export{j as TypedEmitter,le as WizardActiveProgressStrategy,Y as WizardActiveStepRule,De as WizardBack,ji as WizardCategory,Le as WizardCategoryDirection,ee as WizardCompleteEvent,W as WizardCompleteTreeState,Ye as WizardComponentsProvider,Q as WizardConfig,pe as WizardDefaultInitializer,he as WizardDefaultVisibilityStrategy,q as WizardEngine,B as WizardEngineContext,Ot as WizardEngineRefCapture,l as WizardError,z as WizardEvent,Ie as WizardEventType,O as WizardExitEvent,b as WizardExitTreeState,ea as WizardHeader,P as WizardInitializationError,ce as WizardInitializer,V as WizardInitializerService,Oe as WizardLastActiveVisibilityStrategy,Ne as WizardListener,_ as WizardLog,R as WizardNavigation,L as WizardNavigationCancelledEvent,te as WizardNavigationEndEvent,Qt as WizardNavigationError,re as WizardNavigationErrorEvent,ie as WizardNavigationIgnoredEvent,F as WizardNavigationService,ae as WizardNavigationStartEvent,na as WizardNext,G as WizardPassedPrevCategoriesRule,J as WizardPassedPrevStepsRule,ge as WizardProgressStrategy,kt as WizardProvider,Wt as WizardRail,ne as WizardResolveEndEvent,oe as WizardResolveStartEvent,me as WizardResolverError,v as WizardRule,se as WizardScrollEndEvent,de as WizardScrollStartEvent,H as WizardScrollStrategy,X as WizardShownActiveCategoryRule,Z as WizardSingleActiveCategoryRule,ye as WizardSmoothScrollStrategy,$ as WizardStateService,ma as WizardStep,M as WizardStepHideEvent,D as WizardStepShowEvent,xe as WizardStepper,fe as WizardStepperDot,U as WizardStore,u as WizardTreeStateBuilder,k as WizardVisibilityStrategy,Ee as buildWizardBranchState,Pe as buildWizardCategoryState,w as buildWizardTreeState,Xe as composeWizardProviders,Se as scrollToStep,m as useWizard,Be as useWizardCategoriesView,ze as useWizardComponents,Nt as useWizardEngineRef,Dt as useWizardEvent,Ht as useWizardStep,Ze as withConfig,et as withInitializer,tt as withListener,at as withProgressStrategy,it as withScrollContainer,rt as withScrollStrategy,nt as withVisibilityStrategy,Je as wizardDefaultBranch,be as wizardDefaultConfig,We as wizardDefaultState,Ae as wizardRules};