@arolariu/components
Version:
🎨 70+ beautiful, accessible React components built on Base UI. TypeScript-first, CSS Modules styling, tree-shakeable, SSR-ready. Perfect for modern web apps, design systems & rapid prototyping. Zero config, maximum flexibility! ⚡
89 lines (88 loc) • 3.18 kB
JavaScript
"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import { motion } from "motion/react";
import { cn } from "../../lib/utilities.js";
import ripple_button_module from "./ripple-button.module.js";
import * as __rspack_external_react from "react";
const RippleButton = /*#__PURE__*/ __rspack_external_react.forwardRef(({ children, onClick, className, rippleClassName, scale = 10, transition = {
duration: 0.6,
ease: "easeOut"
}, ...props }, ref)=>{
const { key: _ignoredKey, ...restProps } = props;
const [ripples, setRipples] = __rspack_external_react.useState([]);
const buttonRef = __rspack_external_react.useRef(null);
const timeoutIdsRef = __rspack_external_react.useRef([]);
__rspack_external_react.useImperativeHandle(ref, ()=>buttonRef.current, []);
__rspack_external_react.useEffect(()=>()=>{
timeoutIdsRef.current.forEach((timeoutId)=>{
globalThis.window.clearTimeout(timeoutId);
});
}, []);
const createRipple = __rspack_external_react.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((previousRipples)=>[
...previousRipples,
newRipple
]);
const timeoutId = globalThis.window.setTimeout(()=>{
setRipples((previousRipples)=>previousRipples.filter((ripple)=>ripple.id !== newRipple.id));
}, 600);
timeoutIdsRef.current = [
...timeoutIdsRef.current,
timeoutId
];
}, []);
const handleClick = __rspack_external_react.useCallback((event)=>{
createRipple(event);
onClick?.(event);
}, [
createRipple,
onClick
]);
return /*#__PURE__*/ jsxs(motion.button, {
ref: buttonRef,
onClick: handleClick,
whileTap: {
scale: 0.95
},
whileHover: {
scale: 1.05
},
className: cn(ripple_button_module.button, className),
...restProps,
children: [
/*#__PURE__*/ jsx("span", {
className: ripple_button_module.content,
children: children
}),
ripples.map((ripple)=>/*#__PURE__*/ jsx(motion.span, {
initial: {
scale: 0,
opacity: 0.5
},
animate: {
scale,
opacity: 0
},
transition: transition,
className: cn(ripple_button_module.ripple, rippleClassName),
style: {
top: ripple.y - 10,
left: ripple.x - 10
}
}, ripple.id))
]
});
});
RippleButton.displayName = "RippleButton";
export { RippleButton };
//# sourceMappingURL=ripple-button.js.map