diff --git a/registry/default/example/ripple-button-demo.tsx b/registry/default/example/ripple-button-demo.tsx index 192585ef..ec80d3c8 100644 --- a/registry/default/example/ripple-button-demo.tsx +++ b/registry/default/example/ripple-button-demo.tsx @@ -1,5 +1,5 @@ import RippleButton from "@/registry/default/magicui/ripple-button"; export default function RippleButtonDemo() { - return It's Rippling!; + return Click me; } diff --git a/registry/default/magicui/ripple-button.tsx b/registry/default/magicui/ripple-button.tsx index b53cd9a5..ebbe7a70 100644 --- a/registry/default/magicui/ripple-button.tsx +++ b/registry/default/magicui/ripple-button.tsx @@ -9,66 +9,82 @@ interface RippleButtonProps duration?: string; } -export default function RippleButton({ - className, - children, - rippleColor = "#ffffff", - duration = "600ms", - ...props -}: RippleButtonProps) { - const [buttonRipples, setButtonRipples] = useState< - Array<{ x: number; y: number; size: number; key: number }> - >([]); +const RippleButton = React.forwardRef( + ( + { + className, + children, + rippleColor = "#ffffff", + duration = "600ms", + onClick, + ...props + }, + ref, + ) => { + const [buttonRipples, setButtonRipples] = useState< + Array<{ x: number; y: number; size: number; key: number }> + >([]); - const createRipple = (event: MouseEvent) => { - const button = event.currentTarget; - const rect = button.getBoundingClientRect(); - const size = Math.max(rect.width, rect.height); - const x = event.clientX - rect.left - size / 2; - const y = event.clientY - rect.top - size / 2; + const handleClick = (event: MouseEvent) => { + createRipple(event); + onClick?.(event); + }; - const newRipple = { x, y, size, key: Date.now() }; - setButtonRipples((prevRipples) => [...prevRipples, newRipple]); - }; + const createRipple = (event: MouseEvent) => { + const button = event.currentTarget; + const rect = button.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + const x = event.clientX - rect.left - size / 2; + const y = event.clientY - rect.top - size / 2; - useEffect(() => { - if (buttonRipples.length > 0) { - const lastRipple = buttonRipples[buttonRipples.length - 1]; - const timeout = setTimeout(() => { - setButtonRipples((prevRipples) => - prevRipples.filter((ripple) => ripple.key !== lastRipple.key), - ); - }, parseInt(duration)); - return () => clearTimeout(timeout); - } - }, [buttonRipples, duration]); + const newRipple = { x, y, size, key: Date.now() }; + setButtonRipples((prevRipples) => [...prevRipples, newRipple]); + }; - return ( - - ); -} + useEffect(() => { + if (buttonRipples.length > 0) { + const lastRipple = buttonRipples[buttonRipples.length - 1]; + const timeout = setTimeout(() => { + setButtonRipples((prevRipples) => + prevRipples.filter((ripple) => ripple.key !== lastRipple.key), + ); + }, parseInt(duration)); + return () => clearTimeout(timeout); + } + }, [buttonRipples, duration]); + + return ( + + ); + }, +); + +RippleButton.displayName = "RippleButton"; + +export default RippleButton;