UNPKG

@smart-react-components/ui

Version:
94 lines (93 loc) 4.53 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const dom_1 = require("@smart-react-components/core/util/dom"); const CSSTransitionGroup_1 = __importDefault(require("@smart-react-components/transition/CSSTransitionGroup")); const react_1 = __importDefault(require("react")); const styled_components_1 = require("styled-components"); const WaveEffectElement_1 = __importDefault(require("../components/WaveEffect/WaveEffectElement")); const WaveEffect = react_1.default.forwardRef(({ children, duration, palette = 'light' }, forwardRef) => { var _a; const theme = react_1.default.useContext(styled_components_1.ThemeContext); const [effectItems, setEffectItems] = react_1.default.useState(() => []); const isProcessing = react_1.default.useRef(false); const ref = (_a = (forwardRef !== null && forwardRef !== void 0 ? forwardRef : children.ref)) !== null && _a !== void 0 ? _a : react_1.default.useRef(null); const getDuration = () => duration !== null && duration !== void 0 ? duration : theme.$.transition.waveEffectDuration; react_1.default.useEffect(() => { if (effectItems.length > 0) { (0, dom_1.addEventListener)(window, [theme.$.vars.isMobile ? 'touchmove' : 'mousemove'], handleMove); (0, dom_1.addEventListener)(window, [theme.$.vars.isMobile ? 'touchend' : 'mouseup'], handleEnd); return () => { (0, dom_1.removeEventListener)(window, [theme.$.vars.isMobile ? 'touchmove' : 'mousemove'], handleMove); (0, dom_1.removeEventListener)(window, [theme.$.vars.isMobile ? 'touchend' : 'mouseup'], handleEnd); }; } }, [effectItems]); const handleMouseDown = (e) => { var _a, _b; (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a.onMouseDown) === null || _b === void 0 ? void 0 : _b.call(_a, e); if (!theme.$.vars.isMobile && e.button === 0) { start(e); } }; const handleTouchStart = (e) => { var _a, _b; (_b = (_a = children.props) === null || _a === void 0 ? void 0 : _a.onTouchStart) === null || _b === void 0 ? void 0 : _b.call(_a, e); start(e); }; const start = (e) => { isProcessing.current = true; const rect = ref.current.getBoundingClientRect(); const scale = (ref.current.clientWidth / 100) * 2; let left; let top; if (theme.$.vars.isMobile) { const t = e.touches[0]; left = (t.pageX - window.pageXOffset) - rect.left; top = (t.pageY - window.pageYOffset) - rect.top; } else { left = e.clientX - rect.left; top = e.clientY - rect.top; } setEffectItems([ ...effectItems, { element: (react_1.default.createElement(WaveEffectElement_1.default, { key: new Date().getTime(), duration: getDuration() / 2, left: left, palette: palette, scale: scale, top: top })), endTime: new Date().getTime() + getDuration(), }, ]); }; const handleMove = (e) => { if (e.target !== ref.current && !ref.current.contains(e.target)) { handleEnd(); } }; const handleEnd = () => { isProcessing.current = false; const time = new Date().getTime(); setEffectItems(effectItems.filter(e => e.endTime >= time)); }; const handleAfterShow = (child) => { if (!isProcessing.current || (isProcessing.current && effectItems.findIndex(e => e.element.key === child.key) + 1 < effectItems.length)) { setEffectItems(effectItems.filter(e => e.element.key !== child.key)); } }; return react_1.default.cloneElement(children, { children: (react_1.default.createElement(react_1.default.Fragment, null, children.props.children, react_1.default.createElement(CSSTransitionGroup_1.default, { afterShow: handleAfterShow, className: "src-wave-effect", duration: getDuration() / 2 }, effectItems.map(e => e.element)))), isolation: 'isolate', onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, overflow: 'hidden', position: 'relative', ref, webkitTapHighlightColor: 'transparent', }); }); exports.default = WaveEffect;