UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

134 lines (133 loc) 4.97 kB
import { useEffect } from "react"; import { setLastAction } from "../router/lastAction.native.js"; import { subscribeToLoadingState, subscribeToRootState } from "../router/router.native.js"; var KEY = "one-sr", GROUP_KEY = "one-sr-groups", getState = function () { return JSON.parse(sessionStorage.getItem(KEY) || "{}"); }, getGroupState = function () { return JSON.parse(sessionStorage.getItem(GROUP_KEY) || "{}"); }, isFirstLoad = !0, activeGroups = /* @__PURE__ */new Set(); function registerScrollGroup(groupId) { return activeGroups.add(groupId), function () { activeGroups.delete(groupId); }; } function getGroupKey(pathname) { var longestMatch = null, _iteratorNormalCompletion = !0, _didIteratorError = !1, _iteratorError = void 0; try { for (var _iterator = activeGroups[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) { var group = _step.value; pathname.startsWith(group) && (!longestMatch || group.length > longestMatch.length) && (longestMatch = group); } } catch (err) { _didIteratorError = !0, _iteratorError = err; } finally { try { !_iteratorNormalCompletion && _iterator.return != null && _iterator.return(); } finally { if (_didIteratorError) throw _iteratorError; } } return longestMatch; } function restorePosition() { try { var positions = getState(), saved = positions[window.location.pathname]; typeof saved == "number" && setTimeout(function () { window.scrollTo(0, saved); }); } catch (error) { console.error("Error restoring scroll position", error), sessionStorage.removeItem(KEY); } } function restoreGroupPosition(groupId) { try { var positions = getGroupState(), saved = positions[groupId]; typeof saved == "number" && setTimeout(function () { window.scrollTo(0, saved); }); } catch (error) { console.error(`Error restoring scroll position for group ${groupId}`, error), sessionStorage.removeItem(GROUP_KEY); } } var didPop = !1, previousPathname = null; function rememberScrollPosition() { didPop = !1; var pathname = window.location.pathname, state = getState(); state[pathname] = window.scrollY, sessionStorage.setItem(KEY, JSON.stringify(state)); var groupKey = getGroupKey(pathname); if (groupKey) { var groupState = getGroupState(); groupState[groupKey] = window.scrollY, sessionStorage.setItem(GROUP_KEY, JSON.stringify(groupState)); } previousPathname = pathname; } var disable = null; function configure(props) { if (!(typeof window > "u" || !window.addEventListener)) { disable?.(); var popStateController = new AbortController(); window.addEventListener("popstate", function () { didPop = !0, setLastAction(); }, { signal: popStateController.signal }); var disposeOnLoadState = subscribeToLoadingState(function (state) { state === "loading" && rememberScrollPosition(); }), disposeOnRootState = subscribeToRootState(function (state) { var _state_linkOptions; if (isFirstLoad) { isFirstLoad = !1, previousPathname = window.location.pathname; return; } if (((_state_linkOptions = state.linkOptions) === null || _state_linkOptions === void 0 ? void 0 : _state_linkOptions.scroll) !== !1) { var { hash } = state, currentPathname = window.location.pathname; if (hash) setTimeout(function () { scrollToHash(hash); });else if (didPop) props.disable !== "restore" && restorePosition();else { var _state_linkOptions1, prevGroup = previousPathname ? getGroupKey(previousPathname) : null, currentGroup = getGroupKey(currentPathname); prevGroup && currentGroup && prevGroup === currentGroup ? restoreGroupPosition(currentGroup) : !((_state_linkOptions1 = state.linkOptions) === null || _state_linkOptions1 === void 0) && _state_linkOptions1.scrollGroup ? restoreGroupPosition(state.linkOptions.scrollGroup) : window.scrollTo(0, 0); } previousPathname = currentPathname; } }); return disable = function () { popStateController.abort(), disposeOnLoadState(), disposeOnRootState(); }, disable; } } function scrollToHash(hash) { if (!(!hash || !hash.startsWith("#"))) { var id = hash.slice(1), el = document.getElementById(id); el && el.scrollIntoView({ behavior: "instant" }); } } function ScrollBehavior(props) { return process.env.VITE_ENVIRONMENT === "client" && (useEffect(function () { window.location.hash && scrollToHash(window.location.hash); }, []), useEffect(function () { return configure(props); }, [props.disable])), null; } export { ScrollBehavior, registerScrollGroup }; //# sourceMappingURL=ScrollBehavior.native.js.map