@trap_stevo/legendarybuilderproreact-ui
Version:
The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton
548 lines • 23.2 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
import { useState, useEffect, useRef, useCallback, useLayoutEffect } from "react";
export var useBoundsDetection = function useBoundsDetection(containerRef, itemsRefs, data, onDetection) {
useEffect(function () {
var container = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
if (!container || !itemsRefs) {
return;
}
var handleScroll = function handleScroll() {
var containerRect = container.getBoundingClientRect();
Object.entries(itemsRefs).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
itemRef = _ref2[1];
var item = itemRef === null || itemRef === void 0 ? void 0 : itemRef.current;
if (!item) {
return;
}
var itemRect = item.getBoundingClientRect();
var itemInView = itemRect.left < containerRect.right && itemRect.right > containerRect.left;
if (onDetection) {
var itemData = data[key] || {};
onDetection(key, itemData, itemInView, itemRef);
}
});
};
container.addEventListener("scroll", handleScroll);
return function () {
container.removeEventListener("scroll", handleScroll);
};
}, [containerRef, itemsRefs, data]);
};
export var useIdleDetection = function useIdleDetection(callback) {
var idleTimeLimit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5000;
var autoListen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var lastActivityTimestamp = useRef(Date.now());
var idleInterval = useRef(null);
var resetIdleTimer = function resetIdleTimer() {
lastActivityTimestamp.current = Date.now();
if (!idleInterval.current) {
startIdleInterval();
}
};
var startIdleInterval = function startIdleInterval() {
idleInterval.current = setInterval(function () {
var currentTime = Date.now();
var timeSinceLastActivity = currentTime - lastActivityTimestamp.current;
if (timeSinceLastActivity > idleTimeLimit) {
console.log("Idle state detected!");
callback();
clearInterval(idleInterval.current);
idleInterval.current = null;
}
}, 1000);
};
useEffect(function () {
if (autoListen) {
var activityEvents = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
var handleActivity = function handleActivity() {
return resetIdleTimer();
};
activityEvents.forEach(function (event) {
return window.addEventListener(event, handleActivity);
});
startIdleInterval();
return function () {
activityEvents.forEach(function (event) {
return window.removeEventListener(event, handleActivity);
});
if (idleInterval.current) {
clearInterval(idleInterval.current);
idleInterval.current = null;
}
};
}
startIdleInterval();
return function () {
if (idleInterval.current) {
clearInterval(idleInterval.current);
idleInterval.current = null;
}
};
}, [autoListen]);
return resetIdleTimer;
};
export function useTimeout() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _options$multiple = options.multiple,
multiple = _options$multiple === void 0 ? false : _options$multiple;
var timeoutRef = useRef(null);
var initialize = useCallback(function () {
if (multiple && (timeoutRef.current === null || !(timeoutRef.current instanceof Set))) {
timeoutRef.current = new Set();
} else if (!multiple && timeoutRef.current instanceof Set) {
timeoutRef.current = null;
}
}, [multiple]);
var cancelSchedule = useCallback(function () {
var id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
initialize();
if (multiple) {
if (id !== null) {
clearTimeout(id);
timeoutRef.current["delete"](id);
return;
}
var _iterator = _createForOfIteratorHelper(timeoutRef.current),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var timeoutID = _step.value;
clearTimeout(timeoutID);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
timeoutRef.current.clear();
return;
}
if (timeoutRef.current !== null) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
}, [multiple]);
var schedule = useCallback(function (callback, delay) {
initialize();
if (!multiple) {
cancelSchedule();
timeoutRef.current = setTimeout(function () {
try {
callback();
} finally {
cancelSchedule();
}
}, delay);
return;
}
var id = setTimeout(function () {
try {
callback();
} finally {
timeoutRef.current["delete"](id);
}
}, delay);
timeoutRef.current.add(id);
return id;
}, [multiple, cancelSchedule]);
useEffect(function () {
return function () {
return cancelSchedule();
};
}, [cancelSchedule]);
return {
schedule: schedule,
cancelSchedule: cancelSchedule
};
}
;
export function useScrollActivityTracker() {
var configurations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _configurations$targe = configurations.targetRef,
targetRef = _configurations$targe === void 0 ? null : _configurations$targe,
onScrollDirectionUpdate = configurations.onScrollDirectionUpdate,
onScrollPositionUpdate = configurations.onScrollPositionUpdate,
onScrollUpdate = configurations.onScrollUpdate,
_configurations$onScr = configurations.onScrollAt,
onScrollAt = _configurations$onScr === void 0 ? [] : _configurations$onScr,
onStart = configurations.onStart,
onStop = configurations.onStop,
onVelocityUpdate = configurations.onVelocityUpdate,
onAtPosition = configurations.onAtPosition,
_configurations$idleD = configurations.idleDelay,
idleDelay = _configurations$idleD === void 0 ? 200 : _configurations$idleD,
_configurations$thres = configurations.threshold,
threshold = _configurations$thres === void 0 ? 2 : _configurations$thres,
_configurations$track = configurations.trackHorizontal,
trackHorizontal = _configurations$track === void 0 ? false : _configurations$track,
_configurations$cente = configurations.centerTolerance,
centerTolerance = _configurations$cente === void 0 ? 0.05 : _configurations$cente,
_configurations$scrol = configurations.scrollYDebounceDelay,
scrollYDebounceDelay = _configurations$scrol === void 0 ? 100 : _configurations$scrol,
_configurations$scrol2 = configurations.scrollXDebounceDelay,
scrollXDebounceDelay = _configurations$scrol2 === void 0 ? 100 : _configurations$scrol2;
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
scrolling = _useState2[0],
setScrolling = _useState2[1];
var _useState3 = useState(0),
_useState4 = _slicedToArray(_useState3, 2),
scrollY = _useState4[0],
setScrollY = _useState4[1];
var _useState5 = useState(0),
_useState6 = _slicedToArray(_useState5, 2),
scrollX = _useState6[0],
setScrollX = _useState6[1];
var scrollingIdleActivated = useRef(true);
var scrollDirectionRef = useRef(null);
var debounceTimeoutY = useRef(null);
var debounceTimeoutX = useRef(null);
var lastTime = useRef(Date.now());
var scrollVelocityRef = useRef(0);
var firedRef = useRef(new Set());
var atBottomRef = useRef(false);
var atCenterRef = useRef(false);
var atTopRef = useRef(false);
var scrollYRef = useRef(0);
var scrollXRef = useRef(0);
var lastY = useRef(0);
var currentlyScrolling = useIdleDetection(function () {
if (scrollingIdleActivated.current) {
return;
}
scrollingIdleActivated.current = true;
setScrolling(false);
onScrollUpdate === null || onScrollUpdate === void 0 || onScrollUpdate(false);
onStop === null || onStop === void 0 || onStop();
}, idleDelay);
useEffect(function () {
var _targetRef$current;
var el = (_targetRef$current = targetRef === null || targetRef === void 0 ? void 0 : targetRef.current) !== null && _targetRef$current !== void 0 ? _targetRef$current : window;
var getScrollHeight = function getScrollHeight() {
return el === window ? document.documentElement.scrollHeight : el.scrollHeight;
};
var getClientHeight = function getClientHeight() {
return el === window ? document.documentElement.clientHeight : el.clientHeight;
};
var getX = function getX() {
return el === window ? window.scrollX : el.scrollLeft;
};
var getY = function getY() {
return el === window ? window.scrollY : el.scrollTop;
};
var handleScroll = function handleScroll() {
var now = Date.now();
var newY = getY();
var newX = getX();
var deltaTime = now - lastTime.current || 1;
var deltaY = newY - lastY.current;
if (Math.abs(deltaY) < threshold) {
return;
}
var velocity = deltaY / deltaTime;
scrollVelocityRef.current = velocity;
onVelocityUpdate === null || onVelocityUpdate === void 0 || onVelocityUpdate(velocity);
scrollYRef.current = newY;
scrollXRef.current = newX;
if (debounceTimeoutY.current) {
clearTimeout(debounceTimeoutY.current);
}
debounceTimeoutY.current = setTimeout(function () {
setScrollY(scrollYRef.current);
}, scrollYDebounceDelay);
if (trackHorizontal) {
if (debounceTimeoutX.current) {
clearTimeout(debounceTimeoutX.current);
}
debounceTimeoutX.current = setTimeout(function () {
setScrollX(scrollXRef.current);
}, scrollXDebounceDelay);
}
var scrollHeight = getScrollHeight();
var clientHeight = getClientHeight();
var maxScrollY = scrollHeight - clientHeight;
atTopRef.current = newY <= threshold;
atBottomRef.current = Math.abs(newY - maxScrollY) <= threshold;
var centerRange = centerTolerance * maxScrollY;
var centerStart = maxScrollY / 2 - centerRange;
var centerEnd = maxScrollY / 2 + centerRange;
atCenterRef.current = newY >= centerStart && newY <= centerEnd;
if (atTopRef.current) onAtPosition === null || onAtPosition === void 0 || onAtPosition("top");
if (atCenterRef.current) onAtPosition === null || onAtPosition === void 0 || onAtPosition("center");
if (atBottomRef.current) onAtPosition === null || onAtPosition === void 0 || onAtPosition("bottom");
onScrollPositionUpdate === null || onScrollPositionUpdate === void 0 || onScrollPositionUpdate({
x: scrollXRef.current,
y: scrollYRef.current
});
var newDirection = deltaY > 0 ? "down" : "up";
if (newDirection !== scrollDirectionRef.current) {
scrollDirectionRef.current = newDirection;
onScrollDirectionUpdate === null || onScrollDirectionUpdate === void 0 || onScrollDirectionUpdate(newDirection);
}
for (var i = 0; i < onScrollAt.length; i++) {
var rule = onScrollAt[i];
var key = rule.position || rule.y;
if (rule.once && firedRef.current.has(key)) continue;
var hit = false;
if (rule.position === "top" && atTopRef.current) {
hit = true;
} else if (rule.position === "bottom" && atBottomRef.current) {
hit = true;
} else if (rule.position === "center" && atCenterRef.current) {
hit = true;
} else if (typeof rule.y === "number" && scrollYRef.current >= rule.y) {
hit = true;
}
if (hit) {
var _rule$callback;
(_rule$callback = rule.callback) === null || _rule$callback === void 0 || _rule$callback.call(rule);
if (rule.once) {
firedRef.current.add(key);
}
}
}
lastTime.current = now;
lastY.current = newY;
if (!scrollingIdleActivated.current) {
currentlyScrolling();
return;
}
scrollingIdleActivated.current = false;
setScrolling(true);
onScrollUpdate === null || onScrollUpdate === void 0 || onScrollUpdate(true);
onStart === null || onStart === void 0 || onStart();
currentlyScrolling();
};
el.addEventListener("scroll", handleScroll, {
passive: true
});
return function () {
if (debounceTimeoutY.current) {
clearTimeout(debounceTimeoutY.current);
}
if (debounceTimeoutX.current) {
clearTimeout(debounceTimeoutX.current);
}
el.removeEventListener("scroll", handleScroll);
};
}, [idleDelay, threshold, trackHorizontal, centerTolerance, onScrollAt, scrollYDebounceDelay, scrollXDebounceDelay, targetRef]);
return {
scrollDirection: scrollDirectionRef.current,
scrollVelocity: scrollVelocityRef.current,
atBottom: atBottomRef.current,
atCenter: atCenterRef.current,
atTop: atTopRef.current,
scrolling: scrolling,
scrollY: scrollY,
scrollX: scrollX
};
}
;
export var useWrapAroundScroll = function useWrapAroundScroll(containerRef) {
var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "horizontal";
var preventScrollAdjustment = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var adjustingRef = useRef(false);
useEffect(function () {
var container = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
if (!container) {
return;
}
var horizontal = direction === "horizontal";
var handleScroll = function handleScroll() {
if (adjustingRef.current || preventScrollAdjustment) {
return;
}
var scrollLeft = container.scrollLeft,
scrollTop = container.scrollTop,
scrollWidth = container.scrollWidth,
clientWidth = container.clientWidth,
scrollHeight = container.scrollHeight,
clientHeight = container.clientHeight;
var maxScrollTop = scrollHeight - clientHeight;
var maxScrollLeft = scrollWidth - clientWidth;
adjustingRef.current = true;
requestAnimationFrame(function () {
if (horizontal) {
if (scrollLeft <= 1) {
container.scrollLeft = maxScrollLeft - 2;
} else if (scrollLeft >= maxScrollLeft - 1) {
container.scrollLeft = 2;
}
} else {
if (scrollTop <= 1) {
container.scrollTop = maxScrollTop - 2;
} else if (scrollTop >= maxScrollTop - 1) {
container.scrollTop = 2;
}
}
adjustingRef.current = false;
});
};
if (horizontal && !preventScrollAdjustment) {
container.scrollLeft = 2;
} else if (!preventScrollAdjustment) {
container.scrollTop = 2;
}
container.addEventListener("scroll", handleScroll);
return function () {
container.removeEventListener("scroll", handleScroll);
};
}, [containerRef, direction]);
};
var useInfiniteScroll = function useInfiniteScroll(containerRef) {
var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "horizontal";
useLayoutEffect(function () {
var container = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
if (!container) {
return;
}
var children = Array.from(container.children);
if (children.length === 0) {
return;
}
var cloneStart = children.map(function (child) {
return child.cloneNode(true);
});
var cloneEnd = children.map(function (child) {
return child.cloneNode(true);
});
cloneStart.forEach(function (node) {
return container.appendChild(node);
});
cloneEnd.reverse().forEach(function (node) {
return container.insertBefore(node, container.firstChild);
});
if (direction === "horizontal") {
container.scrollLeft = container.scrollWidth / 3;
} else {
container.scrollTop = container.scrollHeight / 3;
}
var handleScroll = function handleScroll() {
var scrollLeft = container.scrollLeft,
scrollTop = container.scrollTop,
scrollWidth = container.scrollWidth,
clientWidth = container.clientWidth,
scrollHeight = container.scrollHeight,
clientHeight = container.clientHeight;
if (direction === "horizontal") {
if (scrollLeft <= 0) {
container.scrollLeft = scrollWidth / 3;
} else if (scrollLeft + clientWidth >= scrollWidth) {
container.scrollLeft = scrollWidth / 3 - clientWidth;
}
} else {
if (scrollTop <= 0) {
container.scrollTop = scrollHeight / 3;
} else if (scrollTop + clientHeight >= scrollHeight) {
container.scrollTop = scrollHeight / 3 - clientHeight;
}
}
};
container.addEventListener("scroll", handleScroll);
return function () {
container.removeEventListener("scroll", handleScroll);
cloneStart.forEach(function (node) {
return container.removeChild(node);
});
cloneEnd.forEach(function (node) {
return container.removeChild(node);
});
};
}, [containerRef, direction]);
};
export var useTiltEffect = function useTiltEffect() {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref3$maxTilt = _ref3.maxTilt,
maxTilt = _ref3$maxTilt === void 0 ? 15 : _ref3$maxTilt,
_ref3$transitionDurat = _ref3.transitionDuration,
transitionDuration = _ref3$transitionDurat === void 0 ? "0.369s" : _ref3$transitionDurat,
_ref3$resetOnLeave = _ref3.resetOnLeave,
resetOnLeave = _ref3$resetOnLeave === void 0 ? true : _ref3$resetOnLeave,
_ref3$scale = _ref3.scale,
scale = _ref3$scale === void 0 ? 1 : _ref3$scale;
var tiltComponentRef = useRef(null);
var handleMouseMove = useCallback(function (e) {
if (!tiltComponentRef.current) {
return;
}
var rect = tiltComponentRef.current.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
var centerX = rect.width / 2;
var centerY = rect.height / 2;
var rotateX = (y - centerY) / centerY * maxTilt;
var rotateY = (x - centerX) / centerX * -maxTilt;
tiltComponentRef.current.style.transform = "perspective(1000px) rotateX(".concat(rotateX, "deg) rotateY(").concat(rotateY, "deg) scale(").concat(scale, ")");
tiltComponentRef.current.style.transition = "transform 0.169s ease-out";
}, [maxTilt, scale]);
var handleMouseLeave = useCallback(function () {
if (resetOnLeave && tiltComponentRef.current) {
tiltComponentRef.current.style.transform = "perspective(1000px) rotateX(0deg) rotateY(0deg) scale(".concat(scale, ")");
tiltComponentRef.current.style.transition = "transform ".concat(transitionDuration, " ease-out");
}
}, [resetOnLeave, transitionDuration, scale]);
return {
tiltComponentRef: tiltComponentRef,
handleMouseMove: handleMouseMove,
handleMouseLeave: handleMouseLeave
};
};
export var useScrollToBottomEffect = function useScrollToBottomEffect(componentRef, items, autoScrollOnNewItem, autoScrollAtBottom) {
useEffect(function () {
if (componentRef.current && autoScrollOnNewItem && !autoScrollAtBottom) {
var component = componentRef.current;
component.scrollTo({
top: component.scrollHeight,
behavior: "smooth"
});
}
if (componentRef.current && autoScrollOnNewItem && autoScrollAtBottom) {
var _component = componentRef.current;
var scrollHeight = _component.scrollHeight;
var scrollTop = _component.scrollTop;
var clientHeight = _component.clientHeight;
var distanceFromBottom = scrollHeight - (scrollTop + clientHeight);
var nearBottom = distanceFromBottom <= 300;
if (nearBottom) {
_component.scrollTo({
top: _component.scrollHeight,
behavior: "smooth"
});
}
}
}, [items, componentRef, autoScrollOnNewItem, autoScrollAtBottom]);
};
export var useScrollWithinBounds = function useScrollWithinBounds(containerRef, itemRef, data) {
var checkIfItemInView = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
useEffect(function () {
var container = containerRef === null || containerRef === void 0 ? void 0 : containerRef.current;
var item = itemRef === null || itemRef === void 0 ? void 0 : itemRef.current;
if (!container || !item) {
return;
}
var handleScroll = function handleScroll() {
var containerRect = container.getBoundingClientRect();
var itemRect = item.getBoundingClientRect();
var itemInView = itemRect.left < containerRect.right && itemRect.right > containerRect.left;
if (checkIfItemInView && !itemInView) {
return;
}
var maxScrollLeft = item.offsetLeft + itemRect.width - containerRect.width;
var minScrollLeft = item.offsetLeft;
if (container.scrollLeft > maxScrollLeft) {
container.scrollLeft = maxScrollLeft;
} else if (container.scrollLeft < minScrollLeft) {
container.scrollLeft = minScrollLeft;
}
};
container.addEventListener("scroll", handleScroll);
return function () {
container.removeEventListener("scroll", handleScroll);
};
}, [containerRef, itemRef, data, checkIfItemInView]);
};