Prism
← All primitives

Spotlight

Interaction

A cursor-following radial glow on any surface. Wrap a card or section; the glow tracks the pointer and fades in on hover. Pure CSS variables.

Requires the .prism-spotlight styles from globals.css.

$npx shadcn@latest add https://prism.icglabs.co/r/spotlight.json
View raw manifest →

components/prism/Spotlight.tsx
"use client";

import { useRef } from "react";

/**
 * Spotlight — a cursor-following radial glow on any surface. Wrap a card/section;
 * the glow tracks the pointer and fades in on hover. Pure CSS variables updated
 * on mousemove (no rAF needed — the browser coalesces). Styles live in globals.css.
 */
export function Spotlight({
  children,
  className = "",
  color = "139, 92, 255",
  size = 360,
}: {
  children: React.ReactNode;
  className?: string;
  /** RGB triplet string, e.g. "139, 92, 255". */
  color?: string;
  size?: number;
}) {
  const ref = useRef<HTMLDivElement>(null);

  function onMove(e: React.MouseEvent<HTMLDivElement>) {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    el.style.setProperty("--spot-x", `${e.clientX - r.left}px`);
    el.style.setProperty("--spot-y", `${e.clientY - r.top}px`);
  }

  return (
    <div
      ref={ref}
      onMouseMove={onMove}
      className={`prism-spotlight ${className}`}
      style={{ "--spot-color": color, "--spot-size": `${size}px` } as React.CSSProperties}
    >
      {children}
    </div>
  );
}
Live demo — read-only. Every section is a real, copyable primitive.