@arolariu/components
Version:
🎨 70+ beautiful, accessible React components built on Radix UI. TypeScript-first, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡
74 lines (73 loc) • 2.54 kB
JavaScript
"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { motion } from "motion/react";
import { forwardRef, useCallback, useImperativeHandle, useRef, useState } from "react";
import { cn } from "../../lib/utilities.js";
const RippleButton = /*#__PURE__*/ forwardRef(({ children, onClick, className, rippleClassName, scale = 10, transition = {
duration: 0.6,
ease: "easeOut"
}, ...props }, ref)=>{
const [ripples, setRipples] = useState([]);
const buttonRef = useRef(null);
useImperativeHandle(ref, ()=>buttonRef.current);
const createRipple = useCallback((event)=>{
const button = buttonRef.current;
if (!button) return;
const rect = button.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const newRipple = {
id: Date.now(),
x,
y
};
setRipples((prev)=>[
...prev,
newRipple
]);
setTimeout(()=>{
setRipples((prev)=>prev.filter((r)=>r.id !== newRipple.id));
}, 600);
}, []);
const handleClick = useCallback((event)=>{
createRipple(event);
if (onClick) onClick(event);
}, [
createRipple,
onClick
]);
return /*#__PURE__*/ jsxs(motion.button, {
ref: buttonRef,
onClick: handleClick,
whileTap: {
scale: 0.95
},
whileHover: {
scale: 1.05
},
className: cn("text-primary-foreground bg-primary relative h-10 cursor-pointer overflow-hidden rounded-lg px-4 py-2 text-sm font-medium focus:outline-none", className),
...props,
children: [
children,
ripples.map((ripple)=>/*#__PURE__*/ jsx(motion.span, {
initial: {
scale: 0,
opacity: 0.5
},
animate: {
scale,
opacity: 0
},
transition: transition,
className: cn("bg-primary-foreground pointer-events-none absolute size-5 rounded-full", rippleClassName),
style: {
top: ripple.y - 10,
left: ripple.x - 10
}
}, ripple.id))
]
});
});
RippleButton.displayName = "RippleButton";
export { RippleButton };
//# sourceMappingURL=ripple-button.js.map