All components
Spotlight Card
cardsA card with a cursor-following radial spotlight over its surface.
responsive · 480px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/spotlight-card.jsonUsage
import { Sparkles } from "lucide-react";
import { SpotlightCard } from "@/registry/cards/spotlight-card";
export default function SpotlightCardDemo() {
return (
<SpotlightCard className="max-w-xs">
<Sparkles className="size-5 text-muted-foreground" />
<h3 className="mt-3 text-base font-semibold">Spotlight Card</h3>
<p className="mt-1 text-sm text-muted-foreground">
Move your cursor across the card to reveal the spotlight that tracks your pointer.
</p>
</SpotlightCard>
);
}Component source
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
export interface SpotlightCardProps
extends React.ComponentPropsWithoutRef<"div"> {
/** Radius of the spotlight in pixels. */
radius?: number;
/** Spotlight color (any valid CSS color). */
color?: string;
}
/**
* A card with a cursor-following radial spotlight on its border/surface.
* The spotlight is driven by CSS variables updated on pointer move.
*/
export const SpotlightCard = React.forwardRef<
HTMLDivElement,
SpotlightCardProps
>(
(
{
radius = 350,
color = "color-mix(in oklch, var(--foreground) 12%, transparent)",
className,
children,
...props
},
ref,
) => {
const localRef = React.useRef<HTMLDivElement>(null);
React.useImperativeHandle(ref, () => localRef.current as HTMLDivElement);
const [active, setActive] = React.useState(false);
const onMove = React.useCallback((e: React.MouseEvent<HTMLDivElement>) => {
const el = localRef.current;
if (!el) return;
const rect = el.getBoundingClientRect();
el.style.setProperty("--x", `${e.clientX - rect.left}px`);
el.style.setProperty("--y", `${e.clientY - rect.top}px`);
}, []);
return (
<div
ref={localRef}
onMouseMove={onMove}
onMouseEnter={() => setActive(true)}
onMouseLeave={() => setActive(false)}
style={
{
"--radius": `${radius}px`,
"--spotlight": color,
} as React.CSSProperties
}
className={cn(
"group relative overflow-hidden rounded-xl border border-border bg-card p-6 text-card-foreground shadow-sm",
className,
)}
{...props}
>
<div
aria-hidden
className="pointer-events-none absolute inset-0 transition-opacity duration-300"
style={{
opacity: active ? 1 : 0,
background:
"radial-gradient(var(--radius) circle at var(--x) var(--y), var(--spotlight), transparent 70%)",
}}
/>
<div className="relative">{children}</div>
</div>
);
},
);
SpotlightCard.displayName = "SpotlightCard";