Interactive 3D Spring Button•React + Framer Motion
Elevated Underglow 3D CTA Button
Multi-tier 3D CTA button featuring 13px spring elevation, dynamic base underglow flare, and specular reflection bottom insets.
preview.tsx
Interactions:0
Hover or click to interact
Customizer
PRESETS & VARIATIONS
All Variants Preview
Hover over each button to trigger realistic 13px 3D lift physics
Figma Electric Bluetheme="figma"
UI Pirate Magmatheme="uipirate"
Neon Emeraldtheme="emerald"
Cyber Violettheme="violet"
Crimson Embertheme="crimson"
Dark Obsidiantheme="dark"
Installation & Setup
Install the required dependencies for Framer Motion spring physics and Lucide icons:
npm install framer-motion clsx lucide-react
Code & Integration
ElevatedUnderglowCTA.tsx• Production Ready
"use client";
import React, { useState } from "react";
import { motion } from "framer-motion";
import { Phone, Calendar, ArrowRight, Sparkles, Mail } from "lucide-react";
export type ElevatedUnderglowTheme =
| "figma"
| "uipirate"
| "cyan"
| "emerald"
| "violet"
| "crimson"
| "amber"
| "dark";
export type ElevatedUnderglowSize = "xs" | "sm" | "md" | "lg" | "xl";
export type ElevatedUnderglowIconType = "phone" | "calendar" | "arrow" | "sparkle" | "mail" | "none";
export interface ElevatedUnderglowCTAProps {
label?: string;
icon?: ElevatedUnderglowIconType | React.ReactNode;
theme?: ElevatedUnderglowTheme;
size?: ElevatedUnderglowSize;
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
disabled?: boolean;
className?: string;
}
export const UNDERGLOW_THEMES = {
figma: {
primaryColor: "#0077FF",
baseBg: "bg-[#0077FF]",
capBg: "bg-[#e8e8e8]",
capBorder: "border-[#efefef]",
capText: "text-[#353535]",
},
uipirate: {
primaryColor: "#FF5B04",
baseBg: "bg-[#FF5B04]",
capBg: "bg-[#f0ece7]",
capBorder: "border-[#fbf8f5]",
capText: "text-[#26211d]",
},
cyan: {
primaryColor: "#06B6D4",
baseBg: "bg-[#06B6D4]",
capBg: "bg-[#e6f4f8]",
capBorder: "border-[#f0f9fb]",
capText: "text-[#164e63]",
},
};
export function ElevatedUnderglowCTA({
label = "Book A Call",
icon = "phone",
theme = "figma",
size = "md",
onClick,
disabled = false,
className = "",
}: ElevatedUnderglowCTAProps) {
const [isHovered, setIsHovered] = useState(false);
const [isPressed, setIsPressed] = useState(false);
const t = UNDERGLOW_THEMES[theme as keyof typeof UNDERGLOW_THEMES] || UNDERGLOW_THEMES.figma;
const renderIcon = () => {
if (typeof icon !== "string") return icon;
switch (icon) {
case "phone": return <Phone className="w-4 h-4" />;
case "calendar": return <Calendar className="w-4 h-4" />;
case "arrow": return <ArrowRight className="w-4 h-4" />;
case "sparkle": return <Sparkles className="w-4 h-4" />;
case "mail": return <Mail className="w-4 h-4" />;
default: return null;
}
};
return (
<div
className={`relative inline-block select-none ${className}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => {
setIsHovered(false);
setIsPressed(false);
}}
>
{/* 3D Underglow Base Extrusion */}
<div
className={`absolute inset-0 rounded-[35px] ${t.baseBg} transition-opacity duration-300 ${
isHovered ? "opacity-100" : "opacity-0"
}`}
style={{
boxShadow: `0px 21px 12px 0px ${t.primaryColor}26, 0px 9px 9px 0px ${t.primaryColor}42`,
}}
/>
{/* Floating Cap Button */}
<motion.button
type="button"
disabled={disabled}
onClick={onClick}
onMouseDown={() => setIsPressed(true)}
onMouseUp={() => setIsPressed(false)}
animate={{
y: isPressed ? 2 : isHovered ? -13 : 0,
}}
transition={{ type: "spring", stiffness: 450, damping: 25 }}
className={`relative flex items-center justify-center gap-3 px-6 py-3.5 rounded-[35px] ${t.capBg} ${t.capBorder} border ${t.capText} font-semibold text-sm cursor-pointer shadow-lg`}
>
{renderIcon()}
<span>{label}</span>
</motion.button>
</div>
);
}Component API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | "Book A Call" | Text displayed inside the button |
| icon | "phone" | "calendar" | "arrow" | "sparkle" | "mail" | ReactNode | "phone" | Leading icon glyph or custom React node |
| theme | ElevatedUnderglowTheme | "figma" | Colorway theme preset (Electric Blue, Orange, Cyan, etc.) |
| size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Scale multiplier |
| onClick | (e) => void | undefined | Click callback event handler |
Personalized Help
Struggling with elevated 3D underglow buttons or interactive UI controls? Let's talk about your product.
UI Pirate is a product design & development agency trusted by 50+ SaaS founders and enterprise teams across the US, UK & beyond. Tell us what you need.