UNPKG

nextjs-router-events

Version:

A router events alternative for Next.js 13+ with app directory with the ability to prevent user navigation.

87 lines (86 loc) 3.74 kB
'use client'; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import { jsx as _jsx } from "react/jsx-runtime"; import { FreezeRequestsContext } from './context'; import { triggerBeforeRouteChangeEvent, triggerRouteChangeEndEvent, triggerRouteChangeStartEvent, } from './events'; import React, { useEffect, useState } from 'react'; var createForceClickEvent = function (event) { var res = new MouseEvent('click', event); res.isForceAnchorClickEvent = true; return res; }; export var RouteChangesProvider = function (_a) { var children = _a.children; var _b = __read(useState([]), 2), freezeRequests = _b[0], setFreezeRequests = _b[1]; useEffect(function () { var abortController = new AbortController(); var handleAnchorClick = function (event) { var target = event.currentTarget; var isFrozen = freezeRequests.length !== 0; if (isFrozen && !event.isForceAnchorClickEvent) { event.preventDefault(); event.stopPropagation(); window.addEventListener('routeChangeConfirmationEvent', function (ev) { if (ev.detail.targetUrl === target.href) { var forceClickEvent = createForceClickEvent(event); target.dispatchEvent(forceClickEvent); // NOTE: may want to use a timeout here } }, { signal: abortController.signal }); triggerBeforeRouteChangeEvent(target.href); return; } triggerRouteChangeStartEvent(target.href); }; var handleAnchors = function (anchors) { anchors.forEach(function (a) { a.addEventListener('click', handleAnchorClick, { signal: abortController.signal, capture: true, }); }); }; var handleMutation = function (mutationList) { mutationList.forEach(function (record) { if (record.type === 'childList' && record.target instanceof HTMLElement) { var anchors_1 = record.target.querySelectorAll('a[href]'); handleAnchors(anchors_1); } }); }; var anchors = document.querySelectorAll('a[href]'); handleAnchors(anchors); var mutationObserver = new MutationObserver(handleMutation); mutationObserver.observe(document, { childList: true, subtree: true }); var pushStateProxy = new Proxy(window.history.pushState, { apply: function (target, thisArg, argArray) { triggerRouteChangeEndEvent(argArray[2]); return target.apply(thisArg, argArray); }, getPrototypeOf: function (target) { return target; }, }); window.history.pushState = pushStateProxy; return function () { mutationObserver.disconnect(); abortController.abort(); window.history.pushState = Object.getPrototypeOf(pushStateProxy); }; }, [freezeRequests]); return (_jsx(FreezeRequestsContext.Provider, { value: { freezeRequests: freezeRequests, setFreezeRequests: setFreezeRequests }, children: children })); };