Chamaac
Components
  • Overview

    • Introduction
  • Gallery

    • CarouselNew
  • Animated Icons
    • CopyNew
    • WavyNew
    • AdjustmentsNew
  • Buttons

    • Slide Up Button
  • Navigation

    • Dock
  • Cards

    • Random Image Reveal
    • Orbiting IconsNew

Slide Up Button

An animated button with a slide-up text effect on hover, inspired by jeton.com. The original text slides up while a clone slides in from below with a rotation effect.

Installation

Install Dependencies

npm install motion

Component Code

Copy and paste the component code into your project.

"use client";

import React from "react";
import { motion } from "motion/react";

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

interface SlideUpButtonProps {
    children: React.ReactNode;
    className?: string;
    textDuration?: number;
    cloneDuration?: number;
    cloneDelay?: number;
    buttonScale?: number;
    buttonOpacity?: number;
}

const SlideUpButton = ({
    children,
    className = "",
    textDuration = 0.25,
    cloneDuration = 0.5,
    cloneDelay = 0.12,
    buttonScale = 0.98,
    buttonOpacity = 0.8,
}: SlideUpButtonProps) => {
    const buttonVariants = {
        initial: { scale: 1 },
        hover: { scale: buttonScale, opacity: buttonOpacity },
    };

    const textVariants = {
        initial: { y: 0 },
        hover: { y: "-190%" },
    };

    const cloneVariants = {
        initial: { y: "190%", rotate: 20 },
        hover: { y: 0, rotate: 0 },
    };

    return (
        <motion.button
            variants={buttonVariants}
            initial="initial"
            whileHover="hover"
            className={cn(
                "relative overflow-hidden px-6 py-3 rounded-[12px] text-[16px] leading-[1.5] cursor-pointer",
                className
            )}
        >
            {/* container for stacked text */}
            <motion.div className="relative overflow-hidden">
                {/* ORIGINAL TEXT */}
                <motion.span
                    variants={textVariants}
                    transition={{
                        duration: textDuration,
                        ease: [0.55, 0.085, 0.68, 0.53],
                    }}
                    className="block"
                >
                    {children}
                </motion.span>

                {/* CLONE TEXT */}
                <motion.span
                    variants={cloneVariants}
                    transition={{
                        duration: cloneDuration,
                        ease: [0.165, 0.84, 0.44, 1],
                        delay: cloneDelay,
                    }}
                    className="block absolute top-0 left-0"
                >
                    {children}
                </motion.span>
            </motion.div>
        </motion.button>
    );
};

export default SlideUpButton;

Props

PropTypeDefaultDescription
children*React.ReactNode-The content to be displayed inside the button
classNamestring""Custom class names for styling
textDurationnumber0.25Duration in seconds for the original text slide-up animation
cloneDurationnumber0.5Duration in seconds for the clone text slide-in animation
cloneDelaynumber0.12Delay in seconds before the clone text animation starts
buttonScalenumber0.98Scale value for the button on hover (1 = no scale)
buttonOpacitynumber0.8Opacity value for the button on hover (0-1)