Skip to content
6

Cursor Glow

Ambient glow layer that follows the pointer across its container and fades when it leaves. Drop it behind heroes, grids or feature panels.

Example

Installation

npx shadcn@latest add https://hirael.com/r/cursor-glow.json

Usage

import { CursorGlow } from "@/components/cursor-glow"

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

API

<CursorGlow />

+ native element props
PropTypeDefault
size

Diameter of the glow, in px.

number400
color

Glow color. Defaults to a soft tint of the foreground token.

string'color-mix(in oklch, var(--foreground) 12%, transparent)'

Component source

'use client';

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

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

interface CursorGlowProps extends React.ComponentProps<'div'> {
  /** Diameter of the glow, in px. */
  size?: number;
  /** Glow color. Defaults to a soft tint of the foreground token. */
  color?: string;
}

const CursorGlow = ({
  className,
  children,
  size = 400,
  color = 'color-mix(in oklch, var(--foreground) 12%, transparent)',
  ...props
}: CursorGlowProps) => {
  const x = useMotionValue(0);
  const y = useMotionValue(0);
  const background = useMotionTemplate`radial-gradient(${size}px circle at ${x}px ${y}px, ${color}, 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="cursor-glow"
      onPointerMove={onPointerMove}
      className={cn('group relative overflow-hidden', className)}
      {...props}
    >
      <motion.div
        aria-hidden
        data-slot="cursor-glow-layer"
        className="pointer-events-none absolute inset-0 opacity-0 blur-2xl transition-opacity duration-500 group-hover:opacity-100"
        style={{ background }}
      />
      <div data-slot="cursor-glow-content" className="relative">
        {children}
      </div>
    </div>
  );
};

export { CursorGlow };

Dependencies

npm

motion