expo-router 0.0.21 → 0.0.22
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/ContextNavigationContainer.d.ts +7 -12
- package/build/ContextNavigationContainer.d.ts.map +1 -1
- package/build/ContextNavigationContainer.js +11 -10
- package/build/ContextNavigationContainer.js.map +1 -1
- package/build/views/Layout.d.ts +6 -0
- package/build/views/Layout.d.ts.map +1 -1
- package/build/views/Layout.js +52 -3
- package/build/views/Layout.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NavigationContainer
|
|
1
|
+
import { NavigationContainer } from "@react-navigation/native";
|
|
2
2
|
import React from "react";
|
|
3
3
|
declare type NavigationContainerProps = React.ComponentProps<typeof NavigationContainer>;
|
|
4
4
|
export declare function useNavigationContainerContext(): [Partial<import("@react-navigation/native").NavigationContainerProps & {
|
|
@@ -8,7 +8,7 @@ export declare function useNavigationContainerContext(): [Partial<import("@react
|
|
|
8
8
|
documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
|
|
9
9
|
onReady?: (() => void) | undefined;
|
|
10
10
|
} & {
|
|
11
|
-
ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
|
|
11
|
+
ref?: React.Ref<import("@react-navigation/native").NavigationContainerRef<{}>> | undefined;
|
|
12
12
|
}>, (props: Partial<import("@react-navigation/native").NavigationContainerProps & {
|
|
13
13
|
theme?: import("@react-navigation/native").Theme | undefined;
|
|
14
14
|
linking?: import("@react-navigation/native").LinkingOptions<{}> | undefined;
|
|
@@ -16,18 +16,13 @@ export declare function useNavigationContainerContext(): [Partial<import("@react
|
|
|
16
16
|
documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
|
|
17
17
|
onReady?: (() => void) | undefined;
|
|
18
18
|
} & {
|
|
19
|
-
ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
|
|
19
|
+
ref?: React.Ref<import("@react-navigation/native").NavigationContainerRef<{}>> | undefined;
|
|
20
20
|
}>) => void];
|
|
21
21
|
/** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */
|
|
22
|
-
export declare
|
|
23
|
-
theme?: import("@react-navigation/native").Theme | undefined;
|
|
24
|
-
linking?: import("@react-navigation/native").LinkingOptions<{}> | undefined;
|
|
25
|
-
fallback?: React.ReactNode;
|
|
26
|
-
documentTitle?: import("@react-navigation/native").DocumentTitleOptions | undefined;
|
|
27
|
-
onReady?: (() => void) | undefined;
|
|
28
|
-
} & {
|
|
29
|
-
ref?: React.Ref<NavigationContainerRef<{}>> | undefined;
|
|
30
|
-
}, keyof import("@react-navigation/native").NavigationContainerProps | "theme" | "linking" | "fallback" | "documentTitle" | "onReady"> & React.RefAttributes<NavigationContainerRef<{}>>>;
|
|
22
|
+
export declare function ContextNavigationContainer(props: NavigationContainerProps): JSX.Element;
|
|
31
23
|
export declare function RootContainer({ documentTitle, fallback, onReady, initialState, onStateChange, onUnhandledAction, theme, }: Omit<NavigationContainerProps, "independent" | "ref" | "children" | "linking">): null;
|
|
24
|
+
export declare namespace RootContainer {
|
|
25
|
+
var getRef: () => import("@react-navigation/native").NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;
|
|
26
|
+
}
|
|
32
27
|
export {};
|
|
33
28
|
//# sourceMappingURL=ContextNavigationContainer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextNavigationContainer.d.ts","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"ContextNavigationContainer.d.ts","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAsB,MAAM,OAAO,CAAC;AAQ3C,aAAK,wBAAwB,GAAG,KAAK,CAAC,cAAc,CAClD,OAAO,mBAAmB,CAC3B,CAAC;AASF,wBAAgB,6BAA6B;;;;;;;;;;;;;;;;aAQ5C;AAED,8GAA8G;AAC9G,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,wBAAwB,eAsBzE;AAoDD,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,KAAK,GACN,EAAE,IAAI,CACL,wBAAwB,EACxB,aAAa,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAC/C,QAwBA;yBAnCe,aAAa"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { findFocusedRoute, NavigationContainer, } from "@react-navigation/native";
|
|
1
|
+
import { createNavigationContainerRef, findFocusedRoute, NavigationContainer, } from "@react-navigation/native";
|
|
2
2
|
import React, { useCallback } from "react";
|
|
3
3
|
import { useLinkingConfig } from "./getLinkingConfig";
|
|
4
4
|
import SplashModule from "./splash";
|
|
5
5
|
import { VirtualRouteContext } from "./useCurrentRoute";
|
|
6
|
+
const navigationRef = createNavigationContainerRef();
|
|
6
7
|
const NavigationContainerContext = React.createContext([{}, function () { }]);
|
|
7
8
|
export function useNavigationContainerContext() {
|
|
8
9
|
const context = React.useContext(NavigationContainerContext);
|
|
@@ -12,7 +13,7 @@ export function useNavigationContainerContext() {
|
|
|
12
13
|
return context;
|
|
13
14
|
}
|
|
14
15
|
/** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */
|
|
15
|
-
export
|
|
16
|
+
export function ContextNavigationContainer(props) {
|
|
16
17
|
const [state, setState] = React.useState({});
|
|
17
18
|
const linking = useLinkingConfig();
|
|
18
19
|
console.log("linking", linking);
|
|
@@ -24,8 +25,8 @@ export const ContextNavigationContainer = React.forwardRef((props, ref) => {
|
|
|
24
25
|
},
|
|
25
26
|
setState,
|
|
26
27
|
] },
|
|
27
|
-
React.createElement(InternalContextNavigationContainer,
|
|
28
|
-
}
|
|
28
|
+
React.createElement(InternalContextNavigationContainer, null)));
|
|
29
|
+
}
|
|
29
30
|
function trimQuery(pathname) {
|
|
30
31
|
const queryIndex = pathname.indexOf("?");
|
|
31
32
|
if (queryIndex !== -1) {
|
|
@@ -33,7 +34,7 @@ function trimQuery(pathname) {
|
|
|
33
34
|
}
|
|
34
35
|
return pathname;
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
+
function InternalContextNavigationContainer(props) {
|
|
37
38
|
const [contextProps] = useNavigationContainerContext();
|
|
38
39
|
const [state, setState] = React.useState({ pathname: null, query: {} });
|
|
39
40
|
const onStateChange = useCallback((state) => {
|
|
@@ -45,10 +46,6 @@ const InternalContextNavigationContainer = React.forwardRef((props, ref) => {
|
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
48
|
}, [setState]);
|
|
48
|
-
const navigationRef = React.useRef(null);
|
|
49
|
-
React.useImperativeHandle(ref, () => navigationRef.current, [
|
|
50
|
-
navigationRef,
|
|
51
|
-
]);
|
|
52
49
|
return (React.createElement(VirtualRouteContext.Provider, { value: state },
|
|
53
50
|
React.createElement(NavigationContainer, { ...props, ...contextProps, ref: navigationRef, onReady: () => {
|
|
54
51
|
contextProps.onReady?.();
|
|
@@ -59,7 +56,7 @@ const InternalContextNavigationContainer = React.forwardRef((props, ref) => {
|
|
|
59
56
|
contextProps.onStateChange?.(state);
|
|
60
57
|
onStateChange(state);
|
|
61
58
|
} })));
|
|
62
|
-
}
|
|
59
|
+
}
|
|
63
60
|
export function RootContainer({ documentTitle, fallback, onReady, initialState, onStateChange, onUnhandledAction, theme, }) {
|
|
64
61
|
const [, setProps] = useNavigationContainerContext();
|
|
65
62
|
React.useEffect(() => {
|
|
@@ -83,4 +80,8 @@ export function RootContainer({ documentTitle, fallback, onReady, initialState,
|
|
|
83
80
|
]);
|
|
84
81
|
return null;
|
|
85
82
|
}
|
|
83
|
+
/** Get the root navigation container ref. */
|
|
84
|
+
RootContainer.getRef = () => {
|
|
85
|
+
return navigationRef;
|
|
86
|
+
};
|
|
86
87
|
//# sourceMappingURL=ContextNavigationContainer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextNavigationContainer.js","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ContextNavigationContainer.js","sourceRoot":"","sources":["../src/ContextNavigationContainer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createNavigationContainerRef,\n findFocusedRoute,\n NavigationContainer,\n} from \"@react-navigation/native\";\nimport React, { useCallback } from \"react\";\n\nimport { useLinkingConfig } from \"./getLinkingConfig\";\nimport SplashModule from \"./splash\";\nimport { VirtualRouteContext } from \"./useCurrentRoute\";\n\nconst navigationRef = createNavigationContainerRef();\n\ntype NavigationContainerProps = React.ComponentProps<\n typeof NavigationContainer\n>;\n\nconst NavigationContainerContext = React.createContext<\n [\n Partial<NavigationContainerProps>,\n (props: Partial<NavigationContainerProps>) => void\n ]\n>([{}, function () {}]);\n\nexport function useNavigationContainerContext() {\n const context = React.useContext(NavigationContainerContext);\n if (!context) {\n throw new Error(\n \"useNavigationContainerContext must be used within a NavigationContainerContext\"\n );\n }\n return context;\n}\n\n/** react-navigation `NavigationContainer` with automatic `linking` prop generated from the routes context. */\nexport function ContextNavigationContainer(props: NavigationContainerProps) {\n const [state, setState] = React.useState<Partial<NavigationContainerProps>>(\n {}\n );\n\n const linking = useLinkingConfig();\n console.log(\"linking\", linking);\n\n return (\n <NavigationContainerContext.Provider\n value={[\n {\n ...props,\n linking,\n ...state,\n },\n setState,\n ]}\n >\n <InternalContextNavigationContainer />\n </NavigationContainerContext.Provider>\n );\n}\n\nfunction trimQuery(pathname: string): string {\n const queryIndex = pathname.indexOf(\"?\");\n if (queryIndex !== -1) {\n return pathname.substring(0, queryIndex);\n }\n return pathname;\n}\n\nfunction InternalContextNavigationContainer(props: object) {\n const [contextProps] = useNavigationContainerContext();\n const [state, setState] = React.useState<{\n pathname: string | null;\n query: Record<string, any>;\n }>({ pathname: null, query: {} });\n\n const onStateChange = useCallback(\n (state) => {\n if (state) {\n const currentRoute = findFocusedRoute(state);\n setState({\n pathname: trimQuery(currentRoute?.path ?? \"/\"),\n query: currentRoute?.params ?? {},\n });\n }\n },\n [setState]\n );\n\n return (\n <VirtualRouteContext.Provider value={state}>\n {/* @ts-expect-error: children are required */}\n <NavigationContainer\n {...props}\n {...contextProps}\n ref={navigationRef}\n onReady={() => {\n contextProps.onReady?.();\n SplashModule?.hideAsync();\n const initialState = navigationRef.current?.getRootState();\n onStateChange(initialState);\n }}\n onStateChange={(state) => {\n contextProps.onStateChange?.(state);\n onStateChange(state);\n }}\n />\n </VirtualRouteContext.Provider>\n );\n}\n\nexport function RootContainer({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n}: Omit<\n NavigationContainerProps,\n \"independent\" | \"ref\" | \"children\" | \"linking\"\n>) {\n const [, setProps] = useNavigationContainerContext();\n\n React.useEffect(() => {\n setProps({\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n });\n }, [\n documentTitle,\n fallback,\n onReady,\n initialState,\n onStateChange,\n onUnhandledAction,\n theme,\n ]);\n\n return null;\n}\n\n/** Get the root navigation container ref. */\nRootContainer.getRef = () => {\n return navigationRef;\n};\n"]}
|
package/build/views/Layout.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ import { RouterFactory, useNavigationBuilder } from "@react-navigation/native";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
export declare const LayoutContext: React.Context<{
|
|
4
4
|
contextKey: string;
|
|
5
|
+
/** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
|
|
5
6
|
pathname: string;
|
|
7
|
+
/** Normalized string representing the selected state `/(group)/any/[id]` */
|
|
8
|
+
statePath: string;
|
|
6
9
|
state: any;
|
|
7
10
|
navigation: any;
|
|
8
11
|
descriptors: any;
|
|
@@ -22,7 +25,10 @@ export declare namespace Layout {
|
|
|
22
25
|
}
|
|
23
26
|
export declare function useLayoutContext(): {
|
|
24
27
|
contextKey: string;
|
|
28
|
+
/** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */
|
|
25
29
|
pathname: string;
|
|
30
|
+
/** Normalized string representing the selected state `/(group)/any/[id]` */
|
|
31
|
+
statePath: string;
|
|
26
32
|
state: any;
|
|
27
33
|
navigation: any;
|
|
28
34
|
descriptors: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,eAAO,MAAM,aAAa;gBACZ,MAAM;IAClB,qFAAqF;cAC3E,MAAM;IAChB,4EAA4E;eACjE,MAAM;WACV,GAAG;gBACE,GAAG;iBACF,GAAG;YACR,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;SACvB,CAAC;AAMhB,oBAAY,WAAW,GAAG;IACxB,gBAAgB,CAAC,EAAE,UAAU,CAC3B,OAAO,oBAAoB,CAC5B,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;IACzB,aAAa,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrD,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,MAAM,CAAC,EACrB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,MAAoB,GACrB,EAAE,WAAW,eA+Bb;yBApCe,MAAM;;;;AAwFtB,wBAAgB,gBAAgB;;IAhH9B,qFAAqF;;IAErF,4EAA4E;;;;;;EAoH7E;AAED,wBAAgB,QAAQ,QAcvB;AAED,8CAA8C;AAC9C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,eAc5D;AAED,wBAAgB,eAAe,QAE9B;AAED,wBAAgB,aAAa,gBAM5B"}
|
package/build/views/Layout.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { StackRouter, useNavigationBuilder, } from "@react-navigation/native";
|
|
1
|
+
import { LinkingContext, StackRouter, useNavigationBuilder, } from "@react-navigation/native";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useContextKey } from "../Route";
|
|
4
|
+
import getPathFromState from "../fork/getPathFromState";
|
|
5
|
+
import { resolveHref } from "../link/href";
|
|
6
|
+
import { matchFragmentName } from "../matchers";
|
|
4
7
|
import { useScreens } from "../useScreens";
|
|
5
8
|
// TODO: This might already exist upstream, maybe something like `useCurrentRender` ?
|
|
6
9
|
export const LayoutContext = React.createContext(null);
|
|
@@ -11,14 +14,18 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
11
14
|
export function Layout({ initialRouteName, screenOptions, children, router = StackRouter, }) {
|
|
12
15
|
const contextKey = useContextKey();
|
|
13
16
|
const screens = useScreens();
|
|
17
|
+
const linking = React.useContext(LinkingContext);
|
|
14
18
|
const { state, navigation, descriptors, NavigationContent } = useNavigationBuilder(router, {
|
|
15
19
|
children: screens,
|
|
16
20
|
screenOptions,
|
|
17
21
|
initialRouteName,
|
|
18
22
|
});
|
|
19
|
-
const
|
|
23
|
+
const statePath = linking.options?.getPathFromState
|
|
24
|
+
? linking.options.getPathFromState(state)
|
|
25
|
+
: getPathFromState(state);
|
|
20
26
|
return (React.createElement(LayoutContext.Provider, { value: {
|
|
21
|
-
pathname:
|
|
27
|
+
pathname: pathnameFromStatePath(statePath),
|
|
28
|
+
statePath: getNormalizedStatePath(statePath),
|
|
22
29
|
contextKey,
|
|
23
30
|
state,
|
|
24
31
|
navigation,
|
|
@@ -27,6 +34,48 @@ export function Layout({ initialRouteName, screenOptions, children, router = Sta
|
|
|
27
34
|
} },
|
|
28
35
|
React.createElement(NavigationContent, null, children)));
|
|
29
36
|
}
|
|
37
|
+
function getNormalizedStatePath(statePath) {
|
|
38
|
+
const pathname = "/" +
|
|
39
|
+
(statePath
|
|
40
|
+
.split("/")
|
|
41
|
+
.map((value) => decodeURIComponent(value))
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.join("/") || "");
|
|
44
|
+
return pathname.split("?")[0];
|
|
45
|
+
}
|
|
46
|
+
function pathnameFromStatePath(statePath) {
|
|
47
|
+
const pathname = "/" +
|
|
48
|
+
(statePath
|
|
49
|
+
.split("/")
|
|
50
|
+
.map((value) => {
|
|
51
|
+
const segment = decodeURIComponent(value);
|
|
52
|
+
if (matchFragmentName(segment) != null || segment === "index") {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return segment;
|
|
56
|
+
})
|
|
57
|
+
.filter(Boolean)
|
|
58
|
+
.join("/") || "");
|
|
59
|
+
const components = pathname.split("?");
|
|
60
|
+
return resolveHref({
|
|
61
|
+
pathname: components[0],
|
|
62
|
+
// TODO: This is not efficient, we should generate based on the state instead
|
|
63
|
+
// of converting to string then back to object
|
|
64
|
+
query: parseQueryString(components[1] ?? ""),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function parseQueryString(val) {
|
|
68
|
+
if (!val) {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
const query = {};
|
|
72
|
+
const a = val.split("&");
|
|
73
|
+
for (let i = 0; i < a.length; i++) {
|
|
74
|
+
const b = a[i].split("=");
|
|
75
|
+
query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || "");
|
|
76
|
+
}
|
|
77
|
+
return query;
|
|
78
|
+
}
|
|
30
79
|
export function useLayoutContext() {
|
|
31
80
|
const context = React.useContext(LayoutContext);
|
|
32
81
|
if (!context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../src/views/Layout.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n LinkingContext,\n RouterFactory,\n StackRouter,\n useNavigationBuilder,\n} from \"@react-navigation/native\";\nimport * as React from \"react\";\n\nimport { useContextKey } from \"../Route\";\nimport getPathFromState from \"../fork/getPathFromState\";\nimport { resolveHref } from \"../link/href\";\nimport { matchFragmentName } from \"../matchers\";\nimport { useScreens } from \"../useScreens\";\n\n// TODO: This might already exist upstream, maybe something like `useCurrentRender` ?\nexport const LayoutContext = React.createContext<{\n contextKey: string;\n /** Normalized path representing the selected route `/[id]?id=normal` -> `/normal` */\n pathname: string;\n /** Normalized string representing the selected state `/(group)/any/[id]` */\n statePath: string;\n state: any;\n navigation: any;\n descriptors: any;\n router: RouterFactory<any, any, any>;\n} | null>(null);\n\nif (process.env.NODE_ENV !== \"production\") {\n LayoutContext.displayName = \"LayoutContext\";\n}\n\nexport type LayoutProps = {\n initialRouteName?: Parameters<\n typeof useNavigationBuilder\n >[1][\"initialRouteName\"];\n screenOptions?: Parameters<typeof useNavigationBuilder>[1][\"screenOptions\"];\n children?: Parameters<typeof useNavigationBuilder>[1][\"children\"];\n router?: Parameters<typeof useNavigationBuilder>[0];\n};\n\n/** An unstyled custom navigator. Good for basic web layouts */\nexport function Layout({\n initialRouteName,\n screenOptions,\n children,\n router = StackRouter,\n}: LayoutProps) {\n const contextKey = useContextKey();\n const screens = useScreens();\n const linking = React.useContext(LinkingContext);\n\n const { state, navigation, descriptors, NavigationContent } =\n useNavigationBuilder(router, {\n children: screens,\n screenOptions,\n initialRouteName,\n });\n\n const statePath = linking.options?.getPathFromState\n ? linking.options.getPathFromState(state)\n : getPathFromState(state);\n\n return (\n <LayoutContext.Provider\n value={{\n pathname: pathnameFromStatePath(statePath),\n statePath: getNormalizedStatePath(statePath),\n contextKey,\n state,\n navigation,\n descriptors,\n router,\n }}\n >\n <NavigationContent>{children}</NavigationContent>\n </LayoutContext.Provider>\n );\n}\n\nfunction getNormalizedStatePath(statePath: string) {\n const pathname =\n \"/\" +\n (statePath\n .split(\"/\")\n .map((value) => decodeURIComponent(value))\n .filter(Boolean)\n .join(\"/\") || \"\");\n\n return pathname.split(\"?\")![0];\n}\n\nfunction pathnameFromStatePath(statePath: string) {\n const pathname =\n \"/\" +\n (statePath\n .split(\"/\")\n .map((value) => {\n const segment = decodeURIComponent(value);\n if (matchFragmentName(segment) != null || segment === \"index\") {\n return null;\n }\n return segment;\n })\n .filter(Boolean)\n .join(\"/\") || \"\");\n\n const components = pathname.split(\"?\");\n\n return resolveHref({\n pathname: components[0],\n // TODO: This is not efficient, we should generate based on the state instead\n // of converting to string then back to object\n query: parseQueryString(components[1] ?? \"\"),\n });\n}\n\nfunction parseQueryString(val: string) {\n if (!val) {\n return {};\n }\n const query = {};\n const a = val.split(\"&\");\n for (let i = 0; i < a.length; i++) {\n const b = a[i].split(\"=\");\n query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || \"\");\n }\n return query;\n}\n\nexport function useLayoutContext() {\n const context = React.useContext(LayoutContext);\n if (!context) {\n throw new Error(\"useLayoutContext must be used within a <Layout />\");\n }\n return context;\n}\n\nexport function useChild() {\n const context = useLayoutContext();\n\n const { state, descriptors } = context;\n\n const current = state.routes.find((route, i) => {\n return state.index === i;\n });\n\n if (!current) {\n return null;\n }\n\n return descriptors[current.key]?.render() ?? null;\n}\n\n/** Renders the currently selected content. */\nexport function Children(props: Omit<LayoutProps, \"children\">) {\n const contextKey = useContextKey();\n const context = React.useContext(LayoutContext);\n // Ensure the context is for the current contextKey\n if (context?.contextKey !== contextKey) {\n // Qualify the content and re-export.\n return (\n <Layout {...props}>\n <TrustedChildren />\n </Layout>\n );\n }\n\n return <TrustedChildren />;\n}\n\nexport function TrustedChildren() {\n return useChild();\n}\n\nexport function DefaultLayout() {\n return (\n <Layout>\n <TrustedChildren />\n </Layout>\n );\n}\n\nLayout.Children = Children;\nLayout.useContext = useLayoutContext;\n"]}
|