Customize
Usage
import { ShimmerButton } from "@/components/motionkit/shimmer-button";
<ShimmerButton>Upgrade to Pro</ShimmerButton>Motion
The exact curves this component runs, plotted with Motion's own maths.
Light sweep
Runs on its own
Works in the App Router as is. Requires Tailwind CSS v4.
npm install motionSave as components/motionkit/shimmer-button.tsx.
"use client";
import type { ComponentProps, ReactNode } from "react";
import { motion, useReducedMotion } from "motion/react";
type ShimmerButtonProps = Omit<ComponentProps<typeof motion.button>, "ref" | "children"> & {
children?: ReactNode;
/** Seconds for one sweep of the shine. */
duration?: number;
};
export function ShimmerButton({
duration = 2.4,
className = "",
children,
...props
}: ShimmerButtonProps) {
const reduceMotion = useReducedMotion();
return (
<motion.button
whileHover={reduceMotion ? undefined : { y: -2 }}
whileTap={{ scale: 0.97 }}
className={`group relative isolate inline-flex items-center justify-center gap-2 overflow-hidden rounded-xl border border-[#2E9098]/40 bg-[#0C1010] px-5 py-3 text-sm font-medium text-[#E6F2F3] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#5FAEB4] ${className}`}
{...props}
>
{/* soft under-glow that brightens on hover */}
<span
aria-hidden
className="absolute inset-0 -z-10 rounded-xl bg-[radial-gradient(120%_120%_at_50%_120%,rgb(14_124_134/0.45),transparent_60%)] opacity-70 transition-opacity group-hover:opacity-100"
/>
{!reduceMotion && (
<motion.span
aria-hidden
initial={{ x: "-120%" }}
animate={{ x: "220%" }}
transition={{ duration, repeat: Infinity, ease: "easeInOut", repeatDelay: 0.6 }}
className="pointer-events-none absolute inset-y-0 left-0 w-1/2 -skew-x-12 bg-gradient-to-r from-transparent via-white/25 to-transparent"
/>
)}
<span className="relative inline-flex items-center gap-2">{children}</span>
</motion.button>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
| duration | number | 2.4 | Seconds for one sweep of the shine. |
| ...props | motion.button props | — | Any button or Motion prop. |
Magnetic Button
A button that leans toward the cursor with a springy, physical pull.
Hold to Confirm
A button that fills while held, so destructive actions can never happen by accident.
Submit Button
Morphs from its label to a spinner, then to a drawn tick or a shake, so every save feels answered.