@launchui/launch-ui 1.0.1 → 1.0.7

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.
@@ -0,0 +1,122 @@
1
+ "use client";
2
+
3
+ import React, { useRef } from "react";
4
+ import {
5
+ motion,
6
+ useMotionValue,
7
+ useSpring,
8
+ useTransform,
9
+ useMotionTemplate,
10
+ } from "motion/react";
11
+
12
+ /**
13
+ * Internal utility replacing external lib requirements ensuring zero-friction installations.
14
+ */
15
+ const cn = (...classes: any[]) => {
16
+ return classes.filter(Boolean).join(" ");
17
+ };
18
+
19
+ export const CometCard = ({
20
+ rotateDepth = 17.5,
21
+ translateDepth = 20,
22
+ className,
23
+ children,
24
+ }: {
25
+ rotateDepth?: number;
26
+ translateDepth?: number;
27
+ className?: string;
28
+ children: React.ReactNode;
29
+ }) => {
30
+ const ref = useRef<HTMLDivElement>(null);
31
+
32
+ const x = useMotionValue(0);
33
+ const y = useMotionValue(0);
34
+
35
+ const mouseXSpring = useSpring(x);
36
+ const mouseYSpring = useSpring(y);
37
+
38
+ const rotateX = useTransform(
39
+ mouseYSpring,
40
+ [-0.5, 0.5],
41
+ [`-${rotateDepth}deg`, `${rotateDepth}deg`],
42
+ );
43
+ const rotateY = useTransform(
44
+ mouseXSpring,
45
+ [-0.5, 0.5],
46
+ [`${rotateDepth}deg`, `-${rotateDepth}deg`],
47
+ );
48
+
49
+ const translateX = useTransform(
50
+ mouseXSpring,
51
+ [-0.5, 0.5],
52
+ [`-${translateDepth}px`, `${translateDepth}px`],
53
+ );
54
+ const translateY = useTransform(
55
+ mouseYSpring,
56
+ [-0.5, 0.5],
57
+ [`${translateDepth}px`, `-${translateDepth}px`],
58
+ );
59
+
60
+ const glareX = useTransform(mouseXSpring, [-0.5, 0.5], [0, 100]);
61
+ const glareY = useTransform(mouseYSpring, [-0.5, 0.5], [0, 100]);
62
+
63
+ const glareBackground = useMotionTemplate`radial-gradient(circle at ${glareX}% ${glareY}%, rgba(255, 255, 255, 0.9) 10%, rgba(255, 255, 255, 0.75) 20%, rgba(255, 255, 255, 0) 80%)`;
64
+
65
+ const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
66
+ if (!ref.current) return;
67
+
68
+ const rect = ref.current.getBoundingClientRect();
69
+
70
+ const width = rect.width;
71
+ const height = rect.height;
72
+
73
+ const mouseX = e.clientX - rect.left;
74
+ const mouseY = e.clientY - rect.top;
75
+
76
+ const xPct = mouseX / width - 0.5;
77
+ const yPct = mouseY / height - 0.5;
78
+
79
+ x.set(xPct);
80
+ y.set(yPct);
81
+ };
82
+
83
+ const handleMouseLeave = () => {
84
+ x.set(0);
85
+ y.set(0);
86
+ };
87
+
88
+ return (
89
+ <div className={cn("[perspective:1500px] [transform-style:preserve-3d]", className)}>
90
+ <motion.div
91
+ ref={ref}
92
+ onMouseMove={handleMouseMove}
93
+ onMouseLeave={handleMouseLeave}
94
+ style={{
95
+ rotateX,
96
+ rotateY,
97
+ translateX,
98
+ translateY,
99
+ boxShadow:
100
+ "rgba(0, 0, 0, 0.01) 0px 520px 146px 0px, rgba(0, 0, 0, 0.04) 0px 333px 133px 0px, rgba(0, 0, 0, 0.26) 0px 83px 83px 0px, rgba(0, 0, 0, 0.29) 0px 21px 46px 0px",
101
+ }}
102
+ initial={{ scale: 1, z: 0 }}
103
+ whileHover={{
104
+ scale: 1.05,
105
+ z: 50,
106
+ transition: { duration: 0.2 },
107
+ }}
108
+ className="relative rounded-2xl"
109
+ >
110
+ {children}
111
+ <motion.div
112
+ className="pointer-events-none absolute inset-0 z-50 h-full w-full rounded-[16px] mix-blend-overlay"
113
+ style={{
114
+ background: glareBackground,
115
+ opacity: 0.6,
116
+ }}
117
+ transition={{ duration: 0.2 }}
118
+ />
119
+ </motion.div>
120
+ </div>
121
+ );
122
+ };