99 lines
3.2 KiB
Plaintext
99 lines
3.2 KiB
Plaintext
import * as React from "react";
|
|
import { trimPathRight, getLocationChangeInfo, handleHashScroll } from "@tanstack/router-core";
|
|
import { usePrevious, useLayoutEffect } from "./utils.js";
|
|
import { useRouter } from "./useRouter.js";
|
|
import { useRouterState } from "./useRouterState.js";
|
|
function Transitioner() {
|
|
const router = useRouter();
|
|
const mountLoadForRouter = React.useRef({ router, mounted: false });
|
|
const isLoading = useRouterState({
|
|
select: ({ isLoading: isLoading2 }) => isLoading2
|
|
});
|
|
const [isTransitioning, setIsTransitioning] = React.useState(false);
|
|
const hasPendingMatches = useRouterState({
|
|
select: (s) => s.matches.some((d) => d.status === "pending"),
|
|
structuralSharing: true
|
|
});
|
|
const previousIsLoading = usePrevious(isLoading);
|
|
const isAnyPending = isLoading || isTransitioning || hasPendingMatches;
|
|
const previousIsAnyPending = usePrevious(isAnyPending);
|
|
const isPagePending = isLoading || hasPendingMatches;
|
|
const previousIsPagePending = usePrevious(isPagePending);
|
|
if (!router.isServer) {
|
|
router.startTransition = (fn) => {
|
|
setIsTransitioning(true);
|
|
React.startTransition(() => {
|
|
fn();
|
|
setIsTransitioning(false);
|
|
});
|
|
};
|
|
}
|
|
React.useEffect(() => {
|
|
const unsub = router.history.subscribe(router.load);
|
|
const nextLocation = router.buildLocation({
|
|
to: router.latestLocation.pathname,
|
|
search: true,
|
|
params: true,
|
|
hash: true,
|
|
state: true,
|
|
_includeValidateSearch: true
|
|
});
|
|
if (trimPathRight(router.latestLocation.href) !== trimPathRight(nextLocation.href)) {
|
|
router.commitLocation({ ...nextLocation, replace: true });
|
|
}
|
|
return () => {
|
|
unsub();
|
|
};
|
|
}, [router, router.history]);
|
|
useLayoutEffect(() => {
|
|
if (typeof window !== "undefined" && router.clientSsr || mountLoadForRouter.current.router === router && mountLoadForRouter.current.mounted) {
|
|
return;
|
|
}
|
|
mountLoadForRouter.current = { router, mounted: true };
|
|
const tryLoad = async () => {
|
|
try {
|
|
await router.load();
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
};
|
|
tryLoad();
|
|
}, [router]);
|
|
useLayoutEffect(() => {
|
|
if (previousIsLoading && !isLoading) {
|
|
router.emit({
|
|
type: "onLoad",
|
|
// When the new URL has committed, when the new matches have been loaded into state.matches
|
|
...getLocationChangeInfo(router.state)
|
|
});
|
|
}
|
|
}, [previousIsLoading, router, isLoading]);
|
|
useLayoutEffect(() => {
|
|
if (previousIsPagePending && !isPagePending) {
|
|
router.emit({
|
|
type: "onBeforeRouteMount",
|
|
...getLocationChangeInfo(router.state)
|
|
});
|
|
}
|
|
}, [isPagePending, previousIsPagePending, router]);
|
|
useLayoutEffect(() => {
|
|
if (previousIsAnyPending && !isAnyPending) {
|
|
router.emit({
|
|
type: "onResolved",
|
|
...getLocationChangeInfo(router.state)
|
|
});
|
|
router.__store.setState((s) => ({
|
|
...s,
|
|
status: "idle",
|
|
resolvedLocation: s.location
|
|
}));
|
|
handleHashScroll(router);
|
|
}
|
|
}, [isAnyPending, previousIsAnyPending, router]);
|
|
return null;
|
|
}
|
|
export {
|
|
Transitioner
|
|
};
|
|
//# sourceMappingURL=Transitioner.js.map
|