Ripple Button
ripple x clickButton with material ripple effect on click. From Animata.
buttonripplematerialanimata
Code
button-ripple.tsx
"use client";
import { useRef, useState } from "react";
export function RippleButton({ children }: { children: React.ReactNode }) {
const [ripples, setRipples] = useState<{ x: number; y: number; id: number }[]>([]);
const id = useRef(0);
function click(e: React.MouseEvent) {
const r = e.currentTarget.getBoundingClientRect();
const newRipple = { x: e.clientX - r.left, y: e.clientY - r.top, id: ++id.current };
setRipples(p => [...p, newRipple]);
setTimeout(() => setRipples(p => p.filter(r => r.id !== newRipple.id)), 600);
}
return (
<button onClick={click} className="relative overflow-hidden rounded-lg bg-brand px-6 py-2.5 text-sm font-medium text-brand-foreground">
{ripples.map(r => (
<span key={r.id} className="absolute size-20 -translate-x-1/2 -translate-y-1/2 animate-[ripple_0.6s_ease-out] rounded-full bg-white/30"
style={{ left: r.x, top: r.y }} />
))}
{children}
</button>
);
}
/* CSS: @keyframes ripple { 0% { transform: translate(-50%,-50%) scale(0); opacity: 0.5 } 100% { transform: translate(-50%,-50%) scale(4); opacity: 0 } } */Use it in another build
Paste the code into a component file, keep your project tokens (background, brand, radius) and it themes itself. Or tell Claude Code: “add the Ripple Button component and wire it to my accent.”


