@moontra/moonui-pro 2.20.1 → 2.20.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.
Files changed (76) hide show
  1. package/dist/index.d.ts +691 -261
  2. package/dist/index.mjs +7418 -4934
  3. package/package.json +4 -3
  4. package/scripts/postbuild.js +27 -0
  5. package/src/components/advanced-chart/index.tsx +5 -1
  6. package/src/components/advanced-forms/index.tsx +175 -16
  7. package/src/components/calendar/event-dialog.tsx +18 -13
  8. package/src/components/calendar/index.tsx +197 -50
  9. package/src/components/dashboard/dashboard-grid.tsx +21 -3
  10. package/src/components/dashboard/types.ts +3 -0
  11. package/src/components/dashboard/widgets/activity-feed.tsx +6 -1
  12. package/src/components/dashboard/widgets/comparison-widget.tsx +177 -0
  13. package/src/components/dashboard/widgets/index.ts +5 -0
  14. package/src/components/dashboard/widgets/metric-card.tsx +21 -1
  15. package/src/components/dashboard/widgets/progress-widget.tsx +113 -0
  16. package/src/components/error-boundary/index.tsx +160 -37
  17. package/src/components/form-wizard/form-wizard-context.tsx +54 -26
  18. package/src/components/form-wizard/form-wizard-progress.tsx +33 -2
  19. package/src/components/form-wizard/types.ts +2 -1
  20. package/src/components/github-stars/hooks.ts +1 -0
  21. package/src/components/github-stars/variants.tsx +3 -1
  22. package/src/components/health-check/index.tsx +14 -14
  23. package/src/components/hover-card-3d/index.tsx +2 -3
  24. package/src/components/index.ts +5 -3
  25. package/src/components/kanban/kanban.tsx +23 -18
  26. package/src/components/license-error/index.tsx +2 -0
  27. package/src/components/magnetic-button/index.tsx +56 -7
  28. package/src/components/memory-efficient-data/index.tsx +117 -115
  29. package/src/components/navbar/index.tsx +781 -0
  30. package/src/components/performance-debugger/index.tsx +62 -38
  31. package/src/components/performance-monitor/index.tsx +47 -33
  32. package/src/components/phone-number-input/index.tsx +32 -27
  33. package/src/components/phone-number-input/phone-number-input-simple.tsx +167 -0
  34. package/src/components/rich-text-editor/index.tsx +26 -28
  35. package/src/components/rich-text-editor/slash-commands-extension.ts +15 -5
  36. package/src/components/sidebar/index.tsx +32 -13
  37. package/src/components/timeline/index.tsx +84 -49
  38. package/src/components/ui/accordion.tsx +550 -42
  39. package/src/components/ui/avatar.tsx +2 -0
  40. package/src/components/ui/badge.tsx +2 -0
  41. package/src/components/ui/breadcrumb.tsx +2 -0
  42. package/src/components/ui/button.tsx +39 -33
  43. package/src/components/ui/card.tsx +2 -0
  44. package/src/components/ui/collapsible.tsx +546 -50
  45. package/src/components/ui/command.tsx +790 -67
  46. package/src/components/ui/dialog.tsx +510 -92
  47. package/src/components/ui/dropdown-menu.tsx +540 -52
  48. package/src/components/ui/index.ts +37 -5
  49. package/src/components/ui/input.tsx +2 -0
  50. package/src/components/ui/magnetic-button.tsx +1 -1
  51. package/src/components/ui/media-gallery.tsx +1 -2
  52. package/src/components/ui/navigation-menu.tsx +130 -0
  53. package/src/components/ui/pagination.tsx +2 -0
  54. package/src/components/ui/select.tsx +6 -2
  55. package/src/components/ui/spotlight-card.tsx +1 -1
  56. package/src/components/ui/table.tsx +2 -0
  57. package/src/components/ui/tabs-pro.tsx +542 -0
  58. package/src/components/ui/tabs.tsx +23 -167
  59. package/src/components/ui/toggle.tsx +12 -12
  60. package/src/index.ts +11 -3
  61. package/src/styles/index.css +596 -0
  62. package/src/use-performance-optimizer.ts +1 -1
  63. package/src/utils/chart-helpers.ts +1 -1
  64. package/src/__tests__/use-intersection-observer.test.tsx +0 -216
  65. package/src/__tests__/use-local-storage.test.tsx +0 -174
  66. package/src/__tests__/use-pro-access.test.tsx +0 -183
  67. package/src/components/advanced-chart/advanced-chart.test.tsx +0 -281
  68. package/src/components/data-table/data-table.test.tsx +0 -187
  69. package/src/components/enhanced/badge.tsx +0 -191
  70. package/src/components/enhanced/button.tsx +0 -362
  71. package/src/components/enhanced/card.tsx +0 -266
  72. package/src/components/enhanced/dialog.tsx +0 -246
  73. package/src/components/enhanced/index.ts +0 -4
  74. package/src/components/file-upload/file-upload.test.tsx +0 -243
  75. package/src/components/rich-text-editor/index-old-backup.tsx +0 -437
  76. package/src/types/moonui.d.ts +0 -22
@@ -1,362 +0,0 @@
1
- "use client"
2
-
3
- import React, { useRef, useState, useEffect } from "react"
4
- import { motion, AnimatePresence } from "framer-motion"
5
- import { Loader2, Check, X, Sparkles } from "lucide-react"
6
- import { cn } from "../../lib/utils"
7
- import { cva, type VariantProps } from "class-variance-authority"
8
-
9
- const enhancedButtonVariants = cva(
10
- "relative inline-flex items-center justify-center whitespace-nowrap text-sm font-medium transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 overflow-hidden transform active:scale-[0.98] rounded-lg",
11
- {
12
- variants: {
13
- variant: {
14
- default: "bg-primary text-primary-foreground dark:bg-primary dark:text-primary-foreground hover:bg-primary/90 dark:hover:bg-primary/90 shadow-sm hover:shadow-md",
15
- destructive: "bg-destructive text-destructive-foreground dark:bg-destructive dark:text-destructive-foreground hover:bg-destructive/90 dark:hover:bg-destructive/90 shadow-sm hover:shadow-md",
16
- outline: "border border-input dark:border-input bg-background dark:bg-background text-foreground dark:text-foreground hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground transition-all duration-200",
17
- secondary: "bg-muted text-muted-foreground dark:bg-muted dark:text-muted-foreground hover:bg-muted/80 dark:hover:bg-muted/80 border border-input dark:border-input shadow-sm hover:shadow-md",
18
- ghost: "text-foreground dark:text-foreground hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent dark:hover:text-accent-foreground transition-all duration-200",
19
- link: "text-primary underline-offset-4 hover:underline hover:text-primary/80",
20
- gradient: "bg-gradient-to-r from-purple-600 to-pink-600 text-white hover:from-purple-700 hover:to-pink-700 shadow-md hover:shadow-lg",
21
- glow: "bg-primary text-primary-foreground shadow-lg shadow-primary/50 hover:shadow-xl hover:shadow-primary/60",
22
- },
23
- size: {
24
- default: "h-10 px-4 py-2",
25
- sm: "h-9 px-3",
26
- lg: "h-11 px-8",
27
- icon: "h-10 w-10",
28
- },
29
- animation: {
30
- ripple: "ripple-effect",
31
- morph: "morph-effect",
32
- particles: "particles-effect",
33
- magnetic: "magnetic-effect",
34
- glitch: "glitch-effect",
35
- }
36
- },
37
- defaultVariants: {
38
- variant: "default",
39
- size: "default",
40
- animation: "ripple",
41
- },
42
- }
43
- )
44
-
45
- interface RippleEffect {
46
- x: number
47
- y: number
48
- id: number
49
- }
50
-
51
- export interface ButtonProProps
52
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
53
- VariantProps<typeof enhancedButtonVariants> {
54
- state?: "idle" | "loading" | "success" | "error"
55
- onStateChange?: (state: "idle" | "loading" | "success" | "error") => void
56
- enableRipple?: boolean
57
- enableMorph?: boolean
58
- enableParticles?: boolean
59
- enableMagnetic?: boolean
60
- enableGlitch?: boolean
61
- }
62
-
63
- export const ButtonPro = React.forwardRef<HTMLButtonElement, ButtonProProps>(
64
- ({
65
- className,
66
- variant,
67
- size,
68
- animation,
69
- state = "idle",
70
- onStateChange,
71
- children,
72
- onClick,
73
- enableRipple = true,
74
- enableMorph = true,
75
- enableParticles = false,
76
- enableMagnetic = false,
77
- enableGlitch = false,
78
- disabled,
79
- type = "button",
80
- ...props
81
- }, ref) => {
82
- const [internalState, setInternalState] = useState<"idle" | "loading" | "success" | "error">("idle")
83
- const [ripples, setRipples] = useState<RippleEffect[]>([])
84
- const [particles, setParticles] = useState<{ x: number; y: number; id: number }[]>([])
85
- const [magneticPosition, setMagneticPosition] = useState({ x: 0, y: 0 })
86
- const buttonRef = useRef<HTMLButtonElement>(null)
87
- const currentState = state !== "idle" ? state : internalState
88
-
89
- // Ripple effect
90
- const createRipple = (event: React.MouseEvent<HTMLButtonElement>) => {
91
- if (!enableRipple) return
92
-
93
- const button = event.currentTarget
94
- const rect = button.getBoundingClientRect()
95
- const ripple = {
96
- x: event.clientX - rect.left,
97
- y: event.clientY - rect.top,
98
- id: Date.now()
99
- }
100
-
101
- setRipples([...ripples, ripple])
102
- setTimeout(() => {
103
- setRipples(prev => prev.filter(r => r.id !== ripple.id))
104
- }, 1000)
105
- }
106
-
107
- // Particle effect
108
- const createParticles = (event: React.MouseEvent<HTMLButtonElement>) => {
109
- if (!enableParticles) return
110
-
111
- const button = event.currentTarget
112
- const rect = button.getBoundingClientRect()
113
- const newParticles = Array.from({ length: 8 }, (_, i) => ({
114
- x: event.clientX - rect.left,
115
- y: event.clientY - rect.top,
116
- id: Date.now() + i
117
- }))
118
-
119
- setParticles([...particles, ...newParticles])
120
- setTimeout(() => {
121
- setParticles([])
122
- }, 1000)
123
- }
124
-
125
- // Magnetic effect
126
- const handleMouseMove = (event: React.MouseEvent<HTMLButtonElement>) => {
127
- if (!enableMagnetic) return
128
-
129
- const button = event.currentTarget
130
- const rect = button.getBoundingClientRect()
131
- const centerX = rect.width / 2
132
- const centerY = rect.height / 2
133
- const x = event.clientX - rect.left - centerX
134
- const y = event.clientY - rect.top - centerY
135
-
136
- setMagneticPosition({
137
- x: x * 0.2,
138
- y: y * 0.2
139
- })
140
- }
141
-
142
- const handleMouseLeave = () => {
143
- if (enableMagnetic) {
144
- setMagneticPosition({ x: 0, y: 0 })
145
- }
146
- }
147
-
148
- const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
149
- createRipple(e)
150
- createParticles(e)
151
-
152
- if (currentState === "loading") return
153
-
154
- if (enableMorph) {
155
- setInternalState("loading")
156
- onStateChange?.("loading")
157
- }
158
-
159
- if (onClick) {
160
- try {
161
- await onClick(e)
162
- if (enableMorph) {
163
- setInternalState("success")
164
- onStateChange?.("success")
165
-
166
- setTimeout(() => {
167
- setInternalState("idle")
168
- onStateChange?.("idle")
169
- }, 2000)
170
- }
171
- } catch (error) {
172
- if (enableMorph) {
173
- setInternalState("error")
174
- onStateChange?.("error")
175
-
176
- setTimeout(() => {
177
- setInternalState("idle")
178
- onStateChange?.("idle")
179
- }, 2000)
180
- }
181
- }
182
- }
183
- }
184
-
185
- const getIcon = () => {
186
- switch (currentState) {
187
- case "loading":
188
- return <Loader2 className="h-4 w-4 animate-spin" />
189
- case "success":
190
- return <Check className="h-4 w-4" />
191
- case "error":
192
- return <X className="h-4 w-4" />
193
- default:
194
- return null
195
- }
196
- }
197
-
198
- const getBackgroundColor = () => {
199
- switch (currentState) {
200
- case "success":
201
- return "bg-success"
202
- case "error":
203
- return "bg-destructive"
204
- default:
205
- return ""
206
- }
207
- }
208
-
209
- return (
210
- <motion.button
211
- className={cn(enhancedButtonVariants({ variant, size }), className)}
212
- ref={buttonRef || ref}
213
- onClick={handleClick}
214
- onMouseMove={handleMouseMove}
215
- onMouseLeave={handleMouseLeave}
216
- disabled={currentState === "loading" || disabled}
217
- type={type}
218
- animate={{
219
- x: magneticPosition.x,
220
- y: magneticPosition.y,
221
- }}
222
- transition={{
223
- type: "spring",
224
- stiffness: 150,
225
- damping: 15,
226
- mass: 0.1
227
- }}
228
- >
229
- {/* Ripple effects */}
230
- <AnimatePresence>
231
- {ripples.map((ripple) => (
232
- <motion.span
233
- key={ripple.id}
234
- className="absolute rounded-full bg-white/30 pointer-events-none"
235
- style={{
236
- left: ripple.x,
237
- top: ripple.y,
238
- }}
239
- initial={{ width: 0, height: 0, x: 0, y: 0, opacity: 1 }}
240
- animate={{
241
- width: 200,
242
- height: 200,
243
- x: -100,
244
- y: -100,
245
- opacity: 0
246
- }}
247
- exit={{ opacity: 0 }}
248
- transition={{ duration: 1, ease: "easeOut" }}
249
- />
250
- ))}
251
- </AnimatePresence>
252
-
253
- {/* Particle effects */}
254
- <AnimatePresence>
255
- {particles.map((particle, i) => (
256
- <motion.span
257
- key={particle.id}
258
- className="absolute w-1 h-1 bg-primary rounded-full pointer-events-none"
259
- style={{
260
- left: particle.x,
261
- top: particle.y,
262
- }}
263
- initial={{ scale: 0, opacity: 1 }}
264
- animate={{
265
- scale: [0, 1, 0],
266
- x: (i % 2 === 0 ? 1 : -1) * (20 + Math.random() * 30),
267
- y: -20 - Math.random() * 30,
268
- opacity: [1, 1, 0]
269
- }}
270
- exit={{ opacity: 0 }}
271
- transition={{ duration: 0.6, ease: "easeOut" }}
272
- />
273
- ))}
274
- </AnimatePresence>
275
-
276
- {/* Morph content */}
277
- <motion.div
278
- className="flex items-center gap-2"
279
- animate={{
280
- width: currentState !== "idle" ? "auto" : "100%"
281
- }}
282
- transition={{ duration: 0.2 }}
283
- >
284
- <AnimatePresence mode="wait">
285
- {currentState !== "idle" && (
286
- <motion.div
287
- initial={{ scale: 0, opacity: 0 }}
288
- animate={{ scale: 1, opacity: 1 }}
289
- exit={{ scale: 0, opacity: 0 }}
290
- transition={{ duration: 0.2 }}
291
- className="flex items-center"
292
- >
293
- {getIcon()}
294
- </motion.div>
295
- )}
296
- </AnimatePresence>
297
-
298
- <motion.span
299
- animate={{
300
- opacity: currentState === "idle" ? 1 : 0,
301
- x: currentState !== "idle" ? -20 : 0
302
- }}
303
- transition={{ duration: 0.2 }}
304
- >
305
- {children}
306
- </motion.span>
307
- </motion.div>
308
-
309
- {/* Background animation for success/error states */}
310
- <AnimatePresence>
311
- {(currentState === "success" || currentState === "error") && (
312
- <motion.div
313
- className={cn(
314
- "absolute inset-0 rounded-md -z-10",
315
- getBackgroundColor()
316
- )}
317
- initial={{ scale: 0, opacity: 0 }}
318
- animate={{ scale: 1, opacity: 1 }}
319
- exit={{ scale: 0, opacity: 0 }}
320
- transition={{ duration: 0.3 }}
321
- />
322
- )}
323
- </AnimatePresence>
324
-
325
- {/* Glitch effect overlay */}
326
- {enableGlitch && (
327
- <motion.div
328
- className="absolute inset-0 pointer-events-none"
329
- animate={{
330
- opacity: [0, 0.1, 0, 0.2, 0],
331
- clipPath: [
332
- "inset(0 0 100% 0)",
333
- "inset(20% 0 60% 0)",
334
- "inset(40% 0 40% 0)",
335
- "inset(80% 0 10% 0)",
336
- "inset(0 0 100% 0)",
337
- ]
338
- }}
339
- transition={{
340
- duration: 0.5,
341
- repeat: Infinity,
342
- repeatDelay: 5,
343
- }}
344
- style={{
345
- background: "linear-gradient(45deg, #ff0080, #00ff88, #0080ff)",
346
- mixBlendMode: "screen"
347
- }}
348
- />
349
- )}
350
-
351
- {/* Sparkle decoration for special variants */}
352
- {variant === "gradient" && (
353
- <Sparkles className="absolute top-1 right-1 h-3 w-3 text-white/50 animate-pulse" />
354
- )}
355
- </motion.button>
356
- )
357
- }
358
- )
359
-
360
- ButtonPro.displayName = "ButtonPro"
361
-
362
- export { ButtonPro as Button, enhancedButtonVariants }
@@ -1,266 +0,0 @@
1
- "use client"
2
-
3
- import React, { useRef, useState } from "react"
4
- import { motion, useMotionValue, useSpring, useTransform } from "framer-motion"
5
- import { cn } from "../../lib/utils"
6
-
7
- export interface CardProProps extends React.HTMLAttributes<HTMLDivElement> {
8
- enableGlassmorphism?: boolean
9
- enableParallax?: boolean
10
- enableTilt?: boolean
11
- enableGlow?: boolean
12
- enableReveal?: boolean
13
- tiltMaxAngle?: number
14
- glowColor?: string
15
- parallaxOffset?: number
16
- }
17
-
18
- export const CardPro = React.forwardRef<HTMLDivElement, CardProProps>(
19
- ({
20
- className,
21
- children,
22
- enableGlassmorphism = true,
23
- enableParallax = false,
24
- enableTilt = true,
25
- enableGlow = false,
26
- enableReveal = false,
27
- tiltMaxAngle = 15,
28
- glowColor = "rgba(59, 130, 246, 0.5)",
29
- parallaxOffset = 20,
30
- ...props
31
- }, ref) => {
32
- const cardRef = useRef<HTMLDivElement>(null)
33
- const [isHovered, setIsHovered] = useState(false)
34
-
35
- // Motion values for tilt effect
36
- const mouseX = useMotionValue(0)
37
- const mouseY = useMotionValue(0)
38
-
39
- // Spring physics for smooth animations
40
- const springConfig = { damping: 20, stiffness: 300 }
41
- const mouseXSpring = useSpring(mouseX, springConfig)
42
- const mouseYSpring = useSpring(mouseY, springConfig)
43
-
44
- // Transform values for 3D tilt
45
- const rotateX = useTransform(mouseYSpring, [-1, 1], [tiltMaxAngle, -tiltMaxAngle])
46
- const rotateY = useTransform(mouseXSpring, [-1, 1], [-tiltMaxAngle, tiltMaxAngle])
47
-
48
- // Glow effect position
49
- const glowX = useTransform(mouseXSpring, [-1, 1], [0, 100])
50
- const glowY = useTransform(mouseYSpring, [-1, 1], [0, 100])
51
-
52
- const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
53
- if (!cardRef.current || (!enableTilt && !enableGlow)) return
54
-
55
- const rect = cardRef.current.getBoundingClientRect()
56
- const centerX = rect.left + rect.width / 2
57
- const centerY = rect.top + rect.height / 2
58
-
59
- const x = (e.clientX - centerX) / (rect.width / 2)
60
- const y = (e.clientY - centerY) / (rect.height / 2)
61
-
62
- mouseX.set(x)
63
- mouseY.set(y)
64
- }
65
-
66
- const handleMouseEnter = () => {
67
- setIsHovered(true)
68
- }
69
-
70
- const handleMouseLeave = () => {
71
- setIsHovered(false)
72
- mouseX.set(0)
73
- mouseY.set(0)
74
- }
75
-
76
- return (
77
- <motion.div
78
- ref={cardRef || ref}
79
- className={cn(
80
- "relative rounded-xl transition-all duration-300",
81
- enableGlassmorphism && [
82
- "backdrop-blur-md",
83
- "bg-white/10 dark:bg-gray-900/10",
84
- "border border-white/20 dark:border-gray-700/20",
85
- "shadow-xl"
86
- ],
87
- !enableGlassmorphism && [
88
- "bg-card",
89
- "border border-border",
90
- "shadow-sm"
91
- ],
92
- isHovered && "shadow-2xl",
93
- className
94
- )}
95
- onMouseMove={handleMouseMove}
96
- onMouseEnter={handleMouseEnter}
97
- onMouseLeave={handleMouseLeave}
98
- style={{
99
- transformStyle: "preserve-3d",
100
- perspective: "1000px"
101
- }}
102
- animate={{
103
- rotateX: enableTilt ? rotateX.get() : 0,
104
- rotateY: enableTilt ? rotateY.get() : 0,
105
- }}
106
- transition={{ type: "spring", ...springConfig }}
107
- >
108
- {/* Glow effect overlay */}
109
- {enableGlow && (
110
- <motion.div
111
- className="absolute inset-0 rounded-xl pointer-events-none opacity-0"
112
- style={{
113
- background: `radial-gradient(600px circle at ${glowX}% ${glowY}%, ${glowColor}, transparent 40%)`,
114
- }}
115
- animate={{
116
- opacity: isHovered ? 1 : 0
117
- }}
118
- transition={{ duration: 0.3 }}
119
- />
120
- )}
121
-
122
- {/* Glassmorphism noise texture */}
123
- {enableGlassmorphism && (
124
- <div
125
- className="absolute inset-0 rounded-xl opacity-[0.03] pointer-events-none"
126
- style={{
127
- backgroundImage: `url("data:image/svg+xml,%3Csvg width='100' height='100' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' /%3E%3C/filter%3E%3Crect width='100' height='100' filter='url(%23noise)' /%3E%3C/svg%3E")`,
128
- }}
129
- />
130
- )}
131
-
132
- {/* Content with parallax effect */}
133
- <motion.div
134
- className="relative z-10"
135
- style={{
136
- transform: enableParallax ? "translateZ(50px)" : undefined,
137
- }}
138
- animate={{
139
- x: enableParallax && isHovered ? mouseXSpring.get() * parallaxOffset : 0,
140
- y: enableParallax && isHovered ? mouseYSpring.get() * parallaxOffset : 0,
141
- }}
142
- >
143
- {children}
144
- </motion.div>
145
-
146
- {/* Reveal effect border */}
147
- {enableReveal && (
148
- <motion.div
149
- className="absolute inset-0 rounded-xl pointer-events-none"
150
- style={{
151
- background: `conic-gradient(from ${glowX}deg, transparent, ${glowColor}, transparent 30%)`,
152
- opacity: 0,
153
- filter: "blur(5px)",
154
- }}
155
- animate={{
156
- opacity: isHovered ? 0.5 : 0,
157
- rotate: isHovered ? 360 : 0,
158
- }}
159
- transition={{
160
- opacity: { duration: 0.3 },
161
- rotate: { duration: 20, repeat: Infinity, ease: "linear" }
162
- }}
163
- />
164
- )}
165
-
166
- {/* Soft shadow layers for depth */}
167
- <div className="absolute inset-0 rounded-xl -z-10">
168
- <motion.div
169
- className="absolute inset-0 rounded-xl bg-black/5 dark:bg-white/5"
170
- animate={{
171
- scale: isHovered ? 1.02 : 1,
172
- opacity: isHovered ? 0.5 : 0,
173
- }}
174
- transition={{ duration: 0.3 }}
175
- style={{ filter: "blur(10px)" }}
176
- />
177
- <motion.div
178
- className="absolute inset-0 rounded-xl bg-black/5 dark:bg-white/5"
179
- animate={{
180
- scale: isHovered ? 1.05 : 1,
181
- opacity: isHovered ? 0.3 : 0,
182
- }}
183
- transition={{ duration: 0.3 }}
184
- style={{ filter: "blur(20px)" }}
185
- />
186
- </div>
187
- </motion.div>
188
- )
189
- }
190
- )
191
-
192
- CardPro.displayName = "CardPro"
193
-
194
- // Enhanced Card sub-components with animations
195
- export const CardProHeader = React.forwardRef<
196
- HTMLDivElement,
197
- React.HTMLAttributes<HTMLDivElement>
198
- >(({ className, ...props }, ref) => (
199
- <motion.div
200
- ref={ref}
201
- className={cn("flex flex-col space-y-1.5 p-6", className)}
202
- initial={{ opacity: 0, y: -10 }}
203
- animate={{ opacity: 1, y: 0 }}
204
- transition={{ duration: 0.3, delay: 0.1 }}
205
- />
206
- ))
207
- CardProHeader.displayName = "CardProHeader"
208
-
209
- export const EnhancedCardTitle = React.forwardRef<
210
- HTMLParagraphElement,
211
- React.HTMLAttributes<HTMLHeadingElement>
212
- >(({ className, ...props }, ref) => (
213
- <motion.h3
214
- ref={ref}
215
- className={cn(
216
- "text-2xl font-semibold leading-none tracking-tight",
217
- className
218
- )}
219
- initial={{ opacity: 0, x: -10 }}
220
- animate={{ opacity: 1, x: 0 }}
221
- transition={{ duration: 0.3, delay: 0.2 }}
222
- />
223
- ))
224
- EnhancedCardTitle.displayName = "EnhancedCardTitle"
225
-
226
- export const EnhancedCardDescription = React.forwardRef<
227
- HTMLParagraphElement,
228
- React.HTMLAttributes<HTMLParagraphElement>
229
- >(({ className, ...props }, ref) => (
230
- <motion.p
231
- ref={ref}
232
- className={cn("text-sm text-muted-foreground", className)}
233
- initial={{ opacity: 0 }}
234
- animate={{ opacity: 1 }}
235
- transition={{ duration: 0.3, delay: 0.3 }}
236
- />
237
- ))
238
- EnhancedCardDescription.displayName = "EnhancedCardDescription"
239
-
240
- export const CardProContent = React.forwardRef<
241
- HTMLDivElement,
242
- React.HTMLAttributes<HTMLDivElement>
243
- >(({ className, ...props }, ref) => (
244
- <motion.div
245
- ref={ref}
246
- className={cn("p-6 pt-0", className)}
247
- initial={{ opacity: 0 }}
248
- animate={{ opacity: 1 }}
249
- transition={{ duration: 0.3, delay: 0.4 }}
250
- />
251
- ))
252
- CardProContent.displayName = "CardProContent"
253
-
254
- export const CardProFooter = React.forwardRef<
255
- HTMLDivElement,
256
- React.HTMLAttributes<HTMLDivElement>
257
- >(({ className, ...props }, ref) => (
258
- <motion.div
259
- ref={ref}
260
- className={cn("flex items-center p-6 pt-0", className)}
261
- initial={{ opacity: 0, y: 10 }}
262
- animate={{ opacity: 1, y: 0 }}
263
- transition={{ duration: 0.3, delay: 0.5 }}
264
- />
265
- ))
266
- CardProFooter.displayName = "CardProFooter"