apex-ui-kit 2.0.5 → 2.0.6
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/dist/ApexUI-Kit/templates/AccordionMarquee/AccordionMarquee.css +1 -0
- package/dist/ApexUI-Kit/templates/AccordionMarquee/AccordionMarquee.jsx +140 -0
- package/dist/ApexUI-Kit/templates/BluePrintBackground/BluePrintBackground.jsx +133 -0
- package/dist/ApexUI-Kit/templates/MeteorCard/MeteorCard.css +95 -0
- package/dist/ApexUI-Kit/templates/MeteorCard/MeteorCard.jsx +93 -0
- package/dist/cli/index.js +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Righteous&display=swap");
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import React, { useLayoutEffect, useRef } from 'react';
|
|
2
|
+
// GSAP ko seedhe CDN se import kiya gaya hai taaki yeh browser mein chale
|
|
3
|
+
import gsap from "gsap";
|
|
4
|
+
import './AccordionMarquee.css'
|
|
5
|
+
// Accordion ka data
|
|
6
|
+
const accordionData = [
|
|
7
|
+
{
|
|
8
|
+
title: "Cybernetic Dreams",
|
|
9
|
+
text: "Explore the Future",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
title: "Quantum Leap",
|
|
13
|
+
text: "Journey Through Spacetime",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: "Neural Networks",
|
|
17
|
+
text: "Unravel Complexity",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: "Digital Odyssey",
|
|
21
|
+
text: "Voyage into the Digital World",
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const AccordionMarquee = ({bgColor='#bbf451', textColor='#27272a'}) => {
|
|
26
|
+
const containerRef = useRef(null);
|
|
27
|
+
|
|
28
|
+
useLayoutEffect(() => {
|
|
29
|
+
const items = gsap.utils.toArray(".accordion-item");
|
|
30
|
+
let activeItem = null;
|
|
31
|
+
let activeMarquee = null;
|
|
32
|
+
|
|
33
|
+
items.forEach((item) => {
|
|
34
|
+
const marqueeText = item.querySelector(".marquee-text");
|
|
35
|
+
const title = item.querySelector(".accordion-title");
|
|
36
|
+
|
|
37
|
+
// Marquee text ko 2 baar duplicate karte hain for seamless loop
|
|
38
|
+
const marqueeContent = marqueeText.innerText;
|
|
39
|
+
const sparkleIconSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="100" height="70" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sparkle-icon lucide-sparkle"><path d="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z" class="sparkle-icon"/></svg>`;
|
|
40
|
+
marqueeText.innerHTML = [marqueeContent, sparkleIconSVG, marqueeContent, sparkleIconSVG, marqueeContent, sparkleIconSVG, marqueeContent, sparkleIconSVG].join("");
|
|
41
|
+
|
|
42
|
+
// Seamless Marquee animation
|
|
43
|
+
const marqueeWidth = marqueeText.scrollWidth / 2;
|
|
44
|
+
const marqueeTl = gsap.to(marqueeText, {
|
|
45
|
+
x: -marqueeWidth,
|
|
46
|
+
duration: marqueeWidth / 30, // Speed ko consistent rakhta hai
|
|
47
|
+
ease: "linear",
|
|
48
|
+
repeat: -1,
|
|
49
|
+
}).pause();
|
|
50
|
+
|
|
51
|
+
item.addEventListener("mouseenter", () => {
|
|
52
|
+
if (activeItem === item) return;
|
|
53
|
+
|
|
54
|
+
if (activeItem) {
|
|
55
|
+
const oldTitle = activeItem.querySelector(".accordion-title");
|
|
56
|
+
const oldMarqueeWrapper = activeItem.querySelector(".marquee-wrapper");
|
|
57
|
+
gsap.to(oldTitle, { autoAlpha: 1, duration: 0.2, ease: "power3.inOut" });
|
|
58
|
+
gsap.to(oldMarqueeWrapper, { autoAlpha: 0, duration: 0.2, ease: "power3.inOut" });
|
|
59
|
+
if (activeMarquee) activeMarquee.pause();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
activeItem = item;
|
|
63
|
+
activeMarquee = marqueeTl;
|
|
64
|
+
|
|
65
|
+
const marqueeWrapper = item.querySelector(".marquee-wrapper");
|
|
66
|
+
gsap.to(title, { autoAlpha: 0, duration: 0.2, ease: "power3.inOut" });
|
|
67
|
+
gsap.to(marqueeWrapper, { autoAlpha: 1, duration: 0.2, delay: 0.1, ease: "power3.inOut" });
|
|
68
|
+
|
|
69
|
+
marqueeTl.play();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
containerRef.current.addEventListener("mouseleave", () => {
|
|
74
|
+
if (!activeItem) return;
|
|
75
|
+
|
|
76
|
+
const activeTitle = activeItem.querySelector(".accordion-title");
|
|
77
|
+
const activeMarqueeWrapper = activeItem.querySelector(".marquee-wrapper");
|
|
78
|
+
|
|
79
|
+
gsap.to(activeTitle, { autoAlpha: 1, duration: 0.2, delay: 0.1, ease: "power3.inOut" });
|
|
80
|
+
gsap.to(activeMarqueeWrapper, { autoAlpha: 0, duration: 0.2, ease: "power3.inOut" });
|
|
81
|
+
|
|
82
|
+
if (activeMarquee) {
|
|
83
|
+
activeMarquee.pause();
|
|
84
|
+
}
|
|
85
|
+
activeItem = null;
|
|
86
|
+
activeMarquee = null;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
}, []);
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<>
|
|
93
|
+
<style>
|
|
94
|
+
{`
|
|
95
|
+
@keyframes sparkle-pulse {
|
|
96
|
+
0%, 100% {
|
|
97
|
+
stroke: #000;
|
|
98
|
+
stroke-width: 0.5;
|
|
99
|
+
}
|
|
100
|
+
50% {
|
|
101
|
+
stroke: #444;
|
|
102
|
+
stroke-width: 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
.sparkle-icon {
|
|
106
|
+
animation: sparkle-pulse 2.5s ease-in-out infinite;
|
|
107
|
+
}
|
|
108
|
+
`}
|
|
109
|
+
</style>
|
|
110
|
+
<div className="flex items-center justify-center w-screen bg-gray-900 text-white font-sans">
|
|
111
|
+
<div ref={containerRef} className="flex flex-col w-full h-[80vh] md:h-[70vh]">
|
|
112
|
+
{accordionData.map((item, index) => (
|
|
113
|
+
<React.Fragment key={index}>
|
|
114
|
+
<div className="accordion-item relative w-full h-40 overflow-hidden cursor-pointer flex items-center justify-center bg-gray-800">
|
|
115
|
+
<div className="relative z-10 w-full text-center px-4">
|
|
116
|
+
<h2 className="accordion-title text-2xl sm:text-3xl lg:text-5xl font-extrabold uppercase tracking-wider whitespace-nowrap" style={{ textShadow: '2px 2px 8px rgba(0,0,0,0.7)' }}>
|
|
117
|
+
{item.title}
|
|
118
|
+
</h2>
|
|
119
|
+
<div className="marquee-wrapper absolute inset-0 w-full h-20 flex items-center overflow-hidden opacity-0" style={{backgroundColor: bgColor}}>
|
|
120
|
+
<p className="marquee-text text-4xl sm:text-5xl md:text-6xl font-bold whitespace-nowrap flex items-center"
|
|
121
|
+
style={{ textShadow: '1px 1px 3px rgba(0,0,0,0.2)', fontFamily: "Righteous, sans-serif", color: textColor }}
|
|
122
|
+
>
|
|
123
|
+
{item.text}
|
|
124
|
+
</p>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
{index < accordionData.length - 1 && (
|
|
129
|
+
<hr className="w-full border-t-2 border-gray-700 my-0" />
|
|
130
|
+
)}
|
|
131
|
+
</React.Fragment>
|
|
132
|
+
))}
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default AccordionMarquee;
|
|
140
|
+
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React, { useRef, useEffect, useState } from "react";
|
|
2
|
+
import { gsap } from "gsap";
|
|
3
|
+
|
|
4
|
+
function BluePrintBackground({ color = '#9ae600', borderColor = 'rgb(98, 116, 142, 0.1)', bgColor, circleColor = 'rgb(154, 230, 0, 0.2)'}) {
|
|
5
|
+
const gridRef = useRef(null);
|
|
6
|
+
const [grid, setGrid] = useState({ cols: 0, rows: 0 });
|
|
7
|
+
const boxSize = 40;
|
|
8
|
+
const lastHighlighted = useRef(null);
|
|
9
|
+
const colorRef = useRef(color);
|
|
10
|
+
|
|
11
|
+
// Effect 1: calculate grid size and keep it updated on resize
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const calculateGrid = () => {
|
|
14
|
+
const cols = Math.ceil(window.innerWidth / boxSize);
|
|
15
|
+
const rows = Math.ceil(window.innerHeight / boxSize) * 2; // double rows for infinite scroll
|
|
16
|
+
// kill any child tweens before we replace children to avoid visual flicker
|
|
17
|
+
const el = gridRef.current;
|
|
18
|
+
if (el) {
|
|
19
|
+
try { gsap.killTweensOf(el); } catch { /* ignore */ }
|
|
20
|
+
Array.from(el.children).forEach((c) => { try { gsap.killTweensOf(c); } catch { /* ignore */ } });
|
|
21
|
+
lastHighlighted.current = null;
|
|
22
|
+
}
|
|
23
|
+
setGrid({ cols, rows });
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
calculateGrid();
|
|
27
|
+
window.addEventListener("resize", calculateGrid);
|
|
28
|
+
return () => window.removeEventListener("resize", calculateGrid);
|
|
29
|
+
}, []);
|
|
30
|
+
|
|
31
|
+
// keep colorRef up-to-date without forcing effect re-run
|
|
32
|
+
useEffect(() => { colorRef.current = color; }, [color]);
|
|
33
|
+
|
|
34
|
+
// Effect 2: initialize GSAP infinite scroll and mouse handlers once (do not recreate on grid changes)
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const el = gridRef.current;
|
|
37
|
+
let scrollTween = null;
|
|
38
|
+
|
|
39
|
+
if (el) {
|
|
40
|
+
// make sure we start from current transform so GSAP doesn't jump
|
|
41
|
+
// create a looping tween on the container only once
|
|
42
|
+
scrollTween = gsap.to(el, {
|
|
43
|
+
y: "-50%",
|
|
44
|
+
duration: 15,
|
|
45
|
+
repeat: -1,
|
|
46
|
+
ease: "linear",
|
|
47
|
+
overwrite: false,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const handleMouseMove = (e) => {
|
|
52
|
+
const el2 = gridRef.current;
|
|
53
|
+
if (!el2) return;
|
|
54
|
+
|
|
55
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
56
|
+
if (!target || !el2.contains(target)) {
|
|
57
|
+
if (lastHighlighted.current !== null) {
|
|
58
|
+
const prev = el2.children[lastHighlighted.current];
|
|
59
|
+
if (prev) gsap.to(prev, { backgroundColor: "transparent", boxShadow: "none", duration: 0.18 });
|
|
60
|
+
lastHighlighted.current = null;
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const child = target.closest("div");
|
|
66
|
+
const index = Array.prototype.indexOf.call(el2.children, child);
|
|
67
|
+
if (index === -1) return;
|
|
68
|
+
|
|
69
|
+
if (lastHighlighted.current !== index) {
|
|
70
|
+
if (lastHighlighted.current !== null) {
|
|
71
|
+
const prevBox = el2.children[lastHighlighted.current];
|
|
72
|
+
if (prevBox) gsap.to(prevBox, { backgroundColor: "transparent", boxShadow: "none", duration: 0.18 });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const newBox = el2.children[index];
|
|
76
|
+
if (newBox) {
|
|
77
|
+
const c = colorRef.current || "#a3e635";
|
|
78
|
+
gsap.to(newBox, { backgroundColor: c, boxShadow: `0 0 12px ${c}`, duration: 0.12 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
lastHighlighted.current = index;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
86
|
+
|
|
87
|
+
return () => {
|
|
88
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
89
|
+
if (scrollTween && typeof scrollTween.kill === "function") {
|
|
90
|
+
try { scrollTween.kill(); } catch { /* ignore */ }
|
|
91
|
+
}
|
|
92
|
+
if (el) {
|
|
93
|
+
try { gsap.killTweensOf(el); } catch { /* ignore */ }
|
|
94
|
+
Array.from(el.children).forEach((c) => { try { gsap.killTweensOf(c); } catch { /* ignore */ } });
|
|
95
|
+
}
|
|
96
|
+
lastHighlighted.current = null;
|
|
97
|
+
};
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
const total = grid.cols * grid.rows;
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div className="absolute inset-0 z-0 w-full h-full overflow-hidden bg-slate-800" style={{ backgroundColor: `${bgColor}` }}>
|
|
104
|
+
<div
|
|
105
|
+
ref={gridRef}
|
|
106
|
+
className="grid"
|
|
107
|
+
style={{
|
|
108
|
+
gridTemplateColumns: `repeat(${grid.cols}, ${boxSize}px)`,
|
|
109
|
+
gridTemplateRows: `repeat(${grid.rows}, ${boxSize}px)`,
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
{Array.from({ length: total }).map((_, i) => (
|
|
113
|
+
<div
|
|
114
|
+
key={i}
|
|
115
|
+
className={`border bg-transparent w-10 h-10`}
|
|
116
|
+
style={{
|
|
117
|
+
borderColor: borderColor
|
|
118
|
+
}}
|
|
119
|
+
/>
|
|
120
|
+
))}
|
|
121
|
+
</div>
|
|
122
|
+
{/* Spotlight overlay - positioned after grid to not interfere with scroll */}
|
|
123
|
+
<div
|
|
124
|
+
className="absolute inset-0 z-10 pointer-events-none blur-3xl"
|
|
125
|
+
style={{
|
|
126
|
+
background: `radial-gradient(circle, ${circleColor} 0%, rgba(0, 0, 255, 0.1) 100%)`
|
|
127
|
+
}}
|
|
128
|
+
/>
|
|
129
|
+
</div >
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default BluePrintBackground;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
.meteor-bg {
|
|
2
|
+
position: absolute;
|
|
3
|
+
width: 2px;
|
|
4
|
+
height: 80px;
|
|
5
|
+
background: linear-gradient(to top, #fff, transparent); /* This line to change the meteor's tail color */
|
|
6
|
+
animation: meteor-fall-bg linear infinite;
|
|
7
|
+
opacity: 0;
|
|
8
|
+
transform: rotate(-45deg);
|
|
9
|
+
}
|
|
10
|
+
/* Meteor ka head (glowing circle) */
|
|
11
|
+
.meteor-bg::before {
|
|
12
|
+
content: "";
|
|
13
|
+
position: absolute;
|
|
14
|
+
bottom: -3px;
|
|
15
|
+
left: 50%;
|
|
16
|
+
transform: translateX(-50%);
|
|
17
|
+
width: 6px;
|
|
18
|
+
height: 6px;
|
|
19
|
+
background-color: #fff; /* This line to change the meteor's head color */
|
|
20
|
+
border-radius: 50%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@keyframes meteor-fall-bg {
|
|
24
|
+
0% {
|
|
25
|
+
transform: translateX(-200px) translateY(-200px) rotate(-45deg);
|
|
26
|
+
opacity: 1;
|
|
27
|
+
}
|
|
28
|
+
100% {
|
|
29
|
+
transform: translateX(500px) translateY(500px) rotate(-45deg);
|
|
30
|
+
opacity: 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Particle Styles */
|
|
35
|
+
.particle-bg {
|
|
36
|
+
position: absolute;
|
|
37
|
+
width: 3px;
|
|
38
|
+
height: 3px;
|
|
39
|
+
background-color: var(--particle-color);
|
|
40
|
+
border-radius: 50%;
|
|
41
|
+
box-shadow: 0 0 8px var(--particle-color), 0 0 12px var(--particle-color);
|
|
42
|
+
animation: particle-float linear infinite;
|
|
43
|
+
opacity: 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@keyframes particle-float {
|
|
47
|
+
0%,
|
|
48
|
+
100% {
|
|
49
|
+
opacity: 0;
|
|
50
|
+
transform: translateY(0px);
|
|
51
|
+
}
|
|
52
|
+
50% {
|
|
53
|
+
opacity: 1;
|
|
54
|
+
transform: translateY(-20px);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Moving Border */
|
|
59
|
+
.moving-border-card {
|
|
60
|
+
position: relative;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.moving-border-card::before {
|
|
65
|
+
content: "";
|
|
66
|
+
position: absolute;
|
|
67
|
+
top: -50%;
|
|
68
|
+
left: -50%;
|
|
69
|
+
width: 200%;
|
|
70
|
+
height: 200%;
|
|
71
|
+
background: conic-gradient(
|
|
72
|
+
from var(--angle),
|
|
73
|
+
transparent 0deg 90deg,
|
|
74
|
+
rgb(0, 132, 209, 0.5) 180deg,
|
|
75
|
+
/* Sky Blue */ transparent 180deg 270deg,
|
|
76
|
+
rgb(0, 132, 209, 0.5) 360deg
|
|
77
|
+
);
|
|
78
|
+
animation: rotate 6s linear infinite;
|
|
79
|
+
z-index: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@property --angle {
|
|
83
|
+
syntax: "<angle>";
|
|
84
|
+
initial-value: 0deg;
|
|
85
|
+
inherits: false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@keyframes rotate {
|
|
89
|
+
from {
|
|
90
|
+
--angle: 0deg;
|
|
91
|
+
}
|
|
92
|
+
to {
|
|
93
|
+
--angle: 360deg;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import './MeteorCard.css';
|
|
3
|
+
const ArrowRightIcon = () => (
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
|
|
5
|
+
viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
6
|
+
strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
|
|
7
|
+
className="ml-2 h-5 w-5 transition-transform duration-300 ease-in-out group-hover:translate-x-1">
|
|
8
|
+
<line x1="5" y1="12" x2="19" y2="12" />
|
|
9
|
+
<polyline points="12 5 19 12 12 19" />
|
|
10
|
+
</svg>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
// Meteor Effect Component
|
|
14
|
+
const Meteors = ({ number = 20 }) => {
|
|
15
|
+
const meteors = [...Array(number)].map((_, i) => (
|
|
16
|
+
<span
|
|
17
|
+
key={i}
|
|
18
|
+
className="meteor-bg"
|
|
19
|
+
style={{
|
|
20
|
+
top: `${Math.random() * 100}%`,
|
|
21
|
+
left: `${Math.random() * 100}%`,
|
|
22
|
+
animationDelay: `${Math.random() * 8}s`,
|
|
23
|
+
animationDuration: `${Math.floor(Math.random() * 6) + 4}s`,
|
|
24
|
+
}}
|
|
25
|
+
></span>
|
|
26
|
+
));
|
|
27
|
+
return <>{meteors}</>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// Particle Effect Component
|
|
31
|
+
const Particles = ({ number = 50, color = '#ffffff', speed = 1 }) => {
|
|
32
|
+
const particles = [...Array(number)].map((_, i) => {
|
|
33
|
+
const animationDuration = (Math.random() * 5 + 3) / speed;
|
|
34
|
+
return (
|
|
35
|
+
<span
|
|
36
|
+
key={i}
|
|
37
|
+
className="particle-bg"
|
|
38
|
+
style={{
|
|
39
|
+
'--particle-color': color,
|
|
40
|
+
top: `${Math.random() * 100}%`,
|
|
41
|
+
left: `${Math.random() * 100}%`,
|
|
42
|
+
animationDelay: `${Math.random() * animationDuration}s`,
|
|
43
|
+
animationDuration: `${animationDuration}s`,
|
|
44
|
+
}}
|
|
45
|
+
></span>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
return <>{particles}</>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Main MeteorCard Component
|
|
52
|
+
const MeteorCard = ({ data, particleNumber, particleColor, particleSpeed }) => {
|
|
53
|
+
return (
|
|
54
|
+
<>
|
|
55
|
+
{data.map((item, index) => (
|
|
56
|
+
<div key={index} className="relative w-full lg:w-[30vw] max-w-4xl mx-auto bg-slate-800/80 p-0.5 rounded-lg moving-border-card">
|
|
57
|
+
{/* Card ka content container */}
|
|
58
|
+
<div className="relative bg-slate-900 rounded-lg p-4 md:p-8 flex flex-col md:flex-row items-center gap-6 md:gap-8 overflow-hidden">
|
|
59
|
+
{/* Background Effects */}
|
|
60
|
+
<div className="absolute inset-0 w-full h-full z-0">
|
|
61
|
+
<Meteors number={5} />
|
|
62
|
+
<Particles
|
|
63
|
+
number={particleNumber}
|
|
64
|
+
color={particleColor}
|
|
65
|
+
speed={particleSpeed}
|
|
66
|
+
/>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{/* Spotlight Effect (hide on small screens to reduce visual noise) */}
|
|
70
|
+
<div className="hidden md:block absolute -top-1/3 -left-1/3 w-2/3 h-2/3 bg-blue-400/90 rounded-full blur-[120px] pointer-events-none z-0"></div>
|
|
71
|
+
|
|
72
|
+
{/* Left Side: Image */}
|
|
73
|
+
<div className="relative w-full md:w-1/2 h-64 md:h-full rounded-md overflow-hidden z-10">
|
|
74
|
+
<img src={item.imageUrl} alt={item.title} className="w-full h-full object-cover lg:aspect-square" />
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{/* Right Side: Content */}
|
|
78
|
+
<div className="relative w-full md:w-2/3 text-center md:text-left z-10">
|
|
79
|
+
<h3 className="text-3xl font-bold mb-2 text-white">{item.title}</h3>
|
|
80
|
+
<p className="text-gray-400 mb-6">{item.description}</p>
|
|
81
|
+
<button className="group relative inline-flex md:inline-flex w-full md:w-auto items-center justify-center px-6 py-2 bg-lime-600 text-white font-semibold rounded-md overflow-hidden transition-all duration-300 hover:bg-lime-700">
|
|
82
|
+
<span className="mx-auto">{item.buttonText}</span>
|
|
83
|
+
<ArrowRightIcon />
|
|
84
|
+
</button>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
))}
|
|
89
|
+
</>
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default MeteorCard;
|
package/dist/cli/index.js
CHANGED
|
@@ -12,7 +12,9 @@ const componentRoot = path.join(__dirname, "..", "ApexUI-Kit", "templates");
|
|
|
12
12
|
// Component name map
|
|
13
13
|
const componentMap = {
|
|
14
14
|
"avatar": "Avatar",
|
|
15
|
+
"accordion-marquee": "AccordionMarquee",
|
|
15
16
|
"beam-bar": "BeamBar",
|
|
17
|
+
"blueprint-background": "BluePrintBackground",
|
|
16
18
|
"carousel": "Carousel",
|
|
17
19
|
"parallax-carousel": "ParallaxCarousel",
|
|
18
20
|
"drag-carousel": "DragCarousel",
|
|
@@ -26,6 +28,7 @@ const componentMap = {
|
|
|
26
28
|
"kinetic-threads-background": "KineticThreadsBackground",
|
|
27
29
|
"lens-flare-background": "LensFlareBackground",
|
|
28
30
|
"luminous-particle-ocean": "LuminousParticleOcean",
|
|
31
|
+
"meteor-card": "MeteorCard",
|
|
29
32
|
"nav-menu": "NavMenu",
|
|
30
33
|
"nav-dropdown": "NavDropDown",
|
|
31
34
|
"orbs-background": "OrbsBackground",
|