'use client'; import { useState } from 'react'; import { usePrefersReducedMotion, useRandomInterval } from '~/hooks'; const DEFAULT_COLOR = '#FFC700'; const random = (min: number, max: number) => Math.floor(Math.random() * (max - min)) + min; const range = (start: number, end?: number, step = 1) => { const output = []; if (typeof end === 'undefined') { end = start; start = 0; } for (let i = start; i < end; i += step) { output.push(i); } return output; }; const generateSparkle = (color: string) => { const sparkle = { id: String(random(10000, 99999)), createdAt: Date.now(), color, size: random(10, 20), style: { top: random(0, 100) + '%', left: random(0, 100) + '%' } }; return sparkle; }; type SparklesProps = { color?: string; children: React.ReactNode; }; const Sparkles = ({ color = DEFAULT_COLOR, children, ...props }: SparklesProps) => { const [sparkles, setSparkles] = useState(() => { return range(3).map(() => generateSparkle(color)); }); const prefersReducedMotion = usePrefersReducedMotion(); useRandomInterval( () => { const sparkle = generateSparkle(color); const now = Date.now(); const nextSparkles = sparkles.filter((sp) => { const delta = now - sp.createdAt; return delta < 750; }); nextSparkles.push(sparkle); setSparkles(nextSparkles); }, prefersReducedMotion ? null : 100, prefersReducedMotion ? null : 1000 ); return ( {sparkles.map((sparkle) => ( ))} {children} ); }; export default Sparkles;