Components

Rainbow Button

A premium button with an animated rainbow gradient border.

Last updated on

Edit on GitHub

Rainbow Button

"use client";
 
import { ArrowRight } from "lucide-react";
import { RainbowButton } from "@/components/ui/rainbow-button";
 
export function RainbowButtonDemo() {
  return (
    <div className="flex items-center justify-center p-8">
      <RainbowButton className="group">
        Get Started
        <ArrowRight className="ml-2 h-4 w-4 transition-transform group-hover:translate-x-1" />
      </RainbowButton>
    </div>
  );
}

Installation

CLI

npx shadcn@latest add "https://jolyui.dev/r/rainbow-button"

Manual

Install the following dependencies:

npm install motion

Copy and paste the following code into your project. component/ui/rainbow-button.tsx

import { motion } from "motion/react";
import * as React from "react";
import { cn } from "@/lib/utils";
 
interface RainbowButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  children: React.ReactNode;
  colors?: string[];
  duration?: number;
  borderWidth?: number;
  animated?: boolean;
}
 
const RainbowButton = React.forwardRef<HTMLButtonElement, RainbowButtonProps>(
  (
    {
      children,
      colors = ["#f43f5e", "#8b5cf6", "#3b82f6", "#22c55e", "#f43f5e"],
      duration = 2,
      borderWidth = 2,
      animated = true,
      className,
      onClick,
      disabled,
      type = "button",
      ...props
    },
    ref,
  ) => {
    const gradientColors = colors.join(", ");
 
    return (
      <button
        ref={ref}
        type={type}
        onClick={onClick}
        disabled={disabled}
        className={cn(
          "relative inline-flex items-center justify-center overflow-hidden rounded-lg font-medium transition-transform hover:scale-105 active:scale-95 disabled:pointer-events-none disabled:opacity-50",
          className,
        )}
        style={{ padding: borderWidth }}
        {...props}
      >
        {/* Animated gradient background */}
        <motion.div
          className="absolute inset-0"
          style={{
            background: `linear-gradient(var(--gradient-angle, 0deg), ${gradientColors})`,
          }}
          animate={
            animated
              ? {
                  "--gradient-angle": ["0deg", "360deg"],
                }
              : undefined
          }
          transition={
            animated
              ? {
                  duration,
                  repeat: Infinity,
                  ease: "linear",
                }
              : undefined
          }
        />
        {/* Button content */}
        <span
          className="relative z-10 flex items-center gap-2 rounded-md bg-background px-6 py-2.5 font-medium text-sm transition-colors hover:bg-background/90"
          style={{
            borderRadius: `calc(0.5rem - ${borderWidth}px)`,
          }}
        >
          {children}
        </span>
      </button>
    );
  },
);
RainbowButton.displayName = "RainbowButton";
 
export { RainbowButton };

Usage

import { RainbowButton } from "@/components/ui/rainbow-button";

function MyComponent() {
  return (
    <RainbowButton>
      Get Started
    </RainbowButton>
  );
}

API Reference

Prop

Type

Notes

  • The button features a rotating rainbow gradient border.
  • You can customize the colors, duration, and border width.
  • The button includes smooth hover and active state animations.
  • Fully accessible and supports all standard button attributes.

How is this guide?

On this page