Component
Spotlight Card
A card with a radial glow that follows the pointer. Powered by Motion.
- motion
Move your pointer
The glow follows you across the card. It fades out when you leave.
Install
npx shadcn@latest add @mewo/spotlight-cardNot using the registry directory?
Point the CLI straight at the item URL:
npx shadcn@latest add https://www.mewo-ui.com/r/spotlight-card.json
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Card content. |
| spotlightColor | string | "color-mix(in oklch, var(--color-foreground) 12%, transparent)" | Colour of the glow. Any CSS colour. |
| className | string | — | Merged onto the root element. |
Source
"use client"
import * as React from "react"
import { motion, useMotionTemplate, useMotionValue, useReducedMotion } from "motion/react"
import { cn } from "@/lib/utils"
export interface SpotlightCardProps extends React.ComponentProps<"div"> {
/** Any CSS colour. Defaults to a soft tint of the theme foreground, so it shows in light and dark. */
spotlightColor?: string
}
export function SpotlightCard({
children,
spotlightColor = "color-mix(in oklch, var(--color-foreground) 12%, transparent)",
className,
onPointerMove,
...props
}: SpotlightCardProps) {
const x = useMotionValue(0)
const y = useMotionValue(0)
const reduceMotion = useReducedMotion()
const background = useMotionTemplate`radial-gradient(320px circle at ${x}px ${y}px, ${spotlightColor}, transparent 70%)`
function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {
if (!reduceMotion) {
const rect = event.currentTarget.getBoundingClientRect()
x.set(event.clientX - rect.left)
y.set(event.clientY - rect.top)
}
onPointerMove?.(event)
}
return (
<div
data-slot="spotlight-card"
onPointerMove={handlePointerMove}
className={cn("group relative overflow-hidden rounded-xl border bg-card p-6 text-card-foreground", className)}
{...props}
>
<motion.div
aria-hidden
className="pointer-events-none absolute inset-0 opacity-0 transition-opacity duration-300 group-hover:opacity-100 motion-reduce:hidden"
style={{ background }}
/>
<div className="relative">{children}</div>
</div>
)
}