Interactive Hover Button
21st.dev interactive-hover-button: violet dot reveals on hover, label padding shift, ArrowRight spring slide. “Explore free tools”.
Dependencies
react
framer-motion
lucide-react
npm install framer-motion lucide-react"use client";
import { motion } from "framer-motion";
import { ArrowRight } from "lucide-react";
export function InteractiveArrowButton({ label = "Explore free tools" }: { label?: string }) {
return (
<motion.button
whileHover="hover"
initial="rest"
whileTap={{ scale: 0.97 }}
variants={{ rest: {}, hover: {} }}
className="group relative inline-flex items-center gap-3 overflow-hidden rounded-xl bg-white px-5 py-2.5 text-sm font-semibold text-zinc-900 shadow-sm ring-1 ring-zinc-200/80"
>
<motion.span
variants={{ rest: { scale: 0, opacity: 0 }, hover: { scale: 1, opacity: 1 } }}
transition={{ type: "spring", stiffness: 400, damping: 22 }}
className="absolute left-3 h-2 w-2 rounded-full bg-violet-500"
/>
<motion.span
variants={{ rest: { x: 0 }, hover: { x: 6 } }}
transition={{ type: "spring", stiffness: 400, damping: 20 }}
className="relative z-10 pl-0 group-hover:pl-4 transition-[padding] duration-300"
>
{label}
</motion.span>
<motion.span
variants={{ rest: { x: 0 }, hover: { x: 4 } }}
transition={{ type: "spring", stiffness: 400, damping: 18 }}
className="relative z-10"
>
<ArrowRight className="h-4 w-4 text-violet-600" />
</motion.span>
</motion.button>
);
}
Please implement this code in the current project and add it to (Your Desired Section, e.g. homepage hero, pricing page, dashboard). Change the primary accent color to (YOUR HEX CODE COLOR, e.g. #6366F1).
Requirements:
- Use React + Tailwind CSS (match the project's existing setup)
- Install dependencies if needed: npm install framer-motion lucide-react
- Keep the layout responsive on mobile and desktop
- Replace placeholder copy with content that fits the project
The UI code:
"use client";
import { motion } from "framer-motion";
import { ArrowRight } from "lucide-react";
export function InteractiveArrowButton({ label = "Explore free tools" }: { label?: string }) {
return (
<motion.button
whileHover="hover"
initial="rest"
whileTap={{ scale: 0.97 }}
variants={{ rest: {}, hover: {} }}
className="group relative inline-flex items-center gap-3 overflow-hidden rounded-xl bg-white px-5 py-2.5 text-sm font-semibold text-zinc-900 shadow-sm ring-1 ring-zinc-200/80"
>
<motion.span
variants={{ rest: { scale: 0, opacity: 0 }, hover: { scale: 1, opacity: 1 } }}
transition={{ type: "spring", stiffness: 400, damping: 22 }}
className="absolute left-3 h-2 w-2 rounded-full bg-violet-500"
/>
<motion.span
variants={{ rest: { x: 0 }, hover: { x: 6 } }}
transition={{ type: "spring", stiffness: 400, damping: 20 }}
className="relative z-10 pl-0 group-hover:pl-4 transition-[padding] duration-300"
>
{label}
</motion.span>
<motion.span
variants={{ rest: { x: 0 }, hover: { x: 4 } }}
transition={{ type: "spring", stiffness: 400, damping: 18 }}
className="relative z-10"
>
<ArrowRight className="h-4 w-4 text-violet-600" />
</motion.span>
</motion.button>
);
}
Replace (Your Desired Section) and (YOUR HEX CODE COLOR) before pasting into Cursor, Copilot, or ChatGPT.