"use client"; import { AnimatePresence, motion, type Variants, } from "motion/react"; import { Children, cloneElement, isValidElement, useId, useState, type ReactElement, type ReactNode, } from "react"; import { cn } from "@/lib/utils"; export interface SharedLayoutBgProps { children: ReactNode; className?: string; /** Tailwind class applied to the moving pill. Defaults to a subtle foreground tint. */ pillClassName?: string; /** Horizontal inset of the pill relative to each row (px). Default 20. */ inset?: number; } const variants: Variants = { initial: { opacity: 0, filter: "blur(6px)" }, animate: { opacity: 1, filter: "blur(0px)" }, exit: (isActive: boolean) => !isActive ? { opacity: 0, filter: "blur(6px)" } : {}, }; export function SharedLayoutBg({ children, className, pillClassName, inset = 20, }: SharedLayoutBgProps) { const [activeId, setActiveId] = useState(null); const uid = useId(); return (
setActiveId(null)} className={cn("flex w-full flex-col", className)} > {Children.toArray(children) .filter(isValidElement) .map((child, index) => { const el = child as ReactElement<{ className?: string; onMouseEnter?: () => void; children?: ReactNode }>; return cloneElement( el, { key: index, className: cn("relative", el.props.className), onMouseEnter: () => setActiveId(index), }, <> {activeId !== null ? ( {activeId === index ? ( ) : null} ) : null}
{el.props.children}
); })}
); }