apex-ui-kit 2.0.7 → 2.1.1

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 (33) hide show
  1. package/dist/ApexUI-Kit/templates/AccordionMarquee/AccordionMarquee.jsx +74 -53
  2. package/dist/ApexUI-Kit/templates/BeamBar/BeamBar.jsx +5 -3
  3. package/dist/ApexUI-Kit/templates/BluePrintBackground/BluePrintBackground.jsx +14 -2
  4. package/dist/ApexUI-Kit/templates/CardStack/CardStack.jsx +56 -28
  5. package/dist/ApexUI-Kit/templates/Cards/BasicCard.jsx +3 -3
  6. package/dist/ApexUI-Kit/templates/DragCarousel/DragCarousel.jsx +1 -1
  7. package/dist/ApexUI-Kit/templates/EdgeGlowForm/EdgeGlowFrom.jsx +116 -98
  8. package/dist/ApexUI-Kit/templates/FlipProfile/FlipProfile.jsx +70 -37
  9. package/dist/ApexUI-Kit/templates/GlareCard/GlareCard.jsx +2 -2
  10. package/dist/ApexUI-Kit/templates/HoverText/HoverText.jsx +14 -13
  11. package/dist/ApexUI-Kit/templates/HyperCard/HyperCard.jsx +59 -42
  12. package/dist/ApexUI-Kit/templates/KineticThreadsBackground/KineticThreadBackground.jsx +17 -2
  13. package/dist/ApexUI-Kit/templates/LensFlareBackground/LensFlareBackground.jsx +18 -3
  14. package/dist/ApexUI-Kit/templates/LuminousParticleOcean/LuminousParticleOcean.jsx +15 -1
  15. package/dist/ApexUI-Kit/templates/MaskView/MaskView.jsx +345 -0
  16. package/dist/ApexUI-Kit/templates/MeteorCard/MeteorCard.jsx +34 -45
  17. package/dist/ApexUI-Kit/templates/NavDropDown/NavDropDown.jsx +272 -101
  18. package/dist/ApexUI-Kit/templates/NavMenu/NavMenu.jsx +8 -2
  19. package/dist/ApexUI-Kit/templates/OrbsBackground/FloatingOrbs.jsx +59 -59
  20. package/dist/ApexUI-Kit/templates/ParallaxCard/ParallaxCard.jsx +13 -11
  21. package/dist/ApexUI-Kit/templates/ParallaxCarousel/ParallaxCarousel.jsx +9 -9
  22. package/dist/ApexUI-Kit/templates/ParallaxProfile/ParallaxProfile.jsx +41 -38
  23. package/dist/ApexUI-Kit/templates/PointerFollower/PointerFollower.jsx +7 -7
  24. package/dist/ApexUI-Kit/templates/SmartGridCard/SmartGridCard.jsx +13 -11
  25. package/dist/ApexUI-Kit/templates/SmokeBackground/SmokeBackground.jsx +13 -2
  26. package/dist/ApexUI-Kit/templates/Testimonials/Testimonials.jsx +11 -8
  27. package/dist/ApexUI-Kit/templates/ThemeToggle/ThemeAnimation.js +40 -69
  28. package/dist/ApexUI-Kit/templates/ThemeToggle/ThemeToggle.css +1 -1
  29. package/dist/ApexUI-Kit/templates/ThemeToggle/ThemeToggle.jsx +25 -7
  30. package/dist/ApexUI-Kit/templates/ToolTip/ToolTip.jsx +71 -52
  31. package/dist/cli/index.js +24 -13
  32. package/package.json +2 -2
  33. package/dist/ApexUI-Kit/templates/WaterDropReveal/WaterDropReveal.jsx +0 -151
@@ -5,81 +5,100 @@ const ToolTip = ({ items }) => {
5
5
  const [hoveredIndex, setHoveredIndex] = useState(null);
6
6
  const tooltipRefs = useRef([]);
7
7
  const avatarRefs = useRef([]);
8
+ const last = items.length - 1;
8
9
 
9
10
  useEffect(() => {
10
- // Animate all avatars based on hover state
11
+ // Lift the active avatar, dim the others
11
12
  items.forEach((_, idx) => {
12
13
  const isHovered = hoveredIndex === idx;
13
-
14
- // Animate the avatar image
15
14
  gsap.to(avatarRefs.current[idx], {
16
- scale: isHovered ? 1.15 : 1,
17
- filter: isHovered ? "blur(0px)" : hoveredIndex !== null ? "blur(1.5px)" : "blur(0px)",
18
- duration: 0.25,
19
- ease: "power2.inOut",
15
+ y: isHovered ? -6 : 0,
16
+ scale: isHovered ? 1.12 : 1,
17
+ opacity: hoveredIndex === null || isHovered ? 1 : 0.55,
18
+ duration: 0.3,
19
+ ease: "power3.out",
20
20
  });
21
21
  });
22
22
 
23
- // Animate the tooltip for the hovered item
23
+ // Pop the tooltip in
24
24
  if (hoveredIndex !== null && tooltipRefs.current[hoveredIndex]) {
25
25
  gsap.fromTo(
26
26
  tooltipRefs.current[hoveredIndex],
27
- { opacity: 0, y: 10, scale: 0.8 },
28
- {
29
- opacity: 1,
30
- y: 0,
31
- scale: 1,
32
- duration: 0.4,
33
- ease: "power3.out",
34
- }
27
+ { opacity: 0, y: 12, scale: 0.85, rotate: 0 },
28
+ { opacity: 1, y: 0, scale: 1, duration: 0.45, ease: "back.out(1.8)" }
35
29
  );
36
30
  }
37
31
  }, [hoveredIndex, items]);
38
32
 
33
+ // The tooltip swings toward the pointer while it moves across the avatar.
34
+ const handlePointerMove = (e, idx) => {
35
+ const tip = tooltipRefs.current[idx];
36
+ if (!tip || e.pointerType !== "mouse") return;
37
+ const rect = e.currentTarget.getBoundingClientRect();
38
+ const offset = ((e.clientX - rect.left) / rect.width - 0.5) * 2; // -1 … 1
39
+ gsap.to(tip, { rotate: offset * 10, x: offset * 12, duration: 0.5, ease: "power3.out", overwrite: "auto" });
40
+ };
41
+
42
+ // Keep the end tooltips inside small screens: align them to their outer edge.
43
+ const placement = (idx) =>
44
+ idx === 0 && last > 0 ? { box: "left-0", arrow: "left-6" }
45
+ : idx === last && last > 0 ? { box: "right-0", arrow: "right-6" }
46
+ : { box: "left-1/2 -translate-x-1/2", arrow: "left-1/2 -translate-x-1/2" };
47
+
39
48
  return (
40
- <div className="flex items-end -space-x-4">
41
- {items.map((item, idx) => (
42
- <div
43
- key={item.name}
44
- onMouseEnter={() => setHoveredIndex(idx)}
45
- onMouseLeave={() => setHoveredIndex(null)}
46
- className="relative group cursor-pointer"
47
- style={{ zIndex: hoveredIndex === idx ? 50 : 10 }}
48
- >
49
- {hoveredIndex === idx && (
50
- <div
51
- ref={(el) => (tooltipRefs.current[idx] = el)}
52
- className="absolute bottom-full left-1/2 -translate-x-1/2 mb-3 z-50 flex flex-col items-center justify-center rounded-lg border border-teal-500/50 bg-gradient-to-br from-black/90 to-zinc-900/80 px-4 py-2 shadow-2xl backdrop-blur-md"
53
- >
54
- <div className="absolute bottom-[-6px] left-1/2 -translate-x-1/2 w-0 h-0 border-t-[8px] border-l-[8px] border-r-[8px] border-t-teal-500/40 border-l-transparent border-r-transparent" />
55
- <span className="text-sm font-bold text-teal-300 drop-shadow-sm whitespace-nowrap">
56
- {item.name}
57
- </span>
58
- <span className="text-xs text-zinc-300 italic whitespace-nowrap">
59
- {item.designation}
60
- </span>
49
+ <div className="flex items-end -space-x-3 sm:-space-x-4">
50
+ {items.map((item, idx) => {
51
+ const { box, arrow } = placement(idx);
52
+ return (
53
+ <div
54
+ key={item.id ?? item.name}
55
+ onPointerEnter={(e) => e.pointerType === "mouse" && setHoveredIndex(idx)}
56
+ onPointerLeave={(e) => e.pointerType === "mouse" && setHoveredIndex(null)}
57
+ onPointerMove={(e) => handlePointerMove(e, idx)}
58
+ // Tap to toggle on touch screens
59
+ onClick={() => setHoveredIndex((cur) => (cur === idx ? null : idx))}
60
+ className="relative cursor-pointer"
61
+ style={{ zIndex: hoveredIndex === idx ? 50 : 10 + idx }}
62
+ >
63
+ {hoveredIndex === idx && (
64
+ <div className={`pointer-events-none absolute bottom-full mb-4 z-50 ${box}`}>
65
+ {/* The card and its arrow animate together, so the arrow follows every swing. */}
66
+ <div ref={(el) => (tooltipRefs.current[idx] = el)} className="relative origin-bottom">
67
+ <div className="relative overflow-hidden rounded-xl border border-white/10 bg-zinc-950 px-3.5 py-2.5 shadow-[0_16px_40px_-12px_rgba(0,0,0,0.7)]">
68
+ <span className="absolute inset-x-3 top-0 h-px bg-gradient-to-r from-transparent via-lime-400 to-cyan-400" />
69
+ <span className="flex items-center gap-1.5 whitespace-nowrap text-sm font-semibold text-white">
70
+ <span className="h-1.5 w-1.5 rounded-full bg-lime-400 shadow-[0_0_8px_#a3e635]" />
71
+ {item.name}
72
+ </span>
73
+ <span className="mt-0.5 block whitespace-nowrap text-xs text-zinc-400">{item.designation}</span>
74
+ </div>
75
+ {/* Downward arrow: filled triangle that covers the card's bottom border, with the border on its two sides only */}
76
+ <svg width="16" height="8" viewBox="0 0 16 8" className={`absolute top-full -mt-px ${arrow}`} aria-hidden="true">
77
+ <path d="M0 0 L8 8 L16 0 Z" fill="#09090b" />
78
+ <path d="M0.5 0 L8 7.5 L15.5 0" fill="none" stroke="rgba(255,255,255,0.1)" />
79
+ </svg>
80
+ </div>
81
+ </div>
82
+ )}
83
+ <div ref={(el) => (avatarRefs.current[idx] = el)} className="rounded-full bg-gradient-to-br from-lime-400 via-emerald-400 to-cyan-400 p-[2px] shadow-lg shadow-black/30">
84
+ <img
85
+ src={item.image}
86
+ alt={item.name}
87
+ draggable="false"
88
+ className="h-12 w-12 sm:h-14 sm:w-14 rounded-full border-2 border-zinc-950 object-cover object-top"
89
+ />
61
90
  </div>
62
- )}
63
- <img
64
- ref={(el) => (avatarRefs.current[idx] = el)}
65
- src={item.image}
66
- alt={item.name}
67
- className="h-14 w-14 object-cover object-center rounded-full border-2 border-white shadow-lg transition-transform"
68
- style={{
69
- zIndex: hoveredIndex === idx ? 50 : 10,
70
- transition: "all 0.25s ease-in-out",
71
- }}
72
- />
73
- </div>
74
- ))}
91
+ </div>
92
+ );
93
+ })}
75
94
  </div>
76
95
  );
77
96
  };
78
97
 
79
98
  export default function ToolTipInner({ items }) {
80
99
  return (
81
- <div className="flex flex-row items-center justify-center">
100
+ <div className="flex flex-row items-center justify-center pt-24">
82
101
  <ToolTip items={items} />
83
102
  </div>
84
103
  );
85
- }
104
+ }
package/dist/cli/index.js CHANGED
@@ -9,7 +9,7 @@ import { execSync } from "child_process";
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
11
11
  const componentRoot = path.join(__dirname, "..", "ApexUI-Kit", "templates");
12
- // Component name map
12
+ // Component name map (CLI name -> folder in templates). Older names stay as aliases.
13
13
  const componentMap = {
14
14
  "avatar": "Avatar",
15
15
  "accordion-marquee": "AccordionMarquee",
@@ -19,10 +19,10 @@ const componentMap = {
19
19
  "parallax-carousel": "ParallaxCarousel",
20
20
  "drag-carousel": "DragCarousel",
21
21
  "basic-card": "Cards",
22
- "edge-glow-from": "EdgeGlowFrom",
22
+ "edge-glow-form": "EdgeGlowForm",
23
+ "edge-glow-from": "EdgeGlowForm",
23
24
  "glare-card": "GlareCard",
24
25
  "card-stack": "CardStack",
25
- "glass-profile": "GlassProfile",
26
26
  "hover-text": "HoverText",
27
27
  "hyper-card": "HyperCard",
28
28
  "kinetic-threads-background": "KineticThreadsBackground",
@@ -33,6 +33,7 @@ const componentMap = {
33
33
  "nav-dropdown": "NavDropDown",
34
34
  "orbs-background": "OrbsBackground",
35
35
  "pointer-follower": "PointerFollower",
36
+ "flip-profile": "FlipProfile",
36
37
  "flip-profiler": "FlipProfile",
37
38
  "parallax-profile": "ParallaxProfile",
38
39
  "parallax-card": "ParallaxCard",
@@ -41,10 +42,18 @@ const componentMap = {
41
42
  "scroll-marquee": "ScrollMarquee",
42
43
  "smart-grid-card": "SmartGridCard",
43
44
  "smoke-background": "SmokeBackground",
45
+ "tooltip": "ToolTip",
44
46
  "tool-tip": "ToolTip",
45
47
  "theme-toggle": "ThemeToggle",
46
48
  "testimonials": "Testimonials",
47
- "water-drop-reveal": "WaterDropReveal",
49
+ "mask-view": "MaskView",
50
+ "water-drop-reveal": "MaskView",
51
+ };
52
+ // Packages only some components need, installed on top of the shared ones.
53
+ const extraDeps = {
54
+ Cards: ["react-router-dom"],
55
+ LuminousParticleOcean: ["@react-three/fiber"],
56
+ SmokeBackground: ["ogl"],
48
57
  };
49
58
  async function main() {
50
59
  const args = process.argv.slice(2);
@@ -52,7 +61,7 @@ async function main() {
52
61
  const rawInput = args[1];
53
62
  if (command !== "add" || !rawInput) {
54
63
  console.log(chalk.yellow("Usage:"));
55
- console.log(" npx apex-ui-templete add <component-name>");
64
+ console.log(" npx apex-ui-kit add <component-name>");
56
65
  return;
57
66
  }
58
67
  const input = rawInput.toLowerCase();
@@ -60,7 +69,7 @@ async function main() {
60
69
  if (!matchedName) {
61
70
  console.log(chalk.red(`❌ Component '${rawInput}' not found in ApexUI-Kit.`));
62
71
  console.log(chalk.gray("👉 Available components:"));
63
- Object.values(componentMap).forEach((c) => console.log(` • ${c}`));
72
+ Object.keys(componentMap).forEach((c) => console.log(` • ${c}`));
64
73
  return;
65
74
  }
66
75
  // Validate package.json
@@ -74,7 +83,7 @@ async function main() {
74
83
  type: "text",
75
84
  name: "dirInput",
76
85
  message: "📁 Install in which folder? (use . for current)",
77
- initial: "."
86
+ initial: ".",
78
87
  });
79
88
  let basePath = "";
80
89
  if (dirInput.trim() === ".") {
@@ -84,8 +93,8 @@ async function main() {
84
93
  message: "📍 Are you currently inside the folder where ApexUI-Kit should be?",
85
94
  choices: [
86
95
  { title: "Yes (install here)", value: "yes" },
87
- { title: "No (I'll choose a path)", value: "no" }
88
- ]
96
+ { title: "No (I'll choose a path)", value: "no" },
97
+ ],
89
98
  });
90
99
  if (confirmInside === "yes") {
91
100
  basePath = process.cwd();
@@ -95,7 +104,7 @@ async function main() {
95
104
  type: "text",
96
105
  name: "targetPath",
97
106
  message: "📂 Enter target folder path (or use . for current)",
98
- initial: "."
107
+ initial: ".",
99
108
  });
100
109
  basePath = path.resolve(targetPath.trim());
101
110
  }
@@ -110,8 +119,8 @@ async function main() {
110
119
  message: "🧠 Choose language",
111
120
  choices: [
112
121
  { title: "JavaScript (JSX)", value: "jsx" },
113
- { title: "TypeScript (Coming Soon)", value: "ts", disabled: true }
114
- ]
122
+ { title: "TypeScript (Coming Soon)", value: "ts", disabled: true },
123
+ ],
115
124
  });
116
125
  // Install dependencies
117
126
  console.log(chalk.cyan("📦 Installing dependencies..."));
@@ -122,7 +131,9 @@ async function main() {
122
131
  "@fortawesome/fontawesome-svg-core",
123
132
  "@fortawesome/free-solid-svg-icons",
124
133
  "@fortawesome/react-fontawesome",
125
- "react-icons"
134
+ "react-icons",
135
+ "lucide-react",
136
+ ...(extraDeps[matchedName] ?? []),
126
137
  ];
127
138
  try {
128
139
  execSync(`npm install ${deps.join(" ")}`, { stdio: "inherit" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apex-ui-kit",
3
- "version": "2.0.7",
3
+ "version": "2.1.1",
4
4
  "license": "MIT",
5
5
  "description": "Apex UI Kit - A React component library for building modern user interfaces",
6
6
  "keywords": [
@@ -23,7 +23,7 @@
23
23
  "type": "module",
24
24
  "main": "dist/cli/index.js",
25
25
  "bin": {
26
- "apex-ui-kit": "./dist/cli/index.js"
26
+ "apex-ui-kit": "dist/cli/index.js"
27
27
  },
28
28
  "files": [
29
29
  "dist"
@@ -1,151 +0,0 @@
1
- import React, { useState, useRef, useEffect } from "react";
2
- import gsap from "gsap";
3
-
4
- const WaterDropReveal = ({
5
- text = "Discover the Water Drop Reveal Effect!\nMake your UI interactive, modern, and magical.\nHover to experience the reveal.",
6
- dropCount = 3,
7
- dropColor = "#a855f7",
8
- animationSpeed = 0.4,
9
- }) => {
10
- // Limit dropCount to max 10
11
- const safeDropCount = Math.min(Math.max(1, dropCount), 10);
12
- const [hovered, setHovered] = useState(false);
13
- const [mouse, setMouse] = useState({ x: 0.5, y: 0.5 });
14
- const dropRef = useRef(null);
15
- const textRef = useRef(null);
16
- const mouseAnim = useRef({ x: 0.5, y: 0.5 });
17
-
18
- useEffect(() => {
19
- if (!hovered) return;
20
- gsap.to(mouseAnim.current, {
21
- x: mouse.x,
22
- y: mouse.y,
23
- duration: animationSpeed,
24
- ease: "power2.out",
25
- onUpdate: () => {
26
- if (dropRef.current) {
27
- dropRef.current.setAttribute("data-x", mouseAnim.current.x);
28
- dropRef.current.setAttribute("data-y", mouseAnim.current.y);
29
- }
30
- if (textRef.current) {
31
- const xShift = (mouseAnim.current.x - 0.5) * 20;
32
- const yShift = (mouseAnim.current.y - 0.5) * 10;
33
- const rotateX = -(mouseAnim.current.y - 0.5) * 10;
34
- const rotateY = (mouseAnim.current.x - 0.5) * 15;
35
- gsap.to(textRef.current, {
36
- x: xShift,
37
- y: yShift,
38
- rotateX,
39
- rotateY,
40
- scale: 1.08,
41
- transformPerspective: 600,
42
- transformOrigin: "center",
43
- duration: animationSpeed,
44
- ease: "power3.out",
45
- });
46
- }
47
- },
48
- });
49
- }, [mouse, hovered, animationSpeed]);
50
-
51
- const handleMouseMove = (e) => {
52
- const rect = e.currentTarget.getBoundingClientRect();
53
- const x = (e.clientX - rect.left) / rect.width;
54
- const y = (e.clientY - rect.top) / rect.height;
55
- setMouse({ x, y });
56
- };
57
-
58
- const animX = hovered ? mouseAnim.current.x : 0.5;
59
- const animY = hovered ? mouseAnim.current.y : 0.5;
60
- const cx = 200 + (animX - 0.5) * 40;
61
- const cy = 80 + (animY - 0.5) * 20;
62
-
63
- return (
64
- <div
65
- className="relative w-full h-full rounded-2xl shadow-2xl flex items-center justify-center cursor-pointer overflow-hidden group border border-gray-800 transition-all duration-300"
66
- onMouseEnter={() => setHovered(true)}
67
- onMouseLeave={() => {
68
- setHovered(false);
69
- gsap.to(textRef.current, {
70
- x: 0,
71
- y: 0,
72
- rotateX: 0,
73
- rotateY: 0,
74
- scale: 1,
75
- duration: 0.6,
76
- ease: "power2.out",
77
- });
78
- }}
79
- onMouseMove={handleMouseMove}
80
- style={{ minHeight: 260 }}
81
- >
82
- {/* Water Drop Layer */}
83
- <div
84
- ref={dropRef}
85
- className={`pointer-events-none absolute left-1/2 top-1/2 z-10 -translate-x-1/2 -translate-y-1/2 transition-opacity duration-700 ${hovered ? "opacity-100" : "opacity-0"}`}
86
- style={{ width: "100%", height: "100%" }}
87
- >
88
- <svg width="100%" height="100%" viewBox="0 0 400 160" preserveAspectRatio="xMidYMid slice">
89
- <defs>
90
- <filter id="drop-shadow" x="-30%" y="-30%" width="160%" height="160%">
91
- <feDropShadow dx="0" dy="6" stdDeviation="18" flood-color="black" flood-opacity="60" />
92
- </filter>
93
- </defs>
94
- {(() => {
95
- // Dynamic radii and opacities for unique drops
96
- const maxRadius = 160;
97
- const minRadius = 36;
98
- const maxOpacity = 0.7;
99
- const minOpacity = 0.18;
100
- const step = safeDropCount > 1 ? (maxRadius - minRadius) / (safeDropCount - 1) : 0;
101
- const opacityStep = safeDropCount > 1 ? (maxOpacity - minOpacity) / (safeDropCount - 1) : 0;
102
- return [...Array(safeDropCount)].map((_, i) => {
103
- const r = Math.round(maxRadius - i * step);
104
- const opacity = +(maxOpacity - i * opacityStep).toFixed(2);
105
- return (
106
- <circle
107
- key={i}
108
- cx={cx}
109
- cy={cy}
110
- r={hovered ? r : 0}
111
- fill={dropColor}
112
- fillOpacity={hovered ? opacity : 0}
113
- style={{ transition: `r 0.7s, fill-opacity 0.7s` }}
114
- filter="url(#drop-shadow)"
115
- />
116
- );
117
- });
118
- })()}
119
- </svg>
120
- </div>
121
-
122
- {/* Text Reveal with 3D */}
123
- <span
124
- ref={textRef}
125
- className={`absolute whitespace-break-spaces z-20 max-sm:text-xl text-4xl font-semibold tracking-wide select-none transition-opacity duration-700 text-center w-full px-4 ${hovered ? "blur-0 opacity-100" : "text-gray-400 blur-sm opacity-60"}`}
126
- style={{
127
- left: 0,
128
- letterSpacing: 0,
129
- willChange: "transform",
130
- background: hovered ? "linear-gradient(90deg, #fff, #38bdf8, #fff)" : undefined,
131
- WebkitBackgroundClip: hovered ? "text" : undefined,
132
- WebkitTextFillColor: hovered ? "transparent" : undefined,
133
- backgroundClip: hovered ? "text" : undefined,
134
- color: hovered ? undefined : undefined,
135
- fontFamily: "Bitcount Prop Double, system-ui",
136
- }}
137
- >
138
- {text}
139
- </span>
140
-
141
- {/* Hover Hint */}
142
- {!hovered && (
143
- <span className="absolute bottom-4 left-1/2 -translate-x-1/2 z-30 text-xs sm:text-sm text-white bg-black/40 px-3 py-1 rounded-full shadow-md animate-pulse pointer-events-none select-none">
144
- Hover to reveal
145
- </span>
146
- )}
147
- </div>
148
- );
149
- };
150
-
151
- export default WaterDropReveal;