Files
Fluxup_PAP/node_modules/expo-router/build/link/preview/HrefPreview.js
2026-03-10 16:18:05 +00:00

162 lines
6.7 KiB
JavaScript

"use strict";
'use client';
Object.defineProperty(exports, "__esModule", { value: true });
exports.HrefPreview = HrefPreview;
const native_1 = require("@react-navigation/native");
const react_1 = require("react");
const react_native_1 = require("react-native");
const PreviewRouteContext_1 = require("./PreviewRouteContext");
const constants_1 = require("../../constants");
const composition_options_1 = require("../../fork/native-stack/composition-options");
const router_store_1 = require("../../global-state/router-store");
const utils_1 = require("../../global-state/utils");
const hooks_1 = require("../../hooks");
const useNavigation_1 = require("../../useNavigation");
const useScreens_1 = require("../../useScreens");
const linking_1 = require("../linking");
function HrefPreview({ href }) {
const hrefState = (0, react_1.useMemo)(() => getHrefState(href), [href]);
const index = hrefState?.index ?? 0;
let isProtected = false;
if (hrefState?.routes[index]?.name === constants_1.INTERNAL_SLOT_NAME) {
let routerState = hrefState;
let rnState = router_store_1.store.state;
while (routerState && rnState) {
const routerRoute = routerState.routes[0];
// When the route we want to show is not present in react-navigation state
// Then most likely it is a protected route
if (rnState.stale === false && !rnState.routeNames?.includes(routerRoute.name)) {
isProtected = true;
break;
}
const rnIndex = rnState.routes.findIndex((route) => route.name === routerRoute.name);
if (rnIndex === -1) {
break;
}
routerState = routerRoute.state;
rnState = rnState.routes[rnIndex]?.state;
}
if (!isProtected) {
return <PreviewForRootHrefState hrefState={hrefState} href={href}/>;
}
}
const pathname = href.toString();
const segments = pathname.split('/').filter(Boolean);
return (<PreviewRouteContext_1.PreviewRouteContext.Provider value={{
params: {},
pathname,
segments,
}}>
<PreviewForInternalRoutes />
</PreviewRouteContext_1.PreviewRouteContext.Provider>);
}
function PreviewForRootHrefState({ hrefState, href }) {
const navigation = (0, useNavigation_1.useNavigation)();
const { routeNode, params, state } = getParamsAndNodeFromHref(hrefState);
const path = state ? (0, linking_1.getPathFromState)(state) : undefined;
const value = (0, react_1.useMemo)(() => ({
params,
pathname: href.toString(),
segments: path?.split('/').filter(Boolean) || [],
}), [params, href]);
// This can happen in a theoretical case where the state is not yet initialized or is incorrectly initialized.
// This check ensures TypeScript type safety as well.
if (!routeNode) {
return null;
}
const Component = (0, useScreens_1.getQualifiedRouteComponent)(routeNode);
return (<PreviewRouteContext_1.PreviewRouteContext value={value}>
<composition_options_1.CompositionContext value={{ set: () => { }, unset: () => { } }}>
{/* Using NavigationContext to override useNavigation */}
<native_1.NavigationContext value={navigationPropWithWarnings}>
<Component navigation={navigation}/>
</native_1.NavigationContext>
</composition_options_1.CompositionContext>
</PreviewRouteContext_1.PreviewRouteContext>);
}
function PreviewForInternalRoutes() {
const pathname = (0, hooks_1.usePathname)();
return (<react_native_1.View style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
gap: 8,
backgroundColor: 'white',
}}>
<react_native_1.Text style={{ fontWeight: '600', fontSize: 24 }}>Invalid preview</react_native_1.Text>
<react_native_1.Text style={{ fontWeight: '200', fontSize: 14 }}>{pathname}</react_native_1.Text>
</react_native_1.View>);
}
function getHrefState(href) {
const hrefState = router_store_1.store.getStateForHref(href);
return hrefState;
}
function getParamsAndNodeFromHref(hrefState) {
const index = hrefState?.index ?? 0;
if (hrefState?.routes[index] && hrefState.routes[index].name !== constants_1.INTERNAL_SLOT_NAME) {
const name = hrefState.routes[index].name;
if (name === constants_1.SITEMAP_ROUTE_NAME || name === constants_1.NOT_FOUND_ROUTE_NAME) {
console.log(router_store_1.store.routeNode);
console.log(hrefState);
}
const error = `Expo Router Error: Expected navigation state to begin with one of [${(0, utils_1.getRootStackRouteNames)().join(', ')}] routes`;
if (process.env.NODE_ENV !== 'production') {
throw new Error(error);
}
else {
console.warn(error);
}
}
const initialState = hrefState?.routes[index]?.state;
let state = initialState;
let routeNode = router_store_1.store.routeNode;
const params = {};
while (state && routeNode) {
const route = state.routes[state.index || state.routes.length - 1];
Object.assign(params, route.params);
state = route.state;
routeNode = routeNode.children.find((child) => child.route === route.name);
}
return { params, routeNode, state: initialState };
}
const displayWarningForProp = (prop) => {
if (process.env.NODE_ENV !== 'production') {
console.warn(`navigation.${prop} should not be used in a previewed screen. To fix this issue, wrap navigation calls with 'if (!isPreview) { ... }'.`);
}
};
const createNOOPWithWarning = (prop) => () => displayWarningForProp(prop);
const navigationPropWithWarnings = {
setParams: createNOOPWithWarning('setParams'),
setOptions: createNOOPWithWarning('setOptions'),
addListener: (() => () => { }),
removeListener: () => { },
isFocused: () => true,
canGoBack: () => false,
dispatch: createNOOPWithWarning('dispatch'),
navigate: createNOOPWithWarning('navigate'),
goBack: createNOOPWithWarning('goBack'),
reset: createNOOPWithWarning('reset'),
push: createNOOPWithWarning('push'),
pop: createNOOPWithWarning('pop'),
popToTop: createNOOPWithWarning('popToTop'),
navigateDeprecated: createNOOPWithWarning('navigateDeprecated'),
preload: createNOOPWithWarning('preload'),
getId: () => {
displayWarningForProp('getId');
return '';
},
// @ts-expect-error
getParent: createNOOPWithWarning('getParent'),
getState: () => {
displayWarningForProp('getState');
return {
key: '',
index: 0,
routeNames: [],
routes: [],
type: '',
stale: false,
};
},
};
//# sourceMappingURL=HrefPreview.js.map