⚡ Zap Button

A dynamic interactive button with a smooth spotlight effect that follows your cursor movement. Perfect for creating engaging call-to-action buttons with visual feedback. ✨

npm i clsx tailwind-merge

Add Utilities

//lib/utils.ts

import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}


 ### Code
 _ZapButton.tsx_

 ```tsx

 
"use client";
import { cn } from "@/lib/utils";
import { useEffect, useRef } from "react";

export default function ZapButton() {
  return (
   <div className="flex h-screen w-full items-center justify-center bg-zinc-950 px-4">
    <Zap></Zap>
   </div>
  );
}

interface btnProps{
    className?:string;
    btnText?:string;
    onClick?: () => void
}

const Zap = ({className,btnText="Hover",onClick}:btnProps) =>{
    const btnRef = useRef<HTMLButtonElement | null>(null);
   const spanRef = useRef<HTMLSpanElement>({} as HTMLSpanElement);

    useEffect( () => {
        const handleMouseMove = (e:any) => {
            const {width} = e.target.getBoundingClientRect();

            const offset = e.offsetX;

            const left = `${(offset / width) * 100}%`;

            spanRef.current.animate({left}, {duration: 250, fill: "forwards"});
        };

         const handleMouseLeave = (e:any) => {
            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 (
        <button onClick={onClick} ref={btnRef} className={cn("w-full max-w-3xs rounded-lg bg-slate-950 px-4 py-3 text-lg font-medium text-white relative overflow-hidden border-1 border-dashed border-slate-400/90", className)}>
            
            <span className="pointer-events-none relative z-10 mix-blend-difference">{btnText}</span>
            <span ref={spanRef} className="pointer-events-none absolute left-[50%] top-[50%] h-20 w-30 -translate-x-[50%] -translate-y-[50%] rounded-full bg-slate-200 border-1 border-dashed border-slate-900"></span>
        
        </button>
    )
}

Props

PropTypeDefaultDescription
classNamestringundefinedAdditional CSS classes for styling customization
btnTextstring"Hover"Text content displayed on the button
onClickfunctionundefinedClick handler function for button interactions
Zap Button16