"use strict"; 'use client'; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.useRouteInfo = void 0; exports.useRootNavigationState = useRootNavigationState; exports.useRootNavigation = useRootNavigation; exports.useNavigationContainerRef = useNavigationContainerRef; exports.useRouter = useRouter; exports.useUnstableGlobalHref = useUnstableGlobalHref; exports.useSegments = useSegments; exports.usePathname = usePathname; exports.useGlobalSearchParams = useGlobalSearchParams; exports.useLocalSearchParams = useLocalSearchParams; exports.useSearchParams = useSearchParams; exports.useLoaderData = useLoaderData; const native_1 = require("@react-navigation/native"); const react_1 = __importStar(require("react")); const Route_1 = require("./Route"); const constants_1 = require("./constants"); const routeInfo_1 = require("./global-state/routeInfo"); const router_store_1 = require("./global-state/router-store"); Object.defineProperty(exports, "useRouteInfo", { enumerable: true, get: function () { return router_store_1.useRouteInfo; } }); const imperative_api_1 = require("./imperative-api"); const PreviewRouteContext_1 = require("./link/preview/PreviewRouteContext"); const LoaderCache_1 = require("./loaders/LoaderCache"); const ServerDataLoaderContext_1 = require("./loaders/ServerDataLoaderContext"); const getLoaderData_1 = require("./loaders/getLoaderData"); const utils_1 = require("./loaders/utils"); const useScreens_1 = require("./useScreens"); /** * Returns the [navigation state](https://reactnavigation.org/docs/navigation-state/) * of the navigator which contains the current screen. * * @example * ```tsx * import { useRootNavigationState } from 'expo-router'; * * export default function Route() { * const { routes } = useRootNavigationState(); * * return {routes[0].name}; * } * ``` */ function useRootNavigationState() { const parent = // We assume that this is called from routes in __root // Users cannot customize the generated Sitemap or NotFound routes, so we should be safe (0, native_1.useNavigation)().getParent(constants_1.INTERNAL_SLOT_NAME); if (!parent) { throw new Error('useRootNavigationState was called from a generated route. This is likely a bug in Expo Router.'); } return parent.getState(); } /** * @deprecated Use [`useNavigationContainerRef`](#usenavigationcontainerref) instead, * which returns a React `ref`. */ function useRootNavigation() { return router_store_1.store.navigationRef.current; } /** * @return The root `` ref for the app. The `ref.current` may be `null` * if the `` hasn't mounted yet. */ function useNavigationContainerRef() { return router_store_1.store.navigationRef; } const displayWarningForProp = (prop) => { if (process.env.NODE_ENV !== 'production') { console.warn(`router.${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 routerWithWarnings = { back: createNOOPWithWarning('back'), canGoBack: () => { displayWarningForProp('canGoBack'); return false; }, push: createNOOPWithWarning('push'), navigate: createNOOPWithWarning('navigate'), replace: createNOOPWithWarning('replace'), dismiss: createNOOPWithWarning('dismiss'), dismissTo: createNOOPWithWarning('dismissTo'), dismissAll: createNOOPWithWarning('dismissAll'), canDismiss: () => { displayWarningForProp('canDismiss'); return false; }, setParams: createNOOPWithWarning('setParams'), reload: createNOOPWithWarning('reload'), prefetch: createNOOPWithWarning('prefetch'), }; /** * * Returns the [Router](#router) object for imperative navigation. * * @example *```tsx * import { useRouter } from 'expo-router'; * import { Text } from 'react-native'; * * export default function Route() { * const router = useRouter(); * * return ( * router.push('/home')}>Go Home * ); *} * ``` */ function useRouter() { const { isPreview } = (0, PreviewRouteContext_1.usePreviewInfo)(); if (isPreview) { return routerWithWarnings; } return imperative_api_1.router; } /** * @private * @returns The current global pathname with query params attached. This may change in the future to include the hostname * from a predefined universal link. For example, `/foobar?hey=world` becomes `https://acme.dev/foobar?hey=world`. */ function useUnstableGlobalHref() { return (0, router_store_1.useRouteInfo)().unstable_globalHref; } function useSegments() { return (0, router_store_1.useRouteInfo)().segments; } /** * Returns the currently selected route location without search parameters. For example, `/acme?foo=bar` returns `/acme`. * Segments will be normalized. For example, `/[id]?id=normal` becomes `/normal`. * * @example * ```tsx app/profile/[user].tsx * import { Text } from 'react-native'; * import { usePathname } from 'expo-router'; * * export default function Route() { * // pathname = "/profile/baconbrix" * const pathname = usePathname(); * * return Pathname: {pathname}; * } * ``` */ function usePathname() { return (0, router_store_1.useRouteInfo)().pathname; } function useGlobalSearchParams() { return (0, router_store_1.useRouteInfo)().params; } function useLocalSearchParams() { const params = react_1.default.use(Route_1.LocalRouteParamsContext) ?? {}; const { params: previewParams } = (0, PreviewRouteContext_1.usePreviewInfo)(); return Object.fromEntries(Object.entries(previewParams ?? params).map(([key, value]) => { // React Navigation doesn't remove "undefined" values from the params object, and you cannot remove them via // navigation.setParams as it shallow merges. Hence, we hide them here if (value === undefined) { return [key, undefined]; } if (Array.isArray(value)) { return [ key, value.map((v) => { try { return decodeURIComponent(v); } catch { return v; } }), ]; } else { try { return [key, decodeURIComponent(value)]; } catch { return [key, value]; } } })); } function useSearchParams({ global = false } = {}) { const globalRef = react_1.default.useRef(global); if (process.env.NODE_ENV !== 'production') { if (global !== globalRef.current) { console.warn(`Detected change in 'global' option of useSearchParams. This value cannot change between renders`); } } // eslint-disable-next-line react-hooks/rules-of-hooks const params = global ? useGlobalSearchParams() : useLocalSearchParams(); const entries = Object.entries(params).flatMap(([key, value]) => { if (global) { if (key === 'params') return []; if (key === 'screen') return []; } return Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]; }); return new ReadOnlyURLSearchParams(entries); } class ReadOnlyURLSearchParams extends URLSearchParams { set() { throw new Error('The URLSearchParams object return from useSearchParams is read-only'); } append() { throw new Error('The URLSearchParams object return from useSearchParams is read-only'); } delete() { throw new Error('The URLSearchParams object return from useSearchParams is read-only'); } } /** * Returns the result of the `loader` function for the calling route. * * @example * ```tsx app/profile/[user].tsx * import { Text } from 'react-native'; * import { useLoaderData } from 'expo-router'; * * export function loader() { * return Promise.resolve({ foo: 'bar' }}; * } * * export default function Route() { * const data = useLoaderData(); // { foo: 'bar' } * * return Data: {JSON.stringify(data)}; * } */ function useLoaderData() { const serverDataLoaderContext = (0, react_1.use)(ServerDataLoaderContext_1.ServerDataLoaderContext); const loaderCache = (0, react_1.use)(LoaderCache_1.LoaderCacheContext); const stateForPath = (0, native_1.useStateForPath)(); const contextKey = (0, Route_1.useContextKey)(); const resolvedPath = (0, react_1.useMemo)(() => { const routeInfo = (0, routeInfo_1.getRouteInfoFromState)(stateForPath); const contextPath = contextKey.startsWith('/') ? contextKey.slice(1) : contextKey; const resolvedPathname = `/${(0, useScreens_1.getSingularId)(contextPath, { params: routeInfo.params })}`; const searchString = routeInfo.searchParams?.toString() || ''; return searchString ? `${resolvedPathname}?${searchString}` : resolvedPathname; }, [contextKey, stateForPath]); // First invocation of this hook will happen server-side, so we look up the loaded data from context if (serverDataLoaderContext) { return serverDataLoaderContext[resolvedPath]; } // The second invocation happens after the client has hydrated on initial load, so we look up the data injected // by `` using `globalThis.__EXPO_ROUTER_LOADER_DATA__` if (typeof window !== 'undefined' && globalThis.__EXPO_ROUTER_LOADER_DATA__) { if (globalThis.__EXPO_ROUTER_LOADER_DATA__[resolvedPath]) { return globalThis.__EXPO_ROUTER_LOADER_DATA__[resolvedPath]; } } const result = (0, getLoaderData_1.getLoaderData)({ resolvedPath, cache: loaderCache, fetcher: utils_1.fetchLoader, }); if (result instanceof Promise) { return (0, react_1.use)(result); } return result; } //# sourceMappingURL=hooks.js.map