lightswind
Version:
A professionally designed animate react component library & templates market that brings together functionality, accessibility, and beautiful aesthetics for modern applications.
75 lines (74 loc) • 4.95 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useEffect, useRef, useState } from 'react';
import { cn } from '../lib/utils';
export const GlowingCard = ({ children, className, glowColor = "#3b82f6", hoverEffect = true, ...props }) => {
return (_jsx("div", { className: cn("relative flex-1 min-w-[14rem] p-6 rounded-2xl text-black dark:text-white", "bg-white dark:bg-black border border-gray-200 dark:border-gray-700", "transition-all duration-400 ease-out",
// Remove background color changes on hover
className), style: {
'--glow-color': glowColor,
}, ...props, children: children }));
};
export const GlowingCards = ({ children, className, enableGlow = true, glowRadius = 25, glowOpacity = 1, animationDuration = 400, enableHover = true, gap = "2.5rem", maxWidth = "75rem", padding = "3rem 1.5rem", backgroundColor, borderRadius = "1rem", responsive = true, customTheme, }) => {
const containerRef = useRef(null);
const overlayRef = useRef(null);
const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const [showOverlay, setShowOverlay] = useState(false);
useEffect(() => {
const container = containerRef.current;
const overlay = overlayRef.current;
if (!container || !overlay || !enableGlow)
return;
const handleMouseMove = (e) => {
const rect = container.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
setMousePosition({ x, y });
setShowOverlay(true);
overlay.style.setProperty('--x', `${x}px`);
overlay.style.setProperty('--y', `${y}px`);
overlay.style.setProperty('--opacity', glowOpacity.toString());
};
const handleMouseLeave = () => {
setShowOverlay(false);
overlay.style.setProperty('--opacity', '0');
};
container.addEventListener('mousemove', handleMouseMove);
container.addEventListener('mouseleave', handleMouseLeave);
return () => {
container.removeEventListener('mousemove', handleMouseMove);
container.removeEventListener('mouseleave', handleMouseLeave);
};
}, [enableGlow, glowOpacity]);
const containerStyle = {
'--gap': gap,
'--max-width': maxWidth,
'--padding': padding,
'--border-radius': borderRadius,
'--animation-duration': `${animationDuration}ms`,
'--glow-radius': `${glowRadius}rem`,
'--glow-opacity': glowOpacity,
backgroundColor: backgroundColor || undefined,
...customTheme,
};
return (_jsx("div", { className: cn("relative w-full", className), style: containerStyle, children: _jsxs("div", { ref: containerRef, className: cn("relative max-w-[var(--max-width)] mx-auto ", "px-6 py-12"), style: { padding: `var(--padding)` }, children: [_jsx("div", { className: cn("flex items-center justify-center flex-wrap gap-[var(--gap)]", responsive && "flex-col sm:flex-row "), children: children }), enableGlow && (_jsx("div", { ref: overlayRef, className: cn("absolute inset-0 pointer-events-none select-none", "opacity-0 transition-all duration-[var(--animation-duration)] ease-out"), style: {
WebkitMask: `radial-gradient(var(--glow-radius) var(--glow-radius) at var(--x, 0) var(--y, 0), #000 1%, transparent 50%)`,
mask: `radial-gradient(var(--glow-radius) var(--glow-radius) at var(--x, 0) var(--y, 0), #000 1%, transparent 50%)`,
opacity: showOverlay ? 'var(--opacity)' : '0',
}, children: _jsx("div", { className: cn("flex items-center justify-center flex-wrap gap-[var(--gap)] max-w-[var(--max-width)] center mx-auto", responsive && "flex-col sm:flex-row"), style: { padding: `var(--padding)` }, children: React.Children.map(children, (child, index) => {
if (React.isValidElement(child) && child.type === GlowingCard) {
const cardGlowColor = child.props.glowColor || "#3b82f6";
return React.cloneElement(child, {
className: cn(child.props.className, "bg-opacity-15 dark:bg-opacity-15", "border-opacity-100 dark:border-opacity-100"),
style: {
...child.props.style,
backgroundColor: `${cardGlowColor}15`,
borderColor: cardGlowColor,
boxShadow: `0 0 0 1px inset ${cardGlowColor}`,
},
});
}
return child;
}) }) }))] }) }));
};
export { GlowingCards as default };