Docs

Spotlight Button

The Spotlight Button highlights or focuses on specific content, making it more visible or prominent in the UI.

Installation

Install dependencies

npm install framer-motion lucide-react

Run the following command

It will create a new file spotlight-button.tsx inside the components/mage-ui/button directory.

mkdir -p components/mage-ui/button && touch components/mage-ui/button/spotlight-button.tsx

Paste the code

Open the newly created file and paste the following code:

"use client"
import { motion } from "framer-motion";
import { useEffect, useRef } from "react";
 
const ButtonWrapper = () => {
  return (
    <div className="flex h-screen w-screen items-center justify-center bg-slate-800">
      <SpotlightButton />
    </div>
  );
};
 
const SpotlightButton = () => {
  const btnRef = useRef<HTMLButtonElement | null>(null);
  const spanRef = useRef<HTMLSpanElement | null>(null);
 
  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      const { width } = (e.target as HTMLElement)?.getBoundingClientRect();
      const offset = e.offsetX;
      const left = `${(offset / width) * 100}%`;
 
      spanRef.current!.animate({ left }, { duration: 250, fill: "forwards" });
    };
 
    const handleMouseLeave = () => {
      spanRef.current!.animate(
        { left: "50%" },
        { duration: 100, fill: "forwards" }
      );
    };
 
    btnRef?.current?.addEventListener("mousemove", handleMouseMove);
    btnRef?.current?.addEventListener("mouseleave", handleMouseLeave);
 
    return () => {
      btnRef?.current?.removeEventListener("mousemove", handleMouseMove);
      btnRef?.current?.removeEventListener("mouseleave", handleMouseLeave);
    };
  }, []);
 
  return (
    <motion.button
      whileTap={{ scale: 0.985 }}
      ref={btnRef}
      className="relative w-64 max-w-full overflow-hidden rounded-lg bg-slate-950 px-4 py-3 text-lg font-medium text-white"
    >
      <span className="pointer-events-none relative z-10 mix-blend-difference">
        Hover me
      </span>
      <span
        ref={spanRef}
        className="pointer-events-none absolute left-[50%] top-[50%] h-32 w-32 -translate-x-[50%] -translate-y-[50%] rounded-full bg-slate-100"
      />
    </motion.button>
  );
};
 
export default ButtonWrapper;