Hazine

Spotlight Card

A card with a mouse-tracking radial spotlight highlight.

Spotlight

Move your cursor over this card to reveal the radial highlight.

Installation

npx shadcn@latest add @hazine/spotlight-card

Source

"use client"

import * as React from "react"

import { cn } from "@/lib/utils"

interface SpotlightCardProps extends React.ComponentProps<"div"> {
  spotlightColor?: string
}

export function SpotlightCard({
  spotlightColor = "oklch(0.65 0.15 80 / 0.15)",
  className,
  children,
  ...props
}: SpotlightCardProps) {
  const ref = React.useRef<HTMLDivElement>(null)
  const [position, setPosition] = React.useState({ x: 0, y: 0 })
  const [opacity, setOpacity] = React.useState(0)

  function onMouseMove(event: React.MouseEvent<HTMLDivElement>) {
    const rect = ref.current?.getBoundingClientRect()
    if (!rect) return
    setPosition({ x: event.clientX - rect.left, y: event.clientY - rect.top })
  }

  return (
    <div
      ref={ref}
      className={cn(
        "relative overflow-hidden rounded-xl border bg-card p-6 text-card-foreground",
        className
      )}
      onMouseMove={onMouseMove}
      onMouseEnter={() => setOpacity(1)}
      onMouseLeave={() => setOpacity(0)}
      {...props}
    >
      <div
        aria-hidden="true"
        className="pointer-events-none absolute inset-0 transition-opacity duration-300 motion-reduce:hidden"
        style={{
          opacity,
          background: `radial-gradient(320px circle at ${position.x}px ${position.y}px, ${spotlightColor}, transparent 70%)`,
        }}
      />
      <div className="relative">{children}</div>
    </div>
  )
}