@moontra/moonui-pro 2.8.0 → 2.8.2
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.mjs +194 -72
- package/package.json +1 -1
- package/src/components/form-wizard/form-wizard-context.tsx +63 -4
- package/src/components/form-wizard/form-wizard-progress.tsx +193 -88
- package/src/components/form-wizard/form-wizard-step.tsx +13 -2
- package/src/components/form-wizard/index.tsx +2 -5
package/dist/index.mjs
CHANGED
|
@@ -60056,16 +60056,61 @@ var FormWizardProvider = ({
|
|
|
60056
60056
|
}, [stepData, currentStep, completedSteps, persistData, storageKey]);
|
|
60057
60057
|
const validateCurrentStep = useCallback(async () => {
|
|
60058
60058
|
const step = steps[currentStep];
|
|
60059
|
+
if (typeof window !== "undefined") {
|
|
60060
|
+
const stepElement = document.querySelector("[data-wizard-step-content]");
|
|
60061
|
+
if (stepElement) {
|
|
60062
|
+
const requiredInputs = stepElement.querySelectorAll("input[required], select[required], textarea[required]");
|
|
60063
|
+
const emptyFields = [];
|
|
60064
|
+
requiredInputs.forEach((input) => {
|
|
60065
|
+
const htmlInput = input;
|
|
60066
|
+
if (!htmlInput.value || htmlInput.value.trim() === "") {
|
|
60067
|
+
const label = document.querySelector(`label[for="${htmlInput.id}"]`);
|
|
60068
|
+
const fieldName = label ? label.textContent?.replace(" *", "") || "Field" : htmlInput.name || htmlInput.id || "Field";
|
|
60069
|
+
emptyFields.push(fieldName);
|
|
60070
|
+
}
|
|
60071
|
+
});
|
|
60072
|
+
const requiredCheckboxes = stepElement.querySelectorAll('input[type="checkbox"][required]');
|
|
60073
|
+
requiredCheckboxes.forEach((checkbox) => {
|
|
60074
|
+
const htmlCheckbox = checkbox;
|
|
60075
|
+
if (!htmlCheckbox.checked) {
|
|
60076
|
+
const label = document.querySelector(`label[for="${htmlCheckbox.id}"]`);
|
|
60077
|
+
const fieldName = label ? label.textContent?.replace(" *", "") || "Checkbox" : htmlCheckbox.name || htmlCheckbox.id || "Checkbox";
|
|
60078
|
+
emptyFields.push(fieldName);
|
|
60079
|
+
}
|
|
60080
|
+
});
|
|
60081
|
+
if (emptyFields.length > 0) {
|
|
60082
|
+
setError(`Please fill in the following required fields: ${emptyFields.join(", ")}`);
|
|
60083
|
+
return false;
|
|
60084
|
+
}
|
|
60085
|
+
}
|
|
60086
|
+
}
|
|
60059
60087
|
if (!step.validation)
|
|
60060
60088
|
return true;
|
|
60061
60089
|
setIsLoading(true);
|
|
60062
60090
|
setError(null);
|
|
60063
60091
|
try {
|
|
60064
|
-
const
|
|
60065
|
-
if (
|
|
60066
|
-
|
|
60092
|
+
const result = await step.validation();
|
|
60093
|
+
if (typeof result === "boolean") {
|
|
60094
|
+
if (!result) {
|
|
60095
|
+
setError("Please complete all required fields before proceeding");
|
|
60096
|
+
}
|
|
60097
|
+
return result;
|
|
60098
|
+
}
|
|
60099
|
+
if (typeof result === "object" && result !== null && "isValid" in result) {
|
|
60100
|
+
const validationResult = result;
|
|
60101
|
+
if (!validationResult.isValid) {
|
|
60102
|
+
if (validationResult.error) {
|
|
60103
|
+
setError(validationResult.error);
|
|
60104
|
+
} else if (validationResult.errors && Array.isArray(validationResult.errors)) {
|
|
60105
|
+
setError(validationResult.errors.join(", "));
|
|
60106
|
+
} else {
|
|
60107
|
+
setError("Please complete all required fields before proceeding");
|
|
60108
|
+
}
|
|
60109
|
+
}
|
|
60110
|
+
return validationResult.isValid;
|
|
60067
60111
|
}
|
|
60068
|
-
|
|
60112
|
+
setError("Invalid validation response");
|
|
60113
|
+
return false;
|
|
60069
60114
|
} catch (err) {
|
|
60070
60115
|
setError(err instanceof Error ? err.message : "Validation failed");
|
|
60071
60116
|
return false;
|
|
@@ -60193,55 +60238,129 @@ var FormWizardProgress = ({
|
|
|
60193
60238
|
const { steps, currentStep, isStepCompleted, isStepAccessible, error: error42 } = useFormWizard();
|
|
60194
60239
|
if (progressType === "linear") {
|
|
60195
60240
|
return /* @__PURE__ */ jsx("div", { className: cn(
|
|
60196
|
-
"relative",
|
|
60197
|
-
orientation === "vertical" ? "flex flex-col space-y-8" : "
|
|
60241
|
+
"relative w-full",
|
|
60242
|
+
orientation === "vertical" ? "flex flex-col space-y-8" : "",
|
|
60198
60243
|
className
|
|
60199
|
-
), children: steps.map((step, index2) => {
|
|
60244
|
+
), children: orientation === "horizontal" ? /* @__PURE__ */ jsx("div", { className: "relative w-full", children: /* @__PURE__ */ jsx("div", { className: "relative flex items-start justify-between w-full", children: steps.map((step, index2) => {
|
|
60200
60245
|
const isActive2 = index2 === currentStep;
|
|
60201
60246
|
const isCompleted = isStepCompleted(index2);
|
|
60202
60247
|
const isAccessible = isStepAccessible(index2);
|
|
60203
60248
|
const hasError = isActive2 && error42;
|
|
60204
60249
|
const StepIcon = typeof step.icon === "function" ? step.icon({ isActive: isActive2, isCompleted }) : step.icon;
|
|
60205
|
-
return /* @__PURE__ */
|
|
60206
|
-
"
|
|
60207
|
-
orientation === "vertical" ? "w-full" : "flex-1"
|
|
60208
|
-
), children: [
|
|
60209
|
-
/* @__PURE__ */ jsx(
|
|
60210
|
-
motion.div,
|
|
60211
|
-
{
|
|
60212
|
-
initial: { scale: 0.8 },
|
|
60213
|
-
animate: { scale: isActive2 ? 1.1 : 1 },
|
|
60214
|
-
className: cn(
|
|
60215
|
-
"relative z-20 flex items-center justify-center rounded-full border-2 transition-all duration-300",
|
|
60216
|
-
stepIconPosition === "inside" ? "w-12 h-12" : "w-10 h-10",
|
|
60217
|
-
isActive2 && "border-primary bg-primary text-primary-foreground shadow-lg",
|
|
60218
|
-
isCompleted && !isActive2 && "border-primary bg-primary text-primary-foreground",
|
|
60219
|
-
!isActive2 && !isCompleted && isAccessible && "border-muted-foreground/50 bg-background text-muted-foreground hover:border-muted-foreground",
|
|
60220
|
-
!isAccessible && "border-muted bg-muted text-muted-foreground cursor-not-allowed opacity-50",
|
|
60221
|
-
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
60222
|
-
),
|
|
60223
|
-
children: hasError ? errorStepIcon : isCompleted && !isActive2 ? completedStepIcon : isActive2 && activeStepIcon ? activeStepIcon : StepIcon ? /* @__PURE__ */ jsx("span", { className: "w-5 h-5 flex items-center justify-center", children: StepIcon }) : showStepNumbers ? /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: index2 + 1 }) : /* @__PURE__ */ jsx(Circle, { className: "w-4 h-4" })
|
|
60224
|
-
}
|
|
60225
|
-
),
|
|
60226
|
-
showStepTitles && /* @__PURE__ */ jsxs("div", { className: cn(
|
|
60227
|
-
"absolute whitespace-nowrap",
|
|
60228
|
-
orientation === "vertical" ? "left-16 top-1/2 -translate-y-1/2" : "top-full mt-2 left-1/2 -translate-x-1/2 text-center"
|
|
60229
|
-
), children: [
|
|
60250
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 flex flex-col items-center", children: [
|
|
60251
|
+
showStepTitles && /* @__PURE__ */ jsxs("div", { className: "text-center mb-3 min-h-[40px] px-2", children: [
|
|
60230
60252
|
/* @__PURE__ */ jsx("p", { className: cn(
|
|
60231
|
-
"text-sm font-
|
|
60253
|
+
"text-sm font-semibold transition-colors",
|
|
60232
60254
|
isActive2 && "text-primary",
|
|
60233
60255
|
isCompleted && !isActive2 && "text-primary",
|
|
60234
60256
|
!isActive2 && !isCompleted && "text-muted-foreground"
|
|
60235
60257
|
), children: step.title }),
|
|
60236
60258
|
step.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: step.description })
|
|
60237
60259
|
] }),
|
|
60238
|
-
|
|
60239
|
-
|
|
60240
|
-
|
|
60241
|
-
|
|
60242
|
-
|
|
60243
|
-
|
|
60244
|
-
|
|
60260
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center w-full", children: [
|
|
60261
|
+
index2 < steps.length - 1 && /* @__PURE__ */ jsxs(
|
|
60262
|
+
"div",
|
|
60263
|
+
{
|
|
60264
|
+
className: "absolute left-1/2 w-full h-[2px]",
|
|
60265
|
+
style: {
|
|
60266
|
+
width: "calc(100% + 24px)",
|
|
60267
|
+
marginLeft: "24px"
|
|
60268
|
+
},
|
|
60269
|
+
children: [
|
|
60270
|
+
/* @__PURE__ */ jsx("div", { className: "h-full bg-gray-200 dark:bg-gray-700" }),
|
|
60271
|
+
index2 < currentStep && /* @__PURE__ */ jsx(
|
|
60272
|
+
motion.div,
|
|
60273
|
+
{
|
|
60274
|
+
className: "absolute inset-0 bg-primary",
|
|
60275
|
+
initial: { scaleX: 0 },
|
|
60276
|
+
animate: { scaleX: 1 },
|
|
60277
|
+
transition: { duration: 0.5, delay: index2 * 0.1 },
|
|
60278
|
+
style: { transformOrigin: "left" }
|
|
60279
|
+
}
|
|
60280
|
+
)
|
|
60281
|
+
]
|
|
60282
|
+
}
|
|
60283
|
+
),
|
|
60284
|
+
/* @__PURE__ */ jsx(
|
|
60285
|
+
motion.div,
|
|
60286
|
+
{
|
|
60287
|
+
initial: { scale: 0.8 },
|
|
60288
|
+
animate: { scale: isActive2 ? 1.05 : 1 },
|
|
60289
|
+
transition: { duration: 0.2 },
|
|
60290
|
+
className: cn(
|
|
60291
|
+
"relative z-10 flex items-center justify-center rounded-full transition-all duration-300 mx-auto",
|
|
60292
|
+
"w-12 h-12 border-2",
|
|
60293
|
+
isActive2 && "border-primary bg-primary text-primary-foreground shadow-lg shadow-primary/20",
|
|
60294
|
+
isCompleted && !isActive2 && "border-primary bg-primary text-primary-foreground",
|
|
60295
|
+
!isActive2 && !isCompleted && isAccessible && "border-gray-300 bg-background text-gray-500 hover:border-gray-400 dark:border-gray-600 dark:text-gray-400",
|
|
60296
|
+
!isAccessible && "border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed dark:border-gray-700 dark:bg-gray-900 dark:text-gray-600",
|
|
60297
|
+
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
60298
|
+
),
|
|
60299
|
+
children: hasError ? errorStepIcon : isCompleted && !isActive2 ? completedStepIcon : isActive2 && activeStepIcon ? activeStepIcon : StepIcon ? /* @__PURE__ */ jsx("span", { className: "w-5 h-5 flex items-center justify-center", children: StepIcon }) : showStepNumbers ? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: index2 + 1 }) : /* @__PURE__ */ jsx(Circle, { className: "w-4 h-4" })
|
|
60300
|
+
}
|
|
60301
|
+
)
|
|
60302
|
+
] }),
|
|
60303
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground font-medium", children: [
|
|
60304
|
+
"Step ",
|
|
60305
|
+
index2 + 1,
|
|
60306
|
+
" of ",
|
|
60307
|
+
steps.length
|
|
60308
|
+
] }) })
|
|
60309
|
+
] }, step.id);
|
|
60310
|
+
}) }) }) : (
|
|
60311
|
+
// Vertical orientation
|
|
60312
|
+
/* @__PURE__ */ jsxs("div", { className: "relative pl-12", children: [
|
|
60313
|
+
steps.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60314
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-6 top-8 bottom-8 w-[2px] bg-gray-200 dark:bg-gray-700" }),
|
|
60315
|
+
/* @__PURE__ */ jsx(
|
|
60316
|
+
motion.div,
|
|
60317
|
+
{
|
|
60318
|
+
className: "absolute left-6 top-8 w-[2px] bg-primary",
|
|
60319
|
+
initial: { height: 0 },
|
|
60320
|
+
animate: {
|
|
60321
|
+
height: `${currentStep / (steps.length - 1) * (100 - 16)}%`
|
|
60322
|
+
},
|
|
60323
|
+
transition: { duration: 0.5 }
|
|
60324
|
+
}
|
|
60325
|
+
)
|
|
60326
|
+
] }),
|
|
60327
|
+
steps.map((step, index2) => {
|
|
60328
|
+
const isActive2 = index2 === currentStep;
|
|
60329
|
+
const isCompleted = isStepCompleted(index2);
|
|
60330
|
+
const isAccessible = isStepAccessible(index2);
|
|
60331
|
+
const hasError = isActive2 && error42;
|
|
60332
|
+
const StepIcon = typeof step.icon === "function" ? step.icon({ isActive: isActive2, isCompleted }) : step.icon;
|
|
60333
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative flex items-center mb-8 last:mb-0", children: [
|
|
60334
|
+
/* @__PURE__ */ jsx(
|
|
60335
|
+
motion.div,
|
|
60336
|
+
{
|
|
60337
|
+
initial: { scale: 0.8 },
|
|
60338
|
+
animate: { scale: isActive2 ? 1.05 : 1 },
|
|
60339
|
+
className: cn(
|
|
60340
|
+
"absolute left-0 z-20 flex items-center justify-center rounded-full border-2 transition-all duration-300",
|
|
60341
|
+
"w-12 h-12",
|
|
60342
|
+
isActive2 && "border-primary bg-primary text-primary-foreground shadow-lg",
|
|
60343
|
+
isCompleted && !isActive2 && "border-primary bg-primary text-primary-foreground",
|
|
60344
|
+
!isActive2 && !isCompleted && isAccessible && "border-gray-300 bg-background text-gray-500 hover:border-gray-400",
|
|
60345
|
+
!isAccessible && "border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed",
|
|
60346
|
+
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
60347
|
+
),
|
|
60348
|
+
children: hasError ? errorStepIcon : isCompleted && !isActive2 ? completedStepIcon : isActive2 && activeStepIcon ? activeStepIcon : StepIcon ? /* @__PURE__ */ jsx("span", { className: "w-5 h-5 flex items-center justify-center", children: StepIcon }) : showStepNumbers ? /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: index2 + 1 }) : /* @__PURE__ */ jsx(Circle, { className: "w-4 h-4" })
|
|
60349
|
+
}
|
|
60350
|
+
),
|
|
60351
|
+
/* @__PURE__ */ jsx("div", { className: "ml-16", children: showStepTitles && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60352
|
+
/* @__PURE__ */ jsx("p", { className: cn(
|
|
60353
|
+
"text-sm font-semibold transition-colors",
|
|
60354
|
+
isActive2 && "text-primary",
|
|
60355
|
+
isCompleted && !isActive2 && "text-primary",
|
|
60356
|
+
!isActive2 && !isCompleted && "text-muted-foreground"
|
|
60357
|
+
), children: step.title }),
|
|
60358
|
+
step.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: step.description })
|
|
60359
|
+
] }) })
|
|
60360
|
+
] }, step.id);
|
|
60361
|
+
})
|
|
60362
|
+
] })
|
|
60363
|
+
) });
|
|
60245
60364
|
}
|
|
60246
60365
|
if (progressType === "dots") {
|
|
60247
60366
|
return /* @__PURE__ */ jsx("div", { className: cn("flex items-center justify-center space-x-2", className), children: steps.map((_, index2) => {
|
|
@@ -60265,28 +60384,28 @@ var FormWizardProgress = ({
|
|
|
60265
60384
|
}
|
|
60266
60385
|
if (progressType === "circular") {
|
|
60267
60386
|
const progress = (currentStep + 1) / steps.length * 100;
|
|
60268
|
-
const circumference = 2 * Math.PI *
|
|
60387
|
+
const circumference = 2 * Math.PI * 45;
|
|
60269
60388
|
const strokeDashoffset = circumference - progress / 100 * circumference;
|
|
60270
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("relative w-
|
|
60271
|
-
/* @__PURE__ */ jsxs("svg", { className: "w-full h-full -rotate-90", children: [
|
|
60389
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative w-36 h-36 mx-auto", className), children: [
|
|
60390
|
+
/* @__PURE__ */ jsxs("svg", { className: "w-full h-full -rotate-90", viewBox: "0 0 144 144", children: [
|
|
60272
60391
|
/* @__PURE__ */ jsx(
|
|
60273
60392
|
"circle",
|
|
60274
60393
|
{
|
|
60275
|
-
cx: "
|
|
60276
|
-
cy: "
|
|
60277
|
-
r: "
|
|
60394
|
+
cx: "72",
|
|
60395
|
+
cy: "72",
|
|
60396
|
+
r: "45",
|
|
60278
60397
|
fill: "none",
|
|
60279
60398
|
stroke: "currentColor",
|
|
60280
60399
|
strokeWidth: "8",
|
|
60281
|
-
className: "text-
|
|
60400
|
+
className: "text-gray-200 dark:text-gray-700"
|
|
60282
60401
|
}
|
|
60283
60402
|
),
|
|
60284
60403
|
/* @__PURE__ */ jsx(
|
|
60285
60404
|
motion.circle,
|
|
60286
60405
|
{
|
|
60287
|
-
cx: "
|
|
60288
|
-
cy: "
|
|
60289
|
-
r: "
|
|
60406
|
+
cx: "72",
|
|
60407
|
+
cy: "72",
|
|
60408
|
+
r: "45",
|
|
60290
60409
|
fill: "none",
|
|
60291
60410
|
stroke: "currentColor",
|
|
60292
60411
|
strokeWidth: "8",
|
|
@@ -60299,7 +60418,7 @@ var FormWizardProgress = ({
|
|
|
60299
60418
|
)
|
|
60300
60419
|
] }),
|
|
60301
60420
|
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
60302
|
-
/* @__PURE__ */ jsx("p", { className: "text-
|
|
60421
|
+
/* @__PURE__ */ jsx("p", { className: "text-3xl font-bold", children: currentStep + 1 }),
|
|
60303
60422
|
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
60304
60423
|
"of ",
|
|
60305
60424
|
steps.length
|
|
@@ -60345,7 +60464,7 @@ var FormWizardStep = ({
|
|
|
60345
60464
|
animationType = "slide",
|
|
60346
60465
|
animationDuration = 0.3
|
|
60347
60466
|
}) => {
|
|
60348
|
-
const { steps, currentStep, goToNext, goToPrevious, goToStep, updateStepData, stepData } = useFormWizard();
|
|
60467
|
+
const { steps, currentStep, goToNext, goToPrevious, goToStep, updateStepData, stepData, error: error42 } = useFormWizard();
|
|
60349
60468
|
const [direction, setDirection] = t__default.useState(0);
|
|
60350
60469
|
const previousStep = t__default.useRef(currentStep);
|
|
60351
60470
|
t__default.useEffect(() => {
|
|
@@ -60380,7 +60499,14 @@ var FormWizardStep = ({
|
|
|
60380
60499
|
ease: "easeInOut"
|
|
60381
60500
|
},
|
|
60382
60501
|
className: cn("w-full", className),
|
|
60383
|
-
|
|
60502
|
+
"data-wizard-step-content": true,
|
|
60503
|
+
children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
60504
|
+
error42 && /* @__PURE__ */ jsxs(MoonUIAlertPro, { variant: "error", children: [
|
|
60505
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
|
|
60506
|
+
/* @__PURE__ */ jsx(MoonUIAlertDescriptionPro, { children: error42 })
|
|
60507
|
+
] }),
|
|
60508
|
+
content
|
|
60509
|
+
] })
|
|
60384
60510
|
},
|
|
60385
60511
|
currentStep
|
|
60386
60512
|
) });
|
|
@@ -60523,23 +60649,20 @@ var MoonUIFormWizardPro = t__default.forwardRef(({
|
|
|
60523
60649
|
persistData,
|
|
60524
60650
|
storageKey,
|
|
60525
60651
|
children: /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), children: [
|
|
60526
|
-
showProgressBar && /* @__PURE__ */
|
|
60527
|
-
|
|
60528
|
-
|
|
60529
|
-
|
|
60530
|
-
|
|
60531
|
-
|
|
60532
|
-
|
|
60533
|
-
|
|
60534
|
-
|
|
60535
|
-
|
|
60536
|
-
|
|
60537
|
-
|
|
60538
|
-
|
|
60539
|
-
|
|
60540
|
-
),
|
|
60541
|
-
/* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "my-8" })
|
|
60542
|
-
] }),
|
|
60652
|
+
showProgressBar && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
60653
|
+
FormWizardProgress,
|
|
60654
|
+
{
|
|
60655
|
+
className: cn("mb-12", progressClassName),
|
|
60656
|
+
progressType,
|
|
60657
|
+
orientation,
|
|
60658
|
+
showStepNumbers,
|
|
60659
|
+
showStepTitles,
|
|
60660
|
+
stepIconPosition,
|
|
60661
|
+
completedStepIcon,
|
|
60662
|
+
activeStepIcon,
|
|
60663
|
+
errorStepIcon
|
|
60664
|
+
}
|
|
60665
|
+
) }),
|
|
60543
60666
|
/* @__PURE__ */ jsx(MoonUICardPro, { className: cn("border-0 shadow-none", contentClassName), children: /* @__PURE__ */ jsx(MoonUICardContentPro, { className: "p-0", children: /* @__PURE__ */ jsx(
|
|
60544
60667
|
FormWizardStep,
|
|
60545
60668
|
{
|
|
@@ -60548,11 +60671,10 @@ var MoonUIFormWizardPro = t__default.forwardRef(({
|
|
|
60548
60671
|
animationDuration
|
|
60549
60672
|
}
|
|
60550
60673
|
) }) }),
|
|
60551
|
-
/* @__PURE__ */ jsx(MoonUISeparatorPro, { className: "my-8" }),
|
|
60552
60674
|
/* @__PURE__ */ jsx(
|
|
60553
60675
|
FormWizardNavigation,
|
|
60554
60676
|
{
|
|
60555
|
-
className: navigationClassName
|
|
60677
|
+
className: cn("mt-8", navigationClassName)
|
|
60556
60678
|
}
|
|
60557
60679
|
)
|
|
60558
60680
|
] })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moontra/moonui-pro",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -95,17 +95,76 @@ export const FormWizardProvider: React.FC<FormWizardProviderProps> = ({
|
|
|
95
95
|
|
|
96
96
|
const validateCurrentStep = useCallback(async (): Promise<boolean> => {
|
|
97
97
|
const step = steps[currentStep]
|
|
98
|
+
|
|
99
|
+
// First check HTML5 validation for required fields
|
|
100
|
+
if (typeof window !== 'undefined') {
|
|
101
|
+
const stepElement = document.querySelector('[data-wizard-step-content]')
|
|
102
|
+
if (stepElement) {
|
|
103
|
+
const requiredInputs = stepElement.querySelectorAll('input[required], select[required], textarea[required]')
|
|
104
|
+
const emptyFields: string[] = []
|
|
105
|
+
|
|
106
|
+
requiredInputs.forEach((input: Element) => {
|
|
107
|
+
const htmlInput = input as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
|
|
108
|
+
if (!htmlInput.value || htmlInput.value.trim() === '') {
|
|
109
|
+
const label = document.querySelector(`label[for="${htmlInput.id}"]`)
|
|
110
|
+
const fieldName = label ? (label.textContent?.replace(' *', '') || 'Field') : htmlInput.name || htmlInput.id || 'Field'
|
|
111
|
+
emptyFields.push(fieldName)
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// Check for required checkboxes
|
|
116
|
+
const requiredCheckboxes = stepElement.querySelectorAll('input[type="checkbox"][required]')
|
|
117
|
+
requiredCheckboxes.forEach((checkbox: Element) => {
|
|
118
|
+
const htmlCheckbox = checkbox as HTMLInputElement
|
|
119
|
+
if (!htmlCheckbox.checked) {
|
|
120
|
+
const label = document.querySelector(`label[for="${htmlCheckbox.id}"]`)
|
|
121
|
+
const fieldName = label ? (label.textContent?.replace(' *', '') || 'Checkbox') : htmlCheckbox.name || htmlCheckbox.id || 'Checkbox'
|
|
122
|
+
emptyFields.push(fieldName)
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
if (emptyFields.length > 0) {
|
|
127
|
+
setError(`Please fill in the following required fields: ${emptyFields.join(', ')}`)
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Then run custom validation if provided
|
|
98
134
|
if (!step.validation) return true
|
|
99
135
|
|
|
100
136
|
setIsLoading(true)
|
|
101
137
|
setError(null)
|
|
102
138
|
|
|
103
139
|
try {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
140
|
+
const result = await step.validation()
|
|
141
|
+
|
|
142
|
+
// Handle boolean return
|
|
143
|
+
if (typeof result === 'boolean') {
|
|
144
|
+
if (!result) {
|
|
145
|
+
setError("Please complete all required fields before proceeding")
|
|
146
|
+
}
|
|
147
|
+
return result
|
|
107
148
|
}
|
|
108
|
-
|
|
149
|
+
|
|
150
|
+
// Handle object return {isValid: boolean, error?: string, errors?: string[]}
|
|
151
|
+
if (typeof result === 'object' && result !== null && 'isValid' in result) {
|
|
152
|
+
const validationResult = result as { isValid: boolean; error?: string; errors?: string[] }
|
|
153
|
+
if (!validationResult.isValid) {
|
|
154
|
+
if (validationResult.error) {
|
|
155
|
+
setError(validationResult.error)
|
|
156
|
+
} else if (validationResult.errors && Array.isArray(validationResult.errors)) {
|
|
157
|
+
setError(validationResult.errors.join(', '))
|
|
158
|
+
} else {
|
|
159
|
+
setError("Please complete all required fields before proceeding")
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return validationResult.isValid
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Invalid return type
|
|
166
|
+
setError("Invalid validation response")
|
|
167
|
+
return false
|
|
109
168
|
} catch (err) {
|
|
110
169
|
setError(err instanceof Error ? err.message : "Validation failed")
|
|
111
170
|
return false
|
|
@@ -35,90 +35,195 @@ export const FormWizardProgress: React.FC<FormWizardProgressProps> = ({
|
|
|
35
35
|
if (progressType === 'linear') {
|
|
36
36
|
return (
|
|
37
37
|
<div className={cn(
|
|
38
|
-
"relative",
|
|
39
|
-
orientation === 'vertical' ? "flex flex-col space-y-8" : "
|
|
38
|
+
"relative w-full",
|
|
39
|
+
orientation === 'vertical' ? "flex flex-col space-y-8" : "",
|
|
40
40
|
className
|
|
41
41
|
)}>
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
{orientation === 'horizontal' ? (
|
|
43
|
+
<div className="relative w-full">
|
|
44
|
+
{/* Steps Container with connecting lines */}
|
|
45
|
+
<div className="relative flex items-start justify-between w-full">
|
|
46
|
+
{steps.map((step, index) => {
|
|
47
|
+
const isActive = index === currentStep
|
|
48
|
+
const isCompleted = isStepCompleted(index)
|
|
49
|
+
const isAccessible = isStepAccessible(index)
|
|
50
|
+
const hasError = isActive && error
|
|
51
|
+
|
|
52
|
+
const StepIcon = typeof step.icon === 'function'
|
|
53
|
+
? step.icon({ isActive, isCompleted })
|
|
54
|
+
: step.icon
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
56
|
+
return (
|
|
57
|
+
<div key={step.id} className="relative flex-1 flex flex-col items-center">
|
|
58
|
+
{/* Step Title & Description - Above the circle */}
|
|
59
|
+
{showStepTitles && (
|
|
60
|
+
<div className="text-center mb-3 min-h-[40px] px-2">
|
|
61
|
+
<p className={cn(
|
|
62
|
+
"text-sm font-semibold transition-colors",
|
|
63
|
+
isActive && "text-primary",
|
|
64
|
+
isCompleted && !isActive && "text-primary",
|
|
65
|
+
!isActive && !isCompleted && "text-muted-foreground"
|
|
66
|
+
)}>
|
|
67
|
+
{step.title}
|
|
68
|
+
</p>
|
|
69
|
+
{step.description && (
|
|
70
|
+
<p className="text-xs text-muted-foreground mt-1">
|
|
71
|
+
{step.description}
|
|
72
|
+
</p>
|
|
73
|
+
)}
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
76
|
+
|
|
77
|
+
{/* Step Circle Container with line */}
|
|
78
|
+
<div className="relative flex items-center w-full">
|
|
79
|
+
{/* Connecting Line - Positioned after each circle except the last */}
|
|
80
|
+
{index < steps.length - 1 && (
|
|
81
|
+
<div
|
|
82
|
+
className="absolute left-1/2 w-full h-[2px]"
|
|
83
|
+
style={{
|
|
84
|
+
width: 'calc(100% + 24px)',
|
|
85
|
+
marginLeft: '24px'
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<div className="h-full bg-gray-200 dark:bg-gray-700" />
|
|
89
|
+
{index < currentStep && (
|
|
90
|
+
<motion.div
|
|
91
|
+
className="absolute inset-0 bg-primary"
|
|
92
|
+
initial={{ scaleX: 0 }}
|
|
93
|
+
animate={{ scaleX: 1 }}
|
|
94
|
+
transition={{ duration: 0.5, delay: index * 0.1 }}
|
|
95
|
+
style={{ transformOrigin: 'left' }}
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
|
|
101
|
+
{/* Step Circle */}
|
|
102
|
+
<motion.div
|
|
103
|
+
initial={{ scale: 0.8 }}
|
|
104
|
+
animate={{ scale: isActive ? 1.05 : 1 }}
|
|
105
|
+
transition={{ duration: 0.2 }}
|
|
106
|
+
className={cn(
|
|
107
|
+
"relative z-10 flex items-center justify-center rounded-full transition-all duration-300 mx-auto",
|
|
108
|
+
"w-12 h-12 border-2",
|
|
109
|
+
isActive && "border-primary bg-primary text-primary-foreground shadow-lg shadow-primary/20",
|
|
110
|
+
isCompleted && !isActive && "border-primary bg-primary text-primary-foreground",
|
|
111
|
+
!isActive && !isCompleted && isAccessible && "border-gray-300 bg-background text-gray-500 hover:border-gray-400 dark:border-gray-600 dark:text-gray-400",
|
|
112
|
+
!isAccessible && "border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed dark:border-gray-700 dark:bg-gray-900 dark:text-gray-600",
|
|
113
|
+
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
114
|
+
)}
|
|
115
|
+
>
|
|
116
|
+
{hasError ? (
|
|
117
|
+
errorStepIcon
|
|
118
|
+
) : isCompleted && !isActive ? (
|
|
119
|
+
completedStepIcon
|
|
120
|
+
) : isActive && activeStepIcon ? (
|
|
121
|
+
activeStepIcon
|
|
122
|
+
) : StepIcon ? (
|
|
123
|
+
<span className="w-5 h-5 flex items-center justify-center">{StepIcon}</span>
|
|
124
|
+
) : showStepNumbers ? (
|
|
125
|
+
<span className="text-sm font-semibold">{index + 1}</span>
|
|
126
|
+
) : (
|
|
127
|
+
<Circle className="w-4 h-4" />
|
|
128
|
+
)}
|
|
129
|
+
</motion.div>
|
|
130
|
+
</div>
|
|
85
131
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
? "left-16 top-1/2 -translate-y-1/2"
|
|
91
|
-
: "top-full mt-2 left-1/2 -translate-x-1/2 text-center"
|
|
92
|
-
)}>
|
|
93
|
-
<p className={cn(
|
|
94
|
-
"text-sm font-medium transition-colors",
|
|
95
|
-
isActive && "text-primary",
|
|
96
|
-
isCompleted && !isActive && "text-primary",
|
|
97
|
-
!isActive && !isCompleted && "text-muted-foreground"
|
|
98
|
-
)}>
|
|
99
|
-
{step.title}
|
|
100
|
-
</p>
|
|
101
|
-
{step.description && (
|
|
102
|
-
<p className="text-xs text-muted-foreground mt-1">
|
|
103
|
-
{step.description}
|
|
132
|
+
{/* Step Label Below Circle */}
|
|
133
|
+
<div className="mt-3">
|
|
134
|
+
<p className="text-xs text-muted-foreground font-medium">
|
|
135
|
+
Step {index + 1} of {steps.length}
|
|
104
136
|
</p>
|
|
105
|
-
|
|
137
|
+
</div>
|
|
106
138
|
</div>
|
|
107
|
-
)
|
|
139
|
+
)
|
|
140
|
+
})}
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
) : (
|
|
144
|
+
// Vertical orientation
|
|
145
|
+
<div className="relative pl-12">
|
|
146
|
+
{/* Vertical Progress Line */}
|
|
147
|
+
{steps.length > 1 && (
|
|
148
|
+
<>
|
|
149
|
+
<div className="absolute left-6 top-8 bottom-8 w-[2px] bg-gray-200 dark:bg-gray-700" />
|
|
150
|
+
<motion.div
|
|
151
|
+
className="absolute left-6 top-8 w-[2px] bg-primary"
|
|
152
|
+
initial={{ height: 0 }}
|
|
153
|
+
animate={{
|
|
154
|
+
height: `${(currentStep / (steps.length - 1)) * (100 - 16)}%`
|
|
155
|
+
}}
|
|
156
|
+
transition={{ duration: 0.5 }}
|
|
157
|
+
/>
|
|
158
|
+
</>
|
|
159
|
+
)}
|
|
108
160
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
161
|
+
{steps.map((step, index) => {
|
|
162
|
+
const isActive = index === currentStep
|
|
163
|
+
const isCompleted = isStepCompleted(index)
|
|
164
|
+
const isAccessible = isStepAccessible(index)
|
|
165
|
+
const hasError = isActive && error
|
|
166
|
+
|
|
167
|
+
const StepIcon = typeof step.icon === 'function'
|
|
168
|
+
? step.icon({ isActive, isCompleted })
|
|
169
|
+
: step.icon
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<div key={step.id} className="relative flex items-center mb-8 last:mb-0">
|
|
173
|
+
{/* Step Circle */}
|
|
174
|
+
<motion.div
|
|
175
|
+
initial={{ scale: 0.8 }}
|
|
176
|
+
animate={{ scale: isActive ? 1.05 : 1 }}
|
|
177
|
+
className={cn(
|
|
178
|
+
"absolute left-0 z-20 flex items-center justify-center rounded-full border-2 transition-all duration-300",
|
|
179
|
+
"w-12 h-12",
|
|
180
|
+
isActive && "border-primary bg-primary text-primary-foreground shadow-lg",
|
|
181
|
+
isCompleted && !isActive && "border-primary bg-primary text-primary-foreground",
|
|
182
|
+
!isActive && !isCompleted && isAccessible && "border-gray-300 bg-background text-gray-500 hover:border-gray-400",
|
|
183
|
+
!isAccessible && "border-gray-200 bg-gray-50 text-gray-400 cursor-not-allowed",
|
|
184
|
+
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
185
|
+
)}
|
|
186
|
+
>
|
|
187
|
+
{hasError ? (
|
|
188
|
+
errorStepIcon
|
|
189
|
+
) : isCompleted && !isActive ? (
|
|
190
|
+
completedStepIcon
|
|
191
|
+
) : isActive && activeStepIcon ? (
|
|
192
|
+
activeStepIcon
|
|
193
|
+
) : StepIcon ? (
|
|
194
|
+
<span className="w-5 h-5 flex items-center justify-center">{StepIcon}</span>
|
|
195
|
+
) : showStepNumbers ? (
|
|
196
|
+
<span className="text-sm font-semibold">{index + 1}</span>
|
|
197
|
+
) : (
|
|
198
|
+
<Circle className="w-4 h-4" />
|
|
199
|
+
)}
|
|
200
|
+
</motion.div>
|
|
201
|
+
|
|
202
|
+
{/* Step Content */}
|
|
203
|
+
<div className="ml-16">
|
|
204
|
+
{showStepTitles && (
|
|
205
|
+
<>
|
|
206
|
+
<p className={cn(
|
|
207
|
+
"text-sm font-semibold transition-colors",
|
|
208
|
+
isActive && "text-primary",
|
|
209
|
+
isCompleted && !isActive && "text-primary",
|
|
210
|
+
!isActive && !isCompleted && "text-muted-foreground"
|
|
211
|
+
)}>
|
|
212
|
+
{step.title}
|
|
213
|
+
</p>
|
|
214
|
+
{step.description && (
|
|
215
|
+
<p className="text-xs text-muted-foreground mt-1">
|
|
216
|
+
{step.description}
|
|
217
|
+
</p>
|
|
218
|
+
)}
|
|
219
|
+
</>
|
|
220
|
+
)}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
)
|
|
224
|
+
})}
|
|
225
|
+
</div>
|
|
226
|
+
)}
|
|
122
227
|
</div>
|
|
123
228
|
)
|
|
124
229
|
}
|
|
@@ -150,25 +255,25 @@ export const FormWizardProgress: React.FC<FormWizardProgressProps> = ({
|
|
|
150
255
|
|
|
151
256
|
if (progressType === 'circular') {
|
|
152
257
|
const progress = ((currentStep + 1) / steps.length) * 100
|
|
153
|
-
const circumference = 2 * Math.PI *
|
|
258
|
+
const circumference = 2 * Math.PI * 45 // radius = 45
|
|
154
259
|
const strokeDashoffset = circumference - (progress / 100) * circumference
|
|
155
260
|
|
|
156
261
|
return (
|
|
157
|
-
<div className={cn("relative w-
|
|
158
|
-
<svg className="w-full h-full -rotate-90">
|
|
262
|
+
<div className={cn("relative w-36 h-36 mx-auto", className)}>
|
|
263
|
+
<svg className="w-full h-full -rotate-90" viewBox="0 0 144 144">
|
|
159
264
|
<circle
|
|
160
|
-
cx="
|
|
161
|
-
cy="
|
|
162
|
-
r="
|
|
265
|
+
cx="72"
|
|
266
|
+
cy="72"
|
|
267
|
+
r="45"
|
|
163
268
|
fill="none"
|
|
164
269
|
stroke="currentColor"
|
|
165
270
|
strokeWidth="8"
|
|
166
|
-
className="text-
|
|
271
|
+
className="text-gray-200 dark:text-gray-700"
|
|
167
272
|
/>
|
|
168
273
|
<motion.circle
|
|
169
|
-
cx="
|
|
170
|
-
cy="
|
|
171
|
-
r="
|
|
274
|
+
cx="72"
|
|
275
|
+
cy="72"
|
|
276
|
+
r="45"
|
|
172
277
|
fill="none"
|
|
173
278
|
stroke="currentColor"
|
|
174
279
|
strokeWidth="8"
|
|
@@ -181,7 +286,7 @@ export const FormWizardProgress: React.FC<FormWizardProgressProps> = ({
|
|
|
181
286
|
</svg>
|
|
182
287
|
<div className="absolute inset-0 flex items-center justify-center">
|
|
183
288
|
<div className="text-center">
|
|
184
|
-
<p className="text-
|
|
289
|
+
<p className="text-3xl font-bold">{currentStep + 1}</p>
|
|
185
290
|
<p className="text-sm text-muted-foreground">of {steps.length}</p>
|
|
186
291
|
</div>
|
|
187
292
|
</div>
|
|
@@ -5,6 +5,8 @@ import { motion, AnimatePresence } from "framer-motion"
|
|
|
5
5
|
import { cn } from "../../lib/utils"
|
|
6
6
|
import { useFormWizard } from "./form-wizard-context"
|
|
7
7
|
import { FormWizardProps } from "./types"
|
|
8
|
+
import { Alert, AlertDescription } from "../ui/alert"
|
|
9
|
+
import { AlertCircle } from "lucide-react"
|
|
8
10
|
|
|
9
11
|
interface FormWizardStepProps {
|
|
10
12
|
className?: string
|
|
@@ -49,7 +51,7 @@ export const FormWizardStep: React.FC<FormWizardStepProps> = ({
|
|
|
49
51
|
animationType = 'slide',
|
|
50
52
|
animationDuration = 0.3
|
|
51
53
|
}) => {
|
|
52
|
-
const { steps, currentStep, goToNext, goToPrevious, goToStep, updateStepData, stepData } = useFormWizard()
|
|
54
|
+
const { steps, currentStep, goToNext, goToPrevious, goToStep, updateStepData, stepData, error } = useFormWizard()
|
|
53
55
|
const [direction, setDirection] = React.useState(0)
|
|
54
56
|
const previousStep = React.useRef(currentStep)
|
|
55
57
|
|
|
@@ -92,8 +94,17 @@ export const FormWizardStep: React.FC<FormWizardStepProps> = ({
|
|
|
92
94
|
ease: "easeInOut"
|
|
93
95
|
}}
|
|
94
96
|
className={cn("w-full", className)}
|
|
97
|
+
data-wizard-step-content
|
|
95
98
|
>
|
|
96
|
-
|
|
99
|
+
<div className="space-y-4">
|
|
100
|
+
{error && (
|
|
101
|
+
<Alert variant="error">
|
|
102
|
+
<AlertCircle className="h-4 w-4" />
|
|
103
|
+
<AlertDescription>{error}</AlertDescription>
|
|
104
|
+
</Alert>
|
|
105
|
+
)}
|
|
106
|
+
{content}
|
|
107
|
+
</div>
|
|
97
108
|
</motion.div>
|
|
98
109
|
</AnimatePresence>
|
|
99
110
|
)
|
|
@@ -59,7 +59,7 @@ export const MoonUIFormWizardPro = React.forwardRef<HTMLDivElement, FormWizardPr
|
|
|
59
59
|
{showProgressBar && (
|
|
60
60
|
<>
|
|
61
61
|
<FormWizardProgress
|
|
62
|
-
className={progressClassName}
|
|
62
|
+
className={cn("mb-12", progressClassName)}
|
|
63
63
|
progressType={progressType}
|
|
64
64
|
orientation={orientation}
|
|
65
65
|
showStepNumbers={showStepNumbers}
|
|
@@ -69,7 +69,6 @@ export const MoonUIFormWizardPro = React.forwardRef<HTMLDivElement, FormWizardPr
|
|
|
69
69
|
activeStepIcon={activeStepIcon}
|
|
70
70
|
errorStepIcon={errorStepIcon}
|
|
71
71
|
/>
|
|
72
|
-
<Separator className="my-8" />
|
|
73
72
|
</>
|
|
74
73
|
)}
|
|
75
74
|
|
|
@@ -83,10 +82,8 @@ export const MoonUIFormWizardPro = React.forwardRef<HTMLDivElement, FormWizardPr
|
|
|
83
82
|
</CardContent>
|
|
84
83
|
</Card>
|
|
85
84
|
|
|
86
|
-
<Separator className="my-8" />
|
|
87
|
-
|
|
88
85
|
<FormWizardNavigation
|
|
89
|
-
className={navigationClassName}
|
|
86
|
+
className={cn("mt-8", navigationClassName)}
|
|
90
87
|
/>
|
|
91
88
|
</div>
|
|
92
89
|
</FormWizardProvider>
|