'use client'; import { cn } from '@/lib/utils'; import { AnimatePresence, Transition, motion } from 'motion/react'; import { Children, cloneElement, ReactElement, useEffect, useState, useId, } from 'react'; export type AnimatedBackgroundProps = { children: | ReactElement<{ 'data-id': string }>[] | ReactElement<{ 'data-id': string }>; defaultValue?: string; onValueChange?: (newActiveId: string | null) => void; className?: string; transition?: Transition; enableHover?: boolean; }; export function AnimatedBackground({ children, defaultValue, onValueChange, className, transition, enableHover = false, }: AnimatedBackgroundProps) { const [activeId, setActiveId] = useState(null); const uniqueId = useId(); const handleSetActiveId = (id: string | null) => { setActiveId(id); if (onValueChange) { onValueChange(id); } }; useEffect(() => { if (defaultValue !== undefined) { setActiveId(defaultValue); } }, [defaultValue]); return Children.map(children, (child: any, index) => { const id = child.props['data-id']; const interactionProps = enableHover ? { onMouseEnter: () => handleSetActiveId(id), onMouseLeave: () => handleSetActiveId(null), } : { onClick: () => handleSetActiveId(id), }; return cloneElement( child, { key: index, className: cn('relative inline-flex', child.props.className), 'data-checked': activeId === id ? 'true' : 'false', ...interactionProps, }, <> {activeId === id && ( )}
{child.props.children}
); }); }