UNPKG

@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
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]); };