react-ripple-click
Version:
Ripple effect for your buttons.
66 lines (63 loc) • 2.65 kB
JavaScript
"use client";
import { __spreadArray } from './_virtual/_tslib.js';
import { jsx } from 'react/jsx-runtime';
import { useState, useRef, useCallback, useEffect } from 'react';
import styles from './Ripple.module.css.js';
var interactiveElementSelector = 'a, button';
var Ripple = function () {
var _a = useState([]), ripples = _a[0], setRipples = _a[1];
var ref = useRef(null);
var handlePointerDown = useCallback(function (event) {
var _a;
var rippleElement = ref.current;
if (!rippleElement) {
return;
}
var parent = (_a = rippleElement.parentElement) === null || _a === void 0 ? void 0 : _a.closest(interactiveElementSelector);
if (!parent) {
return;
}
if (!(event.target instanceof HTMLElement) &&
!(event.target instanceof SVGElement)) {
return;
}
var interactedWithElement = event.target.closest(interactiveElementSelector);
if (interactedWithElement !== parent) {
return;
}
if (interactedWithElement instanceof HTMLButtonElement &&
interactedWithElement.disabled) {
return;
}
var rect = parent.getBoundingClientRect();
var size = 2 * Math.sqrt(Math.pow(rect.width, 2) + Math.pow(rect.height, 2));
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
setRipples(function (ripples) { return __spreadArray(__spreadArray([], ripples, true), [
{
id: event.timeStamp,
size: size,
x: x,
y: y,
},
], false); });
}, []);
useEffect(function () {
document.body.addEventListener('pointerdown', handlePointerDown);
return function () {
document.body.removeEventListener('pointerdown', handlePointerDown);
};
}, [handlePointerDown]);
var discardRipple = useCallback(function (rippleId) {
setRipples(function (ripples) { return ripples.filter(function (ripple) { return ripple.id !== rippleId; }); });
}, []);
return (jsx("span", { ref: ref, className: styles.wrapper, children: ripples.map(function (ripple) { return (jsx("span", { className: styles.ripple, style: {
'--Ripple-size': "".concat(ripple.size, "px"),
'--Ripple-x': "".concat(ripple.x, "px"),
'--Ripple-y': "".concat(ripple.y, "px"),
}, onAnimationEnd: function () {
discardRipple(ripple.id);
} }, ripple.id)); }) }));
};
export { Ripple };
//# sourceMappingURL=Ripple.js.map