Docs

Shiny Button

Shiny Button

A shiny button with a sleek animation effect.

Installation

Install the following dependencies:

npm install motion

Copy and paste the following code into your project.

components/atlas_ui/shiny-button.tsx
"use client";
 
import { cn } from "@/lib/utils";
import { motion, MotionProps } from "motion/react";
import { ButtonHTMLAttributes } from "react";
 
type MergedProps = Omit<
  ButtonHTMLAttributes<HTMLButtonElement>,
  keyof MotionProps
> &
  MotionProps;
 
interface ShinyButtonProps extends MergedProps {
  children: React.ReactNode;
  className?: string;
}
 
export const ShinyButton = ({
  children,
  className,
  ...props
}: ShinyButtonProps) => {
  return (
    <motion.button
      className={cn("px-6 py-2 rounded-md relative radial-gradient", className)}
      initial={{ "--x": "100%", scale: 1 }}
      animate={{ "--x": "-100%" }}
      whileTap={{ scale: 0.97 }}
      transition={{
        repeat: Infinity,
        repeatType: "loop",
        repeatDelay: 1,
        type: "spring",
        stiffness: 20,
        damping: 15,
        mass: 2,
        scale: {
          type: "spring",
          stiffness: 10,
          damping: 5,
          mass: 0.1,
        },
      }}
      {...props}
    >
      <span className="text-neutral-100 tracking-wide font-light h-full w-full block relative linear-mask">
        {children}
      </span>
      <span className="block absolute inset-0 rounded-md p-px linear-overlay" />
    </motion.button>
  );
};

Update globals.css

.radial-gradient {
  background: radial-gradient(
      circle at 50% 0%,
      rgba(250, 250, 250, 0.05) 0%,
      transparent 60%
    ),
    rgba(15, 15, 15, 1);
}
 
.linear-mask {
  mask-image: linear-gradient(
    -75deg,
    white calc(var(--x) + 20%),
    transparent calc(var(--x) + 30%),
    white calc(var(--x) + 100%)
  );
}
 
.linear-overlay {
  background-image: linear-gradient(
    -75deg,
    rgba(255, 255, 255, 0.1) calc(var(--x) + 20%),
    rgba(255, 255, 255, 0.5) calc(var(--x) + 25%),
    rgba(255, 255, 255, 0.1) calc(var(--x) + 100%)
  );
 
  mask: linear-gradient(black, black) content-box, linear-gradient(black, black);
  mask-composite: exclude;
}

Update the import paths to match your project setup.

Usage

import { ShinyButton } from "@/components/atlas_ui/shiny-button";
<ShinyButton>Button</ShinyButton>