UNPKG

@smart-react-components/ui

Version:
217 lines (216 loc) 10.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const dom_1 = require("@smart-react-components/core/util/dom"); const react_1 = require("react"); const styled_components_1 = require("styled-components"); const types_1 = require("../types"); const dom_2 = require("../util/dom"); const useFixedBoxMethods = ({ beforeShow, boxEl, getTriggerEl, handlePosition, hoverDelay, isDismissible, key, setStatus, status, triggerInteraction }) => { const theme = (0, styled_components_1.useTheme)(); const enterTimeout = (0, react_1.useRef)(null); const enterTimeoutMouseMove = (0, react_1.useRef)(null); const leaveTimeout = (0, react_1.useRef)(null); const mouseEvent = (0, react_1.useRef)(null); const touchStartDate = (0, react_1.useRef)(null); const [localStatus, setLocalStatus] = (0, react_1.useState)(() => false); const getStatus = () => status !== null && status !== void 0 ? status : localStatus; const getSetStatus = () => setStatus !== null && setStatus !== void 0 ? setStatus : setLocalStatus; const handleTriggerClick = (e) => { mouseEvent.current = null; const triggerEl = getTriggerEl(); if ((0, dom_2.isTargetClickable)(e.target, triggerEl)) { getSetStatus()(!getStatus()); } }; const handleTriggerRightClick = e => { e.preventDefault(); mouseEvent.current = e; const triggerEl = getTriggerEl(); if ((0, dom_2.isTargetClickable)(e.target, triggerEl)) { getSetStatus()(true); } }; const handleTriggerLongTouchStart = e => { mouseEvent.current = e; touchStartDate.current = Date.now(); const triggerEl = getTriggerEl(); (0, dom_1.addEventListener)(triggerEl, ['touchmove'], handleTriggerLongTouchMove); (0, dom_1.addEventListener)(triggerEl, ['touchend'], handleTriggerLongTouchEnd); setTimeout(() => { if (touchStartDate.current) { touchStartDate.current = null; (0, dom_1.removeEventListener)(triggerEl, ['touchmove'], handleTriggerLongTouchMove); (0, dom_1.removeEventListener)(triggerEl, ['touchend'], handleTriggerLongTouchEnd); setStatus(true); } }, 1500); }; const handleTriggerLongTouchMove = e => { if (touchStartDate.current) { const triggerEl = getTriggerEl(); const touch = e.touches[0]; const x = touch.pageX; const y = touch.pageY; const triggerRect = triggerEl.getBoundingClientRect(); if (x < triggerRect.left || x > triggerRect.right || y < triggerRect.top || y > triggerRect.bottom) { touchStartDate.current = null; (0, dom_1.removeEventListener)(triggerEl, ['touchmove'], handleTriggerLongTouchMove); (0, dom_1.removeEventListener)(triggerEl, ['touchend'], handleTriggerLongTouchEnd); } else { mouseEvent.current = e; } } }; const handleTriggerLongTouchEnd = e => { if (touchStartDate.current) { touchStartDate.current = null; const triggerEl = getTriggerEl(); (0, dom_1.removeEventListener)(triggerEl, ['touchmove'], handleTriggerLongTouchMove); (0, dom_1.removeEventListener)(triggerEl, ['touchend'], handleTriggerLongTouchEnd); } }; const handleTriggerMouseEnter = e => { mouseEvent.current = null; if (e.target === getTriggerEl()) { if (hoverDelay) { if (!enterTimeout.current) { enterTimeout.current = setTimeout(() => getSetStatus()(true), hoverDelay); enterTimeoutMouseMove.current = handleWindowMouseMove; (0, dom_1.addEventListener)(window, ['mousemove'], enterTimeoutMouseMove.current); } } else { getSetStatus()(true); } } }; const handleWindowClick = (e) => { mouseEvent.current = null; const target = e.target; const triggerEl = getTriggerEl(); if (!triggerEl.contains(target) && !boxEl.current.contains(target) && !target.closest('[data-src-not-clickable]')) { getSetStatus()(false); } }; const handleWindowMouseMove = (e) => { var _a; const target = e.target; const triggerEl = getTriggerEl(); if (!triggerEl.contains(target) && !((_a = boxEl.current) === null || _a === void 0 ? void 0 : _a.contains(target))) { if (enterTimeout.current) { (0, dom_1.removeEventListener)(window, ['mousemove'], enterTimeoutMouseMove.current); enterTimeoutMouseMove.current = null; clearTimeout(enterTimeout.current); enterTimeout.current = null; } if (!leaveTimeout.current) { leaveTimeout.current = setTimeout(() => { clearTimeout(leaveTimeout.current); leaveTimeout.current = null; getSetStatus()(false); }, 250); } } else if (leaveTimeout.current) { clearTimeout(leaveTimeout.current); leaveTimeout.current = null; } }; const handleBeforeShow = el => new Promise((resolve) => __awaiter(void 0, void 0, void 0, function* () { yield (beforeShow === null || beforeShow === void 0 ? void 0 : beforeShow(el)); handlePosition(mouseEvent.current); resolve(); })); (0, react_1.useEffect)(() => { if (getStatus()) { handlePosition(null); } }, []); (0, react_1.useEffect)(() => { const triggerEl = getTriggerEl(); const debounceWindowMouseMove = (0, dom_1.debounce)(handleWindowMouseMove); const debouncePosition = (0, dom_1.debounce)(e => { if (!boxEl.current.contains(e.target)) { handlePosition(mouseEvent.current); } }); const handlePositionBind = () => handlePosition(mouseEvent.current); if (triggerInteraction & types_1.TriggerInteraction.CLICK) { (0, dom_1.addEventListener)(triggerEl, ['click'], handleTriggerClick); if (getStatus() && isDismissible) { (0, dom_1.addEventListener)(window, ['click'], handleWindowClick); } } if (!theme.$.vars.isMobile && triggerInteraction & types_1.TriggerInteraction.HOVER) { if (!getStatus()) { (0, dom_1.addEventListener)(triggerEl, ['mouseenter'], handleTriggerMouseEnter); } else { (0, dom_1.addEventListener)(window, ['mousemove'], debounceWindowMouseMove); } } if (triggerInteraction & types_1.TriggerInteraction.RIGHT_CLICK) { if (theme.$.vars.isMobile) { (0, dom_1.addEventListener)(triggerEl, ['touchstart'], handleTriggerLongTouchStart); } else { (0, dom_1.addEventListener)(triggerEl, ['contextmenu'], handleTriggerRightClick); } if (getStatus()) { (0, dom_1.addEventListener)(triggerEl, ['click'], handleTriggerClick); (0, dom_1.addEventListener)(window, ['click', 'contextmenu'], handleWindowClick); } } if (getStatus()) { (0, dom_1.addEventListener)(window, ['resize', 'scroll'], debouncePosition); } (0, dom_1.addEventListener)(triggerEl, ['src.fixedBox.setPosition'], handlePositionBind); return () => { if (triggerInteraction & types_1.TriggerInteraction.CLICK) { (0, dom_1.removeEventListener)(triggerEl, ['click'], handleTriggerClick); if (getStatus() && isDismissible) { (0, dom_1.removeEventListener)(window, ['click'], handleWindowClick); } } if (!theme.$.vars.isMobile && triggerInteraction & types_1.TriggerInteraction.HOVER) { if (!getStatus()) { (0, dom_1.removeEventListener)(triggerEl, ['mouseenter'], handleTriggerMouseEnter); } else { (0, dom_1.removeEventListener)(window, ['mousemove'], debounceWindowMouseMove); } } if (triggerInteraction & types_1.TriggerInteraction.RIGHT_CLICK) { if (theme.$.vars.isMobile) { (0, dom_1.removeEventListener)(triggerEl, ['touchstart'], handleTriggerLongTouchStart); } else { (0, dom_1.removeEventListener)(triggerEl, ['contextmenu'], handleTriggerRightClick); } if (getStatus()) { (0, dom_1.removeEventListener)(triggerEl, ['click'], handleTriggerClick); (0, dom_1.removeEventListener)(window, ['click', 'contextmenu'], handleWindowClick); } } if (getStatus()) { (0, dom_1.removeEventListener)(window, ['resize', 'scroll'], debouncePosition); } (0, dom_1.removeEventListener)(triggerEl, [`src.${key}.setPosition`], handlePositionBind); }; }, [status, setStatus, localStatus, setLocalStatus, triggerInteraction]); return { getStatus, handleBeforeShow, }; }; exports.default = useFixedBoxMethods;