one 1.17.10 → 1.17.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Root.native.js.map +1 -1
- package/dist/cjs/__mocks__/@react-navigation/native-stack.cjs +3 -1
- package/dist/cjs/__mocks__/@react-navigation/native-stack.native.js +4 -0
- package/dist/cjs/__mocks__/@react-navigation/native-stack.native.js.map +1 -1
- package/dist/cjs/__mocks__/expo-linking.native.js.map +1 -1
- package/dist/cjs/__mocks__/expo-modules-core.native.js.map +1 -1
- package/dist/cjs/__mocks__/react-native-screens.native.js.map +1 -1
- package/dist/cjs/babel-plugins/environment-guard.native.js.map +1 -1
- package/dist/cjs/babel-plugins/inline-one-server-url.native.js.map +1 -1
- package/dist/cjs/babel-plugins/one-router-metro.native.js.map +1 -1
- package/dist/cjs/babel-plugins/one-router-metro.test.native.js.map +1 -1
- package/dist/cjs/babel-plugins/remove-server-code.native.js.map +1 -1
- package/dist/cjs/babel-preset/index.native.js.map +1 -1
- package/dist/cjs/babel-preset/index.test.native.js.map +1 -1
- package/dist/cjs/babel-preset/integration.test.native.js.map +1 -1
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js.map +1 -1
- package/dist/cjs/cli/checkNodeVersion.native.js.map +1 -1
- package/dist/cjs/cli/daemon.native.js.map +1 -1
- package/dist/cjs/cli/dev.native.js.map +1 -1
- package/dist/cjs/cli/generateBundlerConfig.native.js.map +1 -1
- package/dist/cjs/cli/generateBundlerConfig.test.native.js.map +1 -1
- package/dist/cjs/cli/generateRoutes.native.js.map +1 -1
- package/dist/cjs/cli/generateSitemap.native.js.map +1 -1
- package/dist/cjs/cli/generateSitemap.test.native.js.map +1 -1
- package/dist/cjs/cli/install-error-handlers.native.js.map +1 -1
- package/dist/cjs/cli/label-process.native.js.map +1 -1
- package/dist/cjs/cli/main.native.js.map +1 -1
- package/dist/cjs/cli/patch.native.js.map +1 -1
- package/dist/cjs/cli/patch.test.native.js.map +1 -1
- package/dist/cjs/cli/prebuild.native.js.map +1 -1
- package/dist/cjs/cli/runAndroid.native.js.map +1 -1
- package/dist/cjs/cli/runIos.native.js.map +1 -1
- package/dist/cjs/cli/securityScan.native.js.map +1 -1
- package/dist/cjs/cli/workerPool.native.js.map +1 -1
- package/dist/cjs/cli.native.js.map +1 -1
- package/dist/cjs/clientLoaderResolver.native.js.map +1 -1
- package/dist/cjs/config.native.js.map +1 -1
- package/dist/cjs/constants.native.js.map +1 -1
- package/dist/cjs/constants.test.native.js.map +1 -1
- package/dist/cjs/createAPIRoute.native.js.map +1 -1
- package/dist/cjs/createHandleRequest.cjs +21 -12
- package/dist/cjs/createHandleRequest.native.js +22 -12
- package/dist/cjs/createHandleRequest.native.js.map +1 -1
- package/dist/cjs/createHandleRequest.test.cjs +51 -6
- package/dist/cjs/createHandleRequest.test.native.js +53 -6
- package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
- package/dist/cjs/createMiddleware.native.js.map +1 -1
- package/dist/cjs/daemon/index.native.js.map +1 -1
- package/dist/cjs/daemon/ipc.native.js.map +1 -1
- package/dist/cjs/daemon/picker.native.js.map +1 -1
- package/dist/cjs/daemon/proxy.native.js.map +1 -1
- package/dist/cjs/daemon/registry.native.js.map +1 -1
- package/dist/cjs/daemon/server.native.js.map +1 -1
- package/dist/cjs/daemon/tui.native.js.map +1 -1
- package/dist/cjs/daemon/types.native.js.map +1 -1
- package/dist/cjs/daemon/utils.native.js.map +1 -1
- package/dist/cjs/devtools/registry.native.js.map +1 -1
- package/dist/cjs/drawer.native.js.map +1 -1
- package/dist/cjs/fallbackViews/Sitemap.native.js.map +1 -1
- package/dist/cjs/fallbackViews/Unmatched.native.js.map +1 -1
- package/dist/cjs/fork/NavigationContainer.native.js.map +1 -1
- package/dist/cjs/fork/SSRNavigationContainer.native.js.map +1 -1
- package/dist/cjs/fork/__tests__/getPathFromState.test.native.js.map +1 -1
- package/dist/cjs/fork/__tests__/getStateFromPath.test.native.js.map +1 -1
- package/dist/cjs/fork/_shared.native.js.map +1 -1
- package/dist/cjs/fork/createMemoryHistory.native.js.map +1 -1
- package/dist/cjs/fork/createMemoryHistory.test.native.js.map +1 -1
- package/dist/cjs/fork/extractPathFromURL.native.js.map +1 -1
- package/dist/cjs/fork/extractPathFromURL.test.native.js.map +1 -1
- package/dist/cjs/fork/findFocusedRoute.native.js.map +1 -1
- package/dist/cjs/fork/getPathFromState-mods.native.js.map +1 -1
- package/dist/cjs/fork/getPathFromState.native.js.map +1 -1
- package/dist/cjs/fork/getPathFromState.test.native.js.map +1 -1
- package/dist/cjs/fork/getStateFromPath-mods.native.js.map +1 -1
- package/dist/cjs/fork/getStateFromPath.native.js.map +1 -1
- package/dist/cjs/fork/getStateFromPath.test.native.js.map +1 -1
- package/dist/cjs/fork/useThenable.native.js.map +1 -1
- package/dist/cjs/fork/validatePathConfig.native.js.map +1 -1
- package/dist/cjs/getReactNavigationConfig.native.js.map +1 -1
- package/dist/cjs/head/Head.native.js.map +1 -1
- package/dist/cjs/head/HeadModule.native.js.map +1 -1
- package/dist/cjs/head/index.native.js.map +1 -1
- package/dist/cjs/head/types.native.js.map +1 -1
- package/dist/cjs/head/url.native.js.map +1 -1
- package/dist/cjs/headless-server.native.js.map +1 -1
- package/dist/cjs/headless.cjs +1 -0
- package/dist/cjs/headless.native.js +1 -0
- package/dist/cjs/headless.native.js.map +1 -1
- package/dist/cjs/hooks.native.js.map +1 -1
- package/dist/cjs/hooks.test.native.js.map +1 -1
- package/dist/cjs/href.native.js.map +1 -1
- package/dist/cjs/image/getImageData.native.js.map +1 -1
- package/dist/cjs/image.native.js.map +1 -1
- package/dist/cjs/index.cjs +3 -0
- package/dist/cjs/index.native.js +4 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/interfaces/router.native.js.map +1 -1
- package/dist/cjs/layouts/Drawer.cjs +46 -1
- package/dist/cjs/layouts/Drawer.native.js +47 -1
- package/dist/cjs/layouts/Drawer.native.js.map +1 -1
- package/dist/cjs/layouts/NativeTabs.native.js.map +1 -1
- package/dist/cjs/layouts/Stack.cjs +12 -3
- package/dist/cjs/layouts/Stack.native.js +13 -4
- package/dist/cjs/layouts/Stack.native.js.map +1 -1
- package/dist/cjs/layouts/Tabs.cjs +42 -8
- package/dist/cjs/layouts/Tabs.native.js +43 -8
- package/dist/cjs/layouts/Tabs.native.js.map +1 -1
- package/dist/cjs/layouts/stack-navigator.cjs +29 -0
- package/dist/cjs/layouts/stack-navigator.native.js +32 -0
- package/dist/cjs/layouts/stack-navigator.native.js.map +1 -0
- package/dist/cjs/layouts/stack-utils/StackHeaderBackButton.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackHeaderComponent.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackHeaderLeft.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackHeaderRight.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackHeaderSearchBar.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackHeaderTitle.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/StackScreen.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/__tests__/composition.test.native.js.map +1 -1
- package/dist/cjs/layouts/stack-utils/index.native.js.map +1 -1
- package/dist/cjs/layouts/withLayoutContext.native.js.map +1 -1
- package/dist/cjs/lazyWithRetry.native.js.map +1 -1
- package/dist/cjs/link/Link.native.js.map +1 -1
- package/dist/cjs/link/Redirect.native.js.map +1 -1
- package/dist/cjs/link/getLinking.native.js.map +1 -1
- package/dist/cjs/link/href.native.js.map +1 -1
- package/dist/cjs/link/path.native.js.map +1 -1
- package/dist/cjs/link/prefetchIntent.native.js.map +1 -1
- package/dist/cjs/link/prefetchIntent.test.native.js.map +1 -1
- package/dist/cjs/link/prefetchViewport.native.js.map +1 -1
- package/dist/cjs/link/prefetchViewport.test.native.js.map +1 -1
- package/dist/cjs/link/useLinkTo.native.js.map +1 -1
- package/dist/cjs/link/useLoadedNavigation.native.js.map +1 -1
- package/dist/cjs/metro-config/buildOneMetroResolverOverrides.native.js.map +1 -1
- package/dist/cjs/metro-config/getViteMetroPluginOptions.integration.test.native.js.map +1 -1
- package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js +1 -1
- package/dist/cjs/metro-config/getViteMetroPluginOptions.native.js.map +1 -1
- package/dist/cjs/metro-config/withOne.native.js.map +1 -1
- package/dist/cjs/metro-config/withOne.test.native.js.map +1 -1
- package/dist/cjs/native-tabs.native.js.map +1 -1
- package/dist/cjs/notFoundState.native.js.map +1 -1
- package/dist/cjs/polyfills-mobile.native.js.map +1 -1
- package/dist/cjs/polyfills-server.native.js.map +1 -1
- package/dist/cjs/router/FlagsContext.native.js.map +1 -1
- package/dist/cjs/router/Route.native.js.map +1 -1
- package/dist/cjs/router/RouteInfoContext.native.js.map +1 -1
- package/dist/cjs/router/RouterStore.native.js.map +1 -1
- package/dist/cjs/router/SpaShellContext.native.js.map +1 -1
- package/dist/cjs/router/createRoute.native.js.map +1 -1
- package/dist/cjs/router/filterRootHTML.native.js.map +1 -1
- package/dist/cjs/router/findRouteNode.native.js.map +1 -1
- package/dist/cjs/router/getLinkingConfig.native.js.map +1 -1
- package/dist/cjs/router/getLinkingConfig.test.native.js.map +1 -1
- package/dist/cjs/router/getNormalizedStatePath.native.js.map +1 -1
- package/dist/cjs/router/getRouteInfo.native.js.map +1 -1
- package/dist/cjs/router/getRoutes.native.js.map +1 -1
- package/dist/cjs/router/getRoutes.test.native.js.map +1 -1
- package/dist/cjs/router/glob-patterns.native.js.map +1 -1
- package/dist/cjs/router/imperative-api.native.js.map +1 -1
- package/dist/cjs/router/interceptRoutes.native.js.map +1 -1
- package/dist/cjs/router/isIndexPath.native.js.map +1 -1
- package/dist/cjs/router/lastAction.native.js.map +1 -1
- package/dist/cjs/router/linkingConfig.native.js.map +1 -1
- package/dist/cjs/router/matchers.native.js.map +1 -1
- package/dist/cjs/router/matchers.test.native.js.map +1 -1
- package/dist/cjs/router/params.native.js.map +1 -1
- package/dist/cjs/router/renderingRegistry.cjs +53 -0
- package/dist/cjs/router/renderingRegistry.native.js +56 -0
- package/dist/cjs/router/renderingRegistry.native.js.map +1 -0
- package/dist/cjs/router/router.cjs +2 -0
- package/dist/cjs/router/router.native.js.map +1 -1
- package/dist/cjs/router/serverLocationContext.native.js.map +1 -1
- package/dist/cjs/router/sitemap.native.js.map +1 -1
- package/dist/cjs/router/sitemap.test.native.js.map +1 -1
- package/dist/cjs/router/sortRoutes.native.js.map +1 -1
- package/dist/cjs/router/useInitializeOneRouter.native.js.map +1 -1
- package/dist/cjs/router/useNavigation.native.js.map +1 -1
- package/dist/cjs/router/useScreens.native.js.map +1 -1
- package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
- package/dist/cjs/router/utils/getNavigateAction.native.js.map +1 -1
- package/dist/cjs/router/utils/getNavigateAction.test.native.js.map +1 -1
- package/dist/cjs/router/web/ScreenRenderContext.cjs +36 -0
- package/dist/cjs/router/web/ScreenRenderContext.native.js +38 -0
- package/dist/cjs/router/web/ScreenRenderContext.native.js.map +1 -0
- package/dist/cjs/router/web/WebStackNavigator.cjs +74 -0
- package/dist/cjs/router/web/WebStackNavigator.native.js +78 -0
- package/dist/cjs/router/web/WebStackNavigator.native.js.map +1 -0
- package/dist/cjs/router/web/WebStackView.cjs +182 -0
- package/dist/cjs/router/web/WebStackView.native.js +235 -0
- package/dist/cjs/router/web/WebStackView.native.js.map +1 -0
- package/dist/cjs/router/web/__tests__/WebStackView.runtime.test.cjs +295 -0
- package/dist/cjs/router/web/__tests__/WebStackView.runtime.test.native.js +335 -0
- package/dist/cjs/router/web/__tests__/WebStackView.runtime.test.native.js.map +1 -0
- package/dist/cjs/router/web/__tests__/WebStackView.test.cjs +464 -0
- package/dist/cjs/router/web/__tests__/WebStackView.test.native.js +515 -0
- package/dist/cjs/router/web/__tests__/WebStackView.test.native.js.map +1 -0
- package/dist/cjs/router/web/__tests__/stackStateUtils.test.cjs +134 -0
- package/dist/cjs/router/web/__tests__/stackStateUtils.test.native.js +163 -0
- package/dist/cjs/router/web/__tests__/stackStateUtils.test.native.js.map +1 -0
- package/dist/cjs/router/web/stackStateUtils.cjs +60 -0
- package/dist/cjs/router/web/stackStateUtils.native.js +66 -0
- package/dist/cjs/router/web/stackStateUtils.native.js.map +1 -0
- package/dist/cjs/screensFeatureFlags.native.js.map +1 -1
- package/dist/cjs/serve-worker.native.js.map +1 -1
- package/dist/cjs/serve.native.js.map +1 -1
- package/dist/cjs/server/ServerContextScript.cjs +2 -1
- package/dist/cjs/server/ServerContextScript.native.js +2 -1
- package/dist/cjs/server/ServerContextScript.native.js.map +1 -1
- package/dist/cjs/server/createRoutesManifest.native.js.map +1 -1
- package/dist/cjs/server/getServerManifest.native.js.map +1 -1
- package/dist/cjs/server/getServerManifest.test.native.js.map +1 -1
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server/setServerGlobals.native.js.map +1 -1
- package/dist/cjs/server/setupBuildOptions.native.js.map +1 -1
- package/dist/cjs/server/setupServerGlobals.native.js.map +1 -1
- package/dist/cjs/server/ssrLoaderData.native.js.map +1 -1
- package/dist/cjs/server/staticHtmlFetcher.native.js.map +1 -1
- package/dist/cjs/server/workerHandler.native.js.map +1 -1
- package/dist/cjs/server-render.native.js.map +1 -1
- package/dist/cjs/skewProtection.native.js.map +1 -1
- package/dist/cjs/testing-utils.native.js.map +1 -1
- package/dist/cjs/typed-routes/generateRouteTypes.native.js.map +1 -1
- package/dist/cjs/typed-routes/generateRouteTypes.test.native.js.map +1 -1
- package/dist/cjs/typed-routes/getTypedRoutesDeclarationFile.native.js.map +1 -1
- package/dist/cjs/typed-routes/getTypedRoutesDeclarationFile.test.native.js.map +1 -1
- package/dist/cjs/typed-routes/injectRouteHelpers.native.js.map +1 -1
- package/dist/cjs/types.native.js.map +1 -1
- package/dist/cjs/ui/Slot.native.js.map +1 -1
- package/dist/cjs/ui/TabContext.native.js.map +1 -1
- package/dist/cjs/ui/TabList.native.js.map +1 -1
- package/dist/cjs/ui/TabRouter.native.js.map +1 -1
- package/dist/cjs/ui/TabSlot.native.js.map +1 -1
- package/dist/cjs/ui/TabTrigger.native.js.map +1 -1
- package/dist/cjs/ui/Tabs.native.js.map +1 -1
- package/dist/cjs/ui/common.native.js.map +1 -1
- package/dist/cjs/ui/index.native.js.map +1 -1
- package/dist/cjs/ui/useComponent.native.js.map +1 -1
- package/dist/cjs/useFocusEffect.native.js.map +1 -1
- package/dist/cjs/useLoader.native.js.map +1 -1
- package/dist/cjs/useMatches.native.js.map +1 -1
- package/dist/cjs/useMatches.test.native.js.map +1 -1
- package/dist/cjs/useServerHeadInsertion.native.js.map +1 -1
- package/dist/cjs/utils/assertIsReady.native.js.map +1 -1
- package/dist/cjs/utils/buildOutputPointer.native.js.map +1 -1
- package/dist/cjs/utils/buildOutputPointer.test.native.js.map +1 -1
- package/dist/cjs/utils/children.native.js.map +1 -1
- package/dist/cjs/utils/cleanUrl.native.js.map +1 -1
- package/dist/cjs/utils/cleanUrl.test.native.js.map +1 -1
- package/dist/cjs/utils/dynamicImport.native.js.map +1 -1
- package/dist/cjs/utils/dynamicImport.test.native.js.map +1 -1
- package/dist/cjs/utils/ensureExists.native.js.map +1 -1
- package/dist/cjs/utils/evictOldest.native.js.map +1 -1
- package/dist/cjs/utils/existsAsync.native.js.map +1 -1
- package/dist/cjs/utils/findRootLayout.native.js.map +1 -1
- package/dist/cjs/utils/getPageExport.native.js.map +1 -1
- package/dist/cjs/utils/getPathnameFromFilePath.native.js.map +1 -1
- package/dist/cjs/utils/getPathnameFromFilePath.test.native.js.map +1 -1
- package/dist/cjs/utils/getRouterRootFromOneOptions.native.js.map +1 -1
- package/dist/cjs/utils/globDir.native.js.map +1 -1
- package/dist/cjs/utils/hashString.native.js.map +1 -1
- package/dist/cjs/utils/htmlEscape.native.js.map +1 -1
- package/dist/cjs/utils/isResponse.native.js.map +1 -1
- package/dist/cjs/utils/isRolldown.native.js.map +1 -1
- package/dist/cjs/utils/isStatus.native.js.map +1 -1
- package/dist/cjs/utils/pLimit.native.js.map +1 -1
- package/dist/cjs/utils/posixPathContract.test.native.js.map +1 -1
- package/dist/cjs/utils/promiseWithResolvers.native.js.map +1 -1
- package/dist/cjs/utils/rand.native.js.map +1 -1
- package/dist/cjs/utils/redirect.native.js.map +1 -1
- package/dist/cjs/utils/removeParams.native.js.map +1 -1
- package/dist/cjs/utils/removeSearch.native.js.map +1 -1
- package/dist/cjs/utils/removeUndefined.native.js.map +1 -1
- package/dist/cjs/utils/routeFileWatch.native.js.map +1 -1
- package/dist/cjs/utils/routeFileWatch.test.native.js.map +1 -1
- package/dist/cjs/utils/style.native.js.map +1 -1
- package/dist/cjs/utils/toAbsolute.native.js.map +1 -1
- package/dist/cjs/utils/toServerOutputPath.native.js.map +1 -1
- package/dist/cjs/utils/toServerOutputPath.test.native.js.map +1 -1
- package/dist/cjs/utils/trackLoaderDependencies.native.js.map +1 -1
- package/dist/cjs/utils/url.native.js.map +1 -1
- package/dist/cjs/utils/useConstant.native.js.map +1 -1
- package/dist/cjs/utils/watchFile.native.js.map +1 -1
- package/dist/cjs/utils/weakKey.native.js.map +1 -1
- package/dist/cjs/utils/weakMemo.native.js.map +1 -1
- package/dist/cjs/utils/withStaticProperties.native.js.map +1 -1
- package/dist/cjs/utils/workerImport.native.js.map +1 -1
- package/dist/cjs/validateParams.native.js.map +1 -1
- package/dist/cjs/validateSearch.native.js.map +1 -1
- package/dist/cjs/vercel/build/buildVercelOutputDirectory.native.js.map +1 -1
- package/dist/cjs/vercel/build/config/vc-build-output-config-base.native.js.map +1 -1
- package/dist/cjs/vercel/build/config/vc-config-base.native.js.map +1 -1
- package/dist/cjs/vercel/build/config/vc-package-base.native.js.map +1 -1
- package/dist/cjs/vercel/build/generate/createApiServerlessFunction.native.js.map +1 -1
- package/dist/cjs/vercel/build/generate/createSsrServerlessFunction.native.js.map +1 -1
- package/dist/cjs/vercel/build/getPathFromRoute.native.js.map +1 -1
- package/dist/cjs/views/EmptyRoute.native.js.map +1 -1
- package/dist/cjs/views/ErrorBoundary.native.js.map +1 -1
- package/dist/cjs/views/LoadProgressBar.native.js.map +1 -1
- package/dist/cjs/views/Navigator.native.js.map +1 -1
- package/dist/cjs/views/OneStackRouter.native.js.map +1 -1
- package/dist/cjs/views/Protected.native.js.map +1 -1
- package/dist/cjs/views/RootErrorBoundary.native.js.map +1 -1
- package/dist/cjs/views/Screen.native.js.map +1 -1
- package/dist/cjs/views/ScrollBehavior.native.js.map +1 -1
- package/dist/cjs/views/SourceInspector.native.js.map +1 -1
- package/dist/cjs/views/Try.native.js.map +1 -1
- package/dist/cjs/vite/DevHead.native.js.map +1 -1
- package/dist/cjs/vite/constants.native.js.map +1 -1
- package/dist/cjs/vite/customNodeExternals.native.js.map +1 -1
- package/dist/cjs/vite/ensureTsConfig.native.js.map +1 -1
- package/dist/cjs/vite/findDepsToOptimize.native.js.map +1 -1
- package/dist/cjs/vite/getManifest.native.js.map +1 -1
- package/dist/cjs/vite/getManifest.test.native.js.map +1 -1
- package/dist/cjs/vite/loadConfig.native.js.map +1 -1
- package/dist/cjs/vite/makePluginWebOnly.native.js.map +1 -1
- package/dist/cjs/vite/one-server-only.test.native.js.map +1 -1
- package/dist/cjs/vite/one.native.js.map +1 -1
- package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/clientTreeShakePlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/clientTreeShakePlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/criticalCSSPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/devtoolsPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fixDependenciesPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/generateFileSystemRouteTypesPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/imageDataPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/imageDataPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/removeReactNativeWebAnimatedPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/sourceInspectorPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/useDomPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryConstants.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/warmRoutesPlugin.native.js.map +1 -1
- package/dist/cjs/vite/replaceLoader.native.js.map +1 -1
- package/dist/cjs/vite/resolveResponse.native.js.map +1 -1
- package/dist/cjs/vite/types.native.js.map +1 -1
- package/dist/cjs/vite-auto-warm.native.js.map +1 -1
- package/dist/cjs/vite.native.js.map +1 -1
- package/dist/cjs/zero/getQueryKey.native.js.map +1 -1
- package/dist/cjs/zero/isZeroQuery.native.js.map +1 -1
- package/dist/cjs/zero/resolveQuery.native.js.map +1 -1
- package/dist/cjs/zero/subscribeToQuery.native.js.map +1 -1
- package/dist/cjs/zero/types.native.js.map +1 -1
- package/dist/cjs/zero/useQuery.native.js.map +1 -1
- package/dist/cjs/zero/useQueryZero.native.js.map +1 -1
- package/dist/cjs/zero.native.js.map +1 -1
- package/dist/esm/__mocks__/@react-navigation/native-stack.mjs +2 -1
- package/dist/esm/__mocks__/@react-navigation/native-stack.mjs.map +1 -1
- package/dist/esm/__mocks__/@react-navigation/native-stack.native.js +4 -1
- package/dist/esm/__mocks__/@react-navigation/native-stack.native.js.map +1 -1
- package/dist/esm/constants.test.mjs.map +1 -1
- package/dist/esm/constants.test.native.js.map +1 -1
- package/dist/esm/createHandleRequest.mjs +21 -12
- package/dist/esm/createHandleRequest.mjs.map +1 -1
- package/dist/esm/createHandleRequest.native.js +22 -12
- package/dist/esm/createHandleRequest.native.js.map +1 -1
- package/dist/esm/createHandleRequest.test.mjs +51 -6
- package/dist/esm/createHandleRequest.test.mjs.map +1 -1
- package/dist/esm/createHandleRequest.test.native.js +53 -6
- package/dist/esm/createHandleRequest.test.native.js.map +1 -1
- package/dist/esm/headless.mjs +1 -0
- package/dist/esm/headless.mjs.map +1 -1
- package/dist/esm/headless.native.js +1 -0
- package/dist/esm/headless.native.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/layouts/Drawer.mjs +35 -1
- package/dist/esm/layouts/Drawer.mjs.map +1 -1
- package/dist/esm/layouts/Drawer.native.js +36 -1
- package/dist/esm/layouts/Drawer.native.js.map +1 -1
- package/dist/esm/layouts/Stack.mjs +12 -3
- package/dist/esm/layouts/Stack.mjs.map +1 -1
- package/dist/esm/layouts/Stack.native.js +12 -3
- package/dist/esm/layouts/Stack.native.js.map +1 -1
- package/dist/esm/layouts/Tabs.mjs +31 -8
- package/dist/esm/layouts/Tabs.mjs.map +1 -1
- package/dist/esm/layouts/Tabs.native.js +32 -8
- package/dist/esm/layouts/Tabs.native.js.map +1 -1
- package/dist/esm/layouts/stack-navigator.mjs +4 -0
- package/dist/esm/layouts/stack-navigator.mjs.map +1 -0
- package/dist/esm/layouts/stack-navigator.native.js +4 -0
- package/dist/esm/layouts/stack-navigator.native.js.map +1 -0
- package/dist/esm/layouts/stack-utils/StackScreen.mjs.map +1 -1
- package/dist/esm/layouts/stack-utils/StackScreen.native.js.map +1 -1
- package/dist/esm/layouts/stack-utils/index.mjs.map +1 -1
- package/dist/esm/router/renderingRegistry.mjs +26 -0
- package/dist/esm/router/renderingRegistry.mjs.map +1 -0
- package/dist/esm/router/renderingRegistry.native.js +26 -0
- package/dist/esm/router/renderingRegistry.native.js.map +1 -0
- package/dist/esm/router/router.mjs +2 -0
- package/dist/esm/router/router.mjs.map +1 -1
- package/dist/esm/router/router.native.js.map +1 -1
- package/dist/esm/router/web/ScreenRenderContext.mjs +10 -0
- package/dist/esm/router/web/ScreenRenderContext.mjs.map +1 -0
- package/dist/esm/router/web/ScreenRenderContext.native.js +10 -0
- package/dist/esm/router/web/ScreenRenderContext.native.js.map +1 -0
- package/dist/esm/router/web/WebStackNavigator.mjs +49 -0
- package/dist/esm/router/web/WebStackNavigator.mjs.map +1 -0
- package/dist/esm/router/web/WebStackNavigator.native.js +51 -0
- package/dist/esm/router/web/WebStackNavigator.native.js.map +1 -0
- package/dist/esm/router/web/WebStackView.mjs +155 -0
- package/dist/esm/router/web/WebStackView.mjs.map +1 -0
- package/dist/esm/router/web/WebStackView.native.js +206 -0
- package/dist/esm/router/web/WebStackView.native.js.map +1 -0
- package/dist/esm/router/web/__tests__/WebStackView.runtime.test.mjs +272 -0
- package/dist/esm/router/web/__tests__/WebStackView.runtime.test.mjs.map +1 -0
- package/dist/esm/router/web/__tests__/WebStackView.runtime.test.native.js +309 -0
- package/dist/esm/router/web/__tests__/WebStackView.runtime.test.native.js.map +1 -0
- package/dist/esm/router/web/__tests__/WebStackView.test.mjs +465 -0
- package/dist/esm/router/web/__tests__/WebStackView.test.mjs.map +1 -0
- package/dist/esm/router/web/__tests__/WebStackView.test.native.js +513 -0
- package/dist/esm/router/web/__tests__/WebStackView.test.native.js.map +1 -0
- package/dist/esm/router/web/__tests__/stackStateUtils.test.mjs +135 -0
- package/dist/esm/router/web/__tests__/stackStateUtils.test.mjs.map +1 -0
- package/dist/esm/router/web/__tests__/stackStateUtils.test.native.js +161 -0
- package/dist/esm/router/web/__tests__/stackStateUtils.test.native.js.map +1 -0
- package/dist/esm/router/web/stackStateUtils.mjs +32 -0
- package/dist/esm/router/web/stackStateUtils.mjs.map +1 -0
- package/dist/esm/router/web/stackStateUtils.native.js +35 -0
- package/dist/esm/router/web/stackStateUtils.native.js.map +1 -0
- package/dist/esm/server/ServerContextScript.mjs +2 -1
- package/dist/esm/server/ServerContextScript.mjs.map +1 -1
- package/dist/esm/server/ServerContextScript.native.js +2 -1
- package/dist/esm/server/ServerContextScript.native.js.map +1 -1
- package/dist/esm/utils/dynamicImport.test.mjs.map +1 -1
- package/dist/esm/utils/dynamicImport.test.native.js.map +1 -1
- package/package.json +10 -9
- package/src/__mocks__/@react-navigation/native-stack.ts +22 -0
- package/src/constants.test.ts +12 -8
- package/src/createHandleRequest.test.ts +50 -6
- package/src/createHandleRequest.ts +26 -24
- package/src/headless.tsx +6 -0
- package/src/index.ts +20 -5
- package/src/layouts/Drawer.tsx +43 -1
- package/src/layouts/Stack.tsx +51 -33
- package/src/layouts/Tabs.tsx +89 -57
- package/src/layouts/stack-navigator.ts +9 -0
- package/src/layouts/stack-navigator.web.ts +3 -0
- package/src/layouts/stack-utils/StackScreen.tsx +30 -9
- package/src/layouts/stack-utils/index.tsx +1 -0
- package/src/router/renderingRegistry.ts +109 -0
- package/src/router/router.ts +33 -9
- package/src/router/web/ScreenRenderContext.tsx +61 -0
- package/src/router/web/WebStackNavigator.tsx +87 -0
- package/src/router/web/WebStackView.tsx +264 -0
- package/src/router/web/__tests__/WebStackView.runtime.test.tsx +309 -0
- package/src/router/web/__tests__/WebStackView.test.tsx +444 -0
- package/src/router/web/__tests__/stackStateUtils.test.ts +153 -0
- package/src/router/web/stackStateUtils.ts +89 -0
- package/src/server/ServerContextScript.tsx +8 -7
- package/src/utils/dynamicImport.test.ts +9 -7
- package/types/__mocks__/@react-navigation/native-stack.d.ts +9 -0
- package/types/__mocks__/@react-navigation/native-stack.d.ts.map +1 -1
- package/types/createHandleRequest.d.ts.map +1 -1
- package/types/headless.d.ts.map +1 -1
- package/types/index.d.ts +4 -2
- package/types/index.d.ts.map +1 -1
- package/types/layouts/Drawer.d.ts +13 -2
- package/types/layouts/Drawer.d.ts.map +1 -1
- package/types/layouts/Stack.d.ts +11 -1
- package/types/layouts/Stack.d.ts.map +1 -1
- package/types/layouts/Tabs.d.ts +14 -4
- package/types/layouts/Tabs.d.ts.map +1 -1
- package/types/layouts/stack-navigator.d.ts +9 -0
- package/types/layouts/stack-navigator.d.ts.map +1 -0
- package/types/layouts/stack-navigator.web.d.ts +2 -0
- package/types/layouts/stack-navigator.web.d.ts.map +1 -0
- package/types/layouts/stack-utils/StackScreen.d.ts +24 -2
- package/types/layouts/stack-utils/StackScreen.d.ts.map +1 -1
- package/types/layouts/stack-utils/index.d.ts +1 -1
- package/types/layouts/stack-utils/index.d.ts.map +1 -1
- package/types/router/renderingRegistry.d.ts +90 -0
- package/types/router/renderingRegistry.d.ts.map +1 -0
- package/types/router/router.d.ts.map +1 -1
- package/types/router/web/ScreenRenderContext.d.ts +46 -0
- package/types/router/web/ScreenRenderContext.d.ts.map +1 -0
- package/types/router/web/WebStackNavigator.d.ts +2 -0
- package/types/router/web/WebStackNavigator.d.ts.map +1 -0
- package/types/router/web/WebStackView.d.ts +42 -0
- package/types/router/web/WebStackView.d.ts.map +1 -0
- package/types/router/web/stackStateUtils.d.ts +35 -0
- package/types/router/web/stackStateUtils.d.ts.map +1 -0
- package/types/server/ServerContextScript.d.ts.map +1 -1
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
import { createElement, type ReactNode } from 'react'
|
|
3
|
+
import { renderToStaticMarkup } from 'react-dom/server'
|
|
4
|
+
|
|
5
|
+
import { OverlayHost, resolveOverlayRender, WebStackView } from '../WebStackView'
|
|
6
|
+
import { StackRenderProvider, type StackRender } from '../ScreenRenderContext'
|
|
7
|
+
|
|
8
|
+
type Descriptor = {
|
|
9
|
+
options: any
|
|
10
|
+
render: () => ReactNode
|
|
11
|
+
navigation: any
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function makeRoute(name: string) {
|
|
15
|
+
return { key: `${name}-key`, name, params: undefined }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function makeState(names: string[], index: number) {
|
|
19
|
+
return {
|
|
20
|
+
key: 'stack-1',
|
|
21
|
+
index,
|
|
22
|
+
routeNames: names,
|
|
23
|
+
routes: names.map(makeRoute),
|
|
24
|
+
type: 'stack',
|
|
25
|
+
stale: false,
|
|
26
|
+
preloadedRoutes: [],
|
|
27
|
+
} as any
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function makeDescriptors(
|
|
31
|
+
perRoute: Record<string, { options: any; content?: ReactNode }>
|
|
32
|
+
): Record<string, Descriptor> {
|
|
33
|
+
const out: Record<string, Descriptor> = {}
|
|
34
|
+
for (const name of Object.keys(perRoute)) {
|
|
35
|
+
out[`${name}-key`] = {
|
|
36
|
+
options: perRoute[name]!.options,
|
|
37
|
+
render: () => perRoute[name]!.content ?? null,
|
|
38
|
+
navigation: {},
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return out
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
describe('resolveOverlayRender', () => {
|
|
45
|
+
const A = () => null
|
|
46
|
+
const B = () => null
|
|
47
|
+
|
|
48
|
+
it('prefers per-route render over context', () => {
|
|
49
|
+
const result = resolveOverlayRender(
|
|
50
|
+
{ presentation: 'formSheet', render: { web: A } },
|
|
51
|
+
{ web: B }
|
|
52
|
+
)
|
|
53
|
+
expect(result).toBe(A)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('falls back to context render when route has none', () => {
|
|
57
|
+
const result = resolveOverlayRender({ presentation: 'formSheet' }, { web: B })
|
|
58
|
+
expect(result).toBe(B)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('returns undefined when nothing is configured', () => {
|
|
62
|
+
expect(resolveOverlayRender({ presentation: 'formSheet' }, undefined)).toBeUndefined()
|
|
63
|
+
expect(
|
|
64
|
+
resolveOverlayRender({ presentation: 'formSheet' }, { ios: A })
|
|
65
|
+
).toBeUndefined()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('does not pick from ios/android slots on web', () => {
|
|
69
|
+
expect(
|
|
70
|
+
resolveOverlayRender({ presentation: 'formSheet', render: { ios: A } }, { web: B })
|
|
71
|
+
).toBe(B)
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
describe('OverlayHost', () => {
|
|
76
|
+
it('invokes the render component with route props for overlay presentations', () => {
|
|
77
|
+
const captured: any[] = []
|
|
78
|
+
const Render = vi.fn((props: any) => {
|
|
79
|
+
captured.push(props)
|
|
80
|
+
return createElement('div', { 'data-modal': props.routeKey }, props.children)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const descriptors = makeDescriptors({
|
|
84
|
+
filter: {
|
|
85
|
+
options: {
|
|
86
|
+
presentation: 'formSheet',
|
|
87
|
+
sheetAllowedDetents: [0.5, 1],
|
|
88
|
+
sheetGrabberVisible: true,
|
|
89
|
+
},
|
|
90
|
+
content: createElement('span', null, 'filter-body'),
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const markup = renderToStaticMarkup(
|
|
95
|
+
createElement(OverlayHost, {
|
|
96
|
+
route: makeRoute('filter'),
|
|
97
|
+
descriptor: descriptors['filter-key']!,
|
|
98
|
+
contextRender: { web: Render },
|
|
99
|
+
onDismiss: () => {},
|
|
100
|
+
})
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
expect(Render).toHaveBeenCalledTimes(1)
|
|
104
|
+
expect(captured[0]).toMatchObject({
|
|
105
|
+
routeKey: 'filter-key',
|
|
106
|
+
presentation: 'formSheet',
|
|
107
|
+
sheetAllowedDetents: [0.5, 1],
|
|
108
|
+
sheetGrabberVisible: true,
|
|
109
|
+
dismissible: true,
|
|
110
|
+
})
|
|
111
|
+
expect(typeof captured[0].dismiss).toBe('function')
|
|
112
|
+
expect(markup).toContain('data-modal="filter-key"')
|
|
113
|
+
expect(markup).toContain('filter-body')
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('falls back to inline rendering when no render is configured', () => {
|
|
117
|
+
const descriptors = makeDescriptors({
|
|
118
|
+
filter: {
|
|
119
|
+
options: { presentation: 'formSheet' },
|
|
120
|
+
content: createElement('span', null, 'inline-content'),
|
|
121
|
+
},
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const markup = renderToStaticMarkup(
|
|
125
|
+
createElement(OverlayHost, {
|
|
126
|
+
route: makeRoute('filter'),
|
|
127
|
+
descriptor: descriptors['filter-key']!,
|
|
128
|
+
contextRender: undefined,
|
|
129
|
+
onDismiss: () => {},
|
|
130
|
+
})
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
expect(markup).toContain('inline-content')
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('skips render when presentation is not an overlay', () => {
|
|
137
|
+
const Render = vi.fn(() => null)
|
|
138
|
+
const descriptors = makeDescriptors({
|
|
139
|
+
home: {
|
|
140
|
+
options: { presentation: 'card' },
|
|
141
|
+
content: createElement('span', null, 'card-content'),
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
const markup = renderToStaticMarkup(
|
|
146
|
+
createElement(OverlayHost, {
|
|
147
|
+
route: makeRoute('home'),
|
|
148
|
+
descriptor: descriptors['home-key']!,
|
|
149
|
+
contextRender: { web: Render },
|
|
150
|
+
onDismiss: () => {},
|
|
151
|
+
})
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
expect(Render).not.toHaveBeenCalled()
|
|
155
|
+
expect(markup).toContain('card-content')
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('per-route render overrides context render', () => {
|
|
159
|
+
const ContextRender = vi.fn(() => null)
|
|
160
|
+
const PerRoute = vi.fn(() => createElement('em', null, 'per-route'))
|
|
161
|
+
const descriptors = makeDescriptors({
|
|
162
|
+
sheet: {
|
|
163
|
+
options: {
|
|
164
|
+
presentation: 'formSheet',
|
|
165
|
+
render: { web: PerRoute },
|
|
166
|
+
},
|
|
167
|
+
content: createElement('span', null, 'body'),
|
|
168
|
+
},
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
const markup = renderToStaticMarkup(
|
|
172
|
+
createElement(OverlayHost, {
|
|
173
|
+
route: makeRoute('sheet'),
|
|
174
|
+
descriptor: descriptors['sheet-key']!,
|
|
175
|
+
contextRender: { web: ContextRender },
|
|
176
|
+
onDismiss: () => {},
|
|
177
|
+
})
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
expect(PerRoute).toHaveBeenCalledTimes(1)
|
|
181
|
+
expect(ContextRender).not.toHaveBeenCalled()
|
|
182
|
+
expect(markup).toContain('per-route')
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
it('dismiss callback wraps the supplied onDismiss', () => {
|
|
186
|
+
const onDismiss = vi.fn()
|
|
187
|
+
let capturedDismiss: (() => void) | undefined
|
|
188
|
+
const Render = (props: any) => {
|
|
189
|
+
capturedDismiss = props.dismiss
|
|
190
|
+
return null
|
|
191
|
+
}
|
|
192
|
+
const descriptors = makeDescriptors({
|
|
193
|
+
sheet: { options: { presentation: 'formSheet' } },
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
renderToStaticMarkup(
|
|
197
|
+
createElement(OverlayHost, {
|
|
198
|
+
route: makeRoute('sheet'),
|
|
199
|
+
descriptor: descriptors['sheet-key']!,
|
|
200
|
+
contextRender: { web: Render },
|
|
201
|
+
onDismiss,
|
|
202
|
+
})
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
expect(typeof capturedDismiss).toBe('function')
|
|
206
|
+
capturedDismiss!()
|
|
207
|
+
expect(onDismiss).toHaveBeenCalledTimes(1)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
it('respects gestureEnabled: false as dismissible: false', () => {
|
|
211
|
+
let captured: any
|
|
212
|
+
const Render = (props: any) => {
|
|
213
|
+
captured = props
|
|
214
|
+
return null
|
|
215
|
+
}
|
|
216
|
+
const descriptors = makeDescriptors({
|
|
217
|
+
sheet: { options: { presentation: 'formSheet', gestureEnabled: false } },
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
renderToStaticMarkup(
|
|
221
|
+
createElement(OverlayHost, {
|
|
222
|
+
route: makeRoute('sheet'),
|
|
223
|
+
descriptor: descriptors['sheet-key']!,
|
|
224
|
+
contextRender: { web: Render },
|
|
225
|
+
onDismiss: () => {},
|
|
226
|
+
})
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
expect(captured.dismissible).toBe(false)
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
describe('WebStackView overlay dispatch', () => {
|
|
234
|
+
it('renders each overlay route via the configured render', () => {
|
|
235
|
+
const calls: string[] = []
|
|
236
|
+
const Render = (props: any) => {
|
|
237
|
+
calls.push(props.routeKey)
|
|
238
|
+
return createElement('div', { 'data-route': props.routeKey })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const state = makeState(['home', 'filter', 'help'], 2)
|
|
242
|
+
const descriptors = makeDescriptors({
|
|
243
|
+
home: { options: { presentation: 'card' } },
|
|
244
|
+
filter: { options: { presentation: 'formSheet' } },
|
|
245
|
+
help: { options: { presentation: 'modal' } },
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
const navigation = { dispatch: vi.fn() } as any
|
|
249
|
+
|
|
250
|
+
const markup = renderToStaticMarkup(
|
|
251
|
+
createElement(
|
|
252
|
+
StackRenderProvider,
|
|
253
|
+
{ value: { web: Render } as StackRender },
|
|
254
|
+
createElement(WebStackView, {
|
|
255
|
+
state,
|
|
256
|
+
navigation,
|
|
257
|
+
descriptors: descriptors as any,
|
|
258
|
+
})
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
expect(calls).toEqual(['filter-key', 'help-key'])
|
|
263
|
+
expect(markup).toContain('data-route="filter-key"')
|
|
264
|
+
expect(markup).toContain('data-route="help-key"')
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('leaves overlay routes in the underlying NativeStackView when no render is configured', () => {
|
|
268
|
+
// No render in context → no overlay split → NativeStackView (mocked to
|
|
269
|
+
// return null) renders the route normally. No extra DOM from overlays.
|
|
270
|
+
const state = makeState(['home', 'filter'], 1)
|
|
271
|
+
const descriptors = makeDescriptors({
|
|
272
|
+
home: { options: { presentation: 'card' } },
|
|
273
|
+
filter: {
|
|
274
|
+
options: { presentation: 'formSheet' },
|
|
275
|
+
content: createElement('span', null, 'should-not-render-as-overlay'),
|
|
276
|
+
},
|
|
277
|
+
})
|
|
278
|
+
const navigation = { dispatch: vi.fn() } as any
|
|
279
|
+
|
|
280
|
+
const markup = renderToStaticMarkup(
|
|
281
|
+
createElement(WebStackView, {
|
|
282
|
+
state,
|
|
283
|
+
navigation,
|
|
284
|
+
descriptors: descriptors as any,
|
|
285
|
+
})
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
// Mock NativeStackView returns null, and we shouldn't have rendered the
|
|
289
|
+
// overlay route ourselves either.
|
|
290
|
+
expect(markup).not.toContain('should-not-render-as-overlay')
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
it('passes open: true to the regular overlay render', () => {
|
|
294
|
+
let captured: any
|
|
295
|
+
const Render = (props: any) => {
|
|
296
|
+
captured = props
|
|
297
|
+
return null
|
|
298
|
+
}
|
|
299
|
+
const state = makeState(['home', 'sheet'], 1)
|
|
300
|
+
const descriptors = makeDescriptors({
|
|
301
|
+
home: { options: { presentation: 'card' } },
|
|
302
|
+
sheet: { options: { presentation: 'formSheet' } },
|
|
303
|
+
})
|
|
304
|
+
const navigation = { dispatch: vi.fn() } as any
|
|
305
|
+
|
|
306
|
+
renderToStaticMarkup(
|
|
307
|
+
createElement(
|
|
308
|
+
StackRenderProvider,
|
|
309
|
+
{ value: { web: Render } as StackRender },
|
|
310
|
+
createElement(WebStackView, {
|
|
311
|
+
state,
|
|
312
|
+
navigation,
|
|
313
|
+
descriptors: descriptors as any,
|
|
314
|
+
})
|
|
315
|
+
)
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
expect(captured.open).toBe(true)
|
|
319
|
+
expect(captured.routeName).toBe('sheet')
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
it('keepMounted: keeps rendering the route via the persistent slot after the route is popped', () => {
|
|
323
|
+
const calls: { name: string; open: boolean; bodyMarker?: any }[] = []
|
|
324
|
+
let mountTrackerCalls = 0
|
|
325
|
+
const Render = (props: any) => {
|
|
326
|
+
calls.push({ name: props.routeName, open: props.open })
|
|
327
|
+
return createElement(
|
|
328
|
+
'div',
|
|
329
|
+
{ 'data-route': props.routeName, 'data-open': String(props.open) },
|
|
330
|
+
props.children
|
|
331
|
+
)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Probe: a component that tracks how many times it mounts vs. re-renders.
|
|
335
|
+
// If the persistent slot works, this mounts once and re-renders many
|
|
336
|
+
// times. If it remounts, mountTrackerCalls increases.
|
|
337
|
+
const MountTracker = () => {
|
|
338
|
+
mountTrackerCalls++
|
|
339
|
+
return createElement('span', null, `mounted-${mountTrackerCalls}`)
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const initialState = makeState(['home', 'settings'], 1)
|
|
343
|
+
const settingsDescriptor: Descriptor = {
|
|
344
|
+
options: { presentation: 'formSheet', keepMounted: true },
|
|
345
|
+
render: () => createElement(MountTracker),
|
|
346
|
+
navigation: {},
|
|
347
|
+
}
|
|
348
|
+
const descriptors: Record<string, Descriptor> = {
|
|
349
|
+
'home-key': {
|
|
350
|
+
options: { presentation: 'card' },
|
|
351
|
+
render: () => null,
|
|
352
|
+
navigation: {},
|
|
353
|
+
},
|
|
354
|
+
'settings-key': settingsDescriptor,
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Render once with settings open.
|
|
358
|
+
const navigation = { dispatch: vi.fn() } as any
|
|
359
|
+
const tree = createElement(
|
|
360
|
+
StackRenderProvider,
|
|
361
|
+
{ value: { web: Render } as StackRender },
|
|
362
|
+
createElement(WebStackView, {
|
|
363
|
+
state: initialState,
|
|
364
|
+
navigation,
|
|
365
|
+
descriptors: descriptors as any,
|
|
366
|
+
})
|
|
367
|
+
)
|
|
368
|
+
const out1 = renderToStaticMarkup(tree)
|
|
369
|
+
|
|
370
|
+
expect(calls.some((c) => c.name === 'settings' && c.open === true)).toBe(true)
|
|
371
|
+
expect(out1).toContain('data-route="settings"')
|
|
372
|
+
expect(out1).toContain('data-open="true"')
|
|
373
|
+
|
|
374
|
+
// Now re-render with settings popped (only home in state). Persistent
|
|
375
|
+
// slot should still render the settings route with open=false.
|
|
376
|
+
// Note: SSR renderToStaticMarkup does NOT share refs across calls, so
|
|
377
|
+
// for this assertion we instead verify the rendered shape: even though
|
|
378
|
+
// the persistent slot ref is fresh in SSR, the API contract says the
|
|
379
|
+
// FIRST render captures and SUBSEQUENT renders keep emitting. We test
|
|
380
|
+
// that path in the jsdom test below - here we just verify single-pass
|
|
381
|
+
// capture happens with open=true on the initial render.
|
|
382
|
+
expect(calls).toHaveLength(1)
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
it('peels off only overlay routes with a render configured, leaving render-less overlays in the underlying view', () => {
|
|
386
|
+
// help (modal, no render) is below filter (formSheet, with render).
|
|
387
|
+
// help should stay in NativeStackView; filter should be dispatched to
|
|
388
|
+
// the render component as the trailing overlay.
|
|
389
|
+
const PerRoute = vi.fn(() => createElement('div', { 'data-route': 'filter' }))
|
|
390
|
+
const state = makeState(['home', 'help', 'filter'], 2)
|
|
391
|
+
const descriptors = makeDescriptors({
|
|
392
|
+
home: { options: { presentation: 'card' } },
|
|
393
|
+
help: { options: { presentation: 'modal' } }, // overlay-presented, no render
|
|
394
|
+
filter: {
|
|
395
|
+
options: { presentation: 'formSheet', render: { web: PerRoute } },
|
|
396
|
+
},
|
|
397
|
+
})
|
|
398
|
+
const navigation = { dispatch: vi.fn() } as any
|
|
399
|
+
|
|
400
|
+
renderToStaticMarkup(
|
|
401
|
+
createElement(WebStackView, {
|
|
402
|
+
state,
|
|
403
|
+
navigation,
|
|
404
|
+
descriptors: descriptors as any,
|
|
405
|
+
})
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
expect(PerRoute).toHaveBeenCalledTimes(1)
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
it('dispatches a pop action when an overlay calls dismiss', () => {
|
|
412
|
+
let captured: any
|
|
413
|
+
const Render = (props: any) => {
|
|
414
|
+
captured = props
|
|
415
|
+
return null
|
|
416
|
+
}
|
|
417
|
+
const state = makeState(['home', 'filter'], 1)
|
|
418
|
+
const descriptors = makeDescriptors({
|
|
419
|
+
home: { options: { presentation: 'card' } },
|
|
420
|
+
filter: { options: { presentation: 'formSheet' } },
|
|
421
|
+
})
|
|
422
|
+
const dispatch = vi.fn()
|
|
423
|
+
const navigation = { dispatch, isFocused: () => true } as any
|
|
424
|
+
|
|
425
|
+
renderToStaticMarkup(
|
|
426
|
+
createElement(
|
|
427
|
+
StackRenderProvider,
|
|
428
|
+
{ value: { web: Render } as StackRender },
|
|
429
|
+
createElement(WebStackView, {
|
|
430
|
+
state,
|
|
431
|
+
navigation,
|
|
432
|
+
descriptors: descriptors as any,
|
|
433
|
+
})
|
|
434
|
+
)
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
captured.dismiss()
|
|
438
|
+
expect(dispatch).toHaveBeenCalledTimes(1)
|
|
439
|
+
const action = dispatch.mock.calls[0]![0]
|
|
440
|
+
expect(action.type).toBe('POP')
|
|
441
|
+
expect(action.source).toBe('filter-key')
|
|
442
|
+
expect(action.target).toBe('stack-1')
|
|
443
|
+
})
|
|
444
|
+
})
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import type { ParamListBase, StackNavigationState } from '@react-navigation/native'
|
|
3
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
convertStackStateToNonOverlayState,
|
|
7
|
+
findLastNonOverlayIndex,
|
|
8
|
+
isOverlayPresentation,
|
|
9
|
+
isTransparentOverlay,
|
|
10
|
+
} from '../stackStateUtils'
|
|
11
|
+
|
|
12
|
+
type Descriptors = Record<string, { options: NativeStackNavigationOptions }>
|
|
13
|
+
|
|
14
|
+
function makeState(
|
|
15
|
+
routeNames: string[],
|
|
16
|
+
index: number
|
|
17
|
+
): StackNavigationState<ParamListBase> {
|
|
18
|
+
const routes = routeNames.map((name) => ({
|
|
19
|
+
key: `${name}-key`,
|
|
20
|
+
name,
|
|
21
|
+
params: undefined,
|
|
22
|
+
})) as StackNavigationState<ParamListBase>['routes']
|
|
23
|
+
return {
|
|
24
|
+
key: 'stack',
|
|
25
|
+
index,
|
|
26
|
+
routeNames,
|
|
27
|
+
routes,
|
|
28
|
+
type: 'stack',
|
|
29
|
+
stale: false,
|
|
30
|
+
preloadedRoutes: [],
|
|
31
|
+
} as unknown as StackNavigationState<ParamListBase>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function makeDescriptors(
|
|
35
|
+
routeNames: string[],
|
|
36
|
+
presentations: Record<string, NativeStackNavigationOptions['presentation']>
|
|
37
|
+
): Descriptors {
|
|
38
|
+
const out: Descriptors = {}
|
|
39
|
+
for (const name of routeNames) {
|
|
40
|
+
out[`${name}-key`] = { options: { presentation: presentations[name] } }
|
|
41
|
+
}
|
|
42
|
+
return out
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe('isOverlayPresentation', () => {
|
|
46
|
+
it('returns true for known overlay presentations', () => {
|
|
47
|
+
for (const p of [
|
|
48
|
+
'modal',
|
|
49
|
+
'transparentModal',
|
|
50
|
+
'fullScreenModal',
|
|
51
|
+
'formSheet',
|
|
52
|
+
'pageSheet',
|
|
53
|
+
'containedModal',
|
|
54
|
+
'containedTransparentModal',
|
|
55
|
+
] as const) {
|
|
56
|
+
expect(isOverlayPresentation({ presentation: p })).toBe(true)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('returns false for card and undefined', () => {
|
|
61
|
+
expect(isOverlayPresentation({ presentation: 'card' })).toBe(false)
|
|
62
|
+
expect(isOverlayPresentation({})).toBe(false)
|
|
63
|
+
expect(isOverlayPresentation(undefined)).toBe(false)
|
|
64
|
+
expect(isOverlayPresentation(null)).toBe(false)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
describe('isTransparentOverlay', () => {
|
|
69
|
+
it('flags transparent variants only', () => {
|
|
70
|
+
expect(isTransparentOverlay({ presentation: 'transparentModal' })).toBe(true)
|
|
71
|
+
expect(isTransparentOverlay({ presentation: 'containedTransparentModal' })).toBe(true)
|
|
72
|
+
expect(isTransparentOverlay({ presentation: 'modal' })).toBe(false)
|
|
73
|
+
expect(isTransparentOverlay({ presentation: 'formSheet' })).toBe(false)
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('convertStackStateToNonOverlayState', () => {
|
|
78
|
+
it('removes overlay routes and keeps card routes', () => {
|
|
79
|
+
const state = makeState(['home', 'detail', 'filter'], 2)
|
|
80
|
+
const descriptors = makeDescriptors(['home', 'detail', 'filter'], {
|
|
81
|
+
home: 'card',
|
|
82
|
+
detail: 'card',
|
|
83
|
+
filter: 'formSheet',
|
|
84
|
+
})
|
|
85
|
+
const out = convertStackStateToNonOverlayState(state, descriptors)
|
|
86
|
+
expect(out.routes.map((r) => r.name)).toEqual(['home', 'detail'])
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('falls back to last remaining route when active route was an overlay', () => {
|
|
90
|
+
const state = makeState(['home', 'detail', 'filter'], 2)
|
|
91
|
+
const descriptors = makeDescriptors(['home', 'detail', 'filter'], {
|
|
92
|
+
home: 'card',
|
|
93
|
+
detail: 'card',
|
|
94
|
+
filter: 'formSheet',
|
|
95
|
+
})
|
|
96
|
+
const out = convertStackStateToNonOverlayState(state, descriptors)
|
|
97
|
+
expect(out.index).toBe(1)
|
|
98
|
+
expect(out.routes[out.index]!.name).toBe('detail')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
it('preserves active index when active route is not an overlay', () => {
|
|
102
|
+
const state = makeState(['home', 'detail', 'filter'], 1)
|
|
103
|
+
const descriptors = makeDescriptors(['home', 'detail', 'filter'], {
|
|
104
|
+
home: 'card',
|
|
105
|
+
detail: 'card',
|
|
106
|
+
filter: 'formSheet',
|
|
107
|
+
})
|
|
108
|
+
const out = convertStackStateToNonOverlayState(state, descriptors)
|
|
109
|
+
expect(out.routes[out.index]!.name).toBe('detail')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('does not strip mid-stack overlays (regression: only the trailing overlay suffix is removed)', () => {
|
|
113
|
+
// User opened a sheet then navigated forward to a card. The sheet is
|
|
114
|
+
// sandwiched in the middle. It MUST stay in the underlying state so
|
|
115
|
+
// detail's previous-route / header-back context references the sheet.
|
|
116
|
+
const state = makeState(['home', 'sheet', 'detail'], 2)
|
|
117
|
+
const descriptors = makeDescriptors(['home', 'sheet', 'detail'], {
|
|
118
|
+
home: 'card',
|
|
119
|
+
sheet: 'formSheet',
|
|
120
|
+
detail: 'card',
|
|
121
|
+
})
|
|
122
|
+
const out = convertStackStateToNonOverlayState(state, descriptors)
|
|
123
|
+
expect(out.routes.map((r) => r.name)).toEqual(['home', 'sheet', 'detail'])
|
|
124
|
+
expect(out.index).toBe(2)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('handles all-overlay state without crashing', () => {
|
|
128
|
+
const state = makeState(['only-sheet'], 0)
|
|
129
|
+
const descriptors = makeDescriptors(['only-sheet'], { 'only-sheet': 'formSheet' })
|
|
130
|
+
const out = convertStackStateToNonOverlayState(state, descriptors)
|
|
131
|
+
expect(out.routes).toHaveLength(0)
|
|
132
|
+
expect(out.index).toBe(0)
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
describe('findLastNonOverlayIndex', () => {
|
|
137
|
+
it('returns the highest index that is not an overlay', () => {
|
|
138
|
+
const state = makeState(['home', 'detail', 'filter', 'pop'], 3)
|
|
139
|
+
const descriptors = makeDescriptors(['home', 'detail', 'filter', 'pop'], {
|
|
140
|
+
home: 'card',
|
|
141
|
+
detail: 'card',
|
|
142
|
+
filter: 'formSheet',
|
|
143
|
+
pop: 'transparentModal',
|
|
144
|
+
})
|
|
145
|
+
expect(findLastNonOverlayIndex(state, descriptors)).toBe(1)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('returns -1 when every route is an overlay', () => {
|
|
149
|
+
const state = makeState(['sheet'], 0)
|
|
150
|
+
const descriptors = makeDescriptors(['sheet'], { sheet: 'formSheet' })
|
|
151
|
+
expect(findLastNonOverlayIndex(state, descriptors)).toBe(-1)
|
|
152
|
+
})
|
|
153
|
+
})
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { ParamListBase, StackNavigationState } from '@react-navigation/native'
|
|
2
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'
|
|
3
|
+
|
|
4
|
+
const OVERLAY_PRESENTATIONS = [
|
|
5
|
+
'modal',
|
|
6
|
+
'transparentModal',
|
|
7
|
+
'fullScreenModal',
|
|
8
|
+
'formSheet',
|
|
9
|
+
'pageSheet',
|
|
10
|
+
'containedModal',
|
|
11
|
+
'containedTransparentModal',
|
|
12
|
+
] as const
|
|
13
|
+
|
|
14
|
+
type OverlayPresentation = (typeof OVERLAY_PRESENTATIONS)[number]
|
|
15
|
+
|
|
16
|
+
type DescriptorMap = Record<string, { options: NativeStackNavigationOptions }>
|
|
17
|
+
|
|
18
|
+
export function isOverlayPresentation(
|
|
19
|
+
options: NativeStackNavigationOptions | undefined | null
|
|
20
|
+
): boolean {
|
|
21
|
+
const presentation = options?.presentation
|
|
22
|
+
if (!presentation) return false
|
|
23
|
+
return (OVERLAY_PRESENTATIONS as readonly string[]).includes(presentation)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isTransparentOverlay(
|
|
27
|
+
options: NativeStackNavigationOptions | undefined | null
|
|
28
|
+
): boolean {
|
|
29
|
+
const presentation = options?.presentation
|
|
30
|
+
return (
|
|
31
|
+
presentation === 'transparentModal' || presentation === 'containedTransparentModal'
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Returns the underlying navigation state for NativeStackView with the
|
|
37
|
+
* trailing overlay suffix removed.
|
|
38
|
+
*
|
|
39
|
+
* Important: we only strip the suffix of overlay routes at the top of the
|
|
40
|
+
* stack. Overlay routes that are SANDWICHED between cards (e.g. user
|
|
41
|
+
* navigated forward from a sheet to a card) stay in the underlying state
|
|
42
|
+
* so NativeStackView still has a complete history and downstream routes
|
|
43
|
+
* keep their correct previous-route / header-back context.
|
|
44
|
+
*
|
|
45
|
+
* The `isOverlay` predicate defaults to `isOverlayPresentation`; callers
|
|
46
|
+
* can narrow it (e.g. only routes that actually have a render component
|
|
47
|
+
* configured).
|
|
48
|
+
*/
|
|
49
|
+
export function convertStackStateToNonOverlayState(
|
|
50
|
+
state: StackNavigationState<ParamListBase>,
|
|
51
|
+
descriptors: DescriptorMap,
|
|
52
|
+
isOverlay: (
|
|
53
|
+
options: NativeStackNavigationOptions | undefined | null
|
|
54
|
+
) => boolean = isOverlayPresentation
|
|
55
|
+
): { routes: typeof state.routes; index: number } {
|
|
56
|
+
const lastNonOverlay = findLastNonOverlayIndex(state, descriptors, isOverlay)
|
|
57
|
+
const routes = state.routes.slice(0, lastNonOverlay + 1)
|
|
58
|
+
|
|
59
|
+
// If the active route was in the trailing overlay suffix, clamp the index
|
|
60
|
+
// to the last route still in the underlying view.
|
|
61
|
+
let index = state.index
|
|
62
|
+
if (index >= routes.length) {
|
|
63
|
+
index = routes.length > 0 ? routes.length - 1 : 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return { routes, index }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Index of the last route that is NOT an overlay. Returns -1 if every route
|
|
71
|
+
* is an overlay. Accepts the same predicate as
|
|
72
|
+
* `convertStackStateToNonOverlayState`.
|
|
73
|
+
*/
|
|
74
|
+
export function findLastNonOverlayIndex(
|
|
75
|
+
state: StackNavigationState<ParamListBase>,
|
|
76
|
+
descriptors: DescriptorMap,
|
|
77
|
+
isOverlay: (
|
|
78
|
+
options: NativeStackNavigationOptions | undefined | null
|
|
79
|
+
) => boolean = isOverlayPresentation
|
|
80
|
+
): number {
|
|
81
|
+
for (let i = state.routes.length - 1; i >= 0; i--) {
|
|
82
|
+
if (!isOverlay(descriptors[state.routes[i]!.key]?.options)) {
|
|
83
|
+
return i
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return -1
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type { OverlayPresentation }
|