"use client"; import { type ComponentProps, type CSSProperties, type PointerEvent, useRef } from "react"; import { cn } from "@/lib/utils"; export interface TorchGridProps extends ComponentProps<"div"> { radius?: number; } export function TorchGrid({ radius = 260, className, style, onPointerEnter, onPointerMove, onPointerLeave, ...props }: TorchGridProps) { const ref = useRef(null); const measure = () => { const grid = ref.current; if (!grid) return; const g = grid.getBoundingClientRect(); for (const card of grid.querySelectorAll("[data-spotlight-card]")) { const c = card.getBoundingClientRect(); card.style.setProperty("--card-x", `${c.left - g.left}px`); card.style.setProperty("--card-y", `${c.top - g.top}px`); } }; const track = (event: PointerEvent) => { const grid = ref.current; if (!grid) return; const g = grid.getBoundingClientRect(); grid.style.setProperty("--spot-x", `${event.clientX - g.left}px`); grid.style.setProperty("--spot-y", `${event.clientY - g.top}px`); }; return (
{ onPointerEnter?.(e); if (e.pointerType !== "mouse") return; measure(); track(e); ref.current?.setAttribute("data-lit", ""); }} onPointerLeave={(e) => { onPointerLeave?.(e); ref.current?.removeAttribute("data-lit"); }} onPointerMove={(e) => { onPointerMove?.(e); if (e.pointerType === "mouse") track(e); }} ref={ref} style={{ "--spot-r": `${radius}px`, ...style } as CSSProperties} {...props} /> ); } export type TorchCardProps = ComponentProps<"div">; const atX = "(var(--spot-x, -999px) - var(--card-x, 0px))"; const atY = "(var(--spot-y, -999px) - var(--card-y, 0px))"; export function TorchCard({ className, children, ...props }: TorchCardProps) { return (
{children}
); }