@webenza/ui 0.0.3 → 0.0.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/README.md CHANGED
@@ -5,21 +5,59 @@ Internal UI and animation components for Webenza.
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @webenza/ui react react-dom gsap
8
+ npm install @webenza/ui
9
+ ```
10
+
11
+ ## Peer Dependencies
12
+
13
+ @webenza/ui does not bundle external animation or rendering libraries.
14
+ Install only the dependencies required for the components you use.
15
+
16
+ > **Note:** Peer dependencies are **not** installed automatically with the library.
17
+
18
+ ### Core (Required)
19
+ ```bash
20
+ npm install react react-dom
21
+ ```
22
+
23
+ ### Motion Components
24
+ If you use components like `HoverFillButton`, `CircularText`, or `ImageTrail`:
25
+ ```bash
26
+ npm install framer-motion
27
+ ```
28
+
29
+ ### GSAP Components
30
+ If you use components like `CursorFollower`:
31
+ ```bash
32
+ npm install gsap
33
+ ```
34
+
35
+ ### Icon / Button Components
36
+ If you use components like `HoverFillButton`:
37
+ ```bash
38
+ npm install react-icons
39
+ ```
40
+
41
+ ### 3D Components
42
+ If you use components like `WaterRipple`:
43
+ ```bash
44
+ npm install three @react-three/fiber
9
45
  ```
10
46
 
11
47
  ## Usage
12
48
 
49
+ Most components are designed to work out of the box with sensible defaults.
50
+
13
51
  ```tsx
14
- import { CursorFollower } from '@webenza/ui';
52
+ import { CursorFollower } from "@webenza/ui";
15
53
 
16
- function App() {
54
+ export default function App() {
17
55
  return (
18
- <CursorFollower />
56
+ <CursorFollower />
19
57
  );
20
58
  }
21
59
  ```
22
60
 
23
- ## Components
24
-
25
- - **CursorFollower**: A custom cursor follower with magnetic and scaling effects.
61
+ - **Works out of the box**
62
+ - **Sensible defaults** included
63
+ - **Optional customization** via props
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1 from 'react';
3
+ import { HTMLMotionProps } from 'framer-motion';
2
4
 
3
5
  type CursorFollowerProps = {
4
6
  text?: string;
@@ -19,4 +21,50 @@ type CursorFollowerProps = {
19
21
  };
20
22
  declare const CursorFollower: ({ text, size, borderWidth, borderColor, background, fontFamily, fontSize, fontWeight, letterSpacing, lerp, showScale, hideScale, enabled, blockSelectors, containerRef, }: CursorFollowerProps) => react_jsx_runtime.JSX.Element | null;
21
23
 
22
- export { CursorFollower, type CursorFollowerProps };
24
+ interface ImageTrailProps {
25
+ images?: string[];
26
+ size?: number;
27
+ rotationRange?: number;
28
+ interval?: number;
29
+ fadeDuration?: number;
30
+ className?: string;
31
+ }
32
+ declare const ImageTrail: React$1.FC<ImageTrailProps>;
33
+
34
+ interface HoverFillButtonProps extends HTMLMotionProps<"button"> {
35
+ label?: string;
36
+ direction?: 'left' | 'right' | 'top' | 'bottom';
37
+ fillColor?: string;
38
+ textColor?: string;
39
+ hoverTextColor?: string;
40
+ padding?: string;
41
+ paddingHorizontal?: string;
42
+ paddingVertical?: string;
43
+ borderRadius?: string;
44
+ backgroundColor?: string;
45
+ borderColor?: string;
46
+ }
47
+ declare const HoverFillButton: React$1.FC<HoverFillButtonProps>;
48
+
49
+ interface ImageMarqueeProps {
50
+ images?: string[];
51
+ direction?: 'left' | 'right';
52
+ speed?: number;
53
+ gap?: string;
54
+ size?: number;
55
+ className?: string;
56
+ }
57
+ declare const ImageMarquee: React$1.FC<ImageMarqueeProps>;
58
+
59
+ interface CircularTextProps {
60
+ text?: string;
61
+ radius?: number;
62
+ fontSize?: string;
63
+ iconSize?: number;
64
+ color?: string;
65
+ spinDuration?: number;
66
+ className?: string;
67
+ }
68
+ declare const CircularText: React$1.FC<CircularTextProps>;
69
+
70
+ export { CircularText, type CircularTextProps, CursorFollower, type CursorFollowerProps, HoverFillButton, type HoverFillButtonProps, ImageMarquee, type ImageMarqueeProps, ImageTrail, type ImageTrailProps };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1 from 'react';
3
+ import { HTMLMotionProps } from 'framer-motion';
2
4
 
3
5
  type CursorFollowerProps = {
4
6
  text?: string;
@@ -19,4 +21,50 @@ type CursorFollowerProps = {
19
21
  };
20
22
  declare const CursorFollower: ({ text, size, borderWidth, borderColor, background, fontFamily, fontSize, fontWeight, letterSpacing, lerp, showScale, hideScale, enabled, blockSelectors, containerRef, }: CursorFollowerProps) => react_jsx_runtime.JSX.Element | null;
21
23
 
22
- export { CursorFollower, type CursorFollowerProps };
24
+ interface ImageTrailProps {
25
+ images?: string[];
26
+ size?: number;
27
+ rotationRange?: number;
28
+ interval?: number;
29
+ fadeDuration?: number;
30
+ className?: string;
31
+ }
32
+ declare const ImageTrail: React$1.FC<ImageTrailProps>;
33
+
34
+ interface HoverFillButtonProps extends HTMLMotionProps<"button"> {
35
+ label?: string;
36
+ direction?: 'left' | 'right' | 'top' | 'bottom';
37
+ fillColor?: string;
38
+ textColor?: string;
39
+ hoverTextColor?: string;
40
+ padding?: string;
41
+ paddingHorizontal?: string;
42
+ paddingVertical?: string;
43
+ borderRadius?: string;
44
+ backgroundColor?: string;
45
+ borderColor?: string;
46
+ }
47
+ declare const HoverFillButton: React$1.FC<HoverFillButtonProps>;
48
+
49
+ interface ImageMarqueeProps {
50
+ images?: string[];
51
+ direction?: 'left' | 'right';
52
+ speed?: number;
53
+ gap?: string;
54
+ size?: number;
55
+ className?: string;
56
+ }
57
+ declare const ImageMarquee: React$1.FC<ImageMarqueeProps>;
58
+
59
+ interface CircularTextProps {
60
+ text?: string;
61
+ radius?: number;
62
+ fontSize?: string;
63
+ iconSize?: number;
64
+ color?: string;
65
+ spinDuration?: number;
66
+ className?: string;
67
+ }
68
+ declare const CircularText: React$1.FC<CircularTextProps>;
69
+
70
+ export { CircularText, type CircularTextProps, CursorFollower, type CursorFollowerProps, HoverFillButton, type HoverFillButtonProps, ImageMarquee, type ImageMarqueeProps, ImageTrail, type ImageTrailProps };
package/dist/index.js CHANGED
@@ -3,6 +3,9 @@
3
3
  var react = require('react');
4
4
  var gsap = require('gsap');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var framerMotion = require('framer-motion');
7
+ var fi = require('react-icons/fi');
8
+ var lu = require('react-icons/lu');
6
9
 
7
10
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
11
 
@@ -159,7 +162,396 @@ var CursorFollower = ({
159
162
  }
160
163
  );
161
164
  };
165
+ var defaultImages = [
166
+ "https://picsum.photos/id/237/200/200",
167
+ "https://picsum.photos/id/10/200/200",
168
+ "https://picsum.photos/id/20/200/200",
169
+ "https://picsum.photos/id/28/200/200",
170
+ "https://picsum.photos/id/29/200/200",
171
+ "https://picsum.photos/id/35/200/200",
172
+ "https://picsum.photos/id/40/200/200",
173
+ "https://picsum.photos/id/55/200/200",
174
+ "https://picsum.photos/id/60/200/200",
175
+ "https://picsum.photos/id/70/200/200"
176
+ ];
177
+ var ImageTrail = ({
178
+ images = defaultImages,
179
+ size = 100,
180
+ rotationRange = 15,
181
+ interval = 30,
182
+ // Default to fairly dense for smooth "train" effect
183
+ fadeDuration = 0.5,
184
+ className
185
+ }) => {
186
+ const [trail, setTrail] = react.useState([]);
187
+ const lastPosRef = react.useRef(null);
188
+ const indexRef = react.useRef(0);
189
+ const idCounterRef = react.useRef(0);
190
+ const containerRef = react.useRef(null);
191
+ react.useEffect(() => {
192
+ const cleanupInterval = setInterval(() => {
193
+ setTrail((prev) => {
194
+ return prev.filter((item) => Date.now() - item.created < fadeDuration * 1e3);
195
+ });
196
+ }, 100);
197
+ return () => clearInterval(cleanupInterval);
198
+ }, [fadeDuration]);
199
+ const handleMouseMove = (e) => {
200
+ if (!containerRef.current) return;
201
+ const rect = containerRef.current.getBoundingClientRect();
202
+ const x = e.clientX - rect.left;
203
+ const y = e.clientY - rect.top;
204
+ const currentPos = { x, y };
205
+ if (!lastPosRef.current) {
206
+ lastPosRef.current = currentPos;
207
+ return;
208
+ }
209
+ const dx = currentPos.x - lastPosRef.current.x;
210
+ const dy = currentPos.y - lastPosRef.current.y;
211
+ const distance = Math.sqrt(dx * dx + dy * dy);
212
+ if (distance > interval) {
213
+ const newImage = {
214
+ id: idCounterRef.current++,
215
+ created: Date.now(),
216
+ src: images[indexRef.current % images.length] || "",
217
+ x: currentPos.x,
218
+ y: currentPos.y,
219
+ rotation: Math.random() * (rotationRange * 2) - rotationRange
220
+ };
221
+ setTrail((prev) => [...prev, newImage]);
222
+ lastPosRef.current = currentPos;
223
+ indexRef.current++;
224
+ }
225
+ };
226
+ const handleMouseLeave = () => {
227
+ lastPosRef.current = null;
228
+ };
229
+ return /* @__PURE__ */ jsxRuntime.jsxs(
230
+ "div",
231
+ {
232
+ ref: containerRef,
233
+ className,
234
+ onMouseMove: handleMouseMove,
235
+ onMouseLeave: handleMouseLeave,
236
+ style: {
237
+ position: "relative",
238
+ width: "100%",
239
+ height: "100%",
240
+ minHeight: "400px",
241
+ overflow: "hidden",
242
+ background: "#111",
243
+ cursor: "none",
244
+ borderRadius: "12px"
245
+ },
246
+ children: [
247
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
248
+ pointerEvents: "none",
249
+ position: "absolute",
250
+ top: 0,
251
+ left: 0,
252
+ width: "100%",
253
+ height: "100%"
254
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "popLayout", children: trail.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
255
+ framerMotion.motion.img,
256
+ {
257
+ src: item.src,
258
+ initial: {
259
+ opacity: 0,
260
+ scale: 0.8,
261
+ x: item.x - size / 2,
262
+ y: item.y - size / 2,
263
+ rotate: item.rotation
264
+ },
265
+ animate: {
266
+ opacity: 1,
267
+ scale: 1,
268
+ x: item.x - size / 2,
269
+ y: item.y - size / 2
270
+ },
271
+ exit: {
272
+ opacity: 0,
273
+ scale: 0.5,
274
+ transition: { duration: fadeDuration }
275
+ },
276
+ transition: { duration: 0.1 },
277
+ style: {
278
+ position: "absolute",
279
+ width: size,
280
+ height: size,
281
+ objectFit: "cover",
282
+ borderRadius: "8px",
283
+ boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
284
+ pointerEvents: "none",
285
+ left: 0,
286
+ top: 0
287
+ }
288
+ },
289
+ item.id
290
+ )) }) }),
291
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
292
+ position: "absolute",
293
+ top: "50%",
294
+ left: "50%",
295
+ transform: "translate(-50%, -50%)",
296
+ color: "#444",
297
+ pointerEvents: "none",
298
+ fontWeight: 500,
299
+ textAlign: "center"
300
+ }, children: "Hover to see trail" })
301
+ ]
302
+ }
303
+ );
304
+ };
305
+ var HoverFillButton = ({
306
+ label = "Hover Me",
307
+ direction = "left",
308
+ fillColor = "#e9590c",
309
+ textColor = "#ffffff",
310
+ hoverTextColor = "#ffffff",
311
+ padding = "12px 24px",
312
+ paddingHorizontal,
313
+ paddingVertical,
314
+ borderRadius = "50px",
315
+ backgroundColor = "#000000",
316
+ borderColor = "#000000",
317
+ style,
318
+ ...props
319
+ }) => {
320
+ const getInitialPosition = () => {
321
+ switch (direction) {
322
+ case "left":
323
+ return { x: "-100%", y: "0%" };
324
+ case "right":
325
+ return { x: "100%", y: "0%" };
326
+ case "top":
327
+ return { x: "0%", y: "-100%" };
328
+ case "bottom":
329
+ return { x: "0%", y: "100%" };
330
+ default:
331
+ return { x: "-100%", y: "0%" };
332
+ }
333
+ };
334
+ const finalPadding = paddingHorizontal || paddingVertical ? `${paddingVertical || "12px"} ${paddingHorizontal || "24px"}` : padding;
335
+ return /* @__PURE__ */ jsxRuntime.jsxs(
336
+ framerMotion.motion.button,
337
+ {
338
+ initial: "initial",
339
+ whileHover: "hover",
340
+ style: {
341
+ position: "relative",
342
+ padding: finalPadding,
343
+ background: backgroundColor,
344
+ border: `1px solid ${borderColor}`,
345
+ color: textColor,
346
+ borderRadius,
347
+ cursor: "pointer",
348
+ overflow: "hidden",
349
+ fontSize: "16px",
350
+ fontWeight: 500,
351
+ ...style
352
+ },
353
+ ...props,
354
+ children: [
355
+ /* @__PURE__ */ jsxRuntime.jsx(
356
+ framerMotion.motion.div,
357
+ {
358
+ variants: {
359
+ initial: getInitialPosition(),
360
+ hover: { x: "0%", y: "0%" }
361
+ },
362
+ transition: { duration: 0.3, ease: "easeInOut" },
363
+ style: {
364
+ position: "absolute",
365
+ top: 0,
366
+ left: 0,
367
+ right: 0,
368
+ bottom: 0,
369
+ background: fillColor,
370
+ zIndex: 0
371
+ }
372
+ },
373
+ direction
374
+ ),
375
+ /* @__PURE__ */ jsxRuntime.jsxs(
376
+ framerMotion.motion.span,
377
+ {
378
+ variants: {
379
+ initial: { color: textColor },
380
+ hover: { color: hoverTextColor }
381
+ },
382
+ transition: { duration: 0.2 },
383
+ style: {
384
+ position: "relative",
385
+ zIndex: 1,
386
+ display: "flex",
387
+ alignItems: "center",
388
+ gap: "12px",
389
+ lineHeight: 1
390
+ },
391
+ children: [
392
+ label,
393
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
394
+ display: "flex",
395
+ alignItems: "center",
396
+ justifyContent: "center",
397
+ width: "24px",
398
+ height: "24px",
399
+ borderRadius: "50%",
400
+ border: "2px solid currentColor",
401
+ // Increased thickness
402
+ fontSize: "16px"
403
+ // Slightly larger container for icon
404
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(fi.FiArrowRight, { strokeWidth: 3 }) })
405
+ ]
406
+ }
407
+ )
408
+ ]
409
+ }
410
+ );
411
+ };
412
+ var defaultImages2 = [
413
+ "/logos/Airbnb.png",
414
+ "/logos/Amazon.png",
415
+ "/logos/Apple.png",
416
+ "/logos/Bookmyshow.png",
417
+ "/logos/FedEx.png",
418
+ "/logos/Google.png",
419
+ "/logos/Microsoft.png",
420
+ "/logos/OLA.png",
421
+ "/logos/OYO.png",
422
+ "/logos/Walmart.png"
423
+ ];
424
+ var ImageMarquee = ({
425
+ images = defaultImages2,
426
+ direction = "left",
427
+ speed = 20,
428
+ gap = "2rem",
429
+ size = 60,
430
+ className
431
+ }) => {
432
+ return /* @__PURE__ */ jsxRuntime.jsxs(
433
+ "div",
434
+ {
435
+ className,
436
+ style: {
437
+ overflow: "hidden",
438
+ whiteSpace: "nowrap",
439
+ display: "flex",
440
+ width: "100%"
441
+ },
442
+ children: [
443
+ /* @__PURE__ */ jsxRuntime.jsx(MarqueeContent, { images, direction, speed, gap, size }),
444
+ /* @__PURE__ */ jsxRuntime.jsx(MarqueeContent, { images, direction, speed, gap, size }),
445
+ /* @__PURE__ */ jsxRuntime.jsx(MarqueeContent, { images, direction, speed, gap, size }),
446
+ /* @__PURE__ */ jsxRuntime.jsx(MarqueeContent, { images, direction, speed, gap, size })
447
+ ]
448
+ }
449
+ );
450
+ };
451
+ var MarqueeContent = ({ images, direction, speed, gap, size }) => {
452
+ return /* @__PURE__ */ jsxRuntime.jsx(
453
+ framerMotion.motion.div,
454
+ {
455
+ initial: { x: direction === "left" ? "0%" : "-100%" },
456
+ animate: { x: direction === "left" ? "-100%" : "0%" },
457
+ transition: {
458
+ duration: speed,
459
+ ease: "linear",
460
+ repeat: Infinity
461
+ },
462
+ style: {
463
+ display: "flex",
464
+ gap,
465
+ minWidth: "max-content",
466
+ flexShrink: 0,
467
+ alignItems: "center",
468
+ paddingRight: gap
469
+ // Ensure spacing at the end matches the gap for seamlessness
470
+ },
471
+ children: images.map((src, index) => /* @__PURE__ */ jsxRuntime.jsx(
472
+ "img",
473
+ {
474
+ src,
475
+ alt: `marquee-item-${index}`,
476
+ style: {
477
+ height: `${size}px`,
478
+ width: "auto",
479
+ objectFit: "contain",
480
+ borderRadius: "0px"
481
+ }
482
+ },
483
+ index
484
+ ))
485
+ },
486
+ `${direction}-${speed}`
487
+ );
488
+ };
489
+ var CircularText = ({
490
+ text = "SCROLL DOWN \u2022 SCROLL DOWN \u2022 ",
491
+ radius = 50,
492
+ fontSize = "12px",
493
+ iconSize = 24,
494
+ color = "#ffffff",
495
+ spinDuration = 10,
496
+ className
497
+ }) => {
498
+ const size = radius * 2 + 40;
499
+ return /* @__PURE__ */ jsxRuntime.jsxs(
500
+ "div",
501
+ {
502
+ className,
503
+ style: {
504
+ position: "relative",
505
+ width: size,
506
+ height: size,
507
+ display: "flex",
508
+ justifyContent: "center",
509
+ alignItems: "center"
510
+ },
511
+ children: [
512
+ /* @__PURE__ */ jsxRuntime.jsx(
513
+ framerMotion.motion.div,
514
+ {
515
+ animate: { rotate: 360 },
516
+ transition: {
517
+ duration: spinDuration,
518
+ repeat: Infinity,
519
+ ease: "linear"
520
+ },
521
+ style: {
522
+ width: "100%",
523
+ height: "100%",
524
+ position: "absolute",
525
+ top: 0,
526
+ left: 0
527
+ },
528
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: "100%", height: "100%", children: [
529
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
530
+ "path",
531
+ {
532
+ id: "circlePath",
533
+ d: `
534
+ M ${size / 2}, ${size / 2}
535
+ m -${radius}, 0
536
+ a ${radius},${radius} 0 1,1 ${radius * 2},0
537
+ a ${radius},${radius} 0 1,1 -${radius * 2},0
538
+ `
539
+ }
540
+ ) }),
541
+ /* @__PURE__ */ jsxRuntime.jsx("text", { fill: color, fontSize, fontWeight: "bold", letterSpacing: "2px", children: /* @__PURE__ */ jsxRuntime.jsx("textPath", { href: "#circlePath", startOffset: "0%", children: text }) })
542
+ ] })
543
+ }
544
+ ),
545
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "relative", color, display: "flex" }, children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMouse, { size: iconSize }) })
546
+ ]
547
+ }
548
+ );
549
+ };
162
550
 
551
+ exports.CircularText = CircularText;
163
552
  exports.CursorFollower = CursorFollower;
553
+ exports.HoverFillButton = HoverFillButton;
554
+ exports.ImageMarquee = ImageMarquee;
555
+ exports.ImageTrail = ImageTrail;
164
556
  //# sourceMappingURL=index.js.map
165
557
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cursor/CursorFollower/CursorFollower.tsx"],"names":["useRef","useLayoutEffect","gsap","jsx"],"mappings":"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","file":"index.js","sourcesContent":["import { useLayoutEffect, useRef } from \"react\";\r\nimport gsap from \"gsap\";\r\n\r\nexport type CursorFollowerProps = {\r\n text?: string;\r\n\r\n size?: number;\r\n borderWidth?: number;\r\n borderColor?: string;\r\n background?: string;\r\n\r\n fontFamily?: string;\r\n fontSize?: number;\r\n fontWeight?: number | string;\r\n letterSpacing?: number;\r\n\r\n lerp?: number;\r\n showScale?: number;\r\n hideScale?: number;\r\n\r\n enabled?: boolean;\r\n blockSelectors?: string[];\r\n containerRef?: React.RefObject<HTMLElement>;\r\n};\r\n\r\nexport const CursorFollower = ({\r\n text = \"PLAY\",\r\n size = 90,\r\n borderWidth = 2,\r\n borderColor = \"#ffffff\",\r\n background = \"transparent\",\r\n\r\n fontFamily = \"inherit\",\r\n fontSize = 12,\r\n fontWeight = 400,\r\n letterSpacing = 2,\r\n\r\n lerp = 0.035,\r\n showScale = 1,\r\n hideScale = 0,\r\n\r\n enabled = true,\r\n blockSelectors = [\"button\", \"a\"],\r\n containerRef,\r\n}: CursorFollowerProps) => {\r\n const cursorRef = useRef<HTMLDivElement>(null);\r\n\r\n useLayoutEffect(() => {\r\n if (!enabled) return;\r\n\r\n const cursor = cursorRef.current;\r\n if (!cursor) return;\r\n\r\n let targetX = 0;\r\n let targetY = 0;\r\n let currentX = 0;\r\n let currentY = 0;\r\n let visible = false;\r\n let blocked = false;\r\n\r\n const show = () => {\r\n if (visible || blocked) return;\r\n visible = true;\r\n gsap.to(cursor, { scale: showScale, opacity: 1, duration: 0.25 });\r\n };\r\n\r\n const hide = () => {\r\n if (!visible) return;\r\n visible = false;\r\n gsap.to(cursor, { scale: hideScale, opacity: 0, duration: 0.25 });\r\n };\r\n\r\n const move = (e: MouseEvent) => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = e.clientX - bounds.left;\r\n targetY = e.clientY - bounds.top;\r\n } else {\r\n targetX = e.clientX;\r\n targetY = e.clientY;\r\n }\r\n\r\n // Ensure cursor is visible if it moves\r\n if (!visible && !blocked) {\r\n show();\r\n }\r\n };\r\n\r\n const update = () => {\r\n currentX += (targetX - currentX) * lerp;\r\n currentY += (targetY - currentY) * lerp;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2,\r\n });\r\n };\r\n\r\n // Event Listeners Source\r\n const target = containerRef?.current || window;\r\n\r\n target.addEventListener(\"mousemove\", move as any);\r\n target.addEventListener(\"mouseenter\", show as any);\r\n target.addEventListener(\"mouseleave\", hide as any);\r\n\r\n gsap.ticker.add(update);\r\n\r\n // Force initial visibility and positioning\r\n requestAnimationFrame(() => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = bounds.width / 2;\r\n targetY = bounds.height / 2;\r\n } else {\r\n targetX = window.innerWidth / 2;\r\n targetY = window.innerHeight / 2;\r\n }\r\n\r\n // Set current position immediately to avoid lerp from 0,0\r\n currentX = targetX;\r\n currentY = targetY;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2\r\n });\r\n\r\n show();\r\n });\r\n\r\n // Handle blocked selectors\r\n const cleanupFns: (() => void)[] = [];\r\n\r\n blockSelectors.forEach((selector) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach((el) => {\r\n const enter = () => {\r\n blocked = true;\r\n hide();\r\n };\r\n const leave = () => {\r\n blocked = false;\r\n show();\r\n };\r\n\r\n el.addEventListener(\"mouseenter\", enter);\r\n el.addEventListener(\"mouseleave\", leave);\r\n\r\n cleanupFns.push(() => {\r\n el.removeEventListener(\"mouseenter\", enter);\r\n el.removeEventListener(\"mouseleave\", leave);\r\n });\r\n });\r\n });\r\n\r\n return () => {\r\n target.removeEventListener(\"mousemove\", move as any);\r\n target.removeEventListener(\"mouseenter\", show as any);\r\n target.removeEventListener(\"mouseleave\", hide as any);\r\n gsap.ticker.remove(update);\r\n cleanupFns.forEach((fn) => fn());\r\n };\r\n }, [\r\n enabled,\r\n size,\r\n lerp,\r\n showScale,\r\n hideScale,\r\n // Stabilize dependency: only re-run if the joined string changes\r\n blockSelectors.join(\",\"),\r\n containerRef\r\n ]);\r\n\r\n if (!enabled) return null;\r\n\r\n return (\r\n <div\r\n ref={cursorRef}\r\n style={{\r\n position: containerRef ? \"absolute\" : \"fixed\",\r\n top: 0,\r\n left: 0,\r\n width: size,\r\n height: size,\r\n border: `${borderWidth}px solid ${borderColor}`,\r\n background,\r\n borderRadius: \"50%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n pointerEvents: \"none\",\r\n zIndex: 9999,\r\n opacity: 0,\r\n transform: \"scale(0)\",\r\n fontFamily,\r\n fontSize,\r\n fontWeight,\r\n letterSpacing,\r\n textTransform: \"uppercase\",\r\n color: borderColor,\r\n }}\r\n >\r\n {text}\r\n </div>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"sources":["../src/cursor/CursorFollower/CursorFollower.tsx","../src/cursor/ImageTrail/ImageTrail.tsx","../src/Button/HoverFillButton/HoverFillButton.tsx","../src/Other/ImageMarquee/ImageMarquee.tsx","../src/Text/CircularText/CircularText.tsx"],"names":["useRef","useLayoutEffect","gsap","jsx","useState","useEffect","jsxs","AnimatePresence","motion","FiArrowRight","defaultImages","LuMouse"],"mappings":"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","file":"index.js","sourcesContent":["import { useLayoutEffect, useRef } from \"react\";\r\nimport gsap from \"gsap\";\r\n\r\nexport type CursorFollowerProps = {\r\n text?: string;\r\n\r\n size?: number;\r\n borderWidth?: number;\r\n borderColor?: string;\r\n background?: string;\r\n\r\n fontFamily?: string;\r\n fontSize?: number;\r\n fontWeight?: number | string;\r\n letterSpacing?: number;\r\n\r\n lerp?: number;\r\n showScale?: number;\r\n hideScale?: number;\r\n\r\n enabled?: boolean;\r\n blockSelectors?: string[];\r\n containerRef?: React.RefObject<HTMLElement>;\r\n};\r\n\r\nexport const CursorFollower = ({\r\n text = \"PLAY\",\r\n size = 90,\r\n borderWidth = 2,\r\n borderColor = \"#ffffff\",\r\n background = \"transparent\",\r\n\r\n fontFamily = \"inherit\",\r\n fontSize = 12,\r\n fontWeight = 400,\r\n letterSpacing = 2,\r\n\r\n lerp = 0.035,\r\n showScale = 1,\r\n hideScale = 0,\r\n\r\n enabled = true,\r\n blockSelectors = [\"button\", \"a\"],\r\n containerRef,\r\n}: CursorFollowerProps) => {\r\n const cursorRef = useRef<HTMLDivElement>(null);\r\n\r\n useLayoutEffect(() => {\r\n if (!enabled) return;\r\n\r\n const cursor = cursorRef.current;\r\n if (!cursor) return;\r\n\r\n let targetX = 0;\r\n let targetY = 0;\r\n let currentX = 0;\r\n let currentY = 0;\r\n let visible = false;\r\n let blocked = false;\r\n\r\n const show = () => {\r\n if (visible || blocked) return;\r\n visible = true;\r\n gsap.to(cursor, { scale: showScale, opacity: 1, duration: 0.25 });\r\n };\r\n\r\n const hide = () => {\r\n if (!visible) return;\r\n visible = false;\r\n gsap.to(cursor, { scale: hideScale, opacity: 0, duration: 0.25 });\r\n };\r\n\r\n const move = (e: MouseEvent) => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = e.clientX - bounds.left;\r\n targetY = e.clientY - bounds.top;\r\n } else {\r\n targetX = e.clientX;\r\n targetY = e.clientY;\r\n }\r\n\r\n // Ensure cursor is visible if it moves\r\n if (!visible && !blocked) {\r\n show();\r\n }\r\n };\r\n\r\n const update = () => {\r\n currentX += (targetX - currentX) * lerp;\r\n currentY += (targetY - currentY) * lerp;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2,\r\n });\r\n };\r\n\r\n // Event Listeners Source\r\n const target = containerRef?.current || window;\r\n\r\n target.addEventListener(\"mousemove\", move as any);\r\n target.addEventListener(\"mouseenter\", show as any);\r\n target.addEventListener(\"mouseleave\", hide as any);\r\n\r\n gsap.ticker.add(update);\r\n\r\n // Force initial visibility and positioning\r\n requestAnimationFrame(() => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = bounds.width / 2;\r\n targetY = bounds.height / 2;\r\n } else {\r\n targetX = window.innerWidth / 2;\r\n targetY = window.innerHeight / 2;\r\n }\r\n\r\n // Set current position immediately to avoid lerp from 0,0\r\n currentX = targetX;\r\n currentY = targetY;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2\r\n });\r\n\r\n show();\r\n });\r\n\r\n // Handle blocked selectors\r\n const cleanupFns: (() => void)[] = [];\r\n\r\n blockSelectors.forEach((selector) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach((el) => {\r\n const enter = () => {\r\n blocked = true;\r\n hide();\r\n };\r\n const leave = () => {\r\n blocked = false;\r\n show();\r\n };\r\n\r\n el.addEventListener(\"mouseenter\", enter);\r\n el.addEventListener(\"mouseleave\", leave);\r\n\r\n cleanupFns.push(() => {\r\n el.removeEventListener(\"mouseenter\", enter);\r\n el.removeEventListener(\"mouseleave\", leave);\r\n });\r\n });\r\n });\r\n\r\n return () => {\r\n target.removeEventListener(\"mousemove\", move as any);\r\n target.removeEventListener(\"mouseenter\", show as any);\r\n target.removeEventListener(\"mouseleave\", hide as any);\r\n gsap.ticker.remove(update);\r\n cleanupFns.forEach((fn) => fn());\r\n };\r\n }, [\r\n enabled,\r\n size,\r\n lerp,\r\n showScale,\r\n hideScale,\r\n // Stabilize dependency: only re-run if the joined string changes\r\n blockSelectors.join(\",\"),\r\n containerRef\r\n ]);\r\n\r\n if (!enabled) return null;\r\n\r\n return (\r\n <div\r\n ref={cursorRef}\r\n style={{\r\n position: containerRef ? \"absolute\" : \"fixed\",\r\n top: 0,\r\n left: 0,\r\n width: size,\r\n height: size,\r\n border: `${borderWidth}px solid ${borderColor}`,\r\n background,\r\n borderRadius: \"50%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n pointerEvents: \"none\",\r\n zIndex: 9999,\r\n opacity: 0,\r\n transform: \"scale(0)\",\r\n fontFamily,\r\n fontSize,\r\n fontWeight,\r\n letterSpacing,\r\n textTransform: \"uppercase\",\r\n color: borderColor,\r\n }}\r\n >\r\n {text}\r\n </div>\r\n );\r\n};\r\n","import React, { useRef, useState, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'framer-motion';\r\n\r\nexport interface ImageTrailProps {\r\n images?: string[];\r\n size?: number;\r\n rotationRange?: number;\r\n interval?: number; // Distance in px required to spawn next image\r\n fadeDuration?: number;\r\n className?: string;\r\n}\r\n\r\nconst defaultImages = [\r\n \"https://picsum.photos/id/237/200/200\",\r\n \"https://picsum.photos/id/10/200/200\",\r\n \"https://picsum.photos/id/20/200/200\",\r\n \"https://picsum.photos/id/28/200/200\",\r\n \"https://picsum.photos/id/29/200/200\",\r\n \"https://picsum.photos/id/35/200/200\",\r\n \"https://picsum.photos/id/40/200/200\",\r\n \"https://picsum.photos/id/55/200/200\",\r\n \"https://picsum.photos/id/60/200/200\",\r\n \"https://picsum.photos/id/70/200/200\"\r\n];\r\n\r\ninterface TrailItem {\r\n id: number;\r\n src: string;\r\n x: number;\r\n y: number;\r\n rotation: number;\r\n}\r\n\r\nexport const ImageTrail: React.FC<ImageTrailProps> = ({\r\n images = defaultImages,\r\n size = 100,\r\n rotationRange = 15,\r\n interval = 30, // Default to fairly dense for smooth \"train\" effect\r\n fadeDuration = 0.5,\r\n className\r\n}) => {\r\n const [trail, setTrail] = useState<TrailItem[]>([]);\r\n const lastPosRef = useRef<{ x: number, y: number } | null>(null);\r\n const indexRef = useRef(0);\r\n const idCounterRef = useRef(0);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // Time-based cleanup\r\n useEffect(() => {\r\n const cleanupInterval = setInterval(() => {\r\n // Assuming IDs are roughly chronological if we used Date.now(), \r\n // but we switched to counter. \r\n // Actually, let's switch back to a safer cleanup that doesn't rely on ID being timestamp\r\n // BUT, for simplicity and since we want a \"fade out\" effect managed by AnimatePresence,\r\n // we really just need to trim the list if it gets too long, or let them expire.\r\n // Let's use a timestamp property for cleanup to be safe.\r\n setTrail(prev => {\r\n // If we want purely time-based expiration, we need a created timestamp.\r\n // However, simply limiting the valid set by time is tricky if we use counter IDs.\r\n // Let's rely on AnimatePresence for the visual fade, and just strictly limit count or use a parallel timestamp.\r\n // Reverting to the simpler \"limit count\" strategy might be more robust for now to avoid complexity,\r\n // but the user specifically asked for \"fade when stop\".\r\n // So let's add a 'created' field to the item state implicitly.\r\n // Actually, let's just use Date.now() for ID again but ensuring uniqueness?\r\n // No, let's stick to counter ID + created timestamp.\r\n return prev.filter(item => Date.now() - (item as any).created < fadeDuration * 1000);\r\n });\r\n }, 100);\r\n\r\n return () => clearInterval(cleanupInterval);\r\n }, [fadeDuration]);\r\n\r\n const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\r\n if (!containerRef.current) return;\r\n\r\n const rect = containerRef.current.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n const currentPos = { x, y };\r\n\r\n if (!lastPosRef.current) {\r\n lastPosRef.current = currentPos;\r\n return;\r\n }\r\n\r\n const dx = currentPos.x - lastPosRef.current.x;\r\n const dy = currentPos.y - lastPosRef.current.y;\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n // Spawn a new image if we've moved enough\r\n if (distance > interval) {\r\n const newImage: TrailItem & { created: number } = {\r\n id: idCounterRef.current++,\r\n created: Date.now(),\r\n src: images[indexRef.current % images.length] || \"\",\r\n x: currentPos.x,\r\n y: currentPos.y,\r\n rotation: Math.random() * (rotationRange * 2) - rotationRange\r\n };\r\n\r\n setTrail(prev => [...prev, newImage]);\r\n\r\n lastPosRef.current = currentPos;\r\n indexRef.current++;\r\n }\r\n };\r\n\r\n const handleMouseLeave = () => {\r\n lastPosRef.current = null; // Break the path trace\r\n };\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n onMouseMove={handleMouseMove}\r\n onMouseLeave={handleMouseLeave}\r\n style={{\r\n position: 'relative',\r\n width: '100%',\r\n height: '100%',\r\n minHeight: '400px',\r\n overflow: 'hidden',\r\n background: '#111',\r\n cursor: 'none',\r\n borderRadius: '12px'\r\n }}\r\n >\r\n <div style={{\r\n pointerEvents: 'none',\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n }}>\r\n <AnimatePresence mode='popLayout'>\r\n {trail.map((item) => (\r\n <motion.img\r\n key={item.id}\r\n src={item.src}\r\n initial={{\r\n opacity: 0,\r\n scale: 0.8,\r\n x: item.x - size / 2,\r\n y: item.y - size / 2,\r\n rotate: item.rotation\r\n }}\r\n animate={{\r\n opacity: 1,\r\n scale: 1,\r\n x: item.x - size / 2,\r\n y: item.y - size / 2\r\n }}\r\n exit={{\r\n opacity: 0,\r\n scale: 0.5,\r\n transition: { duration: fadeDuration }\r\n }}\r\n transition={{ duration: 0.1 }}\r\n style={{\r\n position: 'absolute',\r\n width: size,\r\n height: size,\r\n objectFit: 'cover',\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.3)',\r\n pointerEvents: 'none',\r\n left: 0,\r\n top: 0\r\n }}\r\n />\r\n ))}\r\n </AnimatePresence>\r\n </div>\r\n\r\n <div style={{\r\n position: 'absolute',\r\n top: '50%',\r\n left: '50%',\r\n transform: 'translate(-50%, -50%)',\r\n color: '#444',\r\n pointerEvents: 'none',\r\n fontWeight: 500,\r\n textAlign: 'center'\r\n }}>\r\n Hover to see trail\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion, type HTMLMotionProps } from 'framer-motion';\r\nimport { FiArrowRight } from 'react-icons/fi';\r\n\r\nexport interface HoverFillButtonProps extends HTMLMotionProps<\"button\"> {\r\n label?: string;\r\n direction?: 'left' | 'right' | 'top' | 'bottom';\r\n fillColor?: string;\r\n textColor?: string;\r\n hoverTextColor?: string;\r\n padding?: string;\r\n paddingHorizontal?: string;\r\n paddingVertical?: string;\r\n borderRadius?: string;\r\n backgroundColor?: string;\r\n borderColor?: string;\r\n}\r\n\r\nexport const HoverFillButton: React.FC<HoverFillButtonProps> = ({\r\n label = 'Hover Me',\r\n direction = 'left',\r\n fillColor = '#e9590c',\r\n textColor = '#ffffff',\r\n hoverTextColor = '#ffffff',\r\n padding = '12px 24px',\r\n paddingHorizontal,\r\n paddingVertical,\r\n borderRadius = '50px',\r\n backgroundColor = '#000000',\r\n borderColor = '#000000',\r\n style,\r\n ...props\r\n}) => {\r\n // Determine initial position of the fill layer based on direction\r\n const getInitialPosition = () => {\r\n switch (direction) {\r\n case 'left': return { x: '-100%', y: '0%' };\r\n case 'right': return { x: '100%', y: '0%' };\r\n case 'top': return { x: '0%', y: '-100%' };\r\n case 'bottom': return { x: '0%', y: '100%' };\r\n default: return { x: '-100%', y: '0%' };\r\n }\r\n };\r\n\r\n // Construct final padding\r\n const finalPadding = (paddingHorizontal || paddingVertical)\r\n ? `${paddingVertical || '12px'} ${paddingHorizontal || '24px'}`\r\n : padding;\r\n\r\n return (\r\n <motion.button\r\n initial=\"initial\"\r\n whileHover=\"hover\"\r\n style={{\r\n position: 'relative',\r\n padding: finalPadding,\r\n background: backgroundColor,\r\n border: `1px solid ${borderColor}`,\r\n color: textColor,\r\n borderRadius,\r\n cursor: 'pointer',\r\n overflow: 'hidden',\r\n fontSize: '16px',\r\n fontWeight: 500,\r\n ...style\r\n }}\r\n {...props}\r\n >\r\n {/* Fill Layer */}\r\n <motion.div\r\n key={direction} // Force re-mount when direction changes to apply new initial state\r\n variants={{\r\n initial: getInitialPosition(),\r\n hover: { x: '0%', y: '0%' }\r\n }}\r\n transition={{ duration: 0.3, ease: 'easeInOut' }}\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n background: fillColor,\r\n zIndex: 0\r\n }}\r\n />\r\n\r\n {/* Text Layer - Needs to change color on hover? */}\r\n <motion.span\r\n variants={{\r\n initial: { color: textColor },\r\n hover: { color: hoverTextColor }\r\n }}\r\n transition={{ duration: 0.2 }}\r\n style={{\r\n position: 'relative',\r\n zIndex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n lineHeight: 1\r\n }}\r\n >\r\n {label}\r\n\r\n {/* Arrow in Circle */}\r\n <span style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: '24px',\r\n height: '24px',\r\n borderRadius: '50%',\r\n border: '2px solid currentColor', // Increased thickness\r\n fontSize: '16px' // Slightly larger container for icon\r\n }}>\r\n <FiArrowRight strokeWidth={3} />\r\n </span>\r\n </motion.span>\r\n </motion.button>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion } from 'framer-motion';\r\n\r\nexport interface ImageMarqueeProps {\r\n images?: string[];\r\n direction?: 'left' | 'right';\r\n speed?: number; // duration for one full loop\r\n gap?: string;\r\n size?: number;\r\n className?: string;\r\n}\r\n\r\nconst defaultImages = [\r\n \"/logos/Airbnb.png\",\r\n \"/logos/Amazon.png\",\r\n \"/logos/Apple.png\",\r\n \"/logos/Bookmyshow.png\",\r\n \"/logos/FedEx.png\",\r\n \"/logos/Google.png\",\r\n \"/logos/Microsoft.png\",\r\n \"/logos/OLA.png\",\r\n \"/logos/OYO.png\",\r\n \"/logos/Walmart.png\"\r\n];\r\n\r\nexport const ImageMarquee: React.FC<ImageMarqueeProps> = ({\r\n images = defaultImages,\r\n direction = 'left',\r\n speed = 20,\r\n gap = '2rem',\r\n size = 60,\r\n className\r\n}) => {\r\n // Determine the translation direction\r\n // For 'left', we move from 0 to -100% (partially) or similar math\r\n // A simple way for infinite marquee is to duplicate the content\r\n\r\n return (\r\n <div\r\n className={className}\r\n style={{\r\n overflow: 'hidden',\r\n whiteSpace: 'nowrap',\r\n display: 'flex',\r\n width: '100%'\r\n }}\r\n >\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n </div>\r\n );\r\n};\r\n\r\nconst MarqueeContent = ({ images, direction, speed, gap, size }: { images: string[], direction: 'left' | 'right', speed: number, gap: string, size: number }) => {\r\n return (\r\n <motion.div\r\n key={`${direction}-${speed}`}\r\n initial={{ x: direction === 'left' ? \"0%\" : \"-100%\" }}\r\n animate={{ x: direction === 'left' ? \"-100%\" : \"0%\" }}\r\n transition={{\r\n duration: speed,\r\n ease: \"linear\",\r\n repeat: Infinity\r\n }}\r\n style={{\r\n display: 'flex',\r\n gap: gap,\r\n minWidth: 'max-content',\r\n flexShrink: 0,\r\n alignItems: 'center',\r\n paddingRight: gap // Ensure spacing at the end matches the gap for seamlessness\r\n }}\r\n >\r\n {images.map((src, index) => (\r\n <img\r\n key={index}\r\n src={src}\r\n alt={`marquee-item-${index}`}\r\n style={{\r\n height: `${size}px`,\r\n width: 'auto',\r\n objectFit: 'contain',\r\n borderRadius: '0px'\r\n }}\r\n />\r\n ))}\r\n </motion.div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion } from 'framer-motion';\r\nimport { LuMouse } from 'react-icons/lu';\r\n\r\nexport interface CircularTextProps {\r\n text?: string;\r\n radius?: number;\r\n fontSize?: string;\r\n iconSize?: number;\r\n color?: string;\r\n spinDuration?: number;\r\n className?: string;\r\n}\r\n\r\nexport const CircularText: React.FC<CircularTextProps> = ({\r\n text = \"SCROLL DOWN • SCROLL DOWN • \",\r\n radius = 50,\r\n fontSize = \"12px\",\r\n iconSize = 24,\r\n color = \"#ffffff\",\r\n spinDuration = 10,\r\n className\r\n}) => {\r\n // Determine the circumference to space text properly if needed, \r\n // but textPath usually handles it well. \r\n // We'll use a viewBox that accommodates the radius.\r\n // Box size = (radius * 2) + padding for text height\r\n const size = radius * 2 + 40;\r\n\r\n return (\r\n <div\r\n className={className}\r\n style={{\r\n position: 'relative',\r\n width: size,\r\n height: size,\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center'\r\n }}\r\n >\r\n {/* Rotating Text Ring */}\r\n <motion.div\r\n animate={{ rotate: 360 }}\r\n transition={{\r\n duration: spinDuration,\r\n repeat: Infinity,\r\n ease: \"linear\"\r\n }}\r\n style={{\r\n width: '100%',\r\n height: '100%',\r\n position: 'absolute',\r\n top: 0,\r\n left: 0\r\n }}\r\n >\r\n <svg viewBox={`0 0 ${size} ${size}`} width=\"100%\" height=\"100%\">\r\n <defs>\r\n <path\r\n id=\"circlePath\"\r\n d={`\r\n M ${size / 2}, ${size / 2}\r\n m -${radius}, 0\r\n a ${radius},${radius} 0 1,1 ${radius * 2},0\r\n a ${radius},${radius} 0 1,1 -${radius * 2},0\r\n `}\r\n />\r\n </defs>\r\n <text fill={color} fontSize={fontSize} fontWeight=\"bold\" letterSpacing=\"2px\">\r\n <textPath href=\"#circlePath\" startOffset=\"0%\">\r\n {text}\r\n </textPath>\r\n </text>\r\n </svg>\r\n </motion.div>\r\n\r\n {/* Static Icon */}\r\n <div style={{ position: 'relative', color: color, display: 'flex' }}>\r\n <LuMouse size={iconSize} />\r\n </div>\r\n </div>\r\n );\r\n};\r\n"]}
package/dist/index.mjs CHANGED
@@ -1,6 +1,9 @@
1
- import { useRef, useLayoutEffect } from 'react';
1
+ import { useRef, useLayoutEffect, useState, useEffect } from 'react';
2
2
  import gsap from 'gsap';
3
- import { jsx } from 'react/jsx-runtime';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { AnimatePresence, motion } from 'framer-motion';
5
+ import { FiArrowRight } from 'react-icons/fi';
6
+ import { LuMouse } from 'react-icons/lu';
4
7
 
5
8
  // src/cursor/CursorFollower/CursorFollower.tsx
6
9
  var CursorFollower = ({
@@ -153,7 +156,392 @@ var CursorFollower = ({
153
156
  }
154
157
  );
155
158
  };
159
+ var defaultImages = [
160
+ "https://picsum.photos/id/237/200/200",
161
+ "https://picsum.photos/id/10/200/200",
162
+ "https://picsum.photos/id/20/200/200",
163
+ "https://picsum.photos/id/28/200/200",
164
+ "https://picsum.photos/id/29/200/200",
165
+ "https://picsum.photos/id/35/200/200",
166
+ "https://picsum.photos/id/40/200/200",
167
+ "https://picsum.photos/id/55/200/200",
168
+ "https://picsum.photos/id/60/200/200",
169
+ "https://picsum.photos/id/70/200/200"
170
+ ];
171
+ var ImageTrail = ({
172
+ images = defaultImages,
173
+ size = 100,
174
+ rotationRange = 15,
175
+ interval = 30,
176
+ // Default to fairly dense for smooth "train" effect
177
+ fadeDuration = 0.5,
178
+ className
179
+ }) => {
180
+ const [trail, setTrail] = useState([]);
181
+ const lastPosRef = useRef(null);
182
+ const indexRef = useRef(0);
183
+ const idCounterRef = useRef(0);
184
+ const containerRef = useRef(null);
185
+ useEffect(() => {
186
+ const cleanupInterval = setInterval(() => {
187
+ setTrail((prev) => {
188
+ return prev.filter((item) => Date.now() - item.created < fadeDuration * 1e3);
189
+ });
190
+ }, 100);
191
+ return () => clearInterval(cleanupInterval);
192
+ }, [fadeDuration]);
193
+ const handleMouseMove = (e) => {
194
+ if (!containerRef.current) return;
195
+ const rect = containerRef.current.getBoundingClientRect();
196
+ const x = e.clientX - rect.left;
197
+ const y = e.clientY - rect.top;
198
+ const currentPos = { x, y };
199
+ if (!lastPosRef.current) {
200
+ lastPosRef.current = currentPos;
201
+ return;
202
+ }
203
+ const dx = currentPos.x - lastPosRef.current.x;
204
+ const dy = currentPos.y - lastPosRef.current.y;
205
+ const distance = Math.sqrt(dx * dx + dy * dy);
206
+ if (distance > interval) {
207
+ const newImage = {
208
+ id: idCounterRef.current++,
209
+ created: Date.now(),
210
+ src: images[indexRef.current % images.length] || "",
211
+ x: currentPos.x,
212
+ y: currentPos.y,
213
+ rotation: Math.random() * (rotationRange * 2) - rotationRange
214
+ };
215
+ setTrail((prev) => [...prev, newImage]);
216
+ lastPosRef.current = currentPos;
217
+ indexRef.current++;
218
+ }
219
+ };
220
+ const handleMouseLeave = () => {
221
+ lastPosRef.current = null;
222
+ };
223
+ return /* @__PURE__ */ jsxs(
224
+ "div",
225
+ {
226
+ ref: containerRef,
227
+ className,
228
+ onMouseMove: handleMouseMove,
229
+ onMouseLeave: handleMouseLeave,
230
+ style: {
231
+ position: "relative",
232
+ width: "100%",
233
+ height: "100%",
234
+ minHeight: "400px",
235
+ overflow: "hidden",
236
+ background: "#111",
237
+ cursor: "none",
238
+ borderRadius: "12px"
239
+ },
240
+ children: [
241
+ /* @__PURE__ */ jsx("div", { style: {
242
+ pointerEvents: "none",
243
+ position: "absolute",
244
+ top: 0,
245
+ left: 0,
246
+ width: "100%",
247
+ height: "100%"
248
+ }, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "popLayout", children: trail.map((item) => /* @__PURE__ */ jsx(
249
+ motion.img,
250
+ {
251
+ src: item.src,
252
+ initial: {
253
+ opacity: 0,
254
+ scale: 0.8,
255
+ x: item.x - size / 2,
256
+ y: item.y - size / 2,
257
+ rotate: item.rotation
258
+ },
259
+ animate: {
260
+ opacity: 1,
261
+ scale: 1,
262
+ x: item.x - size / 2,
263
+ y: item.y - size / 2
264
+ },
265
+ exit: {
266
+ opacity: 0,
267
+ scale: 0.5,
268
+ transition: { duration: fadeDuration }
269
+ },
270
+ transition: { duration: 0.1 },
271
+ style: {
272
+ position: "absolute",
273
+ width: size,
274
+ height: size,
275
+ objectFit: "cover",
276
+ borderRadius: "8px",
277
+ boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
278
+ pointerEvents: "none",
279
+ left: 0,
280
+ top: 0
281
+ }
282
+ },
283
+ item.id
284
+ )) }) }),
285
+ /* @__PURE__ */ jsx("div", { style: {
286
+ position: "absolute",
287
+ top: "50%",
288
+ left: "50%",
289
+ transform: "translate(-50%, -50%)",
290
+ color: "#444",
291
+ pointerEvents: "none",
292
+ fontWeight: 500,
293
+ textAlign: "center"
294
+ }, children: "Hover to see trail" })
295
+ ]
296
+ }
297
+ );
298
+ };
299
+ var HoverFillButton = ({
300
+ label = "Hover Me",
301
+ direction = "left",
302
+ fillColor = "#e9590c",
303
+ textColor = "#ffffff",
304
+ hoverTextColor = "#ffffff",
305
+ padding = "12px 24px",
306
+ paddingHorizontal,
307
+ paddingVertical,
308
+ borderRadius = "50px",
309
+ backgroundColor = "#000000",
310
+ borderColor = "#000000",
311
+ style,
312
+ ...props
313
+ }) => {
314
+ const getInitialPosition = () => {
315
+ switch (direction) {
316
+ case "left":
317
+ return { x: "-100%", y: "0%" };
318
+ case "right":
319
+ return { x: "100%", y: "0%" };
320
+ case "top":
321
+ return { x: "0%", y: "-100%" };
322
+ case "bottom":
323
+ return { x: "0%", y: "100%" };
324
+ default:
325
+ return { x: "-100%", y: "0%" };
326
+ }
327
+ };
328
+ const finalPadding = paddingHorizontal || paddingVertical ? `${paddingVertical || "12px"} ${paddingHorizontal || "24px"}` : padding;
329
+ return /* @__PURE__ */ jsxs(
330
+ motion.button,
331
+ {
332
+ initial: "initial",
333
+ whileHover: "hover",
334
+ style: {
335
+ position: "relative",
336
+ padding: finalPadding,
337
+ background: backgroundColor,
338
+ border: `1px solid ${borderColor}`,
339
+ color: textColor,
340
+ borderRadius,
341
+ cursor: "pointer",
342
+ overflow: "hidden",
343
+ fontSize: "16px",
344
+ fontWeight: 500,
345
+ ...style
346
+ },
347
+ ...props,
348
+ children: [
349
+ /* @__PURE__ */ jsx(
350
+ motion.div,
351
+ {
352
+ variants: {
353
+ initial: getInitialPosition(),
354
+ hover: { x: "0%", y: "0%" }
355
+ },
356
+ transition: { duration: 0.3, ease: "easeInOut" },
357
+ style: {
358
+ position: "absolute",
359
+ top: 0,
360
+ left: 0,
361
+ right: 0,
362
+ bottom: 0,
363
+ background: fillColor,
364
+ zIndex: 0
365
+ }
366
+ },
367
+ direction
368
+ ),
369
+ /* @__PURE__ */ jsxs(
370
+ motion.span,
371
+ {
372
+ variants: {
373
+ initial: { color: textColor },
374
+ hover: { color: hoverTextColor }
375
+ },
376
+ transition: { duration: 0.2 },
377
+ style: {
378
+ position: "relative",
379
+ zIndex: 1,
380
+ display: "flex",
381
+ alignItems: "center",
382
+ gap: "12px",
383
+ lineHeight: 1
384
+ },
385
+ children: [
386
+ label,
387
+ /* @__PURE__ */ jsx("span", { style: {
388
+ display: "flex",
389
+ alignItems: "center",
390
+ justifyContent: "center",
391
+ width: "24px",
392
+ height: "24px",
393
+ borderRadius: "50%",
394
+ border: "2px solid currentColor",
395
+ // Increased thickness
396
+ fontSize: "16px"
397
+ // Slightly larger container for icon
398
+ }, children: /* @__PURE__ */ jsx(FiArrowRight, { strokeWidth: 3 }) })
399
+ ]
400
+ }
401
+ )
402
+ ]
403
+ }
404
+ );
405
+ };
406
+ var defaultImages2 = [
407
+ "/logos/Airbnb.png",
408
+ "/logos/Amazon.png",
409
+ "/logos/Apple.png",
410
+ "/logos/Bookmyshow.png",
411
+ "/logos/FedEx.png",
412
+ "/logos/Google.png",
413
+ "/logos/Microsoft.png",
414
+ "/logos/OLA.png",
415
+ "/logos/OYO.png",
416
+ "/logos/Walmart.png"
417
+ ];
418
+ var ImageMarquee = ({
419
+ images = defaultImages2,
420
+ direction = "left",
421
+ speed = 20,
422
+ gap = "2rem",
423
+ size = 60,
424
+ className
425
+ }) => {
426
+ return /* @__PURE__ */ jsxs(
427
+ "div",
428
+ {
429
+ className,
430
+ style: {
431
+ overflow: "hidden",
432
+ whiteSpace: "nowrap",
433
+ display: "flex",
434
+ width: "100%"
435
+ },
436
+ children: [
437
+ /* @__PURE__ */ jsx(MarqueeContent, { images, direction, speed, gap, size }),
438
+ /* @__PURE__ */ jsx(MarqueeContent, { images, direction, speed, gap, size }),
439
+ /* @__PURE__ */ jsx(MarqueeContent, { images, direction, speed, gap, size }),
440
+ /* @__PURE__ */ jsx(MarqueeContent, { images, direction, speed, gap, size })
441
+ ]
442
+ }
443
+ );
444
+ };
445
+ var MarqueeContent = ({ images, direction, speed, gap, size }) => {
446
+ return /* @__PURE__ */ jsx(
447
+ motion.div,
448
+ {
449
+ initial: { x: direction === "left" ? "0%" : "-100%" },
450
+ animate: { x: direction === "left" ? "-100%" : "0%" },
451
+ transition: {
452
+ duration: speed,
453
+ ease: "linear",
454
+ repeat: Infinity
455
+ },
456
+ style: {
457
+ display: "flex",
458
+ gap,
459
+ minWidth: "max-content",
460
+ flexShrink: 0,
461
+ alignItems: "center",
462
+ paddingRight: gap
463
+ // Ensure spacing at the end matches the gap for seamlessness
464
+ },
465
+ children: images.map((src, index) => /* @__PURE__ */ jsx(
466
+ "img",
467
+ {
468
+ src,
469
+ alt: `marquee-item-${index}`,
470
+ style: {
471
+ height: `${size}px`,
472
+ width: "auto",
473
+ objectFit: "contain",
474
+ borderRadius: "0px"
475
+ }
476
+ },
477
+ index
478
+ ))
479
+ },
480
+ `${direction}-${speed}`
481
+ );
482
+ };
483
+ var CircularText = ({
484
+ text = "SCROLL DOWN \u2022 SCROLL DOWN \u2022 ",
485
+ radius = 50,
486
+ fontSize = "12px",
487
+ iconSize = 24,
488
+ color = "#ffffff",
489
+ spinDuration = 10,
490
+ className
491
+ }) => {
492
+ const size = radius * 2 + 40;
493
+ return /* @__PURE__ */ jsxs(
494
+ "div",
495
+ {
496
+ className,
497
+ style: {
498
+ position: "relative",
499
+ width: size,
500
+ height: size,
501
+ display: "flex",
502
+ justifyContent: "center",
503
+ alignItems: "center"
504
+ },
505
+ children: [
506
+ /* @__PURE__ */ jsx(
507
+ motion.div,
508
+ {
509
+ animate: { rotate: 360 },
510
+ transition: {
511
+ duration: spinDuration,
512
+ repeat: Infinity,
513
+ ease: "linear"
514
+ },
515
+ style: {
516
+ width: "100%",
517
+ height: "100%",
518
+ position: "absolute",
519
+ top: 0,
520
+ left: 0
521
+ },
522
+ children: /* @__PURE__ */ jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: "100%", height: "100%", children: [
523
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
524
+ "path",
525
+ {
526
+ id: "circlePath",
527
+ d: `
528
+ M ${size / 2}, ${size / 2}
529
+ m -${radius}, 0
530
+ a ${radius},${radius} 0 1,1 ${radius * 2},0
531
+ a ${radius},${radius} 0 1,1 -${radius * 2},0
532
+ `
533
+ }
534
+ ) }),
535
+ /* @__PURE__ */ jsx("text", { fill: color, fontSize, fontWeight: "bold", letterSpacing: "2px", children: /* @__PURE__ */ jsx("textPath", { href: "#circlePath", startOffset: "0%", children: text }) })
536
+ ] })
537
+ }
538
+ ),
539
+ /* @__PURE__ */ jsx("div", { style: { position: "relative", color, display: "flex" }, children: /* @__PURE__ */ jsx(LuMouse, { size: iconSize }) })
540
+ ]
541
+ }
542
+ );
543
+ };
156
544
 
157
- export { CursorFollower };
545
+ export { CircularText, CursorFollower, HoverFillButton, ImageMarquee, ImageTrail };
158
546
  //# sourceMappingURL=index.mjs.map
159
547
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cursor/CursorFollower/CursorFollower.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { useLayoutEffect, useRef } from \"react\";\r\nimport gsap from \"gsap\";\r\n\r\nexport type CursorFollowerProps = {\r\n text?: string;\r\n\r\n size?: number;\r\n borderWidth?: number;\r\n borderColor?: string;\r\n background?: string;\r\n\r\n fontFamily?: string;\r\n fontSize?: number;\r\n fontWeight?: number | string;\r\n letterSpacing?: number;\r\n\r\n lerp?: number;\r\n showScale?: number;\r\n hideScale?: number;\r\n\r\n enabled?: boolean;\r\n blockSelectors?: string[];\r\n containerRef?: React.RefObject<HTMLElement>;\r\n};\r\n\r\nexport const CursorFollower = ({\r\n text = \"PLAY\",\r\n size = 90,\r\n borderWidth = 2,\r\n borderColor = \"#ffffff\",\r\n background = \"transparent\",\r\n\r\n fontFamily = \"inherit\",\r\n fontSize = 12,\r\n fontWeight = 400,\r\n letterSpacing = 2,\r\n\r\n lerp = 0.035,\r\n showScale = 1,\r\n hideScale = 0,\r\n\r\n enabled = true,\r\n blockSelectors = [\"button\", \"a\"],\r\n containerRef,\r\n}: CursorFollowerProps) => {\r\n const cursorRef = useRef<HTMLDivElement>(null);\r\n\r\n useLayoutEffect(() => {\r\n if (!enabled) return;\r\n\r\n const cursor = cursorRef.current;\r\n if (!cursor) return;\r\n\r\n let targetX = 0;\r\n let targetY = 0;\r\n let currentX = 0;\r\n let currentY = 0;\r\n let visible = false;\r\n let blocked = false;\r\n\r\n const show = () => {\r\n if (visible || blocked) return;\r\n visible = true;\r\n gsap.to(cursor, { scale: showScale, opacity: 1, duration: 0.25 });\r\n };\r\n\r\n const hide = () => {\r\n if (!visible) return;\r\n visible = false;\r\n gsap.to(cursor, { scale: hideScale, opacity: 0, duration: 0.25 });\r\n };\r\n\r\n const move = (e: MouseEvent) => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = e.clientX - bounds.left;\r\n targetY = e.clientY - bounds.top;\r\n } else {\r\n targetX = e.clientX;\r\n targetY = e.clientY;\r\n }\r\n\r\n // Ensure cursor is visible if it moves\r\n if (!visible && !blocked) {\r\n show();\r\n }\r\n };\r\n\r\n const update = () => {\r\n currentX += (targetX - currentX) * lerp;\r\n currentY += (targetY - currentY) * lerp;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2,\r\n });\r\n };\r\n\r\n // Event Listeners Source\r\n const target = containerRef?.current || window;\r\n\r\n target.addEventListener(\"mousemove\", move as any);\r\n target.addEventListener(\"mouseenter\", show as any);\r\n target.addEventListener(\"mouseleave\", hide as any);\r\n\r\n gsap.ticker.add(update);\r\n\r\n // Force initial visibility and positioning\r\n requestAnimationFrame(() => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = bounds.width / 2;\r\n targetY = bounds.height / 2;\r\n } else {\r\n targetX = window.innerWidth / 2;\r\n targetY = window.innerHeight / 2;\r\n }\r\n\r\n // Set current position immediately to avoid lerp from 0,0\r\n currentX = targetX;\r\n currentY = targetY;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2\r\n });\r\n\r\n show();\r\n });\r\n\r\n // Handle blocked selectors\r\n const cleanupFns: (() => void)[] = [];\r\n\r\n blockSelectors.forEach((selector) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach((el) => {\r\n const enter = () => {\r\n blocked = true;\r\n hide();\r\n };\r\n const leave = () => {\r\n blocked = false;\r\n show();\r\n };\r\n\r\n el.addEventListener(\"mouseenter\", enter);\r\n el.addEventListener(\"mouseleave\", leave);\r\n\r\n cleanupFns.push(() => {\r\n el.removeEventListener(\"mouseenter\", enter);\r\n el.removeEventListener(\"mouseleave\", leave);\r\n });\r\n });\r\n });\r\n\r\n return () => {\r\n target.removeEventListener(\"mousemove\", move as any);\r\n target.removeEventListener(\"mouseenter\", show as any);\r\n target.removeEventListener(\"mouseleave\", hide as any);\r\n gsap.ticker.remove(update);\r\n cleanupFns.forEach((fn) => fn());\r\n };\r\n }, [\r\n enabled,\r\n size,\r\n lerp,\r\n showScale,\r\n hideScale,\r\n // Stabilize dependency: only re-run if the joined string changes\r\n blockSelectors.join(\",\"),\r\n containerRef\r\n ]);\r\n\r\n if (!enabled) return null;\r\n\r\n return (\r\n <div\r\n ref={cursorRef}\r\n style={{\r\n position: containerRef ? \"absolute\" : \"fixed\",\r\n top: 0,\r\n left: 0,\r\n width: size,\r\n height: size,\r\n border: `${borderWidth}px solid ${borderColor}`,\r\n background,\r\n borderRadius: \"50%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n pointerEvents: \"none\",\r\n zIndex: 9999,\r\n opacity: 0,\r\n transform: \"scale(0)\",\r\n fontFamily,\r\n fontSize,\r\n fontWeight,\r\n letterSpacing,\r\n textTransform: \"uppercase\",\r\n color: borderColor,\r\n }}\r\n >\r\n {text}\r\n </div>\r\n );\r\n};\r\n"]}
1
+ {"version":3,"sources":["../src/cursor/CursorFollower/CursorFollower.tsx","../src/cursor/ImageTrail/ImageTrail.tsx","../src/Button/HoverFillButton/HoverFillButton.tsx","../src/Other/ImageMarquee/ImageMarquee.tsx","../src/Text/CircularText/CircularText.tsx"],"names":["useRef","jsx","jsxs","motion","defaultImages"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useLayoutEffect, useRef } from \"react\";\r\nimport gsap from \"gsap\";\r\n\r\nexport type CursorFollowerProps = {\r\n text?: string;\r\n\r\n size?: number;\r\n borderWidth?: number;\r\n borderColor?: string;\r\n background?: string;\r\n\r\n fontFamily?: string;\r\n fontSize?: number;\r\n fontWeight?: number | string;\r\n letterSpacing?: number;\r\n\r\n lerp?: number;\r\n showScale?: number;\r\n hideScale?: number;\r\n\r\n enabled?: boolean;\r\n blockSelectors?: string[];\r\n containerRef?: React.RefObject<HTMLElement>;\r\n};\r\n\r\nexport const CursorFollower = ({\r\n text = \"PLAY\",\r\n size = 90,\r\n borderWidth = 2,\r\n borderColor = \"#ffffff\",\r\n background = \"transparent\",\r\n\r\n fontFamily = \"inherit\",\r\n fontSize = 12,\r\n fontWeight = 400,\r\n letterSpacing = 2,\r\n\r\n lerp = 0.035,\r\n showScale = 1,\r\n hideScale = 0,\r\n\r\n enabled = true,\r\n blockSelectors = [\"button\", \"a\"],\r\n containerRef,\r\n}: CursorFollowerProps) => {\r\n const cursorRef = useRef<HTMLDivElement>(null);\r\n\r\n useLayoutEffect(() => {\r\n if (!enabled) return;\r\n\r\n const cursor = cursorRef.current;\r\n if (!cursor) return;\r\n\r\n let targetX = 0;\r\n let targetY = 0;\r\n let currentX = 0;\r\n let currentY = 0;\r\n let visible = false;\r\n let blocked = false;\r\n\r\n const show = () => {\r\n if (visible || blocked) return;\r\n visible = true;\r\n gsap.to(cursor, { scale: showScale, opacity: 1, duration: 0.25 });\r\n };\r\n\r\n const hide = () => {\r\n if (!visible) return;\r\n visible = false;\r\n gsap.to(cursor, { scale: hideScale, opacity: 0, duration: 0.25 });\r\n };\r\n\r\n const move = (e: MouseEvent) => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = e.clientX - bounds.left;\r\n targetY = e.clientY - bounds.top;\r\n } else {\r\n targetX = e.clientX;\r\n targetY = e.clientY;\r\n }\r\n\r\n // Ensure cursor is visible if it moves\r\n if (!visible && !blocked) {\r\n show();\r\n }\r\n };\r\n\r\n const update = () => {\r\n currentX += (targetX - currentX) * lerp;\r\n currentY += (targetY - currentY) * lerp;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2,\r\n });\r\n };\r\n\r\n // Event Listeners Source\r\n const target = containerRef?.current || window;\r\n\r\n target.addEventListener(\"mousemove\", move as any);\r\n target.addEventListener(\"mouseenter\", show as any);\r\n target.addEventListener(\"mouseleave\", hide as any);\r\n\r\n gsap.ticker.add(update);\r\n\r\n // Force initial visibility and positioning\r\n requestAnimationFrame(() => {\r\n if (containerRef?.current) {\r\n const bounds = containerRef.current.getBoundingClientRect();\r\n targetX = bounds.width / 2;\r\n targetY = bounds.height / 2;\r\n } else {\r\n targetX = window.innerWidth / 2;\r\n targetY = window.innerHeight / 2;\r\n }\r\n\r\n // Set current position immediately to avoid lerp from 0,0\r\n currentX = targetX;\r\n currentY = targetY;\r\n\r\n gsap.set(cursor, {\r\n x: currentX - size / 2,\r\n y: currentY - size / 2\r\n });\r\n\r\n show();\r\n });\r\n\r\n // Handle blocked selectors\r\n const cleanupFns: (() => void)[] = [];\r\n\r\n blockSelectors.forEach((selector) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach((el) => {\r\n const enter = () => {\r\n blocked = true;\r\n hide();\r\n };\r\n const leave = () => {\r\n blocked = false;\r\n show();\r\n };\r\n\r\n el.addEventListener(\"mouseenter\", enter);\r\n el.addEventListener(\"mouseleave\", leave);\r\n\r\n cleanupFns.push(() => {\r\n el.removeEventListener(\"mouseenter\", enter);\r\n el.removeEventListener(\"mouseleave\", leave);\r\n });\r\n });\r\n });\r\n\r\n return () => {\r\n target.removeEventListener(\"mousemove\", move as any);\r\n target.removeEventListener(\"mouseenter\", show as any);\r\n target.removeEventListener(\"mouseleave\", hide as any);\r\n gsap.ticker.remove(update);\r\n cleanupFns.forEach((fn) => fn());\r\n };\r\n }, [\r\n enabled,\r\n size,\r\n lerp,\r\n showScale,\r\n hideScale,\r\n // Stabilize dependency: only re-run if the joined string changes\r\n blockSelectors.join(\",\"),\r\n containerRef\r\n ]);\r\n\r\n if (!enabled) return null;\r\n\r\n return (\r\n <div\r\n ref={cursorRef}\r\n style={{\r\n position: containerRef ? \"absolute\" : \"fixed\",\r\n top: 0,\r\n left: 0,\r\n width: size,\r\n height: size,\r\n border: `${borderWidth}px solid ${borderColor}`,\r\n background,\r\n borderRadius: \"50%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n pointerEvents: \"none\",\r\n zIndex: 9999,\r\n opacity: 0,\r\n transform: \"scale(0)\",\r\n fontFamily,\r\n fontSize,\r\n fontWeight,\r\n letterSpacing,\r\n textTransform: \"uppercase\",\r\n color: borderColor,\r\n }}\r\n >\r\n {text}\r\n </div>\r\n );\r\n};\r\n","import React, { useRef, useState, useEffect } from 'react';\r\nimport { motion, AnimatePresence } from 'framer-motion';\r\n\r\nexport interface ImageTrailProps {\r\n images?: string[];\r\n size?: number;\r\n rotationRange?: number;\r\n interval?: number; // Distance in px required to spawn next image\r\n fadeDuration?: number;\r\n className?: string;\r\n}\r\n\r\nconst defaultImages = [\r\n \"https://picsum.photos/id/237/200/200\",\r\n \"https://picsum.photos/id/10/200/200\",\r\n \"https://picsum.photos/id/20/200/200\",\r\n \"https://picsum.photos/id/28/200/200\",\r\n \"https://picsum.photos/id/29/200/200\",\r\n \"https://picsum.photos/id/35/200/200\",\r\n \"https://picsum.photos/id/40/200/200\",\r\n \"https://picsum.photos/id/55/200/200\",\r\n \"https://picsum.photos/id/60/200/200\",\r\n \"https://picsum.photos/id/70/200/200\"\r\n];\r\n\r\ninterface TrailItem {\r\n id: number;\r\n src: string;\r\n x: number;\r\n y: number;\r\n rotation: number;\r\n}\r\n\r\nexport const ImageTrail: React.FC<ImageTrailProps> = ({\r\n images = defaultImages,\r\n size = 100,\r\n rotationRange = 15,\r\n interval = 30, // Default to fairly dense for smooth \"train\" effect\r\n fadeDuration = 0.5,\r\n className\r\n}) => {\r\n const [trail, setTrail] = useState<TrailItem[]>([]);\r\n const lastPosRef = useRef<{ x: number, y: number } | null>(null);\r\n const indexRef = useRef(0);\r\n const idCounterRef = useRef(0);\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n\r\n // Time-based cleanup\r\n useEffect(() => {\r\n const cleanupInterval = setInterval(() => {\r\n // Assuming IDs are roughly chronological if we used Date.now(), \r\n // but we switched to counter. \r\n // Actually, let's switch back to a safer cleanup that doesn't rely on ID being timestamp\r\n // BUT, for simplicity and since we want a \"fade out\" effect managed by AnimatePresence,\r\n // we really just need to trim the list if it gets too long, or let them expire.\r\n // Let's use a timestamp property for cleanup to be safe.\r\n setTrail(prev => {\r\n // If we want purely time-based expiration, we need a created timestamp.\r\n // However, simply limiting the valid set by time is tricky if we use counter IDs.\r\n // Let's rely on AnimatePresence for the visual fade, and just strictly limit count or use a parallel timestamp.\r\n // Reverting to the simpler \"limit count\" strategy might be more robust for now to avoid complexity,\r\n // but the user specifically asked for \"fade when stop\".\r\n // So let's add a 'created' field to the item state implicitly.\r\n // Actually, let's just use Date.now() for ID again but ensuring uniqueness?\r\n // No, let's stick to counter ID + created timestamp.\r\n return prev.filter(item => Date.now() - (item as any).created < fadeDuration * 1000);\r\n });\r\n }, 100);\r\n\r\n return () => clearInterval(cleanupInterval);\r\n }, [fadeDuration]);\r\n\r\n const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {\r\n if (!containerRef.current) return;\r\n\r\n const rect = containerRef.current.getBoundingClientRect();\r\n const x = e.clientX - rect.left;\r\n const y = e.clientY - rect.top;\r\n const currentPos = { x, y };\r\n\r\n if (!lastPosRef.current) {\r\n lastPosRef.current = currentPos;\r\n return;\r\n }\r\n\r\n const dx = currentPos.x - lastPosRef.current.x;\r\n const dy = currentPos.y - lastPosRef.current.y;\r\n const distance = Math.sqrt(dx * dx + dy * dy);\r\n\r\n // Spawn a new image if we've moved enough\r\n if (distance > interval) {\r\n const newImage: TrailItem & { created: number } = {\r\n id: idCounterRef.current++,\r\n created: Date.now(),\r\n src: images[indexRef.current % images.length] || \"\",\r\n x: currentPos.x,\r\n y: currentPos.y,\r\n rotation: Math.random() * (rotationRange * 2) - rotationRange\r\n };\r\n\r\n setTrail(prev => [...prev, newImage]);\r\n\r\n lastPosRef.current = currentPos;\r\n indexRef.current++;\r\n }\r\n };\r\n\r\n const handleMouseLeave = () => {\r\n lastPosRef.current = null; // Break the path trace\r\n };\r\n\r\n return (\r\n <div\r\n ref={containerRef}\r\n className={className}\r\n onMouseMove={handleMouseMove}\r\n onMouseLeave={handleMouseLeave}\r\n style={{\r\n position: 'relative',\r\n width: '100%',\r\n height: '100%',\r\n minHeight: '400px',\r\n overflow: 'hidden',\r\n background: '#111',\r\n cursor: 'none',\r\n borderRadius: '12px'\r\n }}\r\n >\r\n <div style={{\r\n pointerEvents: 'none',\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n width: '100%',\r\n height: '100%',\r\n }}>\r\n <AnimatePresence mode='popLayout'>\r\n {trail.map((item) => (\r\n <motion.img\r\n key={item.id}\r\n src={item.src}\r\n initial={{\r\n opacity: 0,\r\n scale: 0.8,\r\n x: item.x - size / 2,\r\n y: item.y - size / 2,\r\n rotate: item.rotation\r\n }}\r\n animate={{\r\n opacity: 1,\r\n scale: 1,\r\n x: item.x - size / 2,\r\n y: item.y - size / 2\r\n }}\r\n exit={{\r\n opacity: 0,\r\n scale: 0.5,\r\n transition: { duration: fadeDuration }\r\n }}\r\n transition={{ duration: 0.1 }}\r\n style={{\r\n position: 'absolute',\r\n width: size,\r\n height: size,\r\n objectFit: 'cover',\r\n borderRadius: '8px',\r\n boxShadow: '0 4px 12px rgba(0,0,0,0.3)',\r\n pointerEvents: 'none',\r\n left: 0,\r\n top: 0\r\n }}\r\n />\r\n ))}\r\n </AnimatePresence>\r\n </div>\r\n\r\n <div style={{\r\n position: 'absolute',\r\n top: '50%',\r\n left: '50%',\r\n transform: 'translate(-50%, -50%)',\r\n color: '#444',\r\n pointerEvents: 'none',\r\n fontWeight: 500,\r\n textAlign: 'center'\r\n }}>\r\n Hover to see trail\r\n </div>\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion, type HTMLMotionProps } from 'framer-motion';\r\nimport { FiArrowRight } from 'react-icons/fi';\r\n\r\nexport interface HoverFillButtonProps extends HTMLMotionProps<\"button\"> {\r\n label?: string;\r\n direction?: 'left' | 'right' | 'top' | 'bottom';\r\n fillColor?: string;\r\n textColor?: string;\r\n hoverTextColor?: string;\r\n padding?: string;\r\n paddingHorizontal?: string;\r\n paddingVertical?: string;\r\n borderRadius?: string;\r\n backgroundColor?: string;\r\n borderColor?: string;\r\n}\r\n\r\nexport const HoverFillButton: React.FC<HoverFillButtonProps> = ({\r\n label = 'Hover Me',\r\n direction = 'left',\r\n fillColor = '#e9590c',\r\n textColor = '#ffffff',\r\n hoverTextColor = '#ffffff',\r\n padding = '12px 24px',\r\n paddingHorizontal,\r\n paddingVertical,\r\n borderRadius = '50px',\r\n backgroundColor = '#000000',\r\n borderColor = '#000000',\r\n style,\r\n ...props\r\n}) => {\r\n // Determine initial position of the fill layer based on direction\r\n const getInitialPosition = () => {\r\n switch (direction) {\r\n case 'left': return { x: '-100%', y: '0%' };\r\n case 'right': return { x: '100%', y: '0%' };\r\n case 'top': return { x: '0%', y: '-100%' };\r\n case 'bottom': return { x: '0%', y: '100%' };\r\n default: return { x: '-100%', y: '0%' };\r\n }\r\n };\r\n\r\n // Construct final padding\r\n const finalPadding = (paddingHorizontal || paddingVertical)\r\n ? `${paddingVertical || '12px'} ${paddingHorizontal || '24px'}`\r\n : padding;\r\n\r\n return (\r\n <motion.button\r\n initial=\"initial\"\r\n whileHover=\"hover\"\r\n style={{\r\n position: 'relative',\r\n padding: finalPadding,\r\n background: backgroundColor,\r\n border: `1px solid ${borderColor}`,\r\n color: textColor,\r\n borderRadius,\r\n cursor: 'pointer',\r\n overflow: 'hidden',\r\n fontSize: '16px',\r\n fontWeight: 500,\r\n ...style\r\n }}\r\n {...props}\r\n >\r\n {/* Fill Layer */}\r\n <motion.div\r\n key={direction} // Force re-mount when direction changes to apply new initial state\r\n variants={{\r\n initial: getInitialPosition(),\r\n hover: { x: '0%', y: '0%' }\r\n }}\r\n transition={{ duration: 0.3, ease: 'easeInOut' }}\r\n style={{\r\n position: 'absolute',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n background: fillColor,\r\n zIndex: 0\r\n }}\r\n />\r\n\r\n {/* Text Layer - Needs to change color on hover? */}\r\n <motion.span\r\n variants={{\r\n initial: { color: textColor },\r\n hover: { color: hoverTextColor }\r\n }}\r\n transition={{ duration: 0.2 }}\r\n style={{\r\n position: 'relative',\r\n zIndex: 1,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '12px',\r\n lineHeight: 1\r\n }}\r\n >\r\n {label}\r\n\r\n {/* Arrow in Circle */}\r\n <span style={{\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: '24px',\r\n height: '24px',\r\n borderRadius: '50%',\r\n border: '2px solid currentColor', // Increased thickness\r\n fontSize: '16px' // Slightly larger container for icon\r\n }}>\r\n <FiArrowRight strokeWidth={3} />\r\n </span>\r\n </motion.span>\r\n </motion.button>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion } from 'framer-motion';\r\n\r\nexport interface ImageMarqueeProps {\r\n images?: string[];\r\n direction?: 'left' | 'right';\r\n speed?: number; // duration for one full loop\r\n gap?: string;\r\n size?: number;\r\n className?: string;\r\n}\r\n\r\nconst defaultImages = [\r\n \"/logos/Airbnb.png\",\r\n \"/logos/Amazon.png\",\r\n \"/logos/Apple.png\",\r\n \"/logos/Bookmyshow.png\",\r\n \"/logos/FedEx.png\",\r\n \"/logos/Google.png\",\r\n \"/logos/Microsoft.png\",\r\n \"/logos/OLA.png\",\r\n \"/logos/OYO.png\",\r\n \"/logos/Walmart.png\"\r\n];\r\n\r\nexport const ImageMarquee: React.FC<ImageMarqueeProps> = ({\r\n images = defaultImages,\r\n direction = 'left',\r\n speed = 20,\r\n gap = '2rem',\r\n size = 60,\r\n className\r\n}) => {\r\n // Determine the translation direction\r\n // For 'left', we move from 0 to -100% (partially) or similar math\r\n // A simple way for infinite marquee is to duplicate the content\r\n\r\n return (\r\n <div\r\n className={className}\r\n style={{\r\n overflow: 'hidden',\r\n whiteSpace: 'nowrap',\r\n display: 'flex',\r\n width: '100%'\r\n }}\r\n >\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n <MarqueeContent images={images} direction={direction} speed={speed} gap={gap} size={size} />\r\n </div>\r\n );\r\n};\r\n\r\nconst MarqueeContent = ({ images, direction, speed, gap, size }: { images: string[], direction: 'left' | 'right', speed: number, gap: string, size: number }) => {\r\n return (\r\n <motion.div\r\n key={`${direction}-${speed}`}\r\n initial={{ x: direction === 'left' ? \"0%\" : \"-100%\" }}\r\n animate={{ x: direction === 'left' ? \"-100%\" : \"0%\" }}\r\n transition={{\r\n duration: speed,\r\n ease: \"linear\",\r\n repeat: Infinity\r\n }}\r\n style={{\r\n display: 'flex',\r\n gap: gap,\r\n minWidth: 'max-content',\r\n flexShrink: 0,\r\n alignItems: 'center',\r\n paddingRight: gap // Ensure spacing at the end matches the gap for seamlessness\r\n }}\r\n >\r\n {images.map((src, index) => (\r\n <img\r\n key={index}\r\n src={src}\r\n alt={`marquee-item-${index}`}\r\n style={{\r\n height: `${size}px`,\r\n width: 'auto',\r\n objectFit: 'contain',\r\n borderRadius: '0px'\r\n }}\r\n />\r\n ))}\r\n </motion.div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport { motion } from 'framer-motion';\r\nimport { LuMouse } from 'react-icons/lu';\r\n\r\nexport interface CircularTextProps {\r\n text?: string;\r\n radius?: number;\r\n fontSize?: string;\r\n iconSize?: number;\r\n color?: string;\r\n spinDuration?: number;\r\n className?: string;\r\n}\r\n\r\nexport const CircularText: React.FC<CircularTextProps> = ({\r\n text = \"SCROLL DOWN • SCROLL DOWN • \",\r\n radius = 50,\r\n fontSize = \"12px\",\r\n iconSize = 24,\r\n color = \"#ffffff\",\r\n spinDuration = 10,\r\n className\r\n}) => {\r\n // Determine the circumference to space text properly if needed, \r\n // but textPath usually handles it well. \r\n // We'll use a viewBox that accommodates the radius.\r\n // Box size = (radius * 2) + padding for text height\r\n const size = radius * 2 + 40;\r\n\r\n return (\r\n <div\r\n className={className}\r\n style={{\r\n position: 'relative',\r\n width: size,\r\n height: size,\r\n display: 'flex',\r\n justifyContent: 'center',\r\n alignItems: 'center'\r\n }}\r\n >\r\n {/* Rotating Text Ring */}\r\n <motion.div\r\n animate={{ rotate: 360 }}\r\n transition={{\r\n duration: spinDuration,\r\n repeat: Infinity,\r\n ease: \"linear\"\r\n }}\r\n style={{\r\n width: '100%',\r\n height: '100%',\r\n position: 'absolute',\r\n top: 0,\r\n left: 0\r\n }}\r\n >\r\n <svg viewBox={`0 0 ${size} ${size}`} width=\"100%\" height=\"100%\">\r\n <defs>\r\n <path\r\n id=\"circlePath\"\r\n d={`\r\n M ${size / 2}, ${size / 2}\r\n m -${radius}, 0\r\n a ${radius},${radius} 0 1,1 ${radius * 2},0\r\n a ${radius},${radius} 0 1,1 -${radius * 2},0\r\n `}\r\n />\r\n </defs>\r\n <text fill={color} fontSize={fontSize} fontWeight=\"bold\" letterSpacing=\"2px\">\r\n <textPath href=\"#circlePath\" startOffset=\"0%\">\r\n {text}\r\n </textPath>\r\n </text>\r\n </svg>\r\n </motion.div>\r\n\r\n {/* Static Icon */}\r\n <div style={{ position: 'relative', color: color, display: 'flex' }}>\r\n <LuMouse size={iconSize} />\r\n </div>\r\n </div>\r\n );\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webenza/ui",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Internal UI and animation components for Webenza",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -31,17 +31,31 @@
31
31
  },
32
32
  "homepage": "https://github.com/tech-webenza/webenza-ui#readme",
33
33
  "peerDependencies": {
34
- "gsap": ">=3",
35
34
  "react": ">=18",
36
- "react-dom": ">=18"
35
+ "react-dom": ">=18",
36
+ "gsap": ">=3",
37
+ "react-icons": "^5",
38
+ "framer-motion": ">=10 <13"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "gsap": {
42
+ "optional": true
43
+ },
44
+ "react-icons": {
45
+ "optional": true
46
+ },
47
+ "framer-motion": {
48
+ "optional": true
49
+ }
37
50
  },
38
51
  "devDependencies": {
39
52
  "@types/react": "^19.2.10",
40
53
  "@types/react-dom": "^19.2.3",
41
54
  "tsup": "^8.5.1",
42
- "typescript": "^5.9.3"
55
+ "typescript": "^5.9.3",
56
+ "gsap": "^3.12.5",
57
+ "react-icons": "^5.4.0",
58
+ "framer-motion": "^11.16.0"
43
59
  },
44
- "dependencies": {
45
- "@webenza/ui": "^0.0.3"
46
- }
60
+ "dependencies": {}
47
61
  }