'use client'; import * as React from 'react'; import { motion, type SpringOptions, useMotionValue, useSpring, } from 'motion/react'; import { cn } from '@workspace/ui/lib/utils'; type BubbleBackgroundProps = React.ComponentProps<'div'> & { interactive?: boolean; transition?: SpringOptions; colors?: { first: string; second: string; third: string; fourth: string; fifth: string; sixth: string; }; }; function BubbleBackground({ ref, className, children, interactive = false, transition = { stiffness: 100, damping: 20 }, colors = { first: '18,113,255', second: '221,74,255', third: '0,220,255', fourth: '200,50,50', fifth: '180,180,50', sixth: '140,100,255', }, ...props }: BubbleBackgroundProps) { const containerRef = React.useRef(null); React.useImperativeHandle(ref, () => containerRef.current as HTMLDivElement); const mouseX = useMotionValue(0); const mouseY = useMotionValue(0); const springX = useSpring(mouseX, transition); const springY = useSpring(mouseY, transition); React.useEffect(() => { if (!interactive) return; const currentContainer = containerRef.current; if (!currentContainer) return; const handleMouseMove = (e: MouseEvent) => { const rect = currentContainer.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; mouseX.set(e.clientX - centerX); mouseY.set(e.clientY - centerY); }; currentContainer?.addEventListener('mousemove', handleMouseMove); return () => currentContainer?.removeEventListener('mousemove', handleMouseMove); }, [interactive, mouseX, mouseY]); return (
{interactive && ( )}
{children}
); } export { BubbleBackground, type BubbleBackgroundProps };