expo-router 1.7.7 → 2.0.0-rc.1
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/_entry.tsx +3 -2
- package/build/ExpoRoot.d.ts +5 -2
- package/build/ExpoRoot.d.ts.map +1 -1
- package/build/global-state/router-store.d.ts.map +1 -1
- package/build/testing-library/context-stubs.d.ts +2 -2
- package/build/testing-library/context-stubs.d.ts.map +1 -1
- package/build/testing-library/index.d.ts +2 -1
- package/build/testing-library/index.d.ts.map +1 -1
- package/build/views/Unmatched.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/ExpoRoot.tsx +34 -16
- package/src/global-state/{router-store.ts → router-store.tsx} +2 -0
- package/src/static/renderStaticContent.tsx +16 -16
- package/src/testing-library/context-stubs.ts +3 -1
- package/src/testing-library/expect.ts +4 -4
- package/src/testing-library/index.tsx +11 -27
- package/src/views/Toast.tsx +1 -1
- package/src/views/Unmatched.tsx +18 -3
- package/types/jest.d.ts +1 -0
package/_entry.tsx
CHANGED
|
@@ -6,13 +6,14 @@ import React from "react";
|
|
|
6
6
|
|
|
7
7
|
import { ctx } from "./_ctx";
|
|
8
8
|
import { ExpoRoot } from "./src";
|
|
9
|
+
import { ExpoRootProps } from "./src/ExpoRoot";
|
|
9
10
|
import { getNavigationConfig } from "./src/getLinkingConfig";
|
|
10
11
|
import { getRoutes } from "./src/getRoutes";
|
|
11
12
|
import { loadStaticParamsAsync } from "./src/loadStaticParamsAsync";
|
|
12
13
|
|
|
13
14
|
// Must be exported or Fast Refresh won't update the context >:[
|
|
14
|
-
export default function ExpoRouterRoot(
|
|
15
|
-
return <ExpoRoot context={ctx}
|
|
15
|
+
export default function ExpoRouterRoot(props: Omit<ExpoRootProps, "context">) {
|
|
16
|
+
return <ExpoRoot context={ctx} {...props} />;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/** Get the linking manifest from a Node.js process. */
|
package/build/ExpoRoot.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import { FunctionComponent, ReactNode } from "react";
|
|
2
2
|
import { RequireContext } from "./types";
|
|
3
3
|
export type ExpoRootProps = {
|
|
4
4
|
context: RequireContext;
|
|
5
5
|
location?: URL;
|
|
6
|
+
wrapper?: FunctionComponent<{
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}>;
|
|
6
9
|
};
|
|
7
|
-
export declare function ExpoRoot({
|
|
10
|
+
export declare function ExpoRoot({ wrapper: ParentWrapper, ...props }: ExpoRootProps): JSX.Element;
|
|
8
11
|
//# sourceMappingURL=ExpoRoot.d.ts.map
|
package/build/ExpoRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoRoot.d.ts","sourceRoot":"","sources":["../src/ExpoRoot.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ExpoRoot.d.ts","sourceRoot":"","sources":["../src/ExpoRoot.tsx"],"names":[],"mappings":"AACA,OAAc,EAAE,iBAAiB,EAAE,SAAS,EAAY,MAAM,OAAO,CAAC;AAMtE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,OAAO,CAAC,EAAE,iBAAiB,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CACtD,CAAC;AA4BF,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EAAE,aAAwB,EACjC,GAAG,KAAK,EACT,EAAE,aAAa,eAyBf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.
|
|
1
|
+
{"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAGlC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAiC,aAAa,EAAY,MAAM,OAAO,CAAC;AAE/E,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAoB,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM1C;;;;GAIG;AACH,qBAAa,WAAW;IACtB,SAAS,EAAG,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAG,aAAa,CAAC;IAC9B,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,OAAO,EAAE,OAAO,CAAS;IAEzB,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAElC,aAAa,EAAG,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACjF,yBAAyB,EAAG,MAAM,IAAI,CAAC;IAEvC,oBAAoB,YAAiB,IAAI,EAAI;IAC7C,gBAAgB,YAAiB,IAAI,EAAI;IAEzC,MAAM,qDAAqB;IAC3B,eAAe,oBAA8B;IAC7C,MAAM,aAAqB;IAC3B,IAAI,6CAAmB;IACvB,OAAO,6CAAsB;IAC7B,SAAS,gEAAwB;IAEjC,UAAU,CACR,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,EAC/E,eAAe,CAAC,EAAE,GAAG;IA6EvB,YAAY,CAAC,KAAK,EAAE,WAAW;IAgB/B,kBAAkB;IAIlB,uEAAuE;IACvE,OAAO,aAKL;IACF,oBAAoB,eAAgB,MAAM,IAAI,mBAG5C;IACF,gBAAgB,eAAgB,MAAM,IAAI,mBAGxC;IACF,QAAQ,aAEN;IACF,iBAAiB,oBAEf;IACF,iBAAiB,kBAEf;CACH;AAED,eAAO,MAAM,KAAK,aAAoB,CAAC;AAEvC,wBAAgB,aAAa,gBAM5B;AAED,wBAAgB,iBAAiB,gBAMhC;AAED,wBAAgB,iBAAiB,cAMhC;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,cAAc,EACvB,eAAe,EAAE,GAAG,GAAG,SAAS,eASjC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import requireContext from "./require-context-ponyfill";
|
|
3
3
|
export type ReactComponent = () => React.ReactElement<any, any> | null;
|
|
4
|
-
export type FileStub = {
|
|
4
|
+
export type FileStub = (Record<string, unknown> & {
|
|
5
5
|
default: ReactComponent;
|
|
6
|
-
} | ReactComponent;
|
|
6
|
+
}) | ReactComponent;
|
|
7
7
|
export { requireContext };
|
|
8
8
|
export declare function inMemoryContext(context: Record<string, FileStub>): ((id: string) => ReactComponent | {
|
|
9
9
|
default: FileStub;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-stubs.d.ts","sourceRoot":"","sources":["../../src/testing-library/context-stubs.ts"],"names":[],"mappings":";AAEA,OAAO,cAAc,MAAM,4BAA4B,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;AACvE,MAAM,MAAM,QAAQ,GAAG;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"context-stubs.d.ts","sourceRoot":"","sources":["../../src/testing-library/context-stubs.ts"],"names":[],"mappings":";AAEA,OAAO,cAAc,MAAM,4BAA4B,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;AACvE,MAAM,MAAM,QAAQ,GAChB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC,GACvD,cAAc,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,SAE/C,MAAM;;;;mBAQH,MAAM;;EAI1B;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,SAKnB,MAAM;;mBAUH,MAAM;;EAI1B"}
|
|
@@ -7,7 +7,8 @@ type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
|
7
7
|
};
|
|
8
8
|
type Result = ReturnType<typeof render> & {
|
|
9
9
|
getPathname(): string;
|
|
10
|
-
|
|
10
|
+
getSegments(): string[];
|
|
11
|
+
getSearchParams(): Record<string, string | string[]>;
|
|
11
12
|
};
|
|
12
13
|
export declare function renderRouter(context?: string, options?: RenderRouterOptions): Result;
|
|
13
14
|
export declare function renderRouter(context: Record<string, FileStub>, options?: RenderRouterOptions): Result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing-library/index.tsx"],"names":[],"mappings":"AACA,OAAO,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing-library/index.tsx"],"names":[],"mappings":"AACA,OAAO,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAgB,MAAM,+BAA+B,CAAC;AAQrE,OAAO,EACL,QAAQ,EAIT,MAAM,iBAAiB,CAAC;AAIzB,cAAc,+BAA+B,CAAC;AAE9C,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG;IACxD,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB,CAAC;AAEF,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG;IACxC,WAAW,IAAI,MAAM,CAAC;IACtB,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CACtD,CAAC;AAQF,wBAAgB,YAAY,CAC1B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAAC;AACV,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACjC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAAC;AACV,wBAAgB,YAAY,CAC1B,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;CAAE,EAChE,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Unmatched.d.ts","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Unmatched.d.ts","sourceRoot":"","sources":["../../src/views/Unmatched.tsx"],"names":[],"mappings":";AAwBA,2CAA2C;AAC3C,wBAAgB,SAAS,gBAoDxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-router",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-rc.1",
|
|
4
4
|
"main": "src/index.tsx",
|
|
5
5
|
"types": "build/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -104,12 +104,12 @@
|
|
|
104
104
|
},
|
|
105
105
|
"dependencies": {
|
|
106
106
|
"@bacons/react-views": "^1.1.3",
|
|
107
|
-
"@expo/metro-runtime": "2.1.
|
|
107
|
+
"@expo/metro-runtime": "2.1.7",
|
|
108
108
|
"@radix-ui/react-slot": "1.0.1",
|
|
109
109
|
"@react-navigation/bottom-tabs": "~6.5.7",
|
|
110
110
|
"@react-navigation/native": "~6.1.6",
|
|
111
111
|
"@react-navigation/native-stack": "~6.9.12",
|
|
112
|
-
"expo-head": "0.0.
|
|
112
|
+
"expo-head": "0.0.9",
|
|
113
113
|
"expo-splash-screen": "*",
|
|
114
114
|
"query-string": "7.1.3",
|
|
115
115
|
"react-helmet-async": "^1.3.0",
|
package/src/ExpoRoot.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StatusBar } from "expo-status-bar";
|
|
2
|
-
import React from "react";
|
|
2
|
+
import React, { FunctionComponent, ReactNode, Fragment } from "react";
|
|
3
3
|
import { Platform } from "react-native";
|
|
4
4
|
import { SafeAreaProvider } from "react-native-safe-area-context";
|
|
5
5
|
|
|
@@ -11,6 +11,7 @@ import { SplashScreen } from "./views/Splash";
|
|
|
11
11
|
export type ExpoRootProps = {
|
|
12
12
|
context: RequireContext;
|
|
13
13
|
location?: URL;
|
|
14
|
+
wrapper?: FunctionComponent<{ children: ReactNode }>;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
function getGestureHandlerRootView() {
|
|
@@ -39,19 +40,34 @@ const INITIAL_METRICS = {
|
|
|
39
40
|
insets: { top: 0, left: 0, right: 0, bottom: 0 },
|
|
40
41
|
};
|
|
41
42
|
|
|
42
|
-
export function ExpoRoot({
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
export function ExpoRoot({
|
|
44
|
+
wrapper: ParentWrapper = Fragment,
|
|
45
|
+
...props
|
|
46
|
+
}: ExpoRootProps) {
|
|
47
|
+
/*
|
|
48
|
+
* Due to static rendering we need to wrap these top level views in second wrapper
|
|
49
|
+
* View's like <GestureHandlerRootView /> generate a <div> so if the parent wrapper
|
|
50
|
+
* is a HTML document, we need to ensure its inside the <body>
|
|
51
|
+
*/
|
|
52
|
+
const wrapper: ExpoRootProps["wrapper"] = ({ children }) => {
|
|
53
|
+
return (
|
|
54
|
+
<ParentWrapper>
|
|
55
|
+
<GestureHandlerRootView>
|
|
56
|
+
<SafeAreaProvider
|
|
57
|
+
// SSR support
|
|
58
|
+
initialMetrics={INITIAL_METRICS}
|
|
59
|
+
>
|
|
60
|
+
{children}
|
|
61
|
+
|
|
62
|
+
{/* Users can override this by adding another StatusBar element anywhere higher in the component tree. */}
|
|
63
|
+
<StatusBar style="auto" />
|
|
64
|
+
</SafeAreaProvider>
|
|
65
|
+
</GestureHandlerRootView>
|
|
66
|
+
</ParentWrapper>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return <ContextNavigator {...props} wrapper={wrapper} />;
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
const initialUrl =
|
|
@@ -62,6 +78,7 @@ const initialUrl =
|
|
|
62
78
|
function ContextNavigator({
|
|
63
79
|
context,
|
|
64
80
|
location: initialLocation = initialUrl,
|
|
81
|
+
wrapper: WrapperComponent = Fragment,
|
|
65
82
|
}: ExpoRootProps) {
|
|
66
83
|
const store = useInitializeExpoRouter(context, initialLocation);
|
|
67
84
|
|
|
@@ -83,9 +100,10 @@ function ContextNavigator({
|
|
|
83
100
|
ref={store.navigationRef}
|
|
84
101
|
initialState={store.initialState}
|
|
85
102
|
linking={store.linking}
|
|
86
|
-
onReady={store.onReady}
|
|
87
103
|
>
|
|
88
|
-
<
|
|
104
|
+
<WrapperComponent>
|
|
105
|
+
<Component />
|
|
106
|
+
</WrapperComponent>
|
|
89
107
|
</UpstreamNavigationContainer>
|
|
90
108
|
);
|
|
91
109
|
}
|
|
@@ -61,6 +61,7 @@ export class RouterStore {
|
|
|
61
61
|
this.storeSubscribers.clear();
|
|
62
62
|
|
|
63
63
|
this.routeNode = getRoutes(context);
|
|
64
|
+
|
|
64
65
|
this.rootComponent = this.routeNode
|
|
65
66
|
? getQualifiedRouteComponent(this.routeNode)
|
|
66
67
|
: Fragment;
|
|
@@ -76,6 +77,7 @@ export class RouterStore {
|
|
|
76
77
|
this.linking = getLinkingConfig(this.routeNode!);
|
|
77
78
|
|
|
78
79
|
if (initialLocation) {
|
|
80
|
+
this.linking.getInitialURL = () => initialLocation.toString();
|
|
79
81
|
this.initialState = this.linking.getStateFromPath?.(
|
|
80
82
|
initialLocation.pathname + initialLocation.search,
|
|
81
83
|
this.linking.config
|
|
@@ -41,28 +41,28 @@ export function getStaticContent(location: URL): string {
|
|
|
41
41
|
|
|
42
42
|
const Root = getRootComponent();
|
|
43
43
|
|
|
44
|
-
const out = React.createElement(Root, {
|
|
45
|
-
// TODO: Use RNW view after they fix hydration for React 18
|
|
46
|
-
// https://github.com/necolas/react-native-web/blob/e8098fd029102d7801c32c1ede792bce01808c00/packages/react-native-web/src/exports/render/index.js#L10
|
|
47
|
-
// Otherwise this wraps the app with two extra divs
|
|
48
|
-
children:
|
|
49
|
-
// Inject the root tag using createElement to prevent any transforms like the ones in `@expo/html-elements`.
|
|
50
|
-
React.createElement(
|
|
51
|
-
"div",
|
|
52
|
-
{
|
|
53
|
-
id: "root",
|
|
54
|
-
},
|
|
55
|
-
<App location={location} />
|
|
56
|
-
),
|
|
57
|
-
});
|
|
58
|
-
|
|
59
44
|
// This MUST be run before `ReactDOMServer.renderToString` to prevent
|
|
60
45
|
// "Warning: Detected multiple renderers concurrently rendering the same context provider. This is currently unsupported."
|
|
61
46
|
resetReactNavigationContexts();
|
|
62
47
|
|
|
63
48
|
const html = ReactDOMServer.renderToString(
|
|
64
49
|
<Head.Provider context={headContext}>
|
|
65
|
-
<ServerContainer ref={ref}>
|
|
50
|
+
<ServerContainer ref={ref}>
|
|
51
|
+
<App
|
|
52
|
+
location={location}
|
|
53
|
+
wrapper={({ children }) => {
|
|
54
|
+
return React.createElement(Root, {
|
|
55
|
+
children: React.createElement(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
id: "root",
|
|
59
|
+
},
|
|
60
|
+
children
|
|
61
|
+
),
|
|
62
|
+
});
|
|
63
|
+
}}
|
|
64
|
+
/>
|
|
65
|
+
</ServerContainer>
|
|
66
66
|
</Head.Provider>
|
|
67
67
|
);
|
|
68
68
|
|
|
@@ -3,7 +3,9 @@ import path from "path";
|
|
|
3
3
|
import requireContext from "./require-context-ponyfill";
|
|
4
4
|
|
|
5
5
|
export type ReactComponent = () => React.ReactElement<any, any> | null;
|
|
6
|
-
export type FileStub =
|
|
6
|
+
export type FileStub =
|
|
7
|
+
| (Record<string, unknown> & { default: ReactComponent })
|
|
8
|
+
| ReactComponent;
|
|
7
9
|
|
|
8
10
|
export { requireContext };
|
|
9
11
|
|
|
@@ -6,10 +6,10 @@ expect.extend({
|
|
|
6
6
|
toHavePathname(screen, expected) {
|
|
7
7
|
return matchers.toEqual(screen.getPathname(), expected);
|
|
8
8
|
},
|
|
9
|
+
toHaveSegments(screen, expected) {
|
|
10
|
+
return matchers.toEqual(screen.getSegments(), expected);
|
|
11
|
+
},
|
|
9
12
|
toHaveSearchParams(screen, expected) {
|
|
10
|
-
return matchers.toEqual(
|
|
11
|
-
Object.fromEntries(screen.getSearchParams().entries()),
|
|
12
|
-
expected
|
|
13
|
-
);
|
|
13
|
+
return matchers.toEqual(screen.getSearchParams(), expected);
|
|
14
14
|
},
|
|
15
15
|
});
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
/// <reference types="../../types/jest
|
|
1
|
+
/// <reference types="../../types/jest" />
|
|
2
2
|
import "./expect";
|
|
3
3
|
|
|
4
|
-
import { BaseNavigationContainer } from "@react-navigation/core";
|
|
5
4
|
import { render, RenderResult } from "@testing-library/react-native";
|
|
6
|
-
import { findAll } from "@testing-library/react-native/build/helpers/findAll";
|
|
7
5
|
import path from "path";
|
|
8
6
|
import React from "react";
|
|
9
7
|
|
|
10
8
|
import { ExpoRoot } from "../ExpoRoot";
|
|
11
9
|
import { stateCache } from "../getLinkingConfig";
|
|
10
|
+
import { store } from "../global-state/router-store";
|
|
12
11
|
import { RequireContext } from "../types";
|
|
13
12
|
import {
|
|
14
13
|
FileStub,
|
|
@@ -27,7 +26,8 @@ type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
|
27
26
|
|
|
28
27
|
type Result = ReturnType<typeof render> & {
|
|
29
28
|
getPathname(): string;
|
|
30
|
-
|
|
29
|
+
getSegments(): string[];
|
|
30
|
+
getSearchParams(): Record<string, string | string[]>;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
function isOverrideContext(
|
|
@@ -80,7 +80,7 @@ export function renderRouter(
|
|
|
80
80
|
let location: URL | undefined;
|
|
81
81
|
|
|
82
82
|
if (typeof initialUrl === "string") {
|
|
83
|
-
location = new URL(initialUrl, "test://
|
|
83
|
+
location = new URL(initialUrl, "test://");
|
|
84
84
|
} else if (initialUrl instanceof URL) {
|
|
85
85
|
location = initialUrl;
|
|
86
86
|
}
|
|
@@ -91,29 +91,13 @@ export function renderRouter(
|
|
|
91
91
|
|
|
92
92
|
return Object.assign(result, {
|
|
93
93
|
getPathname(this: RenderResult): string {
|
|
94
|
-
|
|
95
|
-
return node.type === BaseNavigationContainer;
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
return (
|
|
99
|
-
"/" +
|
|
100
|
-
containers
|
|
101
|
-
.flatMap((route) => {
|
|
102
|
-
return route.props.initialState.routes.map((r: any) => r.name);
|
|
103
|
-
})
|
|
104
|
-
.join("/")
|
|
105
|
-
);
|
|
94
|
+
return store.routeInfoSnapshot().pathname;
|
|
106
95
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
const params = containers.reduce<Record<string, string>>((acc, route) => {
|
|
113
|
-
return { ...acc, ...route.props.initialState.routes[0].params };
|
|
114
|
-
}, {});
|
|
115
|
-
|
|
116
|
-
return new URLSearchParams(params);
|
|
96
|
+
getSegments(this: RenderResult): string[] {
|
|
97
|
+
return store.routeInfoSnapshot().segments;
|
|
98
|
+
},
|
|
99
|
+
getSearchParams(this: RenderResult): Record<string, string | string[]> {
|
|
100
|
+
return store.routeInfoSnapshot().params;
|
|
117
101
|
},
|
|
118
102
|
});
|
|
119
103
|
}
|
package/src/views/Toast.tsx
CHANGED
package/src/views/Unmatched.tsx
CHANGED
|
@@ -9,6 +9,19 @@ import { useNavigation } from "../useNavigation";
|
|
|
9
9
|
const useLayoutEffect =
|
|
10
10
|
typeof window !== "undefined" ? React.useLayoutEffect : function () {};
|
|
11
11
|
|
|
12
|
+
function NoSSR({ children }: { children: React.ReactNode }) {
|
|
13
|
+
const [render, setRender] = React.useState(false);
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
setRender(true);
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
18
|
+
if (!render) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return <>{children}</>;
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
/** Default screen for unmatched routes. */
|
|
13
26
|
export function Unmatched() {
|
|
14
27
|
const router = useRouter();
|
|
@@ -51,9 +64,11 @@ export function Unmatched() {
|
|
|
51
64
|
</Text>
|
|
52
65
|
</Text>
|
|
53
66
|
|
|
54
|
-
<
|
|
55
|
-
{
|
|
56
|
-
|
|
67
|
+
<NoSSR>
|
|
68
|
+
<Link href={pathname} replace style={styles.link}>
|
|
69
|
+
{url}
|
|
70
|
+
</Link>
|
|
71
|
+
</NoSSR>
|
|
57
72
|
|
|
58
73
|
<Link href="/_sitemap" replace style={[styles.link, { marginTop: 8 }]}>
|
|
59
74
|
Sitemap
|