expo-router 1.7.2 → 1.7.3
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/build/ExpoRoot.d.ts +1 -5
- package/build/ExpoRoot.d.ts.map +1 -1
- package/build/fork/findFocusedRoute.d.ts +1 -1
- package/build/fork/useLinking.native.d.ts +2 -2
- package/build/layouts/Drawer.d.ts +2 -2
- package/build/layouts/Stack.d.ts +2 -2
- package/build/layouts/Tabs.d.ts +2 -2
- package/build/link/stateOperations.d.ts +3 -3
- package/build/testing-library/context-stubs.d.ts +20 -0
- package/build/testing-library/context-stubs.d.ts.map +1 -0
- package/build/testing-library/index.d.ts +3 -7
- package/build/testing-library/index.d.ts.map +1 -1
- package/build/useCreateExpoRouterContext.d.ts +23 -0
- package/build/useCreateExpoRouterContext.d.ts.map +1 -0
- package/build/views/ErrorBoundary.d.ts.map +1 -1
- package/entry.js +3 -1
- package/package.json +3 -3
- package/src/ExpoRoot.tsx +25 -66
- package/src/link/href.ts +1 -1
- package/src/testing-library/context-stubs.ts +47 -0
- package/src/testing-library/index.tsx +13 -45
- package/src/useCreateExpoRouterContext.ts +88 -0
- package/src/views/ErrorBoundary.tsx +94 -52
- package/build/link/useHref.d.ts +0 -10
- package/build/link/useHref.d.ts.map +0 -1
- package/src/link/useHref.ts +0 -21
package/build/ExpoRoot.d.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
3
|
-
export type ExpoRootProps = {
|
|
4
|
-
context: RequireContext;
|
|
5
|
-
location?: URL;
|
|
6
|
-
};
|
|
2
|
+
import { ExpoRootProps } from "./useCreateExpoRouterContext";
|
|
7
3
|
export declare function ExpoRoot({ context, location }: ExpoRootProps): JSX.Element;
|
|
8
4
|
//# 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":";AAaA,OAAO,EACL,aAAa,EAEd,MAAM,8BAA8B,CAAC;AA8BtC,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,aAAa,eAa5D"}
|
|
@@ -16,7 +16,7 @@ export declare function findFocusedRoute(state: InitialState): (Omit<import("@re
|
|
|
16
16
|
})[];
|
|
17
17
|
type: string;
|
|
18
18
|
stale: false;
|
|
19
|
-
}>, "
|
|
19
|
+
}>, "routes" | "stale">> & {
|
|
20
20
|
routes: (Omit<import("@react-navigation/routers").Route<string, object | undefined>, "key"> & any)[];
|
|
21
21
|
}> | undefined;
|
|
22
22
|
}) | undefined;
|
|
@@ -19,7 +19,7 @@ export default function useLinking(ref: React.RefObject<NavigationContainerRef<P
|
|
|
19
19
|
})[];
|
|
20
20
|
type: string;
|
|
21
21
|
stale: false;
|
|
22
|
-
}>, "
|
|
22
|
+
}>, "routes" | "stale">> & Readonly<{
|
|
23
23
|
stale?: true | undefined;
|
|
24
24
|
routes: import("@react-navigation/core").PartialRoute<import("@react-navigation/core").Route<string, object | undefined>>[];
|
|
25
25
|
}> & {
|
|
@@ -39,7 +39,7 @@ export default function useLinking(ref: React.RefObject<NavigationContainerRef<P
|
|
|
39
39
|
})[];
|
|
40
40
|
type: string;
|
|
41
41
|
stale: false;
|
|
42
|
-
}>, "
|
|
42
|
+
}>, "routes" | "stale">> & Readonly<{
|
|
43
43
|
stale?: true | undefined;
|
|
44
44
|
routes: import("@react-navigation/core").PartialRoute<import("@react-navigation/core").Route<string, object | undefined>>[];
|
|
45
45
|
}> & any) | undefined;
|
|
@@ -27,7 +27,7 @@ export declare const Drawer: import("react").ForwardRefExoticComponent<Omit<Omit
|
|
|
27
27
|
backBehavior?: import("@react-navigation/routers/lib/typescript/src/TabRouter").BackBehavior | undefined;
|
|
28
28
|
} & {
|
|
29
29
|
defaultStatus?: import("@react-navigation/routers").DrawerStatus | undefined;
|
|
30
|
-
} & import("@react-navigation/drawer/lib/typescript/src/types").DrawerNavigationConfig, "
|
|
30
|
+
} & import("@react-navigation/drawer/lib/typescript/src/types").DrawerNavigationConfig, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
31
31
|
id?: string | undefined;
|
|
32
32
|
children: import("react").ReactNode;
|
|
33
33
|
screenListeners?: Partial<{
|
|
@@ -77,7 +77,7 @@ export declare const Drawer: import("react").ForwardRefExoticComponent<Omit<Omit
|
|
|
77
77
|
backBehavior?: import("@react-navigation/routers/lib/typescript/src/TabRouter").BackBehavior | undefined;
|
|
78
78
|
} & {
|
|
79
79
|
defaultStatus?: import("@react-navigation/routers").DrawerStatus | undefined;
|
|
80
|
-
} & import("@react-navigation/drawer/lib/typescript/src/types").DrawerNavigationConfig, "
|
|
80
|
+
} & import("@react-navigation/drawer/lib/typescript/src/types").DrawerNavigationConfig, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
81
81
|
id?: string | undefined;
|
|
82
82
|
children: import("react").ReactNode;
|
|
83
83
|
screenListeners?: Partial<{
|
package/build/layouts/Stack.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare const Stack: import("react").ForwardRefExoticComponent<Omit<Omit<
|
|
|
25
25
|
route: import("@react-navigation/core").RouteProp<import("@react-navigation/routers").ParamListBase, string>;
|
|
26
26
|
navigation: any;
|
|
27
27
|
}) => NativeStackNavigationOptions) | undefined;
|
|
28
|
-
} & import("@react-navigation/routers").StackRouterOptions, "
|
|
28
|
+
} & import("@react-navigation/routers").StackRouterOptions, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
29
29
|
id?: string | undefined;
|
|
30
30
|
children: import("react").ReactNode;
|
|
31
31
|
screenListeners?: Partial<{
|
|
@@ -75,7 +75,7 @@ export declare const Stack: import("react").ForwardRefExoticComponent<Omit<Omit<
|
|
|
75
75
|
route: import("@react-navigation/core").RouteProp<import("@react-navigation/routers").ParamListBase, string>;
|
|
76
76
|
navigation: any;
|
|
77
77
|
}) => NativeStackNavigationOptions) | undefined;
|
|
78
|
-
} & import("@react-navigation/routers").StackRouterOptions, "
|
|
78
|
+
} & import("@react-navigation/routers").StackRouterOptions, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
79
79
|
id?: string | undefined;
|
|
80
80
|
children: import("react").ReactNode;
|
|
81
81
|
screenListeners?: Partial<{
|
package/build/layouts/Tabs.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare const Tabs: React.ForwardRefExoticComponent<Omit<Omit<import("@re
|
|
|
28
28
|
}) => BottomTabNavigationOptions) | undefined;
|
|
29
29
|
} & import("@react-navigation/routers").DefaultRouterOptions & {
|
|
30
30
|
backBehavior?: import("@react-navigation/routers/lib/typescript/src/TabRouter").BackBehavior | undefined;
|
|
31
|
-
} & import("@react-navigation/bottom-tabs/lib/typescript/src/types").BottomTabNavigationConfig, "
|
|
31
|
+
} & import("@react-navigation/bottom-tabs/lib/typescript/src/types").BottomTabNavigationConfig, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
32
32
|
id?: string | undefined;
|
|
33
33
|
children: React.ReactNode;
|
|
34
34
|
screenListeners?: Partial<{
|
|
@@ -80,7 +80,7 @@ export declare const Tabs: React.ForwardRefExoticComponent<Omit<Omit<import("@re
|
|
|
80
80
|
}) => BottomTabNavigationOptions) | undefined;
|
|
81
81
|
} & import("@react-navigation/routers").DefaultRouterOptions & {
|
|
82
82
|
backBehavior?: import("@react-navigation/routers/lib/typescript/src/TabRouter").BackBehavior | undefined;
|
|
83
|
-
} & import("@react-navigation/bottom-tabs/lib/typescript/src/types").BottomTabNavigationConfig, "
|
|
83
|
+
} & import("@react-navigation/bottom-tabs/lib/typescript/src/types").BottomTabNavigationConfig, "children" | "id" | "initialRouteName" | "screenListeners" | "screenOptions"> & import("@react-navigation/routers").DefaultRouterOptions<string> & {
|
|
84
84
|
id?: string | undefined;
|
|
85
85
|
children: React.ReactNode;
|
|
86
86
|
screenListeners?: Partial<{
|
|
@@ -30,7 +30,7 @@ export declare function findTopRouteForTarget(state: ResultState): Omit<import("
|
|
|
30
30
|
})[];
|
|
31
31
|
type: string;
|
|
32
32
|
stale: false;
|
|
33
|
-
}>, "
|
|
33
|
+
}>, "routes" | "stale">> & {
|
|
34
34
|
routes: (Omit<import("@react-navigation/native").Route<string, object | undefined>, "key"> & any)[];
|
|
35
35
|
}> | undefined;
|
|
36
36
|
};
|
|
@@ -52,7 +52,7 @@ export declare function getQualifiedStateForTopOfTargetState(rootState: InitialS
|
|
|
52
52
|
})[];
|
|
53
53
|
type: string;
|
|
54
54
|
stale: false;
|
|
55
|
-
}>, "
|
|
55
|
+
}>, "routes" | "stale">> & {
|
|
56
56
|
routes: (Omit<import("@react-navigation/native").Route<string, object | undefined>, "key"> & {
|
|
57
57
|
state?: Readonly<Partial<Omit<Readonly<{
|
|
58
58
|
key: string;
|
|
@@ -70,7 +70,7 @@ export declare function getQualifiedStateForTopOfTargetState(rootState: InitialS
|
|
|
70
70
|
})[];
|
|
71
71
|
type: string;
|
|
72
72
|
stale: false;
|
|
73
|
-
}>, "
|
|
73
|
+
}>, "routes" | "stale">> & any> | undefined;
|
|
74
74
|
})[];
|
|
75
75
|
}>;
|
|
76
76
|
export declare function getEarliestMismatchedRoute<T extends ParamListBase>(rootState: NavigationState<T> | undefined, actionParams: NavigateActionParams): {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import requireContext from "./require-context-ponyfill";
|
|
3
|
+
export type ReactComponent = () => React.ReactElement<any, any> | null;
|
|
4
|
+
export type FileStub = {
|
|
5
|
+
default: ReactComponent;
|
|
6
|
+
} | ReactComponent;
|
|
7
|
+
export { requireContext };
|
|
8
|
+
export declare function inMemoryContext(context: Record<string, FileStub>): ((id: string) => ReactComponent | {
|
|
9
|
+
default: FileStub;
|
|
10
|
+
}) & {
|
|
11
|
+
keys: () => string[];
|
|
12
|
+
resolve: (key: string) => string;
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function requireContextWithOverrides(dir: string, overrides: Record<string, FileStub>): ((id: string) => any) & {
|
|
16
|
+
keys: () => string[];
|
|
17
|
+
resolve: (key: string) => string;
|
|
18
|
+
id: string;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=context-stubs.d.ts.map
|
|
@@ -0,0 +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,GAAG,cAAc,CAAC;AAEpE,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"}
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import "./expect";
|
|
2
2
|
import { render } from "@testing-library/react-native";
|
|
3
|
-
import
|
|
3
|
+
import { FileStub } from "./context-stubs";
|
|
4
4
|
export * from "@testing-library/react-native";
|
|
5
5
|
type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
6
6
|
initialUrl?: string;
|
|
7
7
|
};
|
|
8
|
-
type RouteOverrideFunction = () => React.ReactElement<any, any> | null;
|
|
9
|
-
type RouteOverride = {
|
|
10
|
-
default: RouteOverrideFunction;
|
|
11
|
-
} | RouteOverrideFunction;
|
|
12
8
|
type Result = ReturnType<typeof render> & {
|
|
13
9
|
getPathname(): string;
|
|
14
10
|
getSearchParams(): URLSearchParams;
|
|
15
11
|
};
|
|
16
12
|
export declare function renderRouter(context?: string, options?: RenderRouterOptions): Result;
|
|
17
|
-
export declare function renderRouter(context: Record<string,
|
|
13
|
+
export declare function renderRouter(context: Record<string, FileStub>, options?: RenderRouterOptions): Result;
|
|
18
14
|
export declare function renderRouter(context: {
|
|
19
15
|
appDir: string;
|
|
20
|
-
overrides: Record<string,
|
|
16
|
+
overrides: Record<string, FileStub>;
|
|
21
17
|
}, options?: RenderRouterOptions): Result;
|
|
22
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing-library/index.tsx"],"names":[],"mappings":"AACA,OAAO,UAAU,CAAC;AAGlB,OAAO,EAAE,MAAM,EAAgB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing-library/index.tsx"],"names":[],"mappings":"AACA,OAAO,UAAU,CAAC;AAGlB,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,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,GAAG;IACxC,WAAW,IAAI,MAAM,CAAC;IACtB,eAAe,IAAI,eAAe,CAAC;CACpC,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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ResultState } from "./fork/getStateFromPath";
|
|
2
|
+
import { ExpoRouterContextType, OnboardingExpoRouterContextType } from "./hooks";
|
|
3
|
+
import { RequireContext } from "./types";
|
|
4
|
+
export type ExpoRootProps = {
|
|
5
|
+
context: RequireContext;
|
|
6
|
+
location?: URL;
|
|
7
|
+
};
|
|
8
|
+
/** @private */
|
|
9
|
+
export declare function createExpoRouterContext({ context, location, }: ExpoRootProps): {
|
|
10
|
+
routeNode: null;
|
|
11
|
+
linking: {
|
|
12
|
+
prefixes: never[];
|
|
13
|
+
};
|
|
14
|
+
initialState: undefined;
|
|
15
|
+
getRouteInfo(): never;
|
|
16
|
+
} | {
|
|
17
|
+
routeNode: import("./Route").RouteNode;
|
|
18
|
+
linking: import("./getLinkingConfig").ExpoLinkingOptions;
|
|
19
|
+
initialState: ResultState | undefined;
|
|
20
|
+
getRouteInfo: (state: ResultState) => import("./LocationProvider").UrlObject;
|
|
21
|
+
};
|
|
22
|
+
export declare function useCreateExpoRouterContext(props: ExpoRootProps): Omit<ExpoRouterContextType, "navigationRef"> | Omit<OnboardingExpoRouterContextType, "navigationRef">;
|
|
23
|
+
//# sourceMappingURL=useCreateExpoRouterContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCreateExpoRouterContext.d.ts","sourceRoot":"","sources":["../src/useCreateExpoRouterContext.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EACL,qBAAqB,EACrB,+BAA+B,EAChC,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,CAAC;AAOF,eAAe;AACf,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,QAAqB,GACtB,EAAE,aAAa;;;;;;;;;;;0BAyBe,WAAW;EAsBzC;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,aAAa,yGAO9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/views/ErrorBoundary.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/views/ErrorBoundary.tsx"],"names":[],"mappings":";AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAmC3C,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,kBAAkB,eA2DjE"}
|
package/entry.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
// `@expo/metro-runtime` MUST be the first import to ensure Fast Refresh works
|
|
2
|
+
// on web.
|
|
3
|
+
import "@expo/metro-runtime";
|
|
1
4
|
import { ExpoRoot } from "expo-router";
|
|
2
5
|
import Head from "expo-router/head";
|
|
3
|
-
import "@expo/metro-runtime";
|
|
4
6
|
import { renderRootComponent } from "expo-router/src/renderRootComponent";
|
|
5
7
|
|
|
6
8
|
const ctx = require.context(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-router",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"main": "src/index.tsx",
|
|
5
5
|
"types": "build/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -102,12 +102,12 @@
|
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
104
|
"@bacons/react-views": "^1.1.3",
|
|
105
|
-
"@expo/metro-runtime": "2.1.
|
|
105
|
+
"@expo/metro-runtime": "2.1.2",
|
|
106
106
|
"@radix-ui/react-slot": "^1.0.0",
|
|
107
107
|
"@react-navigation/bottom-tabs": "~6.5.7",
|
|
108
108
|
"@react-navigation/native": "~6.1.6",
|
|
109
109
|
"@react-navigation/native-stack": "~6.9.12",
|
|
110
|
-
"expo-head": "0.0.
|
|
110
|
+
"expo-head": "0.0.4",
|
|
111
111
|
"expo-splash-screen": "*",
|
|
112
112
|
"query-string": "7.1.3",
|
|
113
113
|
"react-helmet-async": "^1.3.0",
|
package/src/ExpoRoot.tsx
CHANGED
|
@@ -4,22 +4,17 @@ import React from "react";
|
|
|
4
4
|
import { Platform } from "react-native";
|
|
5
5
|
import { SafeAreaProvider } from "react-native-safe-area-context";
|
|
6
6
|
|
|
7
|
-
import { getRouteInfoFromState } from "./LocationProvider";
|
|
8
7
|
import UpstreamNavigationContainer from "./fork/NavigationContainer";
|
|
9
|
-
import getPathFromState, {
|
|
10
|
-
getPathDataFromState,
|
|
11
|
-
} from "./fork/getPathFromState";
|
|
12
8
|
import { ResultState } from "./fork/getStateFromPath";
|
|
13
|
-
import { getLinkingConfig } from "./getLinkingConfig";
|
|
14
|
-
import { getRoutes } from "./getRoutes";
|
|
15
9
|
import {
|
|
16
|
-
ExpoRouterContextType,
|
|
17
10
|
ExpoRouterContext,
|
|
18
11
|
RootStateContext,
|
|
19
12
|
RootStateContextType,
|
|
20
|
-
OnboardingExpoRouterContextType,
|
|
21
13
|
} from "./hooks";
|
|
22
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
ExpoRootProps,
|
|
16
|
+
useCreateExpoRouterContext,
|
|
17
|
+
} from "./useCreateExpoRouterContext";
|
|
23
18
|
import { getQualifiedRouteComponent } from "./useScreens";
|
|
24
19
|
import { SplashScreen } from "./views/Splash";
|
|
25
20
|
|
|
@@ -28,9 +23,15 @@ function getGestureHandlerRootView() {
|
|
|
28
23
|
const { GestureHandlerRootView } =
|
|
29
24
|
require("react-native-gesture-handler") as typeof import("react-native-gesture-handler");
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
// eslint-disable-next-line no-inner-declarations
|
|
27
|
+
function GestureHandler(props: any) {
|
|
32
28
|
return <GestureHandlerRootView style={{ flex: 1 }} {...props} />;
|
|
33
|
-
}
|
|
29
|
+
}
|
|
30
|
+
if (process.env.NODE_ENV === "development") {
|
|
31
|
+
// @ts-expect-error
|
|
32
|
+
GestureHandler.displayName = "GestureHandlerRootView";
|
|
33
|
+
}
|
|
34
|
+
return GestureHandler;
|
|
34
35
|
} catch {
|
|
35
36
|
return React.Fragment;
|
|
36
37
|
}
|
|
@@ -43,11 +44,6 @@ const INITIAL_METRICS = {
|
|
|
43
44
|
insets: { top: 0, left: 0, right: 0, bottom: 0 },
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
export type ExpoRootProps = {
|
|
47
|
-
context: RequireContext;
|
|
48
|
-
location?: URL;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
47
|
export function ExpoRoot({ context, location }: ExpoRootProps) {
|
|
52
48
|
return (
|
|
53
49
|
<GestureHandlerRootView>
|
|
@@ -63,57 +59,13 @@ export function ExpoRoot({ context, location }: ExpoRootProps) {
|
|
|
63
59
|
);
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
Platform.OS === "web" && typeof window !== "undefined"
|
|
68
|
-
? new URL(window.location.href)
|
|
69
|
-
: undefined;
|
|
70
|
-
|
|
71
|
-
function ContextNavigator({
|
|
72
|
-
context,
|
|
73
|
-
location: initialLocation = initialUrl,
|
|
74
|
-
}: ExpoRootProps) {
|
|
62
|
+
function ContextNavigator(props: ExpoRootProps) {
|
|
75
63
|
const navigationRef = useNavigationContainerRef();
|
|
76
64
|
const [shouldShowSplash, setShowSplash] = React.useState(
|
|
77
65
|
Platform.OS !== "web"
|
|
78
66
|
);
|
|
79
67
|
|
|
80
|
-
const expoContext =
|
|
81
|
-
ExpoRouterContextType | OnboardingExpoRouterContextType
|
|
82
|
-
>(() => {
|
|
83
|
-
const routeNode = getRoutes(context);
|
|
84
|
-
const linking = getLinkingConfig(routeNode!);
|
|
85
|
-
let initialState: ResultState | undefined;
|
|
86
|
-
|
|
87
|
-
if (initialLocation) {
|
|
88
|
-
initialState = linking.getStateFromPath?.(
|
|
89
|
-
initialLocation.pathname + initialLocation.search,
|
|
90
|
-
linking.config
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function getRouteInfo(state: ResultState) {
|
|
95
|
-
return getRouteInfoFromState(
|
|
96
|
-
(state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {
|
|
97
|
-
return getPathDataFromState(state, {
|
|
98
|
-
screens: [],
|
|
99
|
-
...linking.config,
|
|
100
|
-
preserveDynamicRoutes: asPath,
|
|
101
|
-
preserveGroups: asPath,
|
|
102
|
-
});
|
|
103
|
-
},
|
|
104
|
-
state
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// This looks redundant but it makes TypeScript correctly infer the union return type.
|
|
109
|
-
return {
|
|
110
|
-
routeNode,
|
|
111
|
-
linking,
|
|
112
|
-
navigationRef,
|
|
113
|
-
initialState,
|
|
114
|
-
getRouteInfo,
|
|
115
|
-
};
|
|
116
|
-
}, [context, navigationRef, initialLocation]);
|
|
68
|
+
const expoContext = useCreateExpoRouterContext(props);
|
|
117
69
|
|
|
118
70
|
const { routeNode, initialState, linking, getRouteInfo } = expoContext;
|
|
119
71
|
|
|
@@ -147,6 +99,15 @@ function ContextNavigator({
|
|
|
147
99
|
return () => subscription?.();
|
|
148
100
|
}, [navigationRef, getRouteInfo]);
|
|
149
101
|
|
|
102
|
+
const Component = routeNode ? getQualifiedRouteComponent(routeNode) : null;
|
|
103
|
+
|
|
104
|
+
const comp = React.useMemo(() => {
|
|
105
|
+
if (!Component) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
return <Component />;
|
|
109
|
+
}, [Component, shouldShowSplash]);
|
|
110
|
+
|
|
150
111
|
if (!routeNode) {
|
|
151
112
|
if (process.env.NODE_ENV === "development") {
|
|
152
113
|
const Tutorial = require("./onboard/Tutorial").Tutorial;
|
|
@@ -157,12 +118,10 @@ function ContextNavigator({
|
|
|
157
118
|
}
|
|
158
119
|
}
|
|
159
120
|
|
|
160
|
-
const Component = getQualifiedRouteComponent(routeNode);
|
|
161
|
-
|
|
162
121
|
return (
|
|
163
122
|
<>
|
|
164
123
|
{shouldShowSplash && <SplashScreen />}
|
|
165
|
-
<ExpoRouterContext.Provider value={expoContext}>
|
|
124
|
+
<ExpoRouterContext.Provider value={{ ...expoContext, navigationRef }}>
|
|
166
125
|
<UpstreamNavigationContainer
|
|
167
126
|
ref={navigationRef}
|
|
168
127
|
initialState={initialState}
|
|
@@ -170,7 +129,7 @@ function ContextNavigator({
|
|
|
170
129
|
onReady={() => requestAnimationFrame(() => setShowSplash(false))}
|
|
171
130
|
>
|
|
172
131
|
<RootStateContext.Provider value={rootState}>
|
|
173
|
-
{!shouldShowSplash &&
|
|
132
|
+
{!shouldShowSplash && comp}
|
|
174
133
|
</RootStateContext.Provider>
|
|
175
134
|
</UpstreamNavigationContainer>
|
|
176
135
|
</ExpoRouterContext.Provider>
|
package/src/link/href.ts
CHANGED
|
@@ -55,6 +55,6 @@ function encodeParam(param: any): string {
|
|
|
55
55
|
|
|
56
56
|
function createQueryParams(params: Record<string, any>): string {
|
|
57
57
|
return Object.entries(params)
|
|
58
|
-
.map((
|
|
58
|
+
.map(([key, value]) => `${key}=${encodeURIComponent(value.toString())}`)
|
|
59
59
|
.join("&");
|
|
60
60
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
|
|
3
|
+
import requireContext from "./require-context-ponyfill";
|
|
4
|
+
|
|
5
|
+
export type ReactComponent = () => React.ReactElement<any, any> | null;
|
|
6
|
+
export type FileStub = { default: ReactComponent } | ReactComponent;
|
|
7
|
+
|
|
8
|
+
export { requireContext };
|
|
9
|
+
|
|
10
|
+
export function inMemoryContext(context: Record<string, FileStub>) {
|
|
11
|
+
return Object.assign(
|
|
12
|
+
function (id: string) {
|
|
13
|
+
id = id.replace(/^\.\//, "").replace(/\.js$/, "");
|
|
14
|
+
return typeof context[id] === "function"
|
|
15
|
+
? { default: context[id] }
|
|
16
|
+
: context[id];
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
keys: () => Object.keys(context).map((key) => "./" + key + ".js"),
|
|
20
|
+
resolve: (key: string) => key,
|
|
21
|
+
id: "0",
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function requireContextWithOverrides(
|
|
27
|
+
dir: string,
|
|
28
|
+
overrides: Record<string, FileStub>
|
|
29
|
+
) {
|
|
30
|
+
const existingContext = requireContext(path.resolve(process.cwd(), dir));
|
|
31
|
+
|
|
32
|
+
return Object.assign(
|
|
33
|
+
function (id: string) {
|
|
34
|
+
if (id in overrides) {
|
|
35
|
+
const route = overrides[id];
|
|
36
|
+
return typeof route === "function" ? { default: route } : route;
|
|
37
|
+
} else {
|
|
38
|
+
return existingContext(id);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
keys: () => [...Object.keys(overrides), ...existingContext.keys()],
|
|
43
|
+
resolve: (key: string) => key,
|
|
44
|
+
id: "0",
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
@@ -10,8 +10,13 @@ import React from "react";
|
|
|
10
10
|
import { ExpoRoot } from "../ExpoRoot";
|
|
11
11
|
import { stateCache } from "../getLinkingConfig";
|
|
12
12
|
import { RequireContext } from "../types";
|
|
13
|
+
import {
|
|
14
|
+
FileStub,
|
|
15
|
+
inMemoryContext,
|
|
16
|
+
requireContext,
|
|
17
|
+
requireContextWithOverrides,
|
|
18
|
+
} from "./context-stubs";
|
|
13
19
|
import { initialUrlRef } from "./mocks";
|
|
14
|
-
import requireContext from "./require-context-ponyfill";
|
|
15
20
|
|
|
16
21
|
// re-export everything
|
|
17
22
|
export * from "@testing-library/react-native";
|
|
@@ -20,10 +25,6 @@ type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
|
20
25
|
initialUrl?: string;
|
|
21
26
|
};
|
|
22
27
|
|
|
23
|
-
type RouteOverrideFunction = () => React.ReactElement<any, any> | null;
|
|
24
|
-
|
|
25
|
-
type RouteOverride = { default: RouteOverrideFunction } | RouteOverrideFunction;
|
|
26
|
-
|
|
27
28
|
type Result = ReturnType<typeof render> & {
|
|
28
29
|
getPathname(): string;
|
|
29
30
|
getSearchParams(): URLSearchParams;
|
|
@@ -31,7 +32,7 @@ type Result = ReturnType<typeof render> & {
|
|
|
31
32
|
|
|
32
33
|
function isOverrideContext(
|
|
33
34
|
context: object
|
|
34
|
-
): context is { appDir: string; overrides: Record<string,
|
|
35
|
+
): context is { appDir: string; overrides: Record<string, FileStub> } {
|
|
35
36
|
return Boolean(typeof context === "object" && "appDir" in context);
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -40,18 +41,18 @@ export function renderRouter(
|
|
|
40
41
|
options?: RenderRouterOptions
|
|
41
42
|
): Result;
|
|
42
43
|
export function renderRouter(
|
|
43
|
-
context: Record<string,
|
|
44
|
+
context: Record<string, FileStub>,
|
|
44
45
|
options?: RenderRouterOptions
|
|
45
46
|
): Result;
|
|
46
47
|
export function renderRouter(
|
|
47
|
-
context: { appDir: string; overrides: Record<string,
|
|
48
|
+
context: { appDir: string; overrides: Record<string, FileStub> },
|
|
48
49
|
options?: RenderRouterOptions
|
|
49
50
|
): Result;
|
|
50
51
|
export function renderRouter(
|
|
51
52
|
context:
|
|
52
53
|
| string
|
|
53
|
-
| { appDir: string; overrides: Record<string,
|
|
54
|
-
| Record<string,
|
|
54
|
+
| { appDir: string; overrides: Record<string, FileStub> }
|
|
55
|
+
| Record<string, FileStub> = "./app",
|
|
55
56
|
{ initialUrl = "/", ...options }: RenderRouterOptions = {}
|
|
56
57
|
): Result {
|
|
57
58
|
jest.useFakeTimers();
|
|
@@ -67,42 +68,9 @@ export function renderRouter(
|
|
|
67
68
|
if (typeof context === "string") {
|
|
68
69
|
ctx = requireContext(path.resolve(process.cwd(), context));
|
|
69
70
|
} else if (isOverrideContext(context)) {
|
|
70
|
-
|
|
71
|
-
path.resolve(process.cwd(), context.appDir)
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
ctx = Object.assign(
|
|
75
|
-
function (id: string) {
|
|
76
|
-
if (id in context.overrides) {
|
|
77
|
-
const route = context.overrides[id];
|
|
78
|
-
return typeof route === "function" ? { default: route } : route;
|
|
79
|
-
} else {
|
|
80
|
-
return existingContext(id);
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
keys: () => [
|
|
85
|
-
...Object.keys(context.overrides),
|
|
86
|
-
...existingContext.keys(),
|
|
87
|
-
],
|
|
88
|
-
resolve: (key: string) => key,
|
|
89
|
-
id: "0",
|
|
90
|
-
}
|
|
91
|
-
);
|
|
71
|
+
ctx = requireContextWithOverrides(context.appDir, context.overrides);
|
|
92
72
|
} else {
|
|
93
|
-
ctx =
|
|
94
|
-
function (id: string) {
|
|
95
|
-
id = id.replace(/^\.\//, "").replace(/\.js$/, "");
|
|
96
|
-
return typeof context[id] === "function"
|
|
97
|
-
? { default: context[id] }
|
|
98
|
-
: context[id];
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
keys: () => Object.keys(context).map((key) => "./" + key + ".js"),
|
|
102
|
-
resolve: (key: string) => key,
|
|
103
|
-
id: "0",
|
|
104
|
-
}
|
|
105
|
-
);
|
|
73
|
+
ctx = inMemoryContext(context);
|
|
106
74
|
}
|
|
107
75
|
|
|
108
76
|
stateCache.clear();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Platform } from "react-native";
|
|
3
|
+
|
|
4
|
+
import { getRouteInfoFromState } from "./LocationProvider";
|
|
5
|
+
import getPathFromState, {
|
|
6
|
+
getPathDataFromState,
|
|
7
|
+
} from "./fork/getPathFromState";
|
|
8
|
+
import { ResultState } from "./fork/getStateFromPath";
|
|
9
|
+
import { getLinkingConfig } from "./getLinkingConfig";
|
|
10
|
+
import { getRoutes } from "./getRoutes";
|
|
11
|
+
import {
|
|
12
|
+
ExpoRouterContextType,
|
|
13
|
+
OnboardingExpoRouterContextType,
|
|
14
|
+
} from "./hooks";
|
|
15
|
+
import { RequireContext } from "./types";
|
|
16
|
+
// import URL from "url-parse";
|
|
17
|
+
|
|
18
|
+
export type ExpoRootProps = {
|
|
19
|
+
context: RequireContext;
|
|
20
|
+
location?: URL;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const initialUrl =
|
|
24
|
+
Platform.OS === "web" && typeof window !== "undefined"
|
|
25
|
+
? new URL(window.location.href)
|
|
26
|
+
: undefined;
|
|
27
|
+
|
|
28
|
+
/** @private */
|
|
29
|
+
export function createExpoRouterContext({
|
|
30
|
+
context,
|
|
31
|
+
location = initialUrl,
|
|
32
|
+
}: ExpoRootProps) {
|
|
33
|
+
const routeNode = getRoutes(context);
|
|
34
|
+
|
|
35
|
+
// No app dir exists
|
|
36
|
+
if (!routeNode) {
|
|
37
|
+
return {
|
|
38
|
+
routeNode,
|
|
39
|
+
linking: { prefixes: [] },
|
|
40
|
+
initialState: undefined,
|
|
41
|
+
getRouteInfo() {
|
|
42
|
+
throw new Error("invalid");
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const linking = getLinkingConfig(routeNode);
|
|
48
|
+
let initialState: ResultState | undefined;
|
|
49
|
+
|
|
50
|
+
if (location) {
|
|
51
|
+
initialState = linking.getStateFromPath?.(
|
|
52
|
+
location.pathname + location.search,
|
|
53
|
+
linking.config
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function getRouteInfo(state: ResultState) {
|
|
58
|
+
return getRouteInfoFromState(
|
|
59
|
+
(state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {
|
|
60
|
+
return getPathDataFromState(state, {
|
|
61
|
+
screens: [],
|
|
62
|
+
...linking.config,
|
|
63
|
+
preserveDynamicRoutes: asPath,
|
|
64
|
+
preserveGroups: asPath,
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
state
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// This looks redundant but it makes TypeScript correctly infer the union return type.
|
|
72
|
+
return {
|
|
73
|
+
routeNode,
|
|
74
|
+
linking,
|
|
75
|
+
|
|
76
|
+
initialState,
|
|
77
|
+
getRouteInfo,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function useCreateExpoRouterContext(props: ExpoRootProps) {
|
|
82
|
+
return React.useMemo<
|
|
83
|
+
| Omit<ExpoRouterContextType, "navigationRef">
|
|
84
|
+
| Omit<OnboardingExpoRouterContextType, "navigationRef">
|
|
85
|
+
>(() => {
|
|
86
|
+
return createExpoRouterContext(props);
|
|
87
|
+
}, [props.context, props.location]);
|
|
88
|
+
}
|
|
@@ -1,16 +1,57 @@
|
|
|
1
1
|
import { Pressable, StyleSheet, Text, View } from "@bacons/react-views";
|
|
2
|
+
import { LogContext } from "@expo/metro-runtime/build/error-overlay/Data/LogContext";
|
|
3
|
+
import { LogBoxInspectorStackFrames } from "@expo/metro-runtime/build/error-overlay/overlay/LogBoxInspectorStackFrames";
|
|
4
|
+
import { LogBoxLog, parseErrorStack } from "@expo/metro-runtime/symbolicate";
|
|
5
|
+
import { BottomTabBarHeightContext } from "@react-navigation/bottom-tabs";
|
|
2
6
|
import React from "react";
|
|
3
|
-
import { Platform, ScrollView
|
|
7
|
+
import { Platform, ScrollView } from "react-native";
|
|
4
8
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
5
9
|
|
|
6
10
|
import { Link } from "../link/Link";
|
|
7
11
|
import { ErrorBoundaryProps } from "./Try";
|
|
8
12
|
|
|
13
|
+
function useMetroSymbolication(error: Error) {
|
|
14
|
+
const [logBoxLog, setLogBoxLog] = React.useState<LogBoxLog | null>(null);
|
|
15
|
+
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
let isMounted = true;
|
|
18
|
+
const stack = parseErrorStack(error.stack);
|
|
19
|
+
|
|
20
|
+
const log = new LogBoxLog({
|
|
21
|
+
level: "error",
|
|
22
|
+
message: {
|
|
23
|
+
content: error.message,
|
|
24
|
+
substitutions: [],
|
|
25
|
+
},
|
|
26
|
+
isComponentError: false,
|
|
27
|
+
stack,
|
|
28
|
+
category: error.message,
|
|
29
|
+
componentStack: [],
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
log.symbolicate("stack", (symbolicatedLog) => {
|
|
33
|
+
if (isMounted) {
|
|
34
|
+
setLogBoxLog(log);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return () => {
|
|
39
|
+
isMounted = false;
|
|
40
|
+
};
|
|
41
|
+
}, [error]);
|
|
42
|
+
|
|
43
|
+
return logBoxLog;
|
|
44
|
+
}
|
|
45
|
+
|
|
9
46
|
export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
|
|
47
|
+
const logBoxLog = useMetroSymbolication(error);
|
|
48
|
+
const inTabBar = React.useContext(BottomTabBarHeightContext);
|
|
49
|
+
const Wrapper = inTabBar ? View : SafeAreaView;
|
|
50
|
+
|
|
10
51
|
return (
|
|
11
|
-
<View style={
|
|
12
|
-
<
|
|
13
|
-
style={{ flex: 1, maxWidth: 720, marginHorizontal: "auto" }}
|
|
52
|
+
<View style={styles.container}>
|
|
53
|
+
<Wrapper
|
|
54
|
+
style={{ flex: 1, gap: 8, maxWidth: 720, marginHorizontal: "auto" }}
|
|
14
55
|
>
|
|
15
56
|
<View
|
|
16
57
|
style={{
|
|
@@ -28,63 +69,56 @@ export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
|
|
|
28
69
|
>
|
|
29
70
|
Something went wrong
|
|
30
71
|
</Text>
|
|
31
|
-
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
|
32
|
-
<Pressable>
|
|
33
|
-
{({ hovered }) => (
|
|
34
|
-
<TouchableOpacity onPress={retry}>
|
|
35
|
-
<View
|
|
36
|
-
style={[
|
|
37
|
-
{
|
|
38
|
-
transitionDuration: "100ms",
|
|
39
|
-
paddingVertical: 12,
|
|
40
|
-
paddingHorizontal: 24,
|
|
41
|
-
borderColor: "white",
|
|
42
|
-
borderWidth: 2,
|
|
43
|
-
marginLeft: 8,
|
|
44
|
-
},
|
|
45
|
-
hovered && { backgroundColor: "white" },
|
|
46
|
-
]}
|
|
47
|
-
>
|
|
48
|
-
<Text
|
|
49
|
-
style={[
|
|
50
|
-
styles.buttonText,
|
|
51
|
-
{
|
|
52
|
-
transitionDuration: "100ms",
|
|
53
|
-
color: hovered ? "black" : "white",
|
|
54
|
-
},
|
|
55
|
-
]}
|
|
56
|
-
>
|
|
57
|
-
Retry
|
|
58
|
-
</Text>
|
|
59
|
-
</View>
|
|
60
|
-
</TouchableOpacity>
|
|
61
|
-
)}
|
|
62
|
-
</Pressable>
|
|
63
|
-
</View>
|
|
64
72
|
</View>
|
|
65
73
|
|
|
66
|
-
<StackTrace
|
|
74
|
+
<StackTrace logData={logBoxLog} />
|
|
67
75
|
{process.env.NODE_ENV === "development" && (
|
|
68
76
|
<Link href="/_sitemap" style={styles.link}>
|
|
69
77
|
Sitemap
|
|
70
78
|
</Link>
|
|
71
79
|
)}
|
|
72
|
-
|
|
80
|
+
<Pressable onPress={retry}>
|
|
81
|
+
{({ hovered, pressed }) => (
|
|
82
|
+
<View
|
|
83
|
+
style={[
|
|
84
|
+
styles.buttonInner,
|
|
85
|
+
(hovered || pressed) && { backgroundColor: "white" },
|
|
86
|
+
]}
|
|
87
|
+
>
|
|
88
|
+
<Text
|
|
89
|
+
style={[
|
|
90
|
+
styles.buttonText,
|
|
91
|
+
{
|
|
92
|
+
transitionDuration: "100ms",
|
|
93
|
+
color: hovered || pressed ? "black" : "white",
|
|
94
|
+
},
|
|
95
|
+
]}
|
|
96
|
+
>
|
|
97
|
+
Retry
|
|
98
|
+
</Text>
|
|
99
|
+
</View>
|
|
100
|
+
)}
|
|
101
|
+
</Pressable>
|
|
102
|
+
</Wrapper>
|
|
73
103
|
</View>
|
|
74
104
|
);
|
|
75
105
|
}
|
|
76
106
|
|
|
77
|
-
function StackTrace({
|
|
107
|
+
function StackTrace({ logData }: { logData: LogBoxLog | null }) {
|
|
108
|
+
if (!logData?.symbolicated?.stack?.stack) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
78
111
|
return (
|
|
79
|
-
<ScrollView
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
112
|
+
<ScrollView style={{ flex: 1 }}>
|
|
113
|
+
<LogContext.Provider
|
|
114
|
+
value={{
|
|
115
|
+
isDisabled: false,
|
|
116
|
+
logs: [logData],
|
|
117
|
+
selectedLogIndex: 0,
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
<LogBoxInspectorStackFrames onRetry={function () {}} type="stack" />
|
|
121
|
+
</LogContext.Provider>
|
|
88
122
|
</ScrollView>
|
|
89
123
|
);
|
|
90
124
|
}
|
|
@@ -99,9 +133,7 @@ const styles = StyleSheet.create({
|
|
|
99
133
|
},
|
|
100
134
|
title: {
|
|
101
135
|
color: "white",
|
|
102
|
-
fontSize:
|
|
103
|
-
|
|
104
|
-
// textAlign: "center",
|
|
136
|
+
fontSize: Platform.select({ web: 32, default: 24 }),
|
|
105
137
|
fontWeight: "bold",
|
|
106
138
|
},
|
|
107
139
|
buttonText: {
|
|
@@ -109,6 +141,16 @@ const styles = StyleSheet.create({
|
|
|
109
141
|
fontWeight: "bold",
|
|
110
142
|
color: "black",
|
|
111
143
|
},
|
|
144
|
+
buttonInner: {
|
|
145
|
+
transitionDuration: "100ms",
|
|
146
|
+
paddingVertical: 12,
|
|
147
|
+
paddingHorizontal: 24,
|
|
148
|
+
borderColor: "white",
|
|
149
|
+
borderWidth: 2,
|
|
150
|
+
marginLeft: 8,
|
|
151
|
+
justifyContent: "center",
|
|
152
|
+
alignItems: "center",
|
|
153
|
+
},
|
|
112
154
|
code: {
|
|
113
155
|
fontFamily: Platform.select({
|
|
114
156
|
default: "Courier",
|
package/build/link/useHref.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { HrefObject } from "./href";
|
|
2
|
-
/** @deprecated */
|
|
3
|
-
type RouteInfo = Omit<Required<HrefObject>, "query"> & {
|
|
4
|
-
/** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
|
|
5
|
-
href: string;
|
|
6
|
-
};
|
|
7
|
-
/** @deprecated */
|
|
8
|
-
export declare function useHref(): RouteInfo;
|
|
9
|
-
export {};
|
|
10
|
-
//# sourceMappingURL=useHref.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useHref.d.ts","sourceRoot":"","sources":["../../src/link/useHref.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,kBAAkB;AAClB,KAAK,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,GAAG;IACrD,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,kBAAkB;AAClB,wBAAgB,OAAO,IAAI,SAAS,CAUnC"}
|
package/src/link/useHref.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { usePathname, useSearchParams, useSegments } from "../hooks";
|
|
2
|
-
import { HrefObject } from "./href";
|
|
3
|
-
|
|
4
|
-
/** @deprecated */
|
|
5
|
-
type RouteInfo = Omit<Required<HrefObject>, "query"> & {
|
|
6
|
-
/** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
|
|
7
|
-
href: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/** @deprecated */
|
|
11
|
-
export function useHref(): RouteInfo {
|
|
12
|
-
console.warn(
|
|
13
|
-
"useHref is deprecated in favor of usePathname, useSearchParams, and useSegments"
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
href: usePathname(),
|
|
18
|
-
pathname: useSegments().join("/"),
|
|
19
|
-
params: useSearchParams(),
|
|
20
|
-
};
|
|
21
|
-
}
|