@moontra/moonui-pro 2.20.2 → 2.20.4
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/package.json +8 -3
- package/plugin/index.d.ts +86 -0
- package/plugin/index.js +308 -0
- package/scripts/postinstall.js +191 -23
- package/src/components/advanced-chart/index.tsx +0 -1246
- package/src/components/advanced-forms/index.tsx +0 -585
- package/src/components/animated-button/index.tsx +0 -385
- package/src/components/calendar/event-dialog.tsx +0 -377
- package/src/components/calendar/index.tsx +0 -1220
- package/src/components/calendar-pro/index.tsx +0 -1697
- package/src/components/color-picker/index.tsx +0 -432
- package/src/components/credit-card-input/index.tsx +0 -406
- package/src/components/dashboard/dashboard-grid.tsx +0 -480
- package/src/components/dashboard/demo.tsx +0 -425
- package/src/components/dashboard/index.tsx +0 -1046
- package/src/components/dashboard/time-range-picker.tsx +0 -336
- package/src/components/dashboard/types.ts +0 -225
- package/src/components/dashboard/widgets/activity-feed.tsx +0 -349
- package/src/components/dashboard/widgets/chart-widget.tsx +0 -418
- package/src/components/dashboard/widgets/comparison-widget.tsx +0 -177
- package/src/components/dashboard/widgets/index.ts +0 -5
- package/src/components/dashboard/widgets/metric-card.tsx +0 -363
- package/src/components/dashboard/widgets/progress-widget.tsx +0 -113
- package/src/components/data-table/data-table-bulk-actions.tsx +0 -204
- package/src/components/data-table/data-table-column-toggle.tsx +0 -169
- package/src/components/data-table/data-table-export.ts +0 -156
- package/src/components/data-table/data-table-filter-drawer.tsx +0 -448
- package/src/components/data-table/index.tsx +0 -845
- package/src/components/draggable-list/index.tsx +0 -100
- package/src/components/error-boundary/index.tsx +0 -232
- package/src/components/file-upload/index.tsx +0 -1660
- package/src/components/floating-action-button/index.tsx +0 -206
- package/src/components/form-wizard/form-wizard-context.tsx +0 -335
- package/src/components/form-wizard/form-wizard-navigation.tsx +0 -118
- package/src/components/form-wizard/form-wizard-progress.tsx +0 -329
- package/src/components/form-wizard/form-wizard-step.tsx +0 -111
- package/src/components/form-wizard/index.tsx +0 -102
- package/src/components/form-wizard/types.ts +0 -77
- package/src/components/gesture-drawer/index.tsx +0 -551
- package/src/components/github-stars/github-api.ts +0 -426
- package/src/components/github-stars/hooks.ts +0 -517
- package/src/components/github-stars/index.tsx +0 -375
- package/src/components/github-stars/types.ts +0 -148
- package/src/components/github-stars/variants.tsx +0 -515
- package/src/components/health-check/index.tsx +0 -439
- package/src/components/hover-card-3d/index.tsx +0 -529
- package/src/components/index.ts +0 -130
- package/src/components/internal/index.ts +0 -78
- package/src/components/kanban/add-card-modal.tsx +0 -502
- package/src/components/kanban/card-detail-modal.tsx +0 -761
- package/src/components/kanban/index.ts +0 -13
- package/src/components/kanban/kanban.tsx +0 -1689
- package/src/components/kanban/types.ts +0 -168
- package/src/components/lazy-component/index.tsx +0 -823
- package/src/components/license-error/index.tsx +0 -31
- package/src/components/magnetic-button/index.tsx +0 -216
- package/src/components/memory-efficient-data/index.tsx +0 -1018
- package/src/components/moonui-quiz-form/index.tsx +0 -817
- package/src/components/navbar/index.tsx +0 -781
- package/src/components/optimized-image/index.tsx +0 -425
- package/src/components/performance-debugger/index.tsx +0 -613
- package/src/components/performance-monitor/index.tsx +0 -808
- package/src/components/phone-number-input/index.tsx +0 -343
- package/src/components/phone-number-input/phone-number-input-simple.tsx +0 -167
- package/src/components/pinch-zoom/index.tsx +0 -566
- package/src/components/quiz-form/index.tsx +0 -479
- package/src/components/rich-text-editor/index.tsx +0 -2322
- package/src/components/rich-text-editor/slash-commands-extension.ts +0 -230
- package/src/components/rich-text-editor/slash-commands.css +0 -35
- package/src/components/rich-text-editor/table-styles.css +0 -65
- package/src/components/sidebar/index.tsx +0 -884
- package/src/components/spotlight-card/index.tsx +0 -191
- package/src/components/swipeable-card/index.tsx +0 -100
- package/src/components/timeline/index.tsx +0 -1183
- package/src/components/ui/accordion.tsx +0 -581
- package/src/components/ui/alert-dialog.tsx +0 -141
- package/src/components/ui/alert.tsx +0 -141
- package/src/components/ui/aspect-ratio.tsx +0 -245
- package/src/components/ui/avatar.tsx +0 -155
- package/src/components/ui/badge.tsx +0 -230
- package/src/components/ui/breadcrumb.tsx +0 -216
- package/src/components/ui/button.tsx +0 -228
- package/src/components/ui/calendar.tsx +0 -387
- package/src/components/ui/card.tsx +0 -216
- package/src/components/ui/checkbox.tsx +0 -259
- package/src/components/ui/collapsible.tsx +0 -631
- package/src/components/ui/color-picker.tsx +0 -97
- package/src/components/ui/command.tsx +0 -948
- package/src/components/ui/dialog.tsx +0 -752
- package/src/components/ui/dropdown-menu.tsx +0 -706
- package/src/components/ui/gesture-drawer.tsx +0 -11
- package/src/components/ui/hover-card.tsx +0 -29
- package/src/components/ui/index.ts +0 -222
- package/src/components/ui/input.tsx +0 -224
- package/src/components/ui/label.tsx +0 -29
- package/src/components/ui/lightbox.tsx +0 -606
- package/src/components/ui/magnetic-button.tsx +0 -129
- package/src/components/ui/media-gallery.tsx +0 -611
- package/src/components/ui/navigation-menu.tsx +0 -130
- package/src/components/ui/pagination.tsx +0 -125
- package/src/components/ui/popover.tsx +0 -185
- package/src/components/ui/progress.tsx +0 -30
- package/src/components/ui/radio-group.tsx +0 -257
- package/src/components/ui/scroll-area.tsx +0 -47
- package/src/components/ui/select.tsx +0 -378
- package/src/components/ui/separator.tsx +0 -145
- package/src/components/ui/sheet.tsx +0 -139
- package/src/components/ui/skeleton.tsx +0 -20
- package/src/components/ui/slider.tsx +0 -354
- package/src/components/ui/spotlight-card.tsx +0 -119
- package/src/components/ui/switch.tsx +0 -86
- package/src/components/ui/table.tsx +0 -331
- package/src/components/ui/tabs-pro.tsx +0 -542
- package/src/components/ui/tabs.tsx +0 -54
- package/src/components/ui/textarea.tsx +0 -28
- package/src/components/ui/toast.tsx +0 -317
- package/src/components/ui/toggle.tsx +0 -119
- package/src/components/ui/tooltip.tsx +0 -151
- package/src/components/virtual-list/index.tsx +0 -668
- package/src/hooks/use-chart.ts +0 -205
- package/src/hooks/use-data-table.ts +0 -182
- package/src/hooks/use-docs-pro-access.ts +0 -13
- package/src/hooks/use-license-check.ts +0 -65
- package/src/hooks/use-subscription.ts +0 -19
- package/src/hooks/use-toast.ts +0 -15
- package/src/index.ts +0 -22
- package/src/lib/ai-providers.ts +0 -377
- package/src/lib/component-metadata.ts +0 -18
- package/src/lib/micro-interactions.ts +0 -255
- package/src/lib/paddle.ts +0 -17
- package/src/lib/utils.ts +0 -6
- package/src/patterns/login-form/index.tsx +0 -276
- package/src/patterns/login-form/types.ts +0 -67
- package/src/setupTests.ts +0 -41
- package/src/styles/advanced-chart.css +0 -239
- package/src/styles/calendar.css +0 -35
- package/src/styles/design-system.css +0 -363
- package/src/styles/index.css +0 -681
- package/src/styles/tailwind.css +0 -7
- package/src/styles/tokens.css +0 -455
- package/src/types/next-auth.d.ts +0 -21
- package/src/use-intersection-observer.tsx +0 -154
- package/src/use-local-storage.tsx +0 -71
- package/src/use-paddle.ts +0 -138
- package/src/use-performance-optimizer.ts +0 -389
- package/src/use-pro-access.ts +0 -141
- package/src/use-scroll-animation.ts +0 -219
- package/src/use-subscription.ts +0 -37
- package/src/use-toast.ts +0 -32
- package/src/utils/chart-helpers.ts +0 -357
- package/src/utils/cn.ts +0 -6
- package/src/utils/data-processing.ts +0 -151
- package/src/utils/license-validator.tsx +0 -183
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import React from "react"
|
|
4
|
-
import { motion } from "framer-motion"
|
|
5
|
-
import { CheckCircle, Circle, XCircle } from "lucide-react"
|
|
6
|
-
import { cn } from "../../lib/utils"
|
|
7
|
-
import { useFormWizard } from "./form-wizard-context"
|
|
8
|
-
import { FormWizardProps } from "./types"
|
|
9
|
-
|
|
10
|
-
interface FormWizardProgressProps {
|
|
11
|
-
className?: string
|
|
12
|
-
progressType?: FormWizardProps['progressType']
|
|
13
|
-
orientation?: FormWizardProps['orientation']
|
|
14
|
-
showStepNumbers?: boolean
|
|
15
|
-
showStepTitles?: boolean
|
|
16
|
-
stepIconPosition?: FormWizardProps['stepIconPosition']
|
|
17
|
-
completedStepIcon?: React.ReactNode
|
|
18
|
-
activeStepIcon?: React.ReactNode
|
|
19
|
-
errorStepIcon?: React.ReactNode
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export const FormWizardProgress: React.FC<FormWizardProgressProps> = ({
|
|
23
|
-
className,
|
|
24
|
-
progressType = 'linear',
|
|
25
|
-
orientation = 'horizontal',
|
|
26
|
-
showStepNumbers = true,
|
|
27
|
-
showStepTitles = true,
|
|
28
|
-
stepIconPosition = 'top',
|
|
29
|
-
completedStepIcon = <CheckCircle className="w-5 h-5" />,
|
|
30
|
-
activeStepIcon,
|
|
31
|
-
errorStepIcon = <XCircle className="w-5 h-5" />
|
|
32
|
-
}) => {
|
|
33
|
-
const { steps, currentStep, isStepCompleted, isStepAccessible, error } = useFormWizard()
|
|
34
|
-
|
|
35
|
-
if (progressType === 'linear') {
|
|
36
|
-
return (
|
|
37
|
-
<div className={cn(
|
|
38
|
-
"relative w-full",
|
|
39
|
-
orientation === 'vertical' ? "flex flex-col space-y-8" : "",
|
|
40
|
-
className
|
|
41
|
-
)}>
|
|
42
|
-
{orientation === 'horizontal' ? (
|
|
43
|
-
<div className="relative w-full">
|
|
44
|
-
{/* Steps Container with connecting lines */}
|
|
45
|
-
<div className={cn(
|
|
46
|
-
"relative flex items-start justify-between w-full",
|
|
47
|
-
stepIconPosition === 'left' && "pl-14"
|
|
48
|
-
)}>
|
|
49
|
-
{steps.map((step, index) => {
|
|
50
|
-
const isActive = index === currentStep
|
|
51
|
-
const isCompleted = isStepCompleted(index)
|
|
52
|
-
const isAccessible = isStepAccessible(index)
|
|
53
|
-
const hasError = isActive && error
|
|
54
|
-
|
|
55
|
-
const StepIcon = typeof step.icon === 'function'
|
|
56
|
-
? step.icon({ isActive, isCompleted })
|
|
57
|
-
: step.icon
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<div key={step.id} className="relative flex-1 flex flex-col items-center">
|
|
61
|
-
{/* Step Icon - Left Position */}
|
|
62
|
-
{stepIconPosition === 'left' && StepIcon && (
|
|
63
|
-
<div className="absolute -left-12 top-1/2 -translate-y-1/2 flex items-center justify-center">
|
|
64
|
-
<span className={cn(
|
|
65
|
-
"w-8 h-8 flex items-center justify-center transition-colors",
|
|
66
|
-
isActive && "text-primary",
|
|
67
|
-
isCompleted && !isActive && "text-primary",
|
|
68
|
-
!isActive && !isCompleted && "text-muted-foreground"
|
|
69
|
-
)}>
|
|
70
|
-
{StepIcon}
|
|
71
|
-
</span>
|
|
72
|
-
</div>
|
|
73
|
-
)}
|
|
74
|
-
|
|
75
|
-
{/* Step Icon - Top Position */}
|
|
76
|
-
{stepIconPosition === 'top' && StepIcon && (
|
|
77
|
-
<div className="flex items-center justify-center mb-2">
|
|
78
|
-
<span className={cn(
|
|
79
|
-
"w-8 h-8 flex items-center justify-center transition-colors",
|
|
80
|
-
isActive && "text-primary",
|
|
81
|
-
isCompleted && !isActive && "text-primary",
|
|
82
|
-
!isActive && !isCompleted && "text-muted-foreground"
|
|
83
|
-
)}>
|
|
84
|
-
{StepIcon}
|
|
85
|
-
</span>
|
|
86
|
-
</div>
|
|
87
|
-
)}
|
|
88
|
-
|
|
89
|
-
{/* Step Title & Description - Above the circle */}
|
|
90
|
-
{showStepTitles && (
|
|
91
|
-
<div className="text-center mb-3 min-h-[40px] px-2">
|
|
92
|
-
<p className={cn(
|
|
93
|
-
"text-sm font-semibold transition-colors",
|
|
94
|
-
isActive && "text-primary",
|
|
95
|
-
isCompleted && !isActive && "text-primary",
|
|
96
|
-
!isActive && !isCompleted && "text-muted-foreground"
|
|
97
|
-
)}>
|
|
98
|
-
{step.title}
|
|
99
|
-
</p>
|
|
100
|
-
{step.description && (
|
|
101
|
-
<p className="text-xs text-muted-foreground mt-1">
|
|
102
|
-
{step.description}
|
|
103
|
-
</p>
|
|
104
|
-
)}
|
|
105
|
-
</div>
|
|
106
|
-
)}
|
|
107
|
-
|
|
108
|
-
{/* Step Circle Container with line */}
|
|
109
|
-
<div className="relative flex items-center w-full">
|
|
110
|
-
{/* Connecting Line - Positioned after each circle except the last */}
|
|
111
|
-
{index < steps.length - 1 && (
|
|
112
|
-
<div
|
|
113
|
-
className="absolute left-1/2 w-full h-[2px]"
|
|
114
|
-
style={{
|
|
115
|
-
width: 'calc(100% + 24px)',
|
|
116
|
-
marginLeft: '24px'
|
|
117
|
-
}}
|
|
118
|
-
>
|
|
119
|
-
<div className="h-full bg-border" />
|
|
120
|
-
{index < currentStep && (
|
|
121
|
-
<motion.div
|
|
122
|
-
className="absolute inset-0 bg-primary"
|
|
123
|
-
initial={{ scaleX: 0 }}
|
|
124
|
-
animate={{ scaleX: 1 }}
|
|
125
|
-
transition={{ duration: 0.5, delay: index * 0.1 }}
|
|
126
|
-
style={{ transformOrigin: 'left' }}
|
|
127
|
-
/>
|
|
128
|
-
)}
|
|
129
|
-
</div>
|
|
130
|
-
)}
|
|
131
|
-
|
|
132
|
-
{/* Step Circle */}
|
|
133
|
-
<motion.div
|
|
134
|
-
initial={{ scale: 0.8 }}
|
|
135
|
-
animate={{ scale: isActive ? 1.05 : 1 }}
|
|
136
|
-
transition={{ duration: 0.2 }}
|
|
137
|
-
className={cn(
|
|
138
|
-
"relative z-10 flex items-center justify-center rounded-full transition-all duration-300 mx-auto",
|
|
139
|
-
"w-12 h-12 border-2",
|
|
140
|
-
isActive && "border-primary bg-primary text-primary-foreground shadow-lg shadow-primary/20",
|
|
141
|
-
isCompleted && !isActive && "border-primary bg-primary text-primary-foreground",
|
|
142
|
-
!isActive && !isCompleted && isAccessible && "border-border bg-background text-muted-foreground hover:border-accent",
|
|
143
|
-
!isAccessible && "border-border/50 bg-muted text-muted-foreground/50 cursor-not-allowed",
|
|
144
|
-
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
145
|
-
)}
|
|
146
|
-
>
|
|
147
|
-
{hasError ? (
|
|
148
|
-
errorStepIcon
|
|
149
|
-
) : isCompleted && !isActive ? (
|
|
150
|
-
completedStepIcon
|
|
151
|
-
) : isActive && activeStepIcon ? (
|
|
152
|
-
activeStepIcon
|
|
153
|
-
) : StepIcon && stepIconPosition === 'inside' ? (
|
|
154
|
-
<span className="w-5 h-5 flex items-center justify-center">{StepIcon}</span>
|
|
155
|
-
) : showStepNumbers ? (
|
|
156
|
-
<span className="text-sm font-semibold">{index + 1}</span>
|
|
157
|
-
) : (
|
|
158
|
-
<Circle className="w-4 h-4" />
|
|
159
|
-
)}
|
|
160
|
-
</motion.div>
|
|
161
|
-
</div>
|
|
162
|
-
|
|
163
|
-
{/* Step Label Below Circle */}
|
|
164
|
-
<div className="mt-3">
|
|
165
|
-
<p className="text-xs text-muted-foreground font-medium">
|
|
166
|
-
Step {index + 1} of {steps.length}
|
|
167
|
-
</p>
|
|
168
|
-
</div>
|
|
169
|
-
</div>
|
|
170
|
-
)
|
|
171
|
-
})}
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
) : (
|
|
175
|
-
// Vertical orientation
|
|
176
|
-
<div className="relative pl-12">
|
|
177
|
-
{/* Vertical Progress Line */}
|
|
178
|
-
{steps.length > 1 && (
|
|
179
|
-
<>
|
|
180
|
-
<div className="absolute left-6 top-8 bottom-8 w-[2px] bg-border" />
|
|
181
|
-
<motion.div
|
|
182
|
-
className="absolute left-6 top-8 w-[2px] bg-primary"
|
|
183
|
-
initial={{ height: 0 }}
|
|
184
|
-
animate={{
|
|
185
|
-
height: `${(currentStep / (steps.length - 1)) * (100 - 16)}%`
|
|
186
|
-
}}
|
|
187
|
-
transition={{ duration: 0.5 }}
|
|
188
|
-
/>
|
|
189
|
-
</>
|
|
190
|
-
)}
|
|
191
|
-
|
|
192
|
-
{steps.map((step, index) => {
|
|
193
|
-
const isActive = index === currentStep
|
|
194
|
-
const isCompleted = isStepCompleted(index)
|
|
195
|
-
const isAccessible = isStepAccessible(index)
|
|
196
|
-
const hasError = isActive && error
|
|
197
|
-
|
|
198
|
-
const StepIcon = typeof step.icon === 'function'
|
|
199
|
-
? step.icon({ isActive, isCompleted })
|
|
200
|
-
: step.icon
|
|
201
|
-
|
|
202
|
-
return (
|
|
203
|
-
<div key={step.id} className="relative flex items-center mb-8 last:mb-0">
|
|
204
|
-
{/* Step Circle */}
|
|
205
|
-
<motion.div
|
|
206
|
-
initial={{ scale: 0.8 }}
|
|
207
|
-
animate={{ scale: isActive ? 1.05 : 1 }}
|
|
208
|
-
className={cn(
|
|
209
|
-
"absolute left-0 z-20 flex items-center justify-center rounded-full border-2 transition-all duration-300",
|
|
210
|
-
"w-12 h-12",
|
|
211
|
-
isActive && "border-primary bg-primary text-primary-foreground shadow-lg",
|
|
212
|
-
isCompleted && !isActive && "border-primary bg-primary text-primary-foreground",
|
|
213
|
-
!isActive && !isCompleted && isAccessible && "border-border bg-background text-muted-foreground hover:border-accent",
|
|
214
|
-
!isAccessible && "border-border/50 bg-muted text-muted-foreground/50 cursor-not-allowed",
|
|
215
|
-
hasError && "border-destructive bg-destructive text-destructive-foreground"
|
|
216
|
-
)}
|
|
217
|
-
>
|
|
218
|
-
{hasError ? (
|
|
219
|
-
errorStepIcon
|
|
220
|
-
) : isCompleted && !isActive ? (
|
|
221
|
-
completedStepIcon
|
|
222
|
-
) : isActive && activeStepIcon ? (
|
|
223
|
-
activeStepIcon
|
|
224
|
-
) : StepIcon ? (
|
|
225
|
-
<span className="w-5 h-5 flex items-center justify-center">{StepIcon}</span>
|
|
226
|
-
) : showStepNumbers ? (
|
|
227
|
-
<span className="text-sm font-semibold">{index + 1}</span>
|
|
228
|
-
) : (
|
|
229
|
-
<Circle className="w-4 h-4" />
|
|
230
|
-
)}
|
|
231
|
-
</motion.div>
|
|
232
|
-
|
|
233
|
-
{/* Step Content */}
|
|
234
|
-
<div className="ml-16">
|
|
235
|
-
{showStepTitles && (
|
|
236
|
-
<>
|
|
237
|
-
<p className={cn(
|
|
238
|
-
"text-sm font-semibold transition-colors",
|
|
239
|
-
isActive && "text-primary",
|
|
240
|
-
isCompleted && !isActive && "text-primary",
|
|
241
|
-
!isActive && !isCompleted && "text-muted-foreground"
|
|
242
|
-
)}>
|
|
243
|
-
{step.title}
|
|
244
|
-
</p>
|
|
245
|
-
{step.description && (
|
|
246
|
-
<p className="text-xs text-muted-foreground mt-1">
|
|
247
|
-
{step.description}
|
|
248
|
-
</p>
|
|
249
|
-
)}
|
|
250
|
-
</>
|
|
251
|
-
)}
|
|
252
|
-
</div>
|
|
253
|
-
</div>
|
|
254
|
-
)
|
|
255
|
-
})}
|
|
256
|
-
</div>
|
|
257
|
-
)}
|
|
258
|
-
</div>
|
|
259
|
-
)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (progressType === 'dots') {
|
|
263
|
-
return (
|
|
264
|
-
<div className={cn("flex items-center justify-center space-x-2", className)}>
|
|
265
|
-
{steps.map((_, index) => {
|
|
266
|
-
const isActive = index === currentStep
|
|
267
|
-
const isCompleted = isStepCompleted(index)
|
|
268
|
-
|
|
269
|
-
return (
|
|
270
|
-
<motion.div
|
|
271
|
-
key={index}
|
|
272
|
-
initial={{ scale: 0.8 }}
|
|
273
|
-
animate={{ scale: isActive ? 1.2 : 1 }}
|
|
274
|
-
className={cn(
|
|
275
|
-
"rounded-full transition-all duration-300",
|
|
276
|
-
isActive ? "w-3 h-3 bg-primary" : "w-2 h-2",
|
|
277
|
-
isCompleted && !isActive && "bg-primary/60",
|
|
278
|
-
!isActive && !isCompleted && "bg-muted"
|
|
279
|
-
)}
|
|
280
|
-
/>
|
|
281
|
-
)
|
|
282
|
-
})}
|
|
283
|
-
</div>
|
|
284
|
-
)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (progressType === 'circular') {
|
|
288
|
-
const progress = ((currentStep + 1) / steps.length) * 100
|
|
289
|
-
const circumference = 2 * Math.PI * 45 // radius = 45
|
|
290
|
-
const strokeDashoffset = circumference - (progress / 100) * circumference
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<div className={cn("relative w-36 h-36 mx-auto", className)}>
|
|
294
|
-
<svg className="w-full h-full -rotate-90" viewBox="0 0 144 144">
|
|
295
|
-
<circle
|
|
296
|
-
cx="72"
|
|
297
|
-
cy="72"
|
|
298
|
-
r="45"
|
|
299
|
-
fill="none"
|
|
300
|
-
stroke="currentColor"
|
|
301
|
-
strokeWidth="8"
|
|
302
|
-
className="text-border"
|
|
303
|
-
/>
|
|
304
|
-
<motion.circle
|
|
305
|
-
cx="72"
|
|
306
|
-
cy="72"
|
|
307
|
-
r="45"
|
|
308
|
-
fill="none"
|
|
309
|
-
stroke="currentColor"
|
|
310
|
-
strokeWidth="8"
|
|
311
|
-
strokeDasharray={circumference}
|
|
312
|
-
initial={{ strokeDashoffset: circumference }}
|
|
313
|
-
animate={{ strokeDashoffset }}
|
|
314
|
-
className="text-primary"
|
|
315
|
-
transition={{ duration: 0.5 }}
|
|
316
|
-
/>
|
|
317
|
-
</svg>
|
|
318
|
-
<div className="absolute inset-0 flex items-center justify-center">
|
|
319
|
-
<div className="text-center">
|
|
320
|
-
<p className="text-3xl font-bold">{currentStep + 1}</p>
|
|
321
|
-
<p className="text-sm text-muted-foreground">of {steps.length}</p>
|
|
322
|
-
</div>
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return null
|
|
329
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import React from "react"
|
|
4
|
-
import { motion, AnimatePresence } from "framer-motion"
|
|
5
|
-
import { cn } from "../../lib/utils"
|
|
6
|
-
import { useFormWizard } from "./form-wizard-context"
|
|
7
|
-
import { FormWizardProps } from "./types"
|
|
8
|
-
import { Alert, AlertDescription } from "../ui/alert"
|
|
9
|
-
import { AlertCircle } from "lucide-react"
|
|
10
|
-
|
|
11
|
-
interface FormWizardStepProps {
|
|
12
|
-
className?: string
|
|
13
|
-
animationType?: FormWizardProps['animationType']
|
|
14
|
-
animationDuration?: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const animations = {
|
|
18
|
-
slide: {
|
|
19
|
-
initial: (direction: number) => ({
|
|
20
|
-
x: direction > 0 ? 1000 : -1000,
|
|
21
|
-
opacity: 0
|
|
22
|
-
}),
|
|
23
|
-
animate: {
|
|
24
|
-
x: 0,
|
|
25
|
-
opacity: 1
|
|
26
|
-
},
|
|
27
|
-
exit: (direction: number) => ({
|
|
28
|
-
x: direction < 0 ? 1000 : -1000,
|
|
29
|
-
opacity: 0
|
|
30
|
-
})
|
|
31
|
-
},
|
|
32
|
-
fade: {
|
|
33
|
-
initial: { opacity: 0 },
|
|
34
|
-
animate: { opacity: 1 },
|
|
35
|
-
exit: { opacity: 0 }
|
|
36
|
-
},
|
|
37
|
-
scale: {
|
|
38
|
-
initial: { opacity: 0, scale: 0.8 },
|
|
39
|
-
animate: { opacity: 1, scale: 1 },
|
|
40
|
-
exit: { opacity: 0, scale: 0.8 }
|
|
41
|
-
},
|
|
42
|
-
none: {
|
|
43
|
-
initial: {},
|
|
44
|
-
animate: {},
|
|
45
|
-
exit: {}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export const FormWizardStep: React.FC<FormWizardStepProps> = ({
|
|
50
|
-
className,
|
|
51
|
-
animationType = 'slide',
|
|
52
|
-
animationDuration = 0.3
|
|
53
|
-
}) => {
|
|
54
|
-
const { steps, currentStep, goToNext, goToPrevious, goToStep, updateStepData, stepData, error } = useFormWizard()
|
|
55
|
-
const [direction, setDirection] = React.useState(0)
|
|
56
|
-
const previousStep = React.useRef(currentStep)
|
|
57
|
-
|
|
58
|
-
React.useEffect(() => {
|
|
59
|
-
setDirection(currentStep > previousStep.current ? 1 : -1)
|
|
60
|
-
previousStep.current = currentStep
|
|
61
|
-
}, [currentStep])
|
|
62
|
-
|
|
63
|
-
const currentStepObj = steps[currentStep]
|
|
64
|
-
const isFirstStep = currentStep === 0
|
|
65
|
-
const isLastStep = currentStep === steps.length - 1
|
|
66
|
-
|
|
67
|
-
const stepContentProps = {
|
|
68
|
-
currentStep,
|
|
69
|
-
totalSteps: steps.length,
|
|
70
|
-
goToNext,
|
|
71
|
-
goToPrevious,
|
|
72
|
-
goToStep,
|
|
73
|
-
isFirstStep,
|
|
74
|
-
isLastStep,
|
|
75
|
-
stepData: stepData[currentStepObj.id] || {},
|
|
76
|
-
updateStepData: (data: any) => updateStepData(currentStepObj.id, data)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const content = typeof currentStepObj.content === 'function'
|
|
80
|
-
? currentStepObj.content(stepContentProps)
|
|
81
|
-
: currentStepObj.content
|
|
82
|
-
|
|
83
|
-
return (
|
|
84
|
-
<AnimatePresence mode="wait" custom={direction}>
|
|
85
|
-
<motion.div
|
|
86
|
-
key={currentStep}
|
|
87
|
-
custom={direction}
|
|
88
|
-
variants={animations[animationType]}
|
|
89
|
-
initial="initial"
|
|
90
|
-
animate="animate"
|
|
91
|
-
exit="exit"
|
|
92
|
-
transition={{
|
|
93
|
-
duration: animationDuration,
|
|
94
|
-
ease: "easeInOut"
|
|
95
|
-
}}
|
|
96
|
-
className={cn("w-full", className)}
|
|
97
|
-
data-wizard-step-content
|
|
98
|
-
>
|
|
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>
|
|
108
|
-
</motion.div>
|
|
109
|
-
</AnimatePresence>
|
|
110
|
-
)
|
|
111
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import React from "react"
|
|
4
|
-
import { cn } from "../../lib/utils"
|
|
5
|
-
import { FormWizardProvider } from "./form-wizard-context"
|
|
6
|
-
import { FormWizardProgress } from "./form-wizard-progress"
|
|
7
|
-
import { FormWizardStep } from "./form-wizard-step"
|
|
8
|
-
import { FormWizardNavigation } from "./form-wizard-navigation"
|
|
9
|
-
import { FormWizardProps } from "./types"
|
|
10
|
-
import { Card, CardContent } from "../ui/card"
|
|
11
|
-
import { Separator } from "../ui/separator"
|
|
12
|
-
|
|
13
|
-
export const MoonUIFormWizardPro = React.forwardRef<HTMLDivElement, FormWizardProps>(({
|
|
14
|
-
steps,
|
|
15
|
-
currentStep = 0,
|
|
16
|
-
onStepChange,
|
|
17
|
-
onComplete,
|
|
18
|
-
orientation = 'horizontal',
|
|
19
|
-
progressType = 'linear',
|
|
20
|
-
allowStepSkip = false,
|
|
21
|
-
allowBackNavigation = true,
|
|
22
|
-
validateOnStepChange = true,
|
|
23
|
-
animationType = 'slide',
|
|
24
|
-
animationDuration = 0.3,
|
|
25
|
-
showStepNumbers = true,
|
|
26
|
-
showStepTitles = true,
|
|
27
|
-
showProgressBar = true,
|
|
28
|
-
stepIconPosition = 'top',
|
|
29
|
-
completedStepIcon,
|
|
30
|
-
activeStepIcon,
|
|
31
|
-
errorStepIcon,
|
|
32
|
-
className,
|
|
33
|
-
progressClassName,
|
|
34
|
-
navigationClassName,
|
|
35
|
-
contentClassName,
|
|
36
|
-
stepClassName,
|
|
37
|
-
autoSave = false,
|
|
38
|
-
autoSaveDelay = 2000,
|
|
39
|
-
onAutoSave,
|
|
40
|
-
persistData = false,
|
|
41
|
-
storageKey = "form-wizard-data"
|
|
42
|
-
}, ref) => {
|
|
43
|
-
return (
|
|
44
|
-
<FormWizardProvider
|
|
45
|
-
steps={steps}
|
|
46
|
-
initialStep={currentStep}
|
|
47
|
-
onStepChange={onStepChange}
|
|
48
|
-
onComplete={onComplete}
|
|
49
|
-
validateOnStepChange={validateOnStepChange}
|
|
50
|
-
allowBackNavigation={allowBackNavigation}
|
|
51
|
-
allowStepSkip={allowStepSkip}
|
|
52
|
-
autoSave={autoSave}
|
|
53
|
-
autoSaveDelay={autoSaveDelay}
|
|
54
|
-
onAutoSave={onAutoSave}
|
|
55
|
-
persistData={persistData}
|
|
56
|
-
storageKey={storageKey}
|
|
57
|
-
>
|
|
58
|
-
<div ref={ref} className={cn("w-full", className)}>
|
|
59
|
-
{showProgressBar && (
|
|
60
|
-
<>
|
|
61
|
-
<FormWizardProgress
|
|
62
|
-
className={cn("mb-12", progressClassName)}
|
|
63
|
-
progressType={progressType}
|
|
64
|
-
orientation={orientation}
|
|
65
|
-
showStepNumbers={showStepNumbers}
|
|
66
|
-
showStepTitles={showStepTitles}
|
|
67
|
-
stepIconPosition={stepIconPosition}
|
|
68
|
-
completedStepIcon={completedStepIcon}
|
|
69
|
-
activeStepIcon={activeStepIcon}
|
|
70
|
-
errorStepIcon={errorStepIcon}
|
|
71
|
-
/>
|
|
72
|
-
</>
|
|
73
|
-
)}
|
|
74
|
-
|
|
75
|
-
<Card className={cn("border-0 shadow-none", contentClassName)}>
|
|
76
|
-
<CardContent className="p-0">
|
|
77
|
-
<FormWizardStep
|
|
78
|
-
className={stepClassName}
|
|
79
|
-
animationType={animationType}
|
|
80
|
-
animationDuration={animationDuration}
|
|
81
|
-
/>
|
|
82
|
-
</CardContent>
|
|
83
|
-
</Card>
|
|
84
|
-
|
|
85
|
-
<FormWizardNavigation
|
|
86
|
-
className={cn("mt-8", navigationClassName)}
|
|
87
|
-
/>
|
|
88
|
-
</div>
|
|
89
|
-
</FormWizardProvider>
|
|
90
|
-
)
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
MoonUIFormWizardPro.displayName = "MoonUIFormWizardPro"
|
|
94
|
-
|
|
95
|
-
// Export types and hooks
|
|
96
|
-
export type { FormWizardProps, WizardStep, WizardStepContentProps } from "./types"
|
|
97
|
-
export { useFormWizard } from "./form-wizard-context"
|
|
98
|
-
|
|
99
|
-
// Export sub-components for advanced usage
|
|
100
|
-
export { FormWizardProgress } from "./form-wizard-progress"
|
|
101
|
-
export { FormWizardStep } from "./form-wizard-step"
|
|
102
|
-
export { FormWizardNavigation } from "./form-wizard-navigation"
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from "react"
|
|
2
|
-
|
|
3
|
-
export interface WizardStep {
|
|
4
|
-
id: string
|
|
5
|
-
title: string
|
|
6
|
-
description?: string
|
|
7
|
-
icon?: ReactNode | ((props: { isActive: boolean; isCompleted: boolean }) => ReactNode)
|
|
8
|
-
content: ReactNode | ((props: WizardStepContentProps) => ReactNode)
|
|
9
|
-
validation?: () => boolean | Promise<boolean> | { isValid: boolean; error?: string; errors?: string[] }
|
|
10
|
-
requiredFields?: string[] | boolean // Array of field names or boolean to enable/disable automatic validation
|
|
11
|
-
isOptional?: boolean
|
|
12
|
-
isDisabled?: boolean | ((currentStep: number, steps: WizardStep[]) => boolean)
|
|
13
|
-
onEnter?: () => void | Promise<void>
|
|
14
|
-
onExit?: () => void | Promise<void>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface WizardStepContentProps {
|
|
18
|
-
currentStep: number
|
|
19
|
-
totalSteps: number
|
|
20
|
-
goToNext: () => void
|
|
21
|
-
goToPrevious: () => void
|
|
22
|
-
goToStep: (step: number) => void
|
|
23
|
-
isFirstStep: boolean
|
|
24
|
-
isLastStep: boolean
|
|
25
|
-
stepData: any
|
|
26
|
-
updateStepData: (data: any) => void
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface FormWizardProps {
|
|
30
|
-
steps: WizardStep[]
|
|
31
|
-
currentStep?: number
|
|
32
|
-
onStepChange?: (step: number, previousStep: number) => void
|
|
33
|
-
onComplete?: (data: Record<string, any>) => void | Promise<void>
|
|
34
|
-
orientation?: 'horizontal' | 'vertical'
|
|
35
|
-
progressType?: 'linear' | 'circular' | 'dots' | 'custom'
|
|
36
|
-
allowStepSkip?: boolean
|
|
37
|
-
allowBackNavigation?: boolean
|
|
38
|
-
validateOnStepChange?: boolean
|
|
39
|
-
animationType?: 'slide' | 'fade' | 'scale' | 'none'
|
|
40
|
-
animationDuration?: number
|
|
41
|
-
showStepNumbers?: boolean
|
|
42
|
-
showStepTitles?: boolean
|
|
43
|
-
showProgressBar?: boolean
|
|
44
|
-
stepIconPosition?: 'top' | 'left' | 'inside'
|
|
45
|
-
completedStepIcon?: ReactNode
|
|
46
|
-
activeStepIcon?: ReactNode
|
|
47
|
-
errorStepIcon?: ReactNode
|
|
48
|
-
className?: string
|
|
49
|
-
progressClassName?: string
|
|
50
|
-
navigationClassName?: string
|
|
51
|
-
contentClassName?: string
|
|
52
|
-
stepClassName?: string
|
|
53
|
-
autoSave?: boolean
|
|
54
|
-
autoSaveDelay?: number
|
|
55
|
-
onAutoSave?: (stepId: string, data: any) => void | Promise<void>
|
|
56
|
-
persistData?: boolean
|
|
57
|
-
storageKey?: string
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface WizardContextValue {
|
|
61
|
-
steps: WizardStep[]
|
|
62
|
-
currentStep: number
|
|
63
|
-
stepData: Record<string, any>
|
|
64
|
-
isLoading: boolean
|
|
65
|
-
error: string | null
|
|
66
|
-
goToNext: () => void
|
|
67
|
-
goToPrevious: () => void
|
|
68
|
-
goToStep: (step: number) => void
|
|
69
|
-
updateStepData: (stepId: string, data: any) => void
|
|
70
|
-
validateCurrentStep: () => Promise<boolean>
|
|
71
|
-
completeWizard: () => void
|
|
72
|
-
resetWizard: () => void
|
|
73
|
-
isStepCompleted: (stepIndex: number) => boolean
|
|
74
|
-
isStepAccessible: (stepIndex: number) => boolean
|
|
75
|
-
canGoNext: boolean
|
|
76
|
-
canGoPrevious: boolean
|
|
77
|
-
}
|