UNPKG

@nex-ui/react

Version:

🎉 A beautiful, modern, and reliable React component library.

122 lines (116 loc) • 4.5 kB
"use client"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var hooks = require('@nex-ui/hooks'); var utils = require('@nex-ui/utils'); var react$1 = require('motion/react'); var m = require('motion/react-m'); var react = require('react'); var client = require('react-dom/client'); var index = require('../motionFeatures/index.cjs'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var m__namespace = /*#__PURE__*/_interopNamespace(m); const useRippleMotion = (props)=>{ const { motionProps, motionStyle } = props ?? {}; const rootRef = react.useRef(null); const ripplesRef = react.useRef([]); return hooks.useEvent((event)=>{ const trigger = event.currentTarget; if (!rootRef.current) { const div = document.createElement('div'); div.style.position = 'absolute'; div.style.left = '0'; div.style.top = '0'; const root = client.createRoot(div); trigger.insertBefore(div, trigger.firstChild); // @ts-expect-error root.stateNode = div; rootRef.current = root; } const { width, height, top, left } = trigger.getBoundingClientRect(); const rippleSize = Math.max(width, height); let x; let y; if (event.clientX !== 0 && event.clientY !== 0) { x = event.clientX - left; y = event.clientY - top; } else { x = width / 2; y = height / 2; } ripplesRef.current.push({ key: `${Math.random()}`, size: rippleSize, x: x - rippleSize / 2, y: y - rippleSize / 2 }); rootRef.current.render(/*#__PURE__*/ jsxRuntime.jsx(react$1.LazyMotion, { features: index.motionFeatures, children: ripplesRef.current.map((ripple)=>{ const duration = utils.clamp(0.01 * ripple.size, 0.2, ripple.size > 100 ? 0.75 : 0.5); return /*#__PURE__*/ jsxRuntime.jsx(react$1.AnimatePresence, { mode: "popLayout", children: /*#__PURE__*/ jsxRuntime.jsx(m__namespace.span, { animate: { transform: 'scale(2)', opacity: 0 }, className: "nui-ripple", exit: { opacity: 0 }, initial: { transform: 'scale(0)', opacity: 0.35 }, style: { position: 'absolute', backgroundColor: 'currentcolor', borderRadius: '100%', transformOrigin: 'center', pointerEvents: 'none', overflow: 'hidden', inset: 0, zIndex: 0, top: ripple.y, left: ripple.x, width: `${ripple.size}px`, height: `${ripple.size}px`, ...motionStyle }, transition: { duration }, onAnimationComplete: ()=>{ ripplesRef.current = ripplesRef.current.filter(({ key })=>ripple.key !== key); if (!ripplesRef.current.length) { rootRef.current?.unmount(); // @ts-expect-error trigger.removeChild(rootRef.current.stateNode); rootRef.current = null; } }, ...motionProps }) }, ripple.key); }) })); }); }; exports.useRippleMotion = useRippleMotion;