"use client"; import React, { useEffect, useRef, useState } from 'react'; import { cn } from '../../lib/utils'; export interface GlowingCardProps { children: React.ReactNode; className?: string; glowColor?: string; hoverEffect?: boolean; } export interface GlowingCardsProps { children: React.ReactNode; className?: string; /** Enable the glowing overlay effect */ enableGlow?: boolean; /** Size of the glow effect radius */ glowRadius?: number; /** Opacity of the glow effect */ glowOpacity?: number; /** Animation duration for glow transitions */ animationDuration?: number; /** Enable hover effects on individual cards */ enableHover?: boolean; /** Gap between cards */ gap?: string; /** Maximum width of cards container */ maxWidth?: string; /** Padding around the container */ padding?: string; /** Background color for the container */ backgroundColor?: string; /** Border radius for cards */ borderRadius?: string; /** Enable responsive layout */ responsive?: boolean; /** Custom CSS variables for theming */ customTheme?: { cardBg?: string; cardBorder?: string; textColor?: string; hoverBg?: string; }; } export const GlowingCard: React.FC = ({ children, className, glowColor = "#3b82f6", hoverEffect = true, ...props }) => { return (
{children}
); }; export const GlowingCards: React.FC = ({ 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: MouseEvent) => { const rect = container.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; setMousePosition({ x, y }); setShowOverlay(true); // Using string concatenation for style properties 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', // Concatenation '--glow-radius': glowRadius + 'rem', // Concatenation '--glow-opacity': glowOpacity, backgroundColor: backgroundColor || undefined, ...customTheme, } as React.CSSProperties; return (
{children}
{enableGlow && (
{React.Children.map(children, (child, index) => { if (React.isValidElement(child) && child.type === GlowingCard) { const cardGlowColor = child.props.glowColor || "#3b82f6"; return React.cloneElement(child as React.ReactElement, { className: cn( child.props.className, "bg-opacity-15 dark:bg-opacity-15", "border-opacity-100 dark:border-opacity-100" ), style: { ...child.props.style, // String concatenation for background, border, and boxShadow backgroundColor: cardGlowColor + "15", borderColor: cardGlowColor, boxShadow: "0 0 0 1px inset " + cardGlowColor, }, }); } return child; })}
)}
); }; export { GlowingCards as default };