/ app / src / components / magicui / shimmer-button.tsx
shimmer-button.tsx
 1  import { cn } from "@/lib/utils";
 2  import React, { CSSProperties } from "react";
 3  
 4  export interface ShimmerButtonProps
 5    extends React.ButtonHTMLAttributes<HTMLButtonElement> {
 6    shimmerColor?: string;
 7    shimmerSize?: string;
 8    borderRadius?: string;
 9    shimmerDuration?: string;
10    background?: string;
11    className?: string;
12    children?: React.ReactNode;
13  }
14  
15  const ShimmerButton = React.forwardRef<HTMLButtonElement, ShimmerButtonProps>(
16    (
17      {
18        shimmerColor = "#ffffff",
19        shimmerSize = "0.05em",
20        shimmerDuration = "3s",
21        borderRadius = "100px",
22        background = "rgba(0, 0, 0, 1)",
23        className,
24        children,
25        ...props
26      },
27      ref,
28    ) => {
29      return (
30        <button
31          style={
32            {
33              "--spread": "90deg",
34              "--shimmer-color": shimmerColor,
35              "--radius": borderRadius,
36              "--speed": shimmerDuration,
37              "--cut": shimmerSize,
38              "--bg": background,
39            } as CSSProperties
40          }
41          className={cn(
42            "group relative z-0 flex cursor-pointer items-center justify-center overflow-hidden whitespace-nowrap border border-white/10 px-6 py-3 text-white [background:var(--bg)] [border-radius:var(--radius)] dark:text-black",
43            "transform-gpu transition-transform duration-300 ease-in-out active:translate-y-[1px]",
44            className,
45          )}
46          ref={ref}
47          {...props}
48        >
49          {/* spark container */}
50          <div
51            className={cn(
52              "-z-30 blur-[2px]",
53              "absolute inset-0 overflow-visible [container-type:size]",
54            )}
55          >
56            {/* spark */}
57            <div className="absolute inset-0 h-[100cqh] animate-slide [aspect-ratio:1] [border-radius:0] [mask:none]">
58              {/* spark before */}
59              <div className="animate-spin-around absolute inset-[-100%] w-auto rotate-0 [background:conic-gradient(from_calc(270deg-(var(--spread)*0.5)),transparent_0,var(--shimmer-color)_var(--spread),transparent_var(--spread))] [translate:0_0]" />
60            </div>
61          </div>
62          {children}
63  
64          {/* Highlight */}
65          <div
66            className={cn(
67              "insert-0 absolute h-full w-full",
68  
69              "rounded-2xl px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#ffffff1f]",
70  
71              // transition
72              "transform-gpu transition-all duration-300 ease-in-out",
73  
74              // on hover
75              "group-hover:shadow-[inset_0_-6px_10px_#ffffff3f]",
76  
77              // on click
78              "group-active:shadow-[inset_0_-10px_10px_#ffffff3f]",
79            )}
80          />
81  
82          {/* backdrop */}
83          <div
84            className={cn(
85              "absolute -z-20 [background:var(--bg)] [border-radius:var(--radius)] [inset:var(--cut)]",
86            )}
87          />
88        </button>
89      );
90    },
91  );
92  
93  ShimmerButton.displayName = "ShimmerButton";
94  
95  export default ShimmerButton;