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