expo-router 55.0.0-preview.8 → 55.0.0
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/android/build.gradle +2 -2
- package/build/fork/native-stack/composition-options/CompositionOptionsContext.d.ts +38 -0
- package/build/fork/native-stack/composition-options/CompositionOptionsContext.d.ts.map +1 -0
- package/build/fork/native-stack/composition-options/CompositionOptionsContext.js +75 -0
- package/build/fork/native-stack/composition-options/CompositionOptionsContext.js.map +1 -0
- package/build/fork/native-stack/composition-options/index.d.ts +4 -0
- package/build/fork/native-stack/composition-options/index.d.ts.map +1 -0
- package/build/fork/native-stack/composition-options/index.js +10 -0
- package/build/fork/native-stack/composition-options/index.js.map +1 -0
- package/build/fork/native-stack/composition-options/mergeOptions.d.ts +13 -0
- package/build/fork/native-stack/composition-options/mergeOptions.d.ts.map +1 -0
- package/build/fork/native-stack/composition-options/mergeOptions.js +39 -0
- package/build/fork/native-stack/composition-options/mergeOptions.js.map +1 -0
- package/build/fork/native-stack/composition-options/types.d.ts +25 -0
- package/build/fork/native-stack/composition-options/types.d.ts.map +1 -0
- package/build/fork/native-stack/composition-options/types.js +3 -0
- package/build/fork/native-stack/composition-options/types.js.map +1 -0
- package/build/fork/native-stack/createNativeStackNavigator.d.ts.map +1 -1
- package/build/fork/native-stack/createNativeStackNavigator.js +38 -86
- package/build/fork/native-stack/createNativeStackNavigator.js.map +1 -1
- package/build/fork/native-stack/usePreviewTransition.d.ts +21 -0
- package/build/fork/native-stack/usePreviewTransition.d.ts.map +1 -0
- package/build/fork/native-stack/usePreviewTransition.js +119 -0
- package/build/fork/native-stack/usePreviewTransition.js.map +1 -0
- package/build/layouts/ExperimentalModalStack.d.ts +2 -2
- package/build/layouts/ExperimentalModalStack.d.ts.map +1 -1
- package/build/layouts/ExperimentalModalStack.js +6 -4
- package/build/layouts/ExperimentalModalStack.js.map +1 -1
- package/build/layouts/StackClient.d.ts +2 -2
- package/build/layouts/StackClient.d.ts.map +1 -1
- package/build/layouts/StackClient.js +1 -35
- package/build/layouts/StackClient.js.map +1 -1
- package/build/layouts/stack-utils/StackHeaderComponent.d.ts +4 -1
- package/build/layouts/stack-utils/StackHeaderComponent.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackHeaderComponent.js +10 -6
- package/build/layouts/stack-utils/StackHeaderComponent.js.map +1 -1
- package/build/layouts/stack-utils/StackScreen.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackScreen.js +3 -10
- package/build/layouts/stack-utils/StackScreen.js.map +1 -1
- package/build/layouts/stack-utils/StackSearchBar.d.ts +1 -1
- package/build/layouts/stack-utils/StackSearchBar.d.ts.map +1 -1
- package/build/layouts/stack-utils/StackSearchBar.js +59 -4
- package/build/layouts/stack-utils/StackSearchBar.js.map +1 -1
- package/build/layouts/stack-utils/index.d.ts +1 -0
- package/build/layouts/stack-utils/index.d.ts.map +1 -1
- package/build/layouts/stack-utils/index.js +3 -1
- package/build/layouts/stack-utils/index.js.map +1 -1
- package/build/layouts/stack-utils/mapProtectedScreen.d.ts +3 -0
- package/build/layouts/stack-utils/mapProtectedScreen.d.ts.map +1 -0
- package/build/layouts/stack-utils/mapProtectedScreen.js +76 -0
- package/build/layouts/stack-utils/mapProtectedScreen.js.map +1 -0
- package/build/layouts/stack-utils/screen/StackScreenBackButton.d.ts +4 -1
- package/build/layouts/stack-utils/screen/StackScreenBackButton.d.ts.map +1 -1
- package/build/layouts/stack-utils/screen/StackScreenBackButton.js +10 -4
- package/build/layouts/stack-utils/screen/StackScreenBackButton.js.map +1 -1
- package/build/layouts/stack-utils/screen/StackScreenTitle.d.ts +4 -1
- package/build/layouts/stack-utils/screen/StackScreenTitle.d.ts.map +1 -1
- package/build/layouts/stack-utils/screen/StackScreenTitle.js +10 -4
- package/build/layouts/stack-utils/screen/StackScreenTitle.js.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarButton.js +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarButton.js.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarClient.d.ts +4 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarClient.d.ts.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarClient.js +10 -17
- package/build/layouts/stack-utils/toolbar/StackToolbarClient.js.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.d.ts.map +1 -1
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js +3 -3
- package/build/layouts/stack-utils/toolbar/StackToolbarMenu.js.map +1 -1
- package/build/layouts/stack-utils/toolbar/shared.d.ts +1 -1
- package/build/layouts/stack-utils/toolbar/shared.d.ts.map +1 -1
- package/build/layouts/stack-utils/toolbar/shared.js +12 -17
- package/build/layouts/stack-utils/toolbar/shared.js.map +1 -1
- package/build/layouts/stack-utils/toolbar/toolbar-primitives.d.ts +0 -3
- package/build/layouts/stack-utils/toolbar/toolbar-primitives.d.ts.map +1 -1
- package/build/layouts/stack-utils/toolbar/toolbar-primitives.js.map +1 -1
- package/build/link/preview/HrefPreview.d.ts.map +1 -1
- package/build/link/preview/HrefPreview.js +7 -4
- package/build/link/preview/HrefPreview.js.map +1 -1
- package/build/link/zoom/ZoomTransitionEnabler.ios.d.ts.map +1 -1
- package/build/link/zoom/ZoomTransitionEnabler.ios.js +9 -2
- package/build/link/zoom/ZoomTransitionEnabler.ios.js.map +1 -1
- package/build/native-tabs/common/elements.d.ts +3 -4
- package/build/native-tabs/common/elements.d.ts.map +1 -1
- package/build/native-tabs/common/elements.js.map +1 -1
- package/build/native-tabs/utils/icon.d.ts.map +1 -1
- package/build/native-tabs/utils/icon.js +8 -10
- package/build/native-tabs/utils/icon.js.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/LinkPreview/LinkPreviewNativeNavigation.swift +5 -5
- package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.module → 55.0.0/expo.modules.router-55.0.0.module} +7 -7
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.pom → 55.0.0/expo.modules.router-55.0.0.pom} +13 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0/expo.modules.router-55.0.0.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/maven-metadata.xml.sha512 +1 -1
- package/package.json +10 -9
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.module.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/router/expo.modules.router/55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.pom.sha512 +0 -1
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8-sources.jar → 55.0.0/expo.modules.router-55.0.0-sources.jar} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8-sources.jar.md5 → 55.0.0/expo.modules.router-55.0.0-sources.jar.md5} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8-sources.jar.sha1 → 55.0.0/expo.modules.router-55.0.0-sources.jar.sha1} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8-sources.jar.sha256 → 55.0.0/expo.modules.router-55.0.0-sources.jar.sha256} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8-sources.jar.sha512 → 55.0.0/expo.modules.router-55.0.0-sources.jar.sha512} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.aar → 55.0.0/expo.modules.router-55.0.0.aar} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.aar.md5 → 55.0.0/expo.modules.router-55.0.0.aar.md5} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.aar.sha1 → 55.0.0/expo.modules.router-55.0.0.aar.sha1} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.aar.sha256 → 55.0.0/expo.modules.router-55.0.0.aar.sha256} +0 -0
- /package/local-maven-repo/expo/modules/router/expo.modules.router/{55.0.0-preview.8/expo.modules.router-55.0.0-preview.8.aar.sha512 → 55.0.0/expo.modules.router-55.0.0.aar.sha512} +0 -0
package/android/build.gradle
CHANGED
|
@@ -4,13 +4,13 @@ plugins {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
group = 'expo.modules.router'
|
|
7
|
-
version = '55.0.0
|
|
7
|
+
version = '55.0.0'
|
|
8
8
|
|
|
9
9
|
android {
|
|
10
10
|
namespace "expo.modules.router"
|
|
11
11
|
defaultConfig {
|
|
12
12
|
versionCode 1
|
|
13
|
-
versionName "55.0.0
|
|
13
|
+
versionName "55.0.0"
|
|
14
14
|
}
|
|
15
15
|
lintOptions {
|
|
16
16
|
abortOnError false
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
|
2
|
+
import type { CompositionContextValue, CompositionRegistry } from './types';
|
|
3
|
+
/** @internal */
|
|
4
|
+
export declare const CompositionContext: import("react").Context<CompositionContextValue | null>;
|
|
5
|
+
type RegistryAction = {
|
|
6
|
+
type: 'set';
|
|
7
|
+
routeKey: string;
|
|
8
|
+
options: Partial<NativeStackNavigationOptions>;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'unset';
|
|
11
|
+
routeKey: string;
|
|
12
|
+
options: Partial<NativeStackNavigationOptions>;
|
|
13
|
+
};
|
|
14
|
+
/** @internal */
|
|
15
|
+
export declare function registryReducer(state: CompositionRegistry, action: RegistryAction): CompositionRegistry;
|
|
16
|
+
/**
|
|
17
|
+
* Provides the composition registry to descendant composition components.
|
|
18
|
+
*
|
|
19
|
+
* Uses useReducer with immutable object updates for React Compiler compatibility.
|
|
20
|
+
* Each set/unset call produces a new object reference, which the compiler can
|
|
21
|
+
* track as a reactive dependency.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useCompositionRegistry(): {
|
|
24
|
+
registry: CompositionRegistry;
|
|
25
|
+
contextValue: {
|
|
26
|
+
set: (routeKey: string, options: Partial<NativeStackNavigationOptions>) => void;
|
|
27
|
+
unset: (routeKey: string, options: Partial<NativeStackNavigationOptions>) => void;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Hook used by composition components to register their options in the composition registry.
|
|
32
|
+
*
|
|
33
|
+
* Registers options on mount/update via useSafeLayoutEffect, and unregisters on unmount.
|
|
34
|
+
* Callers should memoize the options object to avoid unnecessary re-registrations.
|
|
35
|
+
*/
|
|
36
|
+
export declare function useCompositionOption(options: Partial<NativeStackNavigationOptions>): void;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=CompositionOptionsContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositionOptionsContext.d.ts","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/CompositionOptionsContext.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAGnF,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG5E,gBAAgB;AAChB,eAAO,MAAM,kBAAkB,yDAAsD,CAAC;AAEtF,KAAK,cAAc,GACf;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAC;CAChD,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAA;CAAE,CAAC;AAExF,gBAAgB;AAChB,wBAAgB,eAAe,CAC7B,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,cAAc,GACrB,mBAAmB,CAuBrB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB;;;wBAGD,MAAM,WAAW,OAAO,CAAC,4BAA4B,CAAC;0BAIpD,MAAM,WAAW,OAAO,CAAC,4BAA4B,CAAC;;EAS5F;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,QAiBlF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.CompositionContext = void 0;
|
|
5
|
+
exports.registryReducer = registryReducer;
|
|
6
|
+
exports.useCompositionRegistry = useCompositionRegistry;
|
|
7
|
+
exports.useCompositionOption = useCompositionOption;
|
|
8
|
+
const native_1 = require("@react-navigation/native");
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
const useSafeLayoutEffect_1 = require("../../../views/useSafeLayoutEffect");
|
|
11
|
+
/** @internal */
|
|
12
|
+
exports.CompositionContext = (0, react_1.createContext)(null);
|
|
13
|
+
/** @internal */
|
|
14
|
+
function registryReducer(state, action) {
|
|
15
|
+
if (action.type === 'set') {
|
|
16
|
+
const { routeKey, options } = action;
|
|
17
|
+
if (state[routeKey]?.includes(options)) {
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
return { ...state, [routeKey]: [...(state[routeKey] ?? []), options] };
|
|
21
|
+
}
|
|
22
|
+
if (action.type === 'unset') {
|
|
23
|
+
const { routeKey, options } = action;
|
|
24
|
+
const existing = state[routeKey];
|
|
25
|
+
const filtered = existing?.filter((o) => o !== options);
|
|
26
|
+
if (!existing || filtered?.length === existing.length) {
|
|
27
|
+
return state;
|
|
28
|
+
}
|
|
29
|
+
if (filtered.length === 0) {
|
|
30
|
+
const { [routeKey]: _, ...newState } = state;
|
|
31
|
+
return newState;
|
|
32
|
+
}
|
|
33
|
+
return { ...state, [routeKey]: filtered };
|
|
34
|
+
}
|
|
35
|
+
return state;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Provides the composition registry to descendant composition components.
|
|
39
|
+
*
|
|
40
|
+
* Uses useReducer with immutable object updates for React Compiler compatibility.
|
|
41
|
+
* Each set/unset call produces a new object reference, which the compiler can
|
|
42
|
+
* track as a reactive dependency.
|
|
43
|
+
*/
|
|
44
|
+
function useCompositionRegistry() {
|
|
45
|
+
const [registry, dispatch] = (0, react_1.useReducer)(registryReducer, {});
|
|
46
|
+
const set = (0, react_1.useCallback)((routeKey, options) => {
|
|
47
|
+
dispatch({ type: 'set', routeKey, options });
|
|
48
|
+
}, []);
|
|
49
|
+
const unset = (0, react_1.useCallback)((routeKey, options) => {
|
|
50
|
+
dispatch({ type: 'unset', routeKey, options });
|
|
51
|
+
}, []);
|
|
52
|
+
const contextValue = (0, react_1.useMemo)(() => ({ set, unset }), [set, unset]);
|
|
53
|
+
return { registry, contextValue };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Hook used by composition components to register their options in the composition registry.
|
|
57
|
+
*
|
|
58
|
+
* Registers options on mount/update via useSafeLayoutEffect, and unregisters on unmount.
|
|
59
|
+
* Callers should memoize the options object to avoid unnecessary re-registrations.
|
|
60
|
+
*/
|
|
61
|
+
function useCompositionOption(options) {
|
|
62
|
+
const context = (0, react_1.use)(exports.CompositionContext);
|
|
63
|
+
if (!context) {
|
|
64
|
+
throw new Error('useCompositionOption must be used within a RouterCompositionOptionsProvider. This is likely a bug in Expo Router.');
|
|
65
|
+
}
|
|
66
|
+
const route = (0, native_1.useRoute)();
|
|
67
|
+
const { set, unset } = context;
|
|
68
|
+
(0, useSafeLayoutEffect_1.useSafeLayoutEffect)(() => {
|
|
69
|
+
set(route.key, options);
|
|
70
|
+
return () => {
|
|
71
|
+
unset(route.key, options);
|
|
72
|
+
};
|
|
73
|
+
}, [route.key, set, unset, options]);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=CompositionOptionsContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositionOptionsContext.js","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/CompositionOptionsContext.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AAqBb,0CA0BC;AASD,wDAgBC;AAQD,oDAiBC;AA/FD,qDAAoD;AAEpD,iCAA6E;AAG7E,4EAAyE;AAEzE,gBAAgB;AACH,QAAA,kBAAkB,GAAG,IAAA,qBAAa,EAAiC,IAAI,CAAC,CAAC;AAUtF,gBAAgB;AAChB,SAAgB,eAAe,CAC7B,KAA0B,EAC1B,MAAsB;IAEtB,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACrC,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;IACzE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,IAAI,QAAQ,EAAE,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,CAAC;YAC7C,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB;IACpC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,IAAA,kBAAU,EAAC,eAAe,EAAE,EAAyB,CAAC,CAAC;IAEpF,MAAM,GAAG,GAAG,IAAA,mBAAW,EAAC,CAAC,QAAgB,EAAE,OAA8C,EAAE,EAAE;QAC3F,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC,CAAC,QAAgB,EAAE,OAA8C,EAAE,EAAE;QAC7F,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,YAAY,GAAG,IAAA,eAAO,EAC1B,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAmC,EACxD,CAAC,GAAG,EAAE,KAAK,CAAC,CACb,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,OAA8C;IACjF,MAAM,OAAO,GAAG,IAAA,WAAG,EAAC,0BAAkB,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAA,iBAAQ,GAAE,CAAC;IACzB,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE/B,IAAA,yCAAmB,EAAC,GAAG,EAAE;QACvB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE;YACV,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AACvC,CAAC","sourcesContent":["'use client';\n\nimport { useRoute } from '@react-navigation/native';\nimport type { NativeStackNavigationOptions } from '@react-navigation/native-stack';\nimport { createContext, use, useCallback, useMemo, useReducer } from 'react';\n\nimport type { CompositionContextValue, CompositionRegistry } from './types';\nimport { useSafeLayoutEffect } from '../../../views/useSafeLayoutEffect';\n\n/** @internal */\nexport const CompositionContext = createContext<CompositionContextValue | null>(null);\n\ntype RegistryAction =\n | {\n type: 'set';\n routeKey: string;\n options: Partial<NativeStackNavigationOptions>;\n }\n | { type: 'unset'; routeKey: string; options: Partial<NativeStackNavigationOptions> };\n\n/** @internal */\nexport function registryReducer(\n state: CompositionRegistry,\n action: RegistryAction\n): CompositionRegistry {\n if (action.type === 'set') {\n const { routeKey, options } = action;\n if (state[routeKey]?.includes(options)) {\n return state;\n }\n return { ...state, [routeKey]: [...(state[routeKey] ?? []), options] };\n }\n\n if (action.type === 'unset') {\n const { routeKey, options } = action;\n const existing = state[routeKey];\n const filtered = existing?.filter((o) => o !== options);\n if (!existing || filtered?.length === existing.length) {\n return state;\n }\n if (filtered.length === 0) {\n const { [routeKey]: _, ...newState } = state;\n return newState;\n }\n return { ...state, [routeKey]: filtered };\n }\n return state;\n}\n\n/**\n * Provides the composition registry to descendant composition components.\n *\n * Uses useReducer with immutable object updates for React Compiler compatibility.\n * Each set/unset call produces a new object reference, which the compiler can\n * track as a reactive dependency.\n */\nexport function useCompositionRegistry() {\n const [registry, dispatch] = useReducer(registryReducer, {} as CompositionRegistry);\n\n const set = useCallback((routeKey: string, options: Partial<NativeStackNavigationOptions>) => {\n dispatch({ type: 'set', routeKey, options });\n }, []);\n\n const unset = useCallback((routeKey: string, options: Partial<NativeStackNavigationOptions>) => {\n dispatch({ type: 'unset', routeKey, options });\n }, []);\n\n const contextValue = useMemo(\n () => ({ set, unset }) satisfies CompositionContextValue,\n [set, unset]\n );\n return { registry, contextValue };\n}\n\n/**\n * Hook used by composition components to register their options in the composition registry.\n *\n * Registers options on mount/update via useSafeLayoutEffect, and unregisters on unmount.\n * Callers should memoize the options object to avoid unnecessary re-registrations.\n */\nexport function useCompositionOption(options: Partial<NativeStackNavigationOptions>) {\n const context = use(CompositionContext);\n if (!context) {\n throw new Error(\n 'useCompositionOption must be used within a RouterCompositionOptionsProvider. This is likely a bug in Expo Router.'\n );\n }\n\n const route = useRoute();\n const { set, unset } = context;\n\n useSafeLayoutEffect(() => {\n set(route.key, options);\n return () => {\n unset(route.key, options);\n };\n }, [route.key, set, unset, options]);\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { mergeOptions } from './mergeOptions';
|
|
2
|
+
export { CompositionContext, useCompositionRegistry, useCompositionOption, } from './CompositionOptionsContext';
|
|
3
|
+
export type { CompositionRegistry, CompositionContextValue } from './types';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useCompositionOption = exports.useCompositionRegistry = exports.CompositionContext = exports.mergeOptions = void 0;
|
|
4
|
+
var mergeOptions_1 = require("./mergeOptions");
|
|
5
|
+
Object.defineProperty(exports, "mergeOptions", { enumerable: true, get: function () { return mergeOptions_1.mergeOptions; } });
|
|
6
|
+
var CompositionOptionsContext_1 = require("./CompositionOptionsContext");
|
|
7
|
+
Object.defineProperty(exports, "CompositionContext", { enumerable: true, get: function () { return CompositionOptionsContext_1.CompositionContext; } });
|
|
8
|
+
Object.defineProperty(exports, "useCompositionRegistry", { enumerable: true, get: function () { return CompositionOptionsContext_1.useCompositionRegistry; } });
|
|
9
|
+
Object.defineProperty(exports, "useCompositionOption", { enumerable: true, get: function () { return CompositionOptionsContext_1.useCompositionOption; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,yEAIqC;AAHnC,+HAAA,kBAAkB,OAAA;AAClB,mIAAA,sBAAsB,OAAA;AACtB,iIAAA,oBAAoB,OAAA","sourcesContent":["export { mergeOptions } from './mergeOptions';\nexport {\n CompositionContext,\n useCompositionRegistry,\n useCompositionOption,\n} from './CompositionOptionsContext';\nexport type { CompositionRegistry, CompositionContextValue } from './types';\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ParamListBase, StackNavigationState } from '@react-navigation/native';
|
|
2
|
+
import type { NativeStackDescriptorMap } from '../descriptors-context';
|
|
3
|
+
import type { CompositionRegistry } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Merges composition component options into navigation descriptors.
|
|
6
|
+
*
|
|
7
|
+
* For each descriptor:
|
|
8
|
+
* 1. If no composition options registered → pass through unchanged
|
|
9
|
+
* 2. If route is preloaded AND not focused → skip composition (pass through)
|
|
10
|
+
* 3. Otherwise → merge descriptor.options with composition options (composition wins)
|
|
11
|
+
*/
|
|
12
|
+
export declare function mergeOptions(descriptors: NativeStackDescriptorMap, registry: CompositionRegistry, state: StackNavigationState<ParamListBase>): NativeStackDescriptorMap;
|
|
13
|
+
//# sourceMappingURL=mergeOptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeOptions.d.ts","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/mergeOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEpF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,wBAAwB,EACrC,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,oBAAoB,CAAC,aAAa,CAAC,GACzC,wBAAwB,CAiC1B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeOptions = mergeOptions;
|
|
4
|
+
/**
|
|
5
|
+
* Merges composition component options into navigation descriptors.
|
|
6
|
+
*
|
|
7
|
+
* For each descriptor:
|
|
8
|
+
* 1. If no composition options registered → pass through unchanged
|
|
9
|
+
* 2. If route is preloaded AND not focused → skip composition (pass through)
|
|
10
|
+
* 3. Otherwise → merge descriptor.options with composition options (composition wins)
|
|
11
|
+
*/
|
|
12
|
+
function mergeOptions(descriptors, registry, state) {
|
|
13
|
+
const result = {};
|
|
14
|
+
const focusedKey = state.routes[state.index]?.key;
|
|
15
|
+
for (const key in descriptors) {
|
|
16
|
+
const descriptor = descriptors[key];
|
|
17
|
+
const routeOptions = registry[key];
|
|
18
|
+
// No composition options or empty array → pass through
|
|
19
|
+
if (!routeOptions || routeOptions.length === 0) {
|
|
20
|
+
result[key] = descriptor;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// Check if route is preloaded and not focused → skip composition
|
|
24
|
+
const isPreloaded = state.preloadedRoutes?.some((r) => r.key === key) ?? false;
|
|
25
|
+
if (isPreloaded && key !== focusedKey) {
|
|
26
|
+
result[key] = descriptor;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// Merge: descriptor options as base, composition options override
|
|
30
|
+
const mergedOptions = Object.assign({}, descriptor.options, ...routeOptions);
|
|
31
|
+
const merged = {
|
|
32
|
+
...descriptor,
|
|
33
|
+
options: mergedOptions,
|
|
34
|
+
};
|
|
35
|
+
result[key] = merged;
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=mergeOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mergeOptions.js","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/mergeOptions.ts"],"names":[],"mappings":";;AAaA,oCAqCC;AA7CD;;;;;;;GAOG;AACH,SAAgB,YAAY,CAC1B,WAAqC,EACrC,QAA6B,EAC7B,KAA0C;IAE1C,MAAM,MAAM,GAA6B,EAAE,CAAC;IAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC;IAElD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAEnC,uDAAuD;QACvD,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;YACzB,SAAS;QACX,CAAC;QAED,iEAAiE;QACjE,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC;QAC/E,IAAI,WAAW,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACtC,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;YACzB,SAAS;QACX,CAAC;QAED,kEAAkE;QAClE,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,CAAC;QAE7E,MAAM,MAAM,GAAG;YACb,GAAG,UAAU;YACb,OAAO,EAAE,aAAa;SACvB,CAAC;QAEF,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { ParamListBase, StackNavigationState } from '@react-navigation/native';\n\nimport type { NativeStackDescriptorMap } from '../descriptors-context';\nimport type { CompositionRegistry } from './types';\n\n/**\n * Merges composition component options into navigation descriptors.\n *\n * For each descriptor:\n * 1. If no composition options registered → pass through unchanged\n * 2. If route is preloaded AND not focused → skip composition (pass through)\n * 3. Otherwise → merge descriptor.options with composition options (composition wins)\n */\nexport function mergeOptions(\n descriptors: NativeStackDescriptorMap,\n registry: CompositionRegistry,\n state: StackNavigationState<ParamListBase>\n): NativeStackDescriptorMap {\n const result: NativeStackDescriptorMap = {};\n const focusedKey = state.routes[state.index]?.key;\n\n for (const key in descriptors) {\n const descriptor = descriptors[key];\n const routeOptions = registry[key];\n\n // No composition options or empty array → pass through\n if (!routeOptions || routeOptions.length === 0) {\n result[key] = descriptor;\n continue;\n }\n\n // Check if route is preloaded and not focused → skip composition\n const isPreloaded = state.preloadedRoutes?.some((r) => r.key === key) ?? false;\n if (isPreloaded && key !== focusedKey) {\n result[key] = descriptor;\n continue;\n }\n\n // Merge: descriptor options as base, composition options override\n const mergedOptions = Object.assign({}, descriptor.options, ...routeOptions);\n\n const merged = {\n ...descriptor,\n options: mergedOptions,\n };\n\n result[key] = merged;\n }\n\n return result;\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { NativeStackNavigationOptions } from '@react-navigation/native-stack';
|
|
2
|
+
/**
|
|
3
|
+
* Registry mapping route keys to composition component options.
|
|
4
|
+
*
|
|
5
|
+
* Structure: Record<routeKey, options[]>
|
|
6
|
+
*
|
|
7
|
+
* Each composition component (Title, BackButton, Header, Toolbar) registers
|
|
8
|
+
* its memoized options object. Array order reflects registration order,
|
|
9
|
+
* so later registrations override earlier ones during merge.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export type CompositionRegistry = Record<string, Partial<NativeStackNavigationOptions>[]>;
|
|
14
|
+
/** @internal */
|
|
15
|
+
export interface CompositionContextValue {
|
|
16
|
+
/**
|
|
17
|
+
* Register or update options for a composition component.
|
|
18
|
+
*/
|
|
19
|
+
set(routeKey: string, options: Partial<NativeStackNavigationOptions>): void;
|
|
20
|
+
/**
|
|
21
|
+
* Remove a composition component's options by reference (should be called on unmount).
|
|
22
|
+
*/
|
|
23
|
+
unset(routeKey: string, options: Partial<NativeStackNavigationOptions>): void;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAEnF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;AAE1F,gBAAgB;AAChB,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC;IAE5E;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC;CAC/E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/fork/native-stack/composition-options/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { NativeStackNavigationOptions } from '@react-navigation/native-stack';\n\n/**\n * Registry mapping route keys to composition component options.\n *\n * Structure: Record<routeKey, options[]>\n *\n * Each composition component (Title, BackButton, Header, Toolbar) registers\n * its memoized options object. Array order reflects registration order,\n * so later registrations override earlier ones during merge.\n *\n * @internal\n */\nexport type CompositionRegistry = Record<string, Partial<NativeStackNavigationOptions>[]>;\n\n/** @internal */\nexport interface CompositionContextValue {\n /**\n * Register or update options for a composition component.\n */\n set(routeKey: string, options: Partial<NativeStackNavigationOptions>): void;\n\n /**\n * Remove a composition component's options by reference (should be called on unmount).\n */\n unset(routeKey: string, options: Partial<NativeStackNavigationOptions>): void;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNativeStackNavigator.d.ts","sourceRoot":"","sources":["../../../src/fork/native-stack/createNativeStackNavigator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAGzB,KAAK,YAAY,EACjB,KAAK,cAAc,EAEpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAE9B,KAAK,yBAAyB,EAC/B,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"createNativeStackNavigator.d.ts","sourceRoot":"","sources":["../../../src/fork/native-stack/createNativeStackNavigator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAGlB,KAAK,oBAAoB,EAGzB,KAAK,YAAY,EACjB,KAAK,cAAc,EAEpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAE9B,KAAK,yBAAyB,EAC/B,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAe/B,iBAAS,oBAAoB,CAAC,EAC5B,EAAE,EACF,gBAAgB,EAChB,QAAQ,EACR,MAAM,EACN,eAAe,EACf,aAAa,EACb,YAAY,EACZ,eAAe,EACf,GAAG,IAAI,EACR,EAAE,yBAAyB,qBAwH3B;AAED,wBAAgB,0BAA0B,CACxC,KAAK,CAAC,SAAS,SAAS,aAAa,EACrC,KAAK,CAAC,WAAW,SAAS,MAAM,GAAG,SAAS,GAAG,SAAS,EACxD,KAAK,CAAC,OAAO,SAAS,oBAAoB,GAAG;IAC3C,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACvC,aAAa,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,EAAE,6BAA6B,CAAC;IACxC,cAAc,EAAE;SACb,SAAS,IAAI,MAAM,SAAS,GAAG,yBAAyB,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC;KAC7F,CAAC;IACF,SAAS,EAAE,OAAO,oBAAoB,CAAC;CACxC,EACD,KAAK,CAAC,MAAM,SAAS,YAAY,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,EAClE,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAElD"}
|
|
@@ -38,9 +38,11 @@ const native_1 = require("@react-navigation/native");
|
|
|
38
38
|
const native_stack_1 = require("@react-navigation/native-stack");
|
|
39
39
|
const expo_glass_effect_1 = require("expo-glass-effect");
|
|
40
40
|
const React = __importStar(require("react"));
|
|
41
|
+
const composition_options_1 = require("./composition-options");
|
|
41
42
|
const descriptors_context_1 = require("./descriptors-context");
|
|
42
|
-
const
|
|
43
|
+
const usePreviewTransition_1 = require("./usePreviewTransition");
|
|
43
44
|
const navigationParams_1 = require("../../navigationParams");
|
|
45
|
+
const GLASS = (0, expo_glass_effect_1.isLiquidGlassAvailable)();
|
|
44
46
|
function NativeStackNavigator({ id, initialRouteName, children, layout, screenListeners, screenOptions, screenLayout, UNSTABLE_router, ...rest }) {
|
|
45
47
|
const { state, describe, descriptors, navigation, NavigationContent } = (0, native_1.useNavigationBuilder)(native_1.StackRouter, {
|
|
46
48
|
id,
|
|
@@ -79,106 +81,56 @@ function NativeStackNavigator({ id, initialRouteName, children, layout, screenLi
|
|
|
79
81
|
});
|
|
80
82
|
}), [navigation, state.index, state.key]);
|
|
81
83
|
// START FORK
|
|
82
|
-
const {
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
React.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}, [state, previewTransitioningScreenId]);
|
|
94
|
-
const navigationWrapper = React.useMemo(() => {
|
|
95
|
-
if (openPreviewKey) {
|
|
96
|
-
const emit = (...args) => {
|
|
97
|
-
const { target, type, data } = args[0];
|
|
98
|
-
if (target === openPreviewKey && data && 'closing' in data && !data.closing) {
|
|
99
|
-
// onWillAppear
|
|
100
|
-
if (type === 'transitionStart') {
|
|
101
|
-
// The screen from preview will appear, so we need to start tracking it
|
|
102
|
-
setPreviewTransitioningScreenId(openPreviewKey);
|
|
103
|
-
}
|
|
104
|
-
// onAppear
|
|
105
|
-
else if (type === 'transitionEnd') {
|
|
106
|
-
// The screen from preview appeared.
|
|
107
|
-
// We can now restore the stack animation
|
|
108
|
-
setOpenPreviewKey(undefined);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return navigation.emit(...args);
|
|
112
|
-
};
|
|
113
|
-
return {
|
|
114
|
-
...navigation,
|
|
115
|
-
emit,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
return navigation;
|
|
119
|
-
}, [navigation, openPreviewKey, setOpenPreviewKey]);
|
|
120
|
-
const { computedState, computedDescriptors } = React.useMemo(() => {
|
|
121
|
-
// The preview screen was pushed on the native side, but react-navigation state was not updated yet
|
|
122
|
-
if (previewTransitioningScreenId) {
|
|
123
|
-
const preloadedRoute = state.preloadedRoutes.find((route) => route.key === previewTransitioningScreenId);
|
|
124
|
-
if (preloadedRoute) {
|
|
125
|
-
const newState = {
|
|
126
|
-
...state,
|
|
127
|
-
// On native side the screen is already pushed, so we need to update the state
|
|
128
|
-
preloadedRoutes: state.preloadedRoutes.filter((route) => route.key !== previewTransitioningScreenId),
|
|
129
|
-
routes: [...state.routes, preloadedRoute],
|
|
130
|
-
index: state.index + 1,
|
|
131
|
-
};
|
|
132
|
-
const newDescriptors = previewTransitioningScreenId in descriptors
|
|
133
|
-
? descriptors
|
|
134
|
-
: {
|
|
135
|
-
...descriptors,
|
|
136
|
-
// We need to add the descriptor. For react-navigation this is still preloaded screen
|
|
137
|
-
// Replicating the logic from https://github.com/react-navigation/react-navigation/blob/eaf1100ac7d99cb93ba11a999549dd0752809a78/packages/native-stack/src/views/NativeStackView.native.tsx#L489
|
|
138
|
-
[previewTransitioningScreenId]: describe(preloadedRoute, true),
|
|
139
|
-
};
|
|
140
|
-
return {
|
|
141
|
-
computedState: newState,
|
|
142
|
-
computedDescriptors: newDescriptors,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
// Map internal gesture option to React Navigation's gestureEnabled option
|
|
147
|
-
// This allows Expo Router to override gesture behavior without affecting user settings
|
|
148
|
-
const GLASS = (0, expo_glass_effect_1.isLiquidGlassAvailable)();
|
|
149
|
-
Object.keys(descriptors).forEach((key) => {
|
|
150
|
-
const options = descriptors[key].options;
|
|
84
|
+
const { computedState, computedDescriptors, navigationWrapper } = (0, usePreviewTransition_1.usePreviewTransition)(state, navigation, descriptors, describe);
|
|
85
|
+
// Map internal gesture option to React Navigation's gestureEnabled option
|
|
86
|
+
// This allows Expo Router to override gesture behavior without affecting user settings
|
|
87
|
+
const finalDescriptors = React.useMemo(() => {
|
|
88
|
+
let needsNewMap = false;
|
|
89
|
+
const result = {};
|
|
90
|
+
for (const key of Object.keys(computedDescriptors)) {
|
|
91
|
+
const descriptor = computedDescriptors[key];
|
|
92
|
+
const options = descriptor.options;
|
|
151
93
|
const internalGestureEnabled = options?.[navigationParams_1.INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME];
|
|
152
|
-
|
|
153
|
-
|
|
94
|
+
const needsGestureFix = internalGestureEnabled !== undefined;
|
|
95
|
+
const needsGlassFix = GLASS && options?.presentation === 'formSheet';
|
|
96
|
+
if (needsGestureFix || needsGlassFix) {
|
|
97
|
+
needsNewMap = true;
|
|
98
|
+
const newOptions = { ...options };
|
|
99
|
+
if (needsGestureFix) {
|
|
100
|
+
newOptions.gestureEnabled = internalGestureEnabled;
|
|
101
|
+
}
|
|
102
|
+
if (needsGlassFix) {
|
|
103
|
+
newOptions.headerTransparent ??= true;
|
|
104
|
+
newOptions.contentStyle ??= { backgroundColor: 'transparent' };
|
|
105
|
+
newOptions.headerShadowVisible ??= false;
|
|
106
|
+
newOptions.headerLargeTitleShadowVisible ??= false;
|
|
107
|
+
}
|
|
108
|
+
result[key] = { ...descriptor, options: newOptions };
|
|
154
109
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
options.headerTransparent ??= true;
|
|
158
|
-
options.contentStyle ??= { backgroundColor: 'transparent' };
|
|
159
|
-
options.headerShadowVisible ??= false;
|
|
160
|
-
options.headerLargeTitleShadowVisible ??= false;
|
|
110
|
+
else {
|
|
111
|
+
result[key] = descriptor;
|
|
161
112
|
}
|
|
162
|
-
}
|
|
163
|
-
return
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}, [state, previewTransitioningScreenId, describe, descriptors]);
|
|
113
|
+
}
|
|
114
|
+
return needsNewMap ? result : computedDescriptors;
|
|
115
|
+
}, [computedDescriptors]);
|
|
116
|
+
const { registry, contextValue } = (0, composition_options_1.useCompositionRegistry)();
|
|
117
|
+
const mergedDescriptors = React.useMemo(() => (0, composition_options_1.mergeOptions)(finalDescriptors, registry, computedState), [finalDescriptors, computedState, registry]);
|
|
168
118
|
// END FORK
|
|
169
119
|
return (
|
|
170
120
|
// START FORK
|
|
171
121
|
<descriptors_context_1.DescriptorsContext value={descriptors}>
|
|
172
122
|
{/* END FORK */}
|
|
173
123
|
<NavigationContent>
|
|
174
|
-
<
|
|
124
|
+
<composition_options_1.CompositionContext value={contextValue}>
|
|
125
|
+
<native_stack_1.NativeStackView {...rest}
|
|
175
126
|
// START FORK
|
|
176
|
-
state={computedState} navigation={navigationWrapper} descriptors={
|
|
127
|
+
state={computedState} navigation={navigationWrapper} descriptors={mergedDescriptors}
|
|
177
128
|
// state={state}
|
|
178
129
|
// navigation={navigation}
|
|
179
130
|
// descriptors={descriptors}
|
|
180
131
|
// END FORK
|
|
181
132
|
describe={describe}/>
|
|
133
|
+
</composition_options_1.CompositionContext>
|
|
182
134
|
</NavigationContent>
|
|
183
135
|
{/* START FORK */}
|
|
184
136
|
</descriptors_context_1.DescriptorsContext>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNativeStackNavigator.js","sourceRoot":"","sources":["../../../src/fork/native-stack/createNativeStackNavigator.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createNavigatorFactory,\n type EventArg,\n type NavigatorTypeBagBase,\n type ParamListBase,\n type StackActionHelpers,\n StackActions,\n type StackNavigationState,\n StackRouter,\n type StackRouterOptions,\n type StaticConfig,\n type TypedNavigator,\n useNavigationBuilder,\n} from '@react-navigation/native';\nimport {\n type NativeStackNavigationEventMap,\n type NativeStackNavigationOptions,\n type NativeStackNavigationProp,\n NativeStackView,\n type NativeStackNavigatorProps,\n} from '@react-navigation/native-stack';\nimport { isLiquidGlassAvailable } from 'expo-glass-effect';\nimport * as React from 'react';\n\nimport { DescriptorsContext } from './descriptors-context';\nimport { useLinkPreviewContext } from '../../link/preview/LinkPreviewContext';\nimport {\n INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME,\n type InternalNavigationOptions,\n} from '../../navigationParams';\n\ntype NativeStackNavigationOptionsWithInternal = NativeStackNavigationOptions &\n InternalNavigationOptions;\n\nfunction NativeStackNavigator({\n id,\n initialRouteName,\n children,\n layout,\n screenListeners,\n screenOptions,\n screenLayout,\n UNSTABLE_router,\n ...rest\n}: NativeStackNavigatorProps) {\n const { state, describe, descriptors, navigation, NavigationContent } = useNavigationBuilder<\n StackNavigationState<ParamListBase>,\n StackRouterOptions,\n StackActionHelpers<ParamListBase>,\n NativeStackNavigationOptionsWithInternal,\n NativeStackNavigationEventMap\n >(StackRouter, {\n id,\n initialRouteName,\n children,\n layout,\n screenListeners,\n screenOptions,\n screenLayout,\n UNSTABLE_router,\n });\n\n React.useEffect(\n () =>\n // @ts-expect-error: there may not be a tab navigator in parent\n navigation?.addListener?.('tabPress', (e: any) => {\n const isFocused = navigation.isFocused();\n\n // Run the operation in the next frame so we're sure all listeners have been run\n // This is necessary to know if preventDefault() has been called\n requestAnimationFrame(() => {\n if (state.index > 0 && isFocused && !(e as EventArg<'tabPress', true>).defaultPrevented) {\n // When user taps on already focused tab and we're inside the tab,\n // reset the stack to replicate native behaviour\n // START FORK\n // navigation.dispatch({\n // ...StackActions.popToTop(),\n // target: state.key,\n // });\n // The popToTop will be automatically triggered on native side for native tabs\n if (e.data?.__internalTabsType !== 'native') {\n navigation.dispatch({\n ...StackActions.popToTop(),\n target: state.key,\n });\n }\n // END FORK\n }\n });\n }),\n [navigation, state.index, state.key]\n );\n\n // START FORK\n const { openPreviewKey, setOpenPreviewKey } = useLinkPreviewContext();\n\n // This is used to track the preview screen that is currently transitioning on the native side\n const [previewTransitioningScreenId, setPreviewTransitioningScreenId] = React.useState<\n string | undefined\n >();\n\n React.useEffect(() => {\n if (previewTransitioningScreenId) {\n // This means that the state was updated after the preview transition\n if (state.routes.some((route) => route.key === previewTransitioningScreenId)) {\n // We no longer need to track the preview transitioning screen\n setPreviewTransitioningScreenId(undefined);\n }\n }\n }, [state, previewTransitioningScreenId]);\n\n const navigationWrapper = React.useMemo(() => {\n if (openPreviewKey) {\n const emit: (typeof navigation)['emit'] = (...args) => {\n const { target, type, data } = args[0];\n if (target === openPreviewKey && data && 'closing' in data && !data.closing) {\n // onWillAppear\n if (type === 'transitionStart') {\n // The screen from preview will appear, so we need to start tracking it\n setPreviewTransitioningScreenId(openPreviewKey);\n }\n // onAppear\n else if (type === 'transitionEnd') {\n // The screen from preview appeared.\n // We can now restore the stack animation\n setOpenPreviewKey(undefined);\n }\n }\n return navigation.emit(...args);\n };\n return {\n ...navigation,\n emit,\n };\n }\n return navigation;\n }, [navigation, openPreviewKey, setOpenPreviewKey]);\n\n const { computedState, computedDescriptors } = React.useMemo(() => {\n // The preview screen was pushed on the native side, but react-navigation state was not updated yet\n if (previewTransitioningScreenId) {\n const preloadedRoute = state.preloadedRoutes.find(\n (route) => route.key === previewTransitioningScreenId\n );\n if (preloadedRoute) {\n const newState = {\n ...state,\n // On native side the screen is already pushed, so we need to update the state\n preloadedRoutes: state.preloadedRoutes.filter(\n (route) => route.key !== previewTransitioningScreenId\n ),\n routes: [...state.routes, preloadedRoute],\n index: state.index + 1,\n };\n\n const newDescriptors =\n previewTransitioningScreenId in descriptors\n ? descriptors\n : {\n ...descriptors,\n // We need to add the descriptor. For react-navigation this is still preloaded screen\n // Replicating the logic from https://github.com/react-navigation/react-navigation/blob/eaf1100ac7d99cb93ba11a999549dd0752809a78/packages/native-stack/src/views/NativeStackView.native.tsx#L489\n [previewTransitioningScreenId]: describe(preloadedRoute, true),\n };\n\n return {\n computedState: newState,\n computedDescriptors: newDescriptors,\n };\n }\n }\n // Map internal gesture option to React Navigation's gestureEnabled option\n // This allows Expo Router to override gesture behavior without affecting user settings\n const GLASS = isLiquidGlassAvailable();\n Object.keys(descriptors).forEach((key) => {\n const options = descriptors[key].options;\n const internalGestureEnabled = options?.[INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME];\n if (internalGestureEnabled !== undefined) {\n options.gestureEnabled = internalGestureEnabled;\n }\n\n // Apply transparent defaults for formSheet presentation on iOS 26 with liquid glass\n if (GLASS && options?.presentation === 'formSheet') {\n options.headerTransparent ??= true;\n options.contentStyle ??= { backgroundColor: 'transparent' };\n options.headerShadowVisible ??= false;\n options.headerLargeTitleShadowVisible ??= false;\n }\n });\n return {\n computedState: state,\n computedDescriptors: descriptors,\n };\n }, [state, previewTransitioningScreenId, describe, descriptors]);\n // END FORK\n\n return (\n // START FORK\n <DescriptorsContext value={descriptors}>\n {/* END FORK */}\n <NavigationContent>\n <NativeStackView\n {...rest}\n // START FORK\n state={computedState}\n navigation={navigationWrapper}\n descriptors={computedDescriptors}\n // state={state}\n // navigation={navigation}\n // descriptors={descriptors}\n // END FORK\n describe={describe}\n />\n </NavigationContent>\n {/* START FORK */}\n </DescriptorsContext>\n // END FORK\n );\n}\n\nexport function createNativeStackNavigator<\n const ParamList extends ParamListBase,\n const NavigatorID extends string | undefined = undefined,\n const TypeBag extends NavigatorTypeBagBase = {\n ParamList: ParamList;\n NavigatorID: NavigatorID;\n State: StackNavigationState<ParamList>;\n ScreenOptions: NativeStackNavigationOptions;\n EventMap: NativeStackNavigationEventMap;\n NavigationList: {\n [RouteName in keyof ParamList]: NativeStackNavigationProp<ParamList, RouteName, NavigatorID>;\n };\n Navigator: typeof NativeStackNavigator;\n },\n const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,\n>(config?: Config): TypedNavigator<TypeBag, Config> {\n return createNavigatorFactory(NativeStackNavigator)(config);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createNativeStackNavigator.js","sourceRoot":"","sources":["../../../src/fork/native-stack/createNativeStackNavigator.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createNavigatorFactory,\n type EventArg,\n type NavigatorTypeBagBase,\n type ParamListBase,\n type StackActionHelpers,\n StackActions,\n type StackNavigationState,\n StackRouter,\n type StackRouterOptions,\n type StaticConfig,\n type TypedNavigator,\n useNavigationBuilder,\n} from '@react-navigation/native';\nimport {\n type NativeStackNavigationEventMap,\n type NativeStackNavigationOptions,\n type NativeStackNavigationProp,\n NativeStackView,\n type NativeStackNavigatorProps,\n} from '@react-navigation/native-stack';\nimport { isLiquidGlassAvailable } from 'expo-glass-effect';\nimport * as React from 'react';\n\nimport { CompositionContext, mergeOptions, useCompositionRegistry } from './composition-options';\nimport { DescriptorsContext } from './descriptors-context';\nimport { usePreviewTransition } from './usePreviewTransition';\nimport {\n INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME,\n type InternalNavigationOptions,\n} from '../../navigationParams';\n\nconst GLASS = isLiquidGlassAvailable();\n\ntype NativeStackNavigationOptionsWithInternal = NativeStackNavigationOptions &\n InternalNavigationOptions;\n\nfunction NativeStackNavigator({\n id,\n initialRouteName,\n children,\n layout,\n screenListeners,\n screenOptions,\n screenLayout,\n UNSTABLE_router,\n ...rest\n}: NativeStackNavigatorProps) {\n const { state, describe, descriptors, navigation, NavigationContent } = useNavigationBuilder<\n StackNavigationState<ParamListBase>,\n StackRouterOptions,\n StackActionHelpers<ParamListBase>,\n NativeStackNavigationOptionsWithInternal,\n NativeStackNavigationEventMap\n >(StackRouter, {\n id,\n initialRouteName,\n children,\n layout,\n screenListeners,\n screenOptions,\n screenLayout,\n UNSTABLE_router,\n });\n\n React.useEffect(\n () =>\n // @ts-expect-error: there may not be a tab navigator in parent\n navigation?.addListener?.('tabPress', (e: any) => {\n const isFocused = navigation.isFocused();\n\n // Run the operation in the next frame so we're sure all listeners have been run\n // This is necessary to know if preventDefault() has been called\n requestAnimationFrame(() => {\n if (state.index > 0 && isFocused && !(e as EventArg<'tabPress', true>).defaultPrevented) {\n // When user taps on already focused tab and we're inside the tab,\n // reset the stack to replicate native behaviour\n // START FORK\n // navigation.dispatch({\n // ...StackActions.popToTop(),\n // target: state.key,\n // });\n // The popToTop will be automatically triggered on native side for native tabs\n if (e.data?.__internalTabsType !== 'native') {\n navigation.dispatch({\n ...StackActions.popToTop(),\n target: state.key,\n });\n }\n // END FORK\n }\n });\n }),\n [navigation, state.index, state.key]\n );\n\n // START FORK\n const { computedState, computedDescriptors, navigationWrapper } = usePreviewTransition(\n state,\n navigation,\n descriptors,\n describe\n );\n\n // Map internal gesture option to React Navigation's gestureEnabled option\n // This allows Expo Router to override gesture behavior without affecting user settings\n const finalDescriptors = React.useMemo(() => {\n let needsNewMap = false;\n const result: typeof computedDescriptors = {};\n for (const key of Object.keys(computedDescriptors)) {\n const descriptor = computedDescriptors[key];\n const options = descriptor.options as NativeStackNavigationOptionsWithInternal;\n const internalGestureEnabled = options?.[INTERNAL_EXPO_ROUTER_GESTURE_ENABLED_OPTION_NAME];\n const needsGestureFix = internalGestureEnabled !== undefined;\n const needsGlassFix = GLASS && options?.presentation === 'formSheet';\n\n if (needsGestureFix || needsGlassFix) {\n needsNewMap = true;\n const newOptions = { ...options };\n if (needsGestureFix) {\n newOptions.gestureEnabled = internalGestureEnabled;\n }\n if (needsGlassFix) {\n newOptions.headerTransparent ??= true;\n newOptions.contentStyle ??= { backgroundColor: 'transparent' };\n newOptions.headerShadowVisible ??= false;\n newOptions.headerLargeTitleShadowVisible ??= false;\n }\n result[key] = { ...descriptor, options: newOptions };\n } else {\n result[key] = descriptor;\n }\n }\n return needsNewMap ? result : computedDescriptors;\n }, [computedDescriptors]);\n const { registry, contextValue } = useCompositionRegistry();\n\n const mergedDescriptors = React.useMemo(\n () => mergeOptions(finalDescriptors, registry, computedState),\n [finalDescriptors, computedState, registry]\n );\n // END FORK\n\n return (\n // START FORK\n <DescriptorsContext value={descriptors}>\n {/* END FORK */}\n <NavigationContent>\n <CompositionContext value={contextValue}>\n <NativeStackView\n {...rest}\n // START FORK\n state={computedState}\n navigation={navigationWrapper}\n descriptors={mergedDescriptors}\n // state={state}\n // navigation={navigation}\n // descriptors={descriptors}\n // END FORK\n describe={describe}\n />\n </CompositionContext>\n </NavigationContent>\n {/* START FORK */}\n </DescriptorsContext>\n // END FORK\n );\n}\n\nexport function createNativeStackNavigator<\n const ParamList extends ParamListBase,\n const NavigatorID extends string | undefined = undefined,\n const TypeBag extends NavigatorTypeBagBase = {\n ParamList: ParamList;\n NavigatorID: NavigatorID;\n State: StackNavigationState<ParamList>;\n ScreenOptions: NativeStackNavigationOptions;\n EventMap: NativeStackNavigationEventMap;\n NavigationList: {\n [RouteName in keyof ParamList]: NativeStackNavigationProp<ParamList, RouteName, NavigatorID>;\n };\n Navigator: typeof NativeStackNavigator;\n },\n const Config extends StaticConfig<TypeBag> = StaticConfig<TypeBag>,\n>(config?: Config): TypedNavigator<TypeBag, Config> {\n return createNavigatorFactory(NativeStackNavigator)(config);\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ParamListBase, StackNavigationState } from '@react-navigation/native';
|
|
2
|
+
import type { NativeStackDescriptor, NativeStackDescriptorMap } from './descriptors-context';
|
|
3
|
+
/** Mirrors the `describe` function returned by `useNavigationBuilder` */
|
|
4
|
+
type DescribeFn = (route: StackNavigationState<ParamListBase>['preloadedRoutes'][number], placeholder: boolean) => NativeStackDescriptor;
|
|
5
|
+
/**
|
|
6
|
+
* Manages the preview transition state for link previews.
|
|
7
|
+
*
|
|
8
|
+
* Tracks when a preloaded screen is transitioning on the native side (after
|
|
9
|
+
* the preview is committed) but before React Navigation state is updated.
|
|
10
|
+
* During this window, the hook synthesizes state/descriptors to keep native
|
|
11
|
+
* and JS state in sync.
|
|
12
|
+
*/
|
|
13
|
+
export declare function usePreviewTransition<TNavigation extends {
|
|
14
|
+
emit: (...args: any[]) => any;
|
|
15
|
+
}>(state: StackNavigationState<ParamListBase>, navigation: TNavigation, descriptors: NativeStackDescriptorMap, describe: DescribeFn): {
|
|
16
|
+
computedState: StackNavigationState<ParamListBase>;
|
|
17
|
+
computedDescriptors: NativeStackDescriptorMap;
|
|
18
|
+
navigationWrapper: TNavigation;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=usePreviewTransition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePreviewTransition.d.ts","sourceRoot":"","sources":["../../../src/fork/native-stack/usePreviewTransition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGpF,OAAO,KAAK,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAG7F,yEAAyE;AACzE,KAAK,UAAU,GAAG,CAChB,KAAK,EAAE,oBAAoB,CAAC,aAAa,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,EACrE,WAAW,EAAE,OAAO,KACjB,qBAAqB,CAAC;AAE3B;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,SAAS;IAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAA;CAAE,EACxF,KAAK,EAAE,oBAAoB,CAAC,aAAa,CAAC,EAC1C,UAAU,EAAE,WAAW,EACvB,WAAW,EAAE,wBAAwB,EACrC,QAAQ,EAAE,UAAU;;;;EAuFrB"}
|