Spotlight Card
A radial glow that follows the cursor across the card.
0.8 KB gzippedZero dependenciesReduced-motion safeBase UI & Radix compatible
Move your cursor here
The glow follows the pointer across the card surface.
Installation
npx shadcn@latest add https://velora.colorlib.com/r/spotlight-card.jsonSource
"use client";
import { useRef } from "react";
import { cn } from "@/lib/utils";
interface SpotlightCardProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
/** Radius of the spotlight in px */
radius?: number;
/** Any CSS color for the glow */
color?: string;
}
export function SpotlightCard({
children,
className,
radius = 320,
color = "color-mix(in oklab, var(--brand) 14%, transparent)",
...props
}: SpotlightCardProps) {
const ref = useRef<HTMLDivElement>(null);
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
const el = ref.current;
if (!el) return;
const rect = el.getBoundingClientRect();
el.style.setProperty("--spot-x", `${e.clientX - rect.left}px`);
el.style.setProperty("--spot-y", `${e.clientY - rect.top}px`);
};
return (
<div
ref={ref}
data-slot="spotlight-card"
onMouseMove={handleMouseMove}
className={cn(
"group relative overflow-hidden rounded-2xl border bg-card",
className
)}
style={
{
"--spot-radius": `${radius}px`,
"--spot-color": color,
} as React.CSSProperties
}
{...props}
>
<div
aria-hidden
className="pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100"
style={{
background:
"radial-gradient(var(--spot-radius) circle at var(--spot-x, 50%) var(--spot-y, 50%), var(--spot-color), transparent 65%)",
}}
/>
<div className="relative z-10">{children}</div>
</div>
);
}