nextjs-router-events
Version:
A router events alternative for Next.js 13+ with app directory with the ability to prevent user navigation.
59 lines (58 loc) • 2.5 kB
JavaScript
'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 { useEffect, useId, useState } from 'react';
import { useFreezeRequestsContext } from './context';
import { triggerRouteChangeConfirmationEvent } from './events';
export var useRouteChangeEvents = function (callbacks) {
var id = useId();
var _a = useFreezeRequestsContext(), request = _a.request, revoke = _a.revoke;
var _b = __read(useState(null), 2), confrimationTarget = _b[0], setConfirmationTarget = _b[1];
useEffect(function () {
request(id);
return function () { return revoke(id); };
}, []);
useEffect(function () {
var abortController = new AbortController();
window.addEventListener('beforeRouteChangeEvent', function (ev) {
var targetUrl = ev.detail.targetUrl;
var shouldProceed = callbacks.onBeforeRouteChange && callbacks.onBeforeRouteChange(targetUrl);
if (shouldProceed !== null && shouldProceed !== void 0 ? shouldProceed : true) {
triggerRouteChangeConfirmationEvent(targetUrl);
}
else {
setConfirmationTarget(targetUrl);
}
}, { signal: abortController.signal });
window.addEventListener('routeChangeEndEvent', function (ev) {
callbacks.onRouteChangeComplete && callbacks.onRouteChangeComplete(ev.detail.targetUrl);
}, { signal: abortController.signal });
window.addEventListener('routeChangeStartEvent', function (ev) {
callbacks.onRouteChangeStart && callbacks.onRouteChangeStart(ev.detail.targetUrl);
}, { signal: abortController.signal });
return function () { return abortController.abort(); };
}, [callbacks]);
return {
allowRouteChange: function () {
if (!confrimationTarget) {
console.warn('allowRouteChange called for no specified confirmation target');
return;
}
triggerRouteChangeConfirmationEvent(confrimationTarget);
},
};
};