@smart-react-components/ui
Version:
SRC UI includes React and Styled components.
94 lines (93 loc) • 4.53 kB
JavaScript
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;
;