Skip to content
6

Spotlight Card

Card surface with a soft spotlight that tracks the cursor and fades in on hover. Built on design tokens, no hard-coded colors.

Example

Installation

npx shadcn@latest add https://hirael.com/r/spotlight-card.json

Usage

import { SpotlightCard } from "@/components/spotlight-card"

Paths assume the default @/ alias from your components.json. The example above shows the parts composed.

API

<SpotlightCard />

+ native element props
PropTypeDefault
size

Diameter of the spotlight, in px.

number350

Component source

'use client';

import * as React from 'react';
import { motion, useMotionTemplate, useMotionValue } from 'motion/react';

import { cn } from '@/lib/utils';

interface SpotlightCardProps extends React.ComponentProps<'div'> {
  /** Diameter of the spotlight, in px. */
  size?: number;
}

const SpotlightCard = ({ className, children, size = 350, ...props }: SpotlightCardProps) => {
  const x = useMotionValue(0);
  const y = useMotionValue(0);
  const background = useMotionTemplate`radial-gradient(${size}px circle at ${x}px ${y}px, color-mix(in oklch, var(--foreground) 10%, transparent), transparent 70%)`;

  const onPointerMove = (event: React.PointerEvent<HTMLDivElement>) => {
    const rect = event.currentTarget.getBoundingClientRect();
    x.set(event.clientX - rect.left);
    y.set(event.clientY - rect.top);
  };

  return (
    <div
      data-slot="spotlight-card"
      onPointerMove={onPointerMove}
      className={cn(
        'group relative overflow-hidden rounded-lg border border-border bg-card text-card-foreground',
        className,
      )}
      {...props}
    >
      <motion.div
        aria-hidden
        data-slot="spotlight-card-glow"
        className="pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100"
        style={{ background }}
      />
      <div data-slot="spotlight-card-content" className="relative">
        {children}
      </div>
    </div>
  );
};

export { SpotlightCard };

Dependencies

npm

motion