UNPKG

nextjs-router-events

Version:

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

63 lines (62 loc) 2.65 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; }; var _this = this; import { useEffect, useRef, useState } from 'react'; import { useRouter as usePrimitiveRouter } from 'next/navigation'; import { triggerBeforeRouteChangeEvent, triggerRouteChangeStartEvent } from './events'; import { useFreezeRequestsContext } from './context'; var createRouterProxy = function (router, isFrozen, signal) { return new Proxy(router, { get: function (target, prop, receiver) { if (prop === 'push') { return function (href, options) { var resolvePush = function () { triggerRouteChangeStartEvent(href); Reflect.apply(target.push, _this, [href, options]); }; if (isFrozen) { window.addEventListener('routeChangeConfirmationEvent', function (ev) { if (ev.detail.targetUrl === href) resolvePush(); }, { signal: signal }); triggerBeforeRouteChangeEvent(href); // NOTE: may wanna use a timeout here return; } resolvePush(); }; } return Reflect.get(target, prop, receiver); }, }); }; export var useRouter = function () { var router = usePrimitiveRouter(); var freezeRequests = useFreezeRequestsContext().freezeRequests; var abortControllerRef = useRef(new AbortController()); var _a = __read(useState(createRouterProxy(router, freezeRequests.length !== 0, abortControllerRef.current.signal)), 2), routerProxy = _a[0], setRouterProxy = _a[1]; useEffect(function () { return function () { return abortControllerRef.current.abort(); }; }, []); useEffect(function () { abortControllerRef.current.abort(); var abortController = new AbortController(); setRouterProxy(createRouterProxy(router, freezeRequests.length !== 0, abortController.signal)); return function () { return abortController.abort(); }; }, [router, freezeRequests]); return routerProxy; };