Installation
Copy and paste the following code into your project.
// tailwind.config.js
module.exports = {
theme: {
extend: {
animation: {
"spin-around": "spin-around calc(var(--speed) * 2) infinite linear",
slide: "slide var(--speed) ease-in-out infinite alternate",
},
keyframes: {
"spin-around": {
"0%": {
transform: "translateZ(0) rotate(0)",
},
"15%, 35%": {
transform: "translateZ(0) rotate(90deg)",
},
"65%, 85%": {
transform: "translateZ(0) rotate(270deg)",
},
"100%": {
transform: "translateZ(0) rotate(360deg)",
},
},
slide: {
to: {
transform: "translate(calc(100cqw - 100%), 0)",
},
},
},
},
},
};
components/magicui/shimmer-button.tsx
import { cn } from "@/lib/utils";
import React, { CSSProperties } from "react";
export interface ShimmerButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
shimmerColor?: string;
shimmerSize?: string;
borderRadius?: string;
shimmerDuration?: string;
background?: string;
className?: string;
children?: React.ReactNode;
}
const ShimmerButton = React.forwardRef<HTMLButtonElement, ShimmerButtonProps>(
(
{
shimmerColor = "#ffffff",
shimmerSize = "0.05em",
shimmerDuration = "3s",
borderRadius = "100px",
background = "rgba(0, 0, 0, 1)",
className,
children,
...props
},
ref,
) => {
return (
<button
style={
{
"--spread": "90deg",
"--shimmer-color": shimmerColor,
"--radius": borderRadius,
"--speed": shimmerDuration,
"--cut": shimmerSize,
"--bg": background,
} as CSSProperties
}
className={cn(
"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",
"transform-gpu transition-transform duration-300 ease-in-out active:translate-y-[1px]",
className,
)}
ref={ref}
{...props}
>
{/* spark container */}
<div
className={cn(
"-z-30 blur-[2px]",
"absolute inset-0 overflow-visible [container-type:size]",
)}
>
{/* spark */}
<div className="absolute inset-0 h-[100cqh] animate-slide [aspect-ratio:1] [border-radius:0] [mask:none]">
{/* spark before */}
<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]" />
</div>
</div>
{children}
{/* Highlight */}
<div
className={cn(
"insert-0 absolute h-full w-full",
"rounded-2xl px-4 py-1.5 text-sm font-medium shadow-[inset_0_-8px_10px_#ffffff1f]",
// transition
"transform-gpu transition-all duration-300 ease-in-out",
// on hover
"group-hover:shadow-[inset_0_-6px_10px_#ffffff3f]",
// on click
"group-active:shadow-[inset_0_-10px_10px_#ffffff3f]",
)}
/>
{/* backdrop */}
<div
className={cn(
"absolute -z-20 [background:var(--bg)] [border-radius:var(--radius)] [inset:var(--cut)]",
)}
/>
</button>
);
},
);
ShimmerButton.displayName = "ShimmerButton";
export default ShimmerButton;
Props
Prop Name | Type | Description | Default Value |
---|---|---|---|
shimmerColor | string | The color of the shimmer | #ffffff |
shimmerSize | string | The size of the shimmer | 0.05em |
borderRadius | string | The border radius of the button | 100px |
sparkDuration | string | The duration of the spark animation | 3s |
background | string | The background of the button | rgba(0, 0, 0, 1) |
className | string | The class name of the button | undefined |
children | React.ReactNode | The children of the button | undefined |
Credits
Credit to @jh3yy for the inspiration behind this component.