expo-router 0.0.35 → 0.0.36
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/Route.d.ts +3 -5
- package/build/Route.d.ts.map +1 -1
- package/build/Route.js.map +1 -1
- package/build/getLinkingConfig.d.ts +1 -0
- package/build/getLinkingConfig.d.ts.map +1 -1
- package/build/getLinkingConfig.js +9 -1
- package/build/getLinkingConfig.js.map +1 -1
- package/build/getRoutes.d.ts +1 -1
- package/build/getRoutes.d.ts.map +1 -1
- package/build/getRoutes.js +7 -22
- package/build/getRoutes.js.map +1 -1
- package/build/useScreens.d.ts.map +1 -1
- package/build/useScreens.js +2 -3
- package/build/useScreens.js.map +1 -1
- package/package.json +1 -1
package/build/Route.d.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
2
|
/** The list of input keys will become optional, everything else will remain the same. */
|
|
3
3
|
export declare type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
4
4
|
export declare type RouteNode = {
|
|
5
|
+
/** Load a route into memory. Returns the exports from a route. */
|
|
6
|
+
loadRoute: () => any;
|
|
5
7
|
/** nested routes */
|
|
6
8
|
children: RouteNode[];
|
|
7
|
-
/** Lazily get the React component */
|
|
8
|
-
getComponent: () => React.ComponentType<any>;
|
|
9
9
|
/** Is the route a dynamic path */
|
|
10
10
|
dynamic: null | {
|
|
11
11
|
name: string;
|
|
12
12
|
deep: boolean;
|
|
13
13
|
};
|
|
14
|
-
/** All static exports from the file. */
|
|
15
|
-
getExtras: () => Record<string, any>;
|
|
16
14
|
/** `index`, `error-boundary`, etc. */
|
|
17
15
|
route: string;
|
|
18
16
|
/** require.context key, used for matching children. */
|
package/build/Route.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../src/Route.tsx"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"Route.d.ts","sourceRoot":"","sources":["../src/Route.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,SAAS,EAAc,MAAM,OAAO,CAAC;AAKrD,yFAAyF;AACzF,oBAAY,WAAW,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACxD,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEtB,oBAAY,SAAS,GAAG;IACtB,kEAAkE;IAClE,SAAS,EAAE,MAAM,GAAG,CAAC;IACrB,oBAAoB;IACpB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,kCAAkC;IAClC,OAAO,EAAE,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAChD,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAWF,+DAA+D;AAC/D,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAED,iEAAiE;AACjE,wBAAgB,KAAK,CAAC,EACpB,QAAQ,EACR,IAAI,GACL,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;CACjB,eAkBA;AAED,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,GAAG,MAAM,CA4B7D"}
|
package/build/Route.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Route.js","sourceRoot":"","sources":["../src/Route.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAa,UAAU,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Route.js","sourceRoot":"","sources":["../src/Route.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactNode, useContext } from \"react\";\n\nimport { RootRouteNodeContext } from \"./context\";\nimport { getNameFromFilePath, matchFragmentName } from \"./matchers\";\n\n/** The list of input keys will become optional, everything else will remain the same. */\nexport type PickPartial<T, K extends keyof T> = Omit<T, K> &\n Partial<Pick<T, K>>;\n\nexport type RouteNode = {\n /** Load a route into memory. Returns the exports from a route. */\n loadRoute: () => any;\n /** nested routes */\n children: RouteNode[];\n /** Is the route a dynamic path */\n dynamic: null | { name: string; deep: boolean };\n /** `index`, `error-boundary`, etc. */\n route: string;\n /** require.context key, used for matching children. */\n contextKey: string;\n /** Added in-memory */\n generated?: boolean;\n\n /** Internal screens like the directory or the auto 404 should be marked as internal. */\n internal?: boolean;\n};\n\nconst CurrentRoutePathContext = React.createContext<string | null>(null);\n\nconst CurrentRouteContext = React.createContext<RouteNode | null>(null);\n\nif (process.env.NODE_ENV !== \"production\") {\n CurrentRoutePathContext.displayName = \"RoutePath\";\n CurrentRouteContext.displayName = \"Route\";\n}\n\n/** Return the RouteNode at the current contextual boundary. */\nexport function useRouteNode(): RouteNode | null {\n return useContext(CurrentRouteContext);\n}\n\nexport function useContextKey(): string {\n const filename = useContext(CurrentRoutePathContext);\n if (filename == null) {\n throw new Error(\"No filename found. This is likely a bug in expo-router.\");\n }\n return filename;\n}\n\n/** Provides the matching routes and filename to the children. */\nexport function Route({\n children,\n node,\n}: {\n children: ReactNode;\n node: RouteNode;\n}) {\n const normalName = React.useMemo(() => {\n // The root path is `` (empty string) so always prepend `/` to ensure\n // there is some value.\n const normal = \"/\" + getNameFromFilePath(node.contextKey);\n if (!normal.endsWith(\"_layout\")) {\n return normal;\n }\n return normal.replace(/\\/?_layout$/, \"\");\n }, [node.contextKey]);\n\n return (\n <CurrentRoutePathContext.Provider value={normalName}>\n <CurrentRouteContext.Provider value={node}>\n {children}\n </CurrentRouteContext.Provider>\n </CurrentRoutePathContext.Provider>\n );\n}\n\nexport function useRootRoute(): RouteNode | null {\n return useContext(RootRouteNodeContext);\n}\n\nexport function sortRoutes(a: RouteNode, b: RouteNode): number {\n if (a.dynamic && !b.dynamic) {\n return 1;\n }\n if (!a.dynamic && b.dynamic) {\n return -1;\n }\n if (a.dynamic && b.dynamic) {\n if (a.dynamic.deep && !b.dynamic.deep) {\n return 1;\n }\n if (!a.dynamic.deep && b.dynamic.deep) {\n return -1;\n }\n return 0;\n }\n\n const aIndex = a.route === \"index\" || matchFragmentName(a.route) != null;\n const bIndex = b.route === \"index\" || matchFragmentName(b.route) != null;\n\n if (aIndex && !bIndex) {\n return -1;\n }\n if (!aIndex && bIndex) {\n return 1;\n }\n\n return a.route.length - b.route.length;\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import { RouteNode } from "./Route";
|
|
|
3
3
|
declare type Screen = string | {
|
|
4
4
|
path: string;
|
|
5
5
|
screens: Record<string, Screen>;
|
|
6
|
+
initialRouteName?: string;
|
|
6
7
|
};
|
|
7
8
|
export declare function getReactNavigationScreensConfig(nodes: RouteNode[]): Record<string, Screen>;
|
|
8
9
|
export declare function getLinkingConfig(routes: RouteNode): LinkingOptions<object>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLinkingConfig.d.ts","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAepC,aAAK,MAAM,GACP,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"getLinkingConfig.d.ts","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAepC,aAAK,MAAM,GACP,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAqDN,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,SAAS,EAAE,GACjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAuB1E"}
|
|
@@ -36,7 +36,15 @@ function convertRouteNodeToScreen(node) {
|
|
|
36
36
|
return path;
|
|
37
37
|
}
|
|
38
38
|
const screens = getReactNavigationScreensConfig(node.children);
|
|
39
|
-
return {
|
|
39
|
+
return {
|
|
40
|
+
path,
|
|
41
|
+
screens,
|
|
42
|
+
// NOTE(EvanBacon): This is bad because it forces all Layout Routes
|
|
43
|
+
// to be loaded into memory. We should move towards a system where
|
|
44
|
+
// the initial route name is either loaded asynchronously in the Layout Route
|
|
45
|
+
// or defined via a file system convention.
|
|
46
|
+
initialRouteName: node.loadRoute?.().unstable_settings?.initialRouteName,
|
|
47
|
+
};
|
|
40
48
|
}
|
|
41
49
|
export function getReactNavigationScreensConfig(nodes) {
|
|
42
50
|
return Object.fromEntries(nodes.map((node) => [node.route, convertRouteNodeToScreen(node)]));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getLinkingConfig.js","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"getLinkingConfig.js","sourceRoot":"","sources":["../src/getLinkingConfig.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAUpB,sBAAsB;AACtB,mBAAmB;AACnB,SAAS,oCAAoC,CAAC,IAAY;IACxD,IAAI,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE;QACvD,OAAO,EAAE,CAAC;KACX;IACD,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE;QAC3C,OAAO,GAAG,CAAC;KACZ;IACD,MAAM,WAAW,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAE3C,IAAI,WAAW,IAAI,IAAI,EAAE;QACvB,OAAO,IAAI,WAAW,EAAE,CAAC;KAC1B;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,OAAO;IACL,gEAAgE;IAChE,yDAAyD;IACzD,qEAAqE;IACrE,QAAQ;SACL,KAAK,CAAC,GAAG,CAAC;QACX,qDAAqD;SACpD,GAAG,CAAC,oCAAoC,CAAC;QAC1C,yDAAyD;SACxD,MAAM,CAAC,OAAO,CAAC;QAChB,4BAA4B;SAC3B,IAAI,CAAC,GAAG,CAAC,CACb,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,IAAe;IAC/C,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;QACzB,OAAO,IAAI,CAAC;KACb;IACD,MAAM,OAAO,GAAG,+BAA+B,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/D,OAAO;QACL,IAAI;QACJ,OAAO;QACP,mEAAmE;QACnE,kEAAkE;QAClE,6EAA6E;QAC7E,2CAA2C;QAC3C,gBAAgB,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,iBAAiB,EAAE,gBAAgB;KACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,KAAkB;IAElB,OAAO,MAAM,CAAC,WAAW,CACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,wBAAwB,CAAC,IAAI,CAAC,CAAU,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,OAAO;QACL,QAAQ,EAAE;YACR,2BAA2B;YAC3B,UAAU,EAAE;YAEZ,4FAA4F;YAC5F,0BAA0B;YAC1B,GAAG,kBAAkB,EAAE;SACxB;QACD,MAAM,EAAE;YACN,OAAO,EAAE,+BAA+B,CAAC,MAAM,CAAC,QAAQ,CAAC;SAC1D;QACD,8EAA8E;QAC9E,wEAAwE;QACxE,+EAA+E;QAC/E,8GAA8G;QAC9G,8EAA8E;QAC9E,aAAa;QACb,SAAS,EAAE,gBAAgB;QAC3B,gBAAgB;QAChB,gBAAgB;KACjB,CAAC;AACJ,CAAC","sourcesContent":["import { LinkingOptions } from \"@react-navigation/native\";\n\nimport { RouteNode } from \"./Route\";\nimport { getAllWebRedirects } from \"./aasa\";\nimport {\n addEventListener,\n getInitialURL,\n getRootURL,\n getPathFromState,\n getStateFromPath,\n} from \"./link/linking\";\nimport {\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchFragmentName,\n} from \"./matchers\";\n\ntype Screen =\n | string\n | {\n path: string;\n screens: Record<string, Screen>;\n initialRouteName?: string;\n };\n\n// `[page]` -> `:page`\n// `page` -> `page`\nfunction convertDynamicRouteToReactNavigation(name: string) {\n if (name === \"index\" || matchFragmentName(name) != null) {\n return \"\";\n }\n if (matchDeepDynamicRouteName(name) != null) {\n return \"*\";\n }\n const dynamicName = matchDynamicName(name);\n\n if (dynamicName != null) {\n return `:${dynamicName}`;\n }\n\n return name;\n}\n\nfunction parseRouteSegments(segments: string): string {\n return (\n // NOTE(EvanBacon): When there are nested routes without layouts\n // the node.route will be something like `app/home/index`\n // this needs to be split to ensure each segment is parsed correctly.\n segments\n .split(\"/\")\n // Convert each segment to a React Navigation format.\n .map(convertDynamicRouteToReactNavigation)\n // Remove any empty paths from fragments or index routes.\n .filter(Boolean)\n // Join to return as a path.\n .join(\"/\")\n );\n}\n\nfunction convertRouteNodeToScreen(node: RouteNode): Screen {\n const path = parseRouteSegments(node.route);\n if (!node.children.length) {\n return path;\n }\n const screens = getReactNavigationScreensConfig(node.children);\n return {\n path,\n screens,\n // NOTE(EvanBacon): This is bad because it forces all Layout Routes\n // to be loaded into memory. We should move towards a system where\n // the initial route name is either loaded asynchronously in the Layout Route\n // or defined via a file system convention.\n initialRouteName: node.loadRoute?.().unstable_settings?.initialRouteName,\n };\n}\n\nexport function getReactNavigationScreensConfig(\n nodes: RouteNode[]\n): Record<string, Screen> {\n return Object.fromEntries(\n nodes.map((node) => [node.route, convertRouteNodeToScreen(node)] as const)\n );\n}\n\nexport function getLinkingConfig(routes: RouteNode): LinkingOptions<object> {\n return {\n prefixes: [\n /* your linking prefixes */\n getRootURL(),\n\n // This ensures that we can redirect correctly when the user comes from an associated domain\n // i.e. iOS Safari banner.\n ...getAllWebRedirects(),\n ],\n config: {\n screens: getReactNavigationScreensConfig(routes.children),\n },\n // A custom getInitialURL is used on native to ensure the app always starts at\n // the root path if it's launched from something other than a deep link.\n // This helps keep the native functionality working like the web functionality.\n // For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`\n // then `/index` would be used on web and `/settings` would be used on native.\n getInitialURL,\n subscribe: addEventListener,\n getStateFromPath,\n getPathFromState,\n };\n}\n"]}
|
package/build/getRoutes.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RouteNode } from "./Route";
|
|
2
2
|
import { RequireContext } from "./types";
|
|
3
|
-
export declare type FileNode = Pick<RouteNode, "contextKey" | "
|
|
3
|
+
export declare type FileNode = Pick<RouteNode, "contextKey" | "loadRoute"> & {
|
|
4
4
|
/** Like `(tab)/index` */
|
|
5
5
|
normalizedName: string;
|
|
6
6
|
};
|
package/build/getRoutes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRoutes.d.ts","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAOpC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,oBAAY,QAAQ,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"getRoutes.d.ts","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAOpC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,oBAAY,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IACnE,yBAAyB;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,aAAK,QAAQ,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8CAA8C;IAC9C,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,CA+C5D;AAsBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM;;;SAK3C;AAsGD,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,aAAa,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAezE;AA4CD;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,SAAS,GAChB,SAAS,GAAG,IAAI,CAgBlB"}
|
package/build/getRoutes.js
CHANGED
|
@@ -67,9 +67,8 @@ function treeNodeToRouteNode({ name, node, children, }) {
|
|
|
67
67
|
if (node) {
|
|
68
68
|
return [
|
|
69
69
|
{
|
|
70
|
+
loadRoute: node.loadRoute,
|
|
70
71
|
route: name,
|
|
71
|
-
getExtras: node.getExtras,
|
|
72
|
-
getComponent: node.getComponent,
|
|
73
72
|
contextKey: node.contextKey,
|
|
74
73
|
children: getTreeNodesAsRouteNodes(children),
|
|
75
74
|
dynamic,
|
|
@@ -104,15 +103,9 @@ function contextModuleToFileNodes(contextModule) {
|
|
|
104
103
|
return null;
|
|
105
104
|
}
|
|
106
105
|
const node = {
|
|
106
|
+
loadRoute: () => contextModule(key),
|
|
107
107
|
normalizedName: getNameFromFilePath(key),
|
|
108
|
-
getComponent() {
|
|
109
|
-
return contextModule(key).default;
|
|
110
|
-
},
|
|
111
108
|
contextKey: key,
|
|
112
|
-
getExtras() {
|
|
113
|
-
const { default: mod, ...extras } = contextModule(key);
|
|
114
|
-
return extras;
|
|
115
|
-
},
|
|
116
109
|
};
|
|
117
110
|
return node;
|
|
118
111
|
});
|
|
@@ -139,13 +132,12 @@ function treeNodesToRootRoute(treeNode) {
|
|
|
139
132
|
return routes[0];
|
|
140
133
|
}
|
|
141
134
|
return {
|
|
135
|
+
loadRoute: () => ({ default: DefaultLayout }),
|
|
142
136
|
// Generate a fake file name for the directory
|
|
143
137
|
contextKey: "./_layout.tsx",
|
|
144
138
|
route: "",
|
|
145
139
|
generated: true,
|
|
146
140
|
dynamic: null,
|
|
147
|
-
getExtras: () => ({}),
|
|
148
|
-
getComponent: () => DefaultLayout,
|
|
149
141
|
children: routes,
|
|
150
142
|
};
|
|
151
143
|
}
|
|
@@ -154,7 +146,6 @@ export function getRoutes(contextModule) {
|
|
|
154
146
|
const files = contextModuleToFileNodes(contextModule);
|
|
155
147
|
const treeNodes = getRecursiveTree(files);
|
|
156
148
|
const route = treeNodesToRootRoute(treeNodes);
|
|
157
|
-
console.log("route", route);
|
|
158
149
|
if (!route) {
|
|
159
150
|
return null;
|
|
160
151
|
}
|
|
@@ -171,11 +162,8 @@ function appendSitemapRoute(routes) {
|
|
|
171
162
|
}
|
|
172
163
|
const { Sitemap, getNavOptions } = require("./views/Sitemap");
|
|
173
164
|
routes.children.push({
|
|
174
|
-
|
|
175
|
-
return Sitemap;
|
|
176
|
-
},
|
|
177
|
-
getExtras() {
|
|
178
|
-
return { getNavOptions };
|
|
165
|
+
loadRoute() {
|
|
166
|
+
return { default: Sitemap, getNavOptions };
|
|
179
167
|
},
|
|
180
168
|
route: "_sitemap",
|
|
181
169
|
contextKey: "./_sitemap.tsx",
|
|
@@ -191,11 +179,8 @@ function appendUnmatchedRoute(routes) {
|
|
|
191
179
|
const userDefinedDynamicRoute = getUserDefinedDeepDynamicRoute(routes);
|
|
192
180
|
if (!userDefinedDynamicRoute) {
|
|
193
181
|
routes.children.push({
|
|
194
|
-
|
|
195
|
-
return require("./views/Unmatched").Unmatched;
|
|
196
|
-
},
|
|
197
|
-
getExtras() {
|
|
198
|
-
return {};
|
|
182
|
+
loadRoute() {
|
|
183
|
+
return { default: require("./views/Unmatched").Unmatched };
|
|
199
184
|
},
|
|
200
185
|
route: "[...404]",
|
|
201
186
|
contextKey: "./[...404].tsx",
|
package/build/getRoutes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getRoutes.js","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { RouteNode } from \"./Route\";\nimport {\n getNameFromFilePath,\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchFragmentName,\n} from \"./matchers\";\nimport { RequireContext } from \"./types\";\nimport { DefaultLayout } from \"./views/Layout\";\n\nexport type FileNode = Pick<\n RouteNode,\n \"contextKey\" | \"getComponent\" | \"getExtras\"\n> & {\n /** Like `(tab)/index` */\n normalizedName: string;\n};\n\ntype TreeNode = {\n name: string;\n children: TreeNode[];\n parents: string[];\n /** null when there is no file in a folder. */\n node: FileNode | null;\n};\n\n/** Convert a flat map of file nodes into a nested tree of files. */\nexport function getRecursiveTree(files: FileNode[]): TreeNode {\n const tree = {\n name: \"\",\n children: [],\n parents: [],\n node: null,\n };\n\n for (const file of files) {\n // ['(tab)', 'settings', '[...another]']\n const parts = file.normalizedName.split(\"/\");\n let currentNode: TreeNode = tree;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n\n if (i === parts.length - 1 && part === \"_layout\") {\n if (currentNode.node) {\n const overwritten = currentNode.node.contextKey;\n throw new Error(\n `Higher priority Layout Route \"${file.contextKey}\" overriding redundant Layout Route \"${overwritten}\". Remove the Layout Route \"${overwritten}\" to fix this.`\n );\n }\n continue;\n }\n\n const existing = currentNode.children.find((item) => item.name === part);\n if (existing) {\n currentNode = existing;\n } else {\n const newNode: TreeNode = {\n name: part,\n children: [],\n parents: [...currentNode.parents, currentNode.name],\n node: null,\n };\n currentNode.children.push(newNode);\n currentNode = newNode;\n }\n }\n currentNode.node = file;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n assertDeprecatedFormat(tree);\n }\n\n return tree;\n}\n\nfunction assertDeprecatedFormat(tree: TreeNode) {\n for (const child of tree.children) {\n if (\n child.node &&\n child.children.length &&\n !child.node.normalizedName.endsWith(\"_layout\")\n ) {\n const ext = child.node.contextKey.split(\".\").pop();\n throw new Error(\n `Using deprecated Layout Route format: Move \\`./app/${child.node.normalizedName}.${ext}\\` to \\`./app/${child.node.normalizedName}/_layout.${ext}\\``\n );\n }\n assertDeprecatedFormat(child);\n }\n}\n\nfunction getTreeNodesAsRouteNodes(nodes: TreeNode[]): RouteNode[] {\n return nodes.map(treeNodeToRouteNode).flat().filter(Boolean) as RouteNode[];\n}\n\nexport function generateDynamic(name: string) {\n const deepDynamicName = matchDeepDynamicRouteName(name);\n const dynamicName = deepDynamicName ?? matchDynamicName(name);\n\n return dynamicName ? { name: dynamicName, deep: !!deepDynamicName } : null;\n}\n\nfunction treeNodeToRouteNode({\n name,\n node,\n children,\n}: TreeNode): RouteNode[] | null {\n const dynamic = generateDynamic(name);\n\n if (node) {\n return [\n {\n route: name,\n getExtras: node.getExtras,\n getComponent: node.getComponent,\n contextKey: node.contextKey,\n children: getTreeNodesAsRouteNodes(children),\n dynamic,\n },\n ];\n }\n\n // Empty folder, skip it.\n if (!children.length) {\n return null;\n }\n\n // When there's a directory, but no layout route file (with valid export), the child routes won't be grouped.\n // This pushes all children into the nearest layout route.\n return getTreeNodesAsRouteNodes(\n children.map((child) => {\n return {\n ...child,\n name: [name, child.name].filter(Boolean).join(\"/\"),\n };\n })\n );\n}\n\nfunction contextModuleToFileNodes(contextModule: RequireContext): FileNode[] {\n const nodes = contextModule.keys().map((key) => {\n // In development, check if the file exports a default component\n // this helps keep things snappy when creating files. In production we load all screens lazily.\n try {\n if (!contextModule(key)?.default) {\n return null;\n }\n } catch (error) {\n // Probably this won't stop metro from freaking out but it's worth a try.\n console.warn('Error loading route \"' + key + '\"', error);\n return null;\n }\n\n const node: FileNode = {\n normalizedName: getNameFromFilePath(key),\n getComponent() {\n return contextModule(key).default;\n },\n contextKey: key,\n getExtras() {\n const { default: mod, ...extras } = contextModule(key);\n return extras;\n },\n };\n\n return node;\n });\n\n return nodes.filter(Boolean) as FileNode[];\n}\n\nfunction hasCustomRootLayoutNode(routes: RouteNode[]) {\n if (routes.length !== 1) {\n return false;\n }\n // This could either be the root _layout or an app with a single file.\n const route = routes[0];\n\n if (\n route.route === \"\" &&\n route.contextKey.match(/^\\.\\/_layout\\.([jt]sx?)$/)\n ) {\n return true;\n }\n return false;\n}\n\nfunction treeNodesToRootRoute(treeNode: TreeNode): RouteNode | null {\n const routes = treeNodeToRouteNode(treeNode);\n\n if (!routes?.length) {\n return null;\n }\n\n if (hasCustomRootLayoutNode(routes)) {\n return routes[0];\n }\n\n return {\n // Generate a fake file name for the directory\n contextKey: \"./_layout.tsx\",\n route: \"\",\n generated: true,\n dynamic: null,\n getExtras: () => ({}),\n getComponent: () => DefaultLayout,\n children: routes,\n };\n}\n\n/** Given a Metro context module, return an array of nested routes. */\nexport function getRoutes(contextModule: RequireContext): RouteNode | null {\n const files = contextModuleToFileNodes(contextModule);\n const treeNodes = getRecursiveTree(files);\n const route = treeNodesToRootRoute(treeNodes);\n\n console.log(\"route\", route);\n if (!route) {\n return null;\n }\n\n appendSitemapRoute(route);\n\n // Auto add not found route if it doesn't exist\n appendUnmatchedRoute(route);\n\n return route;\n}\n\nfunction appendSitemapRoute(routes: RouteNode) {\n if (\n !routes.children.length ||\n // Allow overriding the sitemap route\n routes.children.some((route) => route.route === \"_sitemap\")\n ) {\n return routes;\n }\n const { Sitemap, getNavOptions } = require(\"./views/Sitemap\");\n routes.children.push({\n getComponent() {\n return Sitemap;\n },\n getExtras() {\n return { getNavOptions };\n },\n route: \"_sitemap\",\n contextKey: \"./_sitemap.tsx\",\n generated: true,\n internal: true,\n dynamic: null,\n children: [],\n });\n return routes;\n}\n\nfunction appendUnmatchedRoute(routes: RouteNode) {\n // Auto add not found route if it doesn't exist\n const userDefinedDynamicRoute = getUserDefinedDeepDynamicRoute(routes);\n if (!userDefinedDynamicRoute) {\n routes.children.push({\n getComponent() {\n return require(\"./views/Unmatched\").Unmatched;\n },\n getExtras() {\n return {};\n },\n route: \"[...404]\",\n contextKey: \"./[...404].tsx\",\n dynamic: { name: \"404\", deep: true },\n children: [],\n generated: true,\n internal: true,\n });\n }\n return routes;\n}\n\n/**\n * Exposed for testing.\n * @returns a top-level deep dynamic route if it exists, otherwise null.\n */\nexport function getUserDefinedDeepDynamicRoute(\n routes: RouteNode\n): RouteNode | null {\n // Auto add not found route if it doesn't exist\n for (const route of routes.children ?? []) {\n const isDeepDynamic = matchDeepDynamicRouteName(route.route);\n if (isDeepDynamic) {\n return route;\n }\n // Recurse through fragment routes\n if (matchFragmentName(route.route)) {\n const child = getUserDefinedDeepDynamicRoute(route);\n if (child) {\n return child;\n }\n }\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"getRoutes.js","sourceRoot":"","sources":["../src/getRoutes.ts"],"names":[],"mappings":"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","sourcesContent":["import { RouteNode } from \"./Route\";\nimport {\n getNameFromFilePath,\n matchDeepDynamicRouteName,\n matchDynamicName,\n matchFragmentName,\n} from \"./matchers\";\nimport { RequireContext } from \"./types\";\nimport { DefaultLayout } from \"./views/Layout\";\n\nexport type FileNode = Pick<RouteNode, \"contextKey\" | \"loadRoute\"> & {\n /** Like `(tab)/index` */\n normalizedName: string;\n};\n\ntype TreeNode = {\n name: string;\n children: TreeNode[];\n parents: string[];\n /** null when there is no file in a folder. */\n node: FileNode | null;\n};\n\n/** Convert a flat map of file nodes into a nested tree of files. */\nexport function getRecursiveTree(files: FileNode[]): TreeNode {\n const tree = {\n name: \"\",\n children: [],\n parents: [],\n node: null,\n };\n\n for (const file of files) {\n // ['(tab)', 'settings', '[...another]']\n const parts = file.normalizedName.split(\"/\");\n let currentNode: TreeNode = tree;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n\n if (i === parts.length - 1 && part === \"_layout\") {\n if (currentNode.node) {\n const overwritten = currentNode.node.contextKey;\n throw new Error(\n `Higher priority Layout Route \"${file.contextKey}\" overriding redundant Layout Route \"${overwritten}\". Remove the Layout Route \"${overwritten}\" to fix this.`\n );\n }\n continue;\n }\n\n const existing = currentNode.children.find((item) => item.name === part);\n if (existing) {\n currentNode = existing;\n } else {\n const newNode: TreeNode = {\n name: part,\n children: [],\n parents: [...currentNode.parents, currentNode.name],\n node: null,\n };\n currentNode.children.push(newNode);\n currentNode = newNode;\n }\n }\n currentNode.node = file;\n }\n\n if (process.env.NODE_ENV !== \"production\") {\n assertDeprecatedFormat(tree);\n }\n\n return tree;\n}\n\nfunction assertDeprecatedFormat(tree: TreeNode) {\n for (const child of tree.children) {\n if (\n child.node &&\n child.children.length &&\n !child.node.normalizedName.endsWith(\"_layout\")\n ) {\n const ext = child.node.contextKey.split(\".\").pop();\n throw new Error(\n `Using deprecated Layout Route format: Move \\`./app/${child.node.normalizedName}.${ext}\\` to \\`./app/${child.node.normalizedName}/_layout.${ext}\\``\n );\n }\n assertDeprecatedFormat(child);\n }\n}\n\nfunction getTreeNodesAsRouteNodes(nodes: TreeNode[]): RouteNode[] {\n return nodes.map(treeNodeToRouteNode).flat().filter(Boolean) as RouteNode[];\n}\n\nexport function generateDynamic(name: string) {\n const deepDynamicName = matchDeepDynamicRouteName(name);\n const dynamicName = deepDynamicName ?? matchDynamicName(name);\n\n return dynamicName ? { name: dynamicName, deep: !!deepDynamicName } : null;\n}\n\nfunction treeNodeToRouteNode({\n name,\n node,\n children,\n}: TreeNode): RouteNode[] | null {\n const dynamic = generateDynamic(name);\n\n if (node) {\n return [\n {\n loadRoute: node.loadRoute,\n route: name,\n contextKey: node.contextKey,\n children: getTreeNodesAsRouteNodes(children),\n dynamic,\n },\n ];\n }\n\n // Empty folder, skip it.\n if (!children.length) {\n return null;\n }\n\n // When there's a directory, but no layout route file (with valid export), the child routes won't be grouped.\n // This pushes all children into the nearest layout route.\n return getTreeNodesAsRouteNodes(\n children.map((child) => {\n return {\n ...child,\n name: [name, child.name].filter(Boolean).join(\"/\"),\n };\n })\n );\n}\n\nfunction contextModuleToFileNodes(contextModule: RequireContext): FileNode[] {\n const nodes = contextModule.keys().map((key) => {\n // In development, check if the file exports a default component\n // this helps keep things snappy when creating files. In production we load all screens lazily.\n try {\n if (!contextModule(key)?.default) {\n return null;\n }\n } catch (error) {\n // Probably this won't stop metro from freaking out but it's worth a try.\n console.warn('Error loading route \"' + key + '\"', error);\n return null;\n }\n\n const node: FileNode = {\n loadRoute: () => contextModule(key),\n normalizedName: getNameFromFilePath(key),\n contextKey: key,\n };\n\n return node;\n });\n\n return nodes.filter(Boolean) as FileNode[];\n}\n\nfunction hasCustomRootLayoutNode(routes: RouteNode[]) {\n if (routes.length !== 1) {\n return false;\n }\n // This could either be the root _layout or an app with a single file.\n const route = routes[0];\n\n if (\n route.route === \"\" &&\n route.contextKey.match(/^\\.\\/_layout\\.([jt]sx?)$/)\n ) {\n return true;\n }\n return false;\n}\n\nfunction treeNodesToRootRoute(treeNode: TreeNode): RouteNode | null {\n const routes = treeNodeToRouteNode(treeNode);\n\n if (!routes?.length) {\n return null;\n }\n\n if (hasCustomRootLayoutNode(routes)) {\n return routes[0];\n }\n\n return {\n loadRoute: () => ({ default: DefaultLayout }),\n // Generate a fake file name for the directory\n contextKey: \"./_layout.tsx\",\n route: \"\",\n generated: true,\n dynamic: null,\n children: routes,\n };\n}\n\n/** Given a Metro context module, return an array of nested routes. */\nexport function getRoutes(contextModule: RequireContext): RouteNode | null {\n const files = contextModuleToFileNodes(contextModule);\n const treeNodes = getRecursiveTree(files);\n const route = treeNodesToRootRoute(treeNodes);\n\n if (!route) {\n return null;\n }\n\n appendSitemapRoute(route);\n\n // Auto add not found route if it doesn't exist\n appendUnmatchedRoute(route);\n\n return route;\n}\n\nfunction appendSitemapRoute(routes: RouteNode) {\n if (\n !routes.children.length ||\n // Allow overriding the sitemap route\n routes.children.some((route) => route.route === \"_sitemap\")\n ) {\n return routes;\n }\n const { Sitemap, getNavOptions } = require(\"./views/Sitemap\");\n routes.children.push({\n loadRoute() {\n return { default: Sitemap, getNavOptions };\n },\n route: \"_sitemap\",\n contextKey: \"./_sitemap.tsx\",\n generated: true,\n internal: true,\n dynamic: null,\n children: [],\n });\n return routes;\n}\n\nfunction appendUnmatchedRoute(routes: RouteNode) {\n // Auto add not found route if it doesn't exist\n const userDefinedDynamicRoute = getUserDefinedDeepDynamicRoute(routes);\n if (!userDefinedDynamicRoute) {\n routes.children.push({\n loadRoute() {\n return { default: require(\"./views/Unmatched\").Unmatched };\n },\n route: \"[...404]\",\n contextKey: \"./[...404].tsx\",\n dynamic: { name: \"404\", deep: true },\n children: [],\n generated: true,\n internal: true,\n });\n }\n return routes;\n}\n\n/**\n * Exposed for testing.\n * @returns a top-level deep dynamic route if it exists, otherwise null.\n */\nexport function getUserDefinedDeepDynamicRoute(\n routes: RouteNode\n): RouteNode | null {\n // Auto add not found route if it doesn't exist\n for (const route of routes.children ?? []) {\n const isDeepDynamic = matchDeepDynamicRouteName(route.route);\n if (isDeepDynamic) {\n return route;\n }\n // Recurse through fragment routes\n if (matchFragmentName(route.route)) {\n const child = getUserDefinedDeepDynamicRoute(route);\n if (child) {\n return child;\n }\n }\n }\n return null;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAS,SAAS,EAA4B,MAAM,SAAS,CAAC;AAIrE,oBAAY,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC;AAyDF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AAMD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAS,SAAS,EAA4B,MAAM,SAAS,CAAC;AAIrE,oBAAY,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;CACpB,CAAC;AAyDF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AAMD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS;WAQtC,GAAG;gBAAc,GAAG;kCAsBxC;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;;uBAuB5C"}
|
package/build/useScreens.js
CHANGED
|
@@ -55,8 +55,7 @@ export function getQualifiedRouteComponent(value) {
|
|
|
55
55
|
if (qualifiedStore.has(value)) {
|
|
56
56
|
return qualifiedStore.get(value);
|
|
57
57
|
}
|
|
58
|
-
const Component = value.
|
|
59
|
-
const { ErrorBoundary } = value.getExtras();
|
|
58
|
+
const { default: Component, ErrorBoundary } = value.loadRoute();
|
|
60
59
|
const QualifiedRoute = React.forwardRef((props, ref) => {
|
|
61
60
|
// Surface dynamic name as props to the view
|
|
62
61
|
const children = React.createElement(Component, {
|
|
@@ -100,7 +99,7 @@ function routeToScreen(route, { options, ...props } = {}) {
|
|
|
100
99
|
getId: createGetIdForRoute(route), ...props, name: route.route, key: route.route, options: (args) => {
|
|
101
100
|
// Only eager load generated components
|
|
102
101
|
const staticOptions = route.generated
|
|
103
|
-
? route.
|
|
102
|
+
? route.loadRoute()?.getNavOptions
|
|
104
103
|
: null;
|
|
105
104
|
const staticResult = typeof staticOptions === "function"
|
|
106
105
|
? staticOptions(args)
|
package/build/useScreens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreens.js","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from \"react\";\n\nimport { Route, RouteNode, sortRoutes, useRouteNode } from \"./Route\";\nimport { Screen } from \"./primitives\";\nimport { Try } from \"./views/Try\";\n\nexport type ScreenProps<\n TOptions extends Record<string, any> = Record<string, any>\n> = {\n /** Name is required when used inside a Layout component. */\n name?: string;\n /**\n * Redirect to the nearest or provided sibling route.\n * If all children are redirect={true}, the layout will render `null` as there are no children to render.\n */\n redirect?: boolean | string;\n initialParams?: { [key: string]: any };\n options?: TOptions;\n};\n\nfunction getSortedChildren(\n children: RouteNode[],\n order?: ScreenProps[]\n): { route: RouteNode; props: any }[] {\n if (!order?.length) {\n return children.sort(sortRoutes).map((route) => ({ route, props: {} }));\n }\n const entries = [...children];\n\n const ordered = order\n .map(({ name, redirect, initialParams, options }) => {\n if (!entries.length) {\n console.warn(\n `[Layout children]: Too many screens defined. Route \"${name}\" is extraneous.`\n );\n return null;\n }\n const matchIndex = entries.findIndex((child) => child.route === name);\n if (matchIndex === -1) {\n console.warn(\n `[Layout children]: No route named \"${name}\" exists in nested children:`,\n children.map(({ route }) => route)\n );\n return null;\n } else {\n // Get match and remove from entries\n const match = entries[matchIndex];\n entries.splice(matchIndex, 1);\n\n // Ensure to return null after removing from entries.\n if (redirect) {\n if (typeof redirect === \"string\") {\n throw new Error(\n `Redirecting to a specific route is not supported yet.`\n );\n }\n return null;\n }\n\n return { route: match, props: { initialParams, options } };\n }\n })\n .filter(Boolean) as {\n route: RouteNode;\n props: Partial<ScreenProps>;\n }[];\n\n // Add any remaining children\n ordered.push(\n ...entries.sort(sortRoutes).map((route) => ({ route, props: {} }))\n );\n\n return ordered;\n}\n\n/**\n * @returns React Navigation screens sorted by the `route` property.\n */\nexport function useSortedScreens(order: ScreenProps[]): React.ReactNode[] {\n const node = useRouteNode();\n\n const sorted = node?.children?.length\n ? getSortedChildren(node.children, order)\n : [];\n return React.useMemo(\n () => sorted.map((value) => routeToScreen(value.route, value.props)),\n [sorted]\n );\n}\n\n// TODO: Maybe there's a more React-y way to do this?\n// Without this store, the process enters a recursive loop.\nconst qualifiedStore = new WeakMap<RouteNode, React.ComponentType<any>>();\n\n/** Wrap the component with various enhancements and add access to child routes. */\nexport function getQualifiedRouteComponent(value: RouteNode) {\n if (qualifiedStore.has(value)) {\n return qualifiedStore.get(value)!;\n }\n\n const Component = value.getComponent();\n\n const { ErrorBoundary } = value.getExtras();\n\n const QualifiedRoute = React.forwardRef(\n (props: { route: any; navigation: any }, ref: any) => {\n // Surface dynamic name as props to the view\n const children = React.createElement(Component, {\n ...props,\n ref,\n });\n\n const errorBoundary = ErrorBoundary ? (\n <Try catch={ErrorBoundary}>{children}</Try>\n ) : (\n children\n );\n\n return <Route node={value}>{errorBoundary}</Route>;\n }\n );\n\n QualifiedRoute.displayName = `Route(${\n Component.displayName || Component.name || value.route\n })`;\n qualifiedStore.set(value, QualifiedRoute);\n return QualifiedRoute;\n}\n\n/** @returns a function which provides a screen id that matches the dynamic route name in params. */\nexport function createGetIdForRoute(\n route: Pick<RouteNode, \"dynamic\" | \"route\">\n) {\n if (!route.dynamic) {\n return undefined;\n }\n const dynamicName = route.dynamic.name;\n const routeName = route.route;\n return ({ params }) => {\n // Params can be undefined when there are no params in the route.\n const preferredId = params?.[dynamicName];\n // If the route has a dynamic segment, use the matching parameter\n // as the screen id. This enables pushing a screen like `/[user]` multiple times\n // when the user is different.\n if (preferredId) {\n // Deep dynamic routes will return as an array, so we'll join them to create a\n // fully qualified string.\n return (\n (Array.isArray(preferredId) ? preferredId.join(\"/\") : preferredId) ||\n routeName\n );\n }\n return routeName;\n };\n}\n\nfunction routeToScreen(\n route: RouteNode,\n { options, ...props }: Partial<ScreenProps> = {}\n) {\n return (\n <Screen\n // Users can override the screen getId function.\n getId={createGetIdForRoute(route)}\n {...props}\n name={route.route}\n key={route.route}\n options={(args) => {\n // Only eager load generated components\n const staticOptions = route.generated\n ? route.getExtras()?.getNavOptions\n : null;\n const staticResult =\n typeof staticOptions === \"function\"\n ? staticOptions(args)\n : staticOptions;\n const dynamicResult =\n typeof options === \"function\" ? options?.(args) : options;\n return {\n ...staticResult,\n ...dynamicResult,\n };\n }}\n getComponent={() => getQualifiedRouteComponent(route)}\n />\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"useScreens.js","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,KAAK,EAAa,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAgBlC,SAAS,iBAAiB,CACxB,QAAqB,EACrB,KAAqB;IAErB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;QAClB,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;KACzE;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAE9B,MAAM,OAAO,GAAG,KAAK;SAClB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,EAAE;QAClD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACnB,OAAO,CAAC,IAAI,CACV,uDAAuD,IAAI,kBAAkB,CAC9E,CAAC;YACF,OAAO,IAAI,CAAC;SACb;QACD,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;QACtE,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE;YACrB,OAAO,CAAC,IAAI,CACV,sCAAsC,IAAI,8BAA8B,EACxE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,CACnC,CAAC;YACF,OAAO,IAAI,CAAC;SACb;aAAM;YACL,oCAAoC;YACpC,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YAClC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAE9B,qDAAqD;YACrD,IAAI,QAAQ,EAAE;gBACZ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE;oBAChC,MAAM,IAAI,KAAK,CACb,uDAAuD,CACxD,CAAC;iBACH;gBACD,OAAO,IAAI,CAAC;aACb;YAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC;SAC5D;IACH,CAAC,CAAC;SACD,MAAM,CAAC,OAAO,CAGd,CAAC;IAEJ,6BAA6B;IAC7B,OAAO,CAAC,IAAI,CACV,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CACnE,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACnD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM;QACnC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC;QACzC,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,KAAK,CAAC,OAAO,CAClB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EACpE,CAAC,MAAM,CAAC,CACT,CAAC;AACJ,CAAC;AAED,qDAAqD;AACrD,2DAA2D;AAC3D,MAAM,cAAc,GAAG,IAAI,OAAO,EAAuC,CAAC;AAE1E,mFAAmF;AACnF,MAAM,UAAU,0BAA0B,CAAC,KAAgB;IACzD,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC7B,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;KACnC;IAED,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;IAEhE,MAAM,cAAc,GAAG,KAAK,CAAC,UAAU,CACrC,CAAC,KAAsC,EAAE,GAAQ,EAAE,EAAE;QACnD,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE;YAC9C,GAAG,KAAK;YACR,GAAG;SACJ,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC,CACpC,oBAAC,GAAG,IAAC,KAAK,EAAE,aAAa,IAAG,QAAQ,CAAO,CAC5C,CAAC,CAAC,CAAC,CACF,QAAQ,CACT,CAAC;QAEF,OAAO,oBAAC,KAAK,IAAC,IAAI,EAAE,KAAK,IAAG,aAAa,CAAS,CAAC;IACrD,CAAC,CACF,CAAC;IAEF,cAAc,CAAC,WAAW,GAAG,SAC3B,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,IAAI,KAAK,CAAC,KACnD,GAAG,CAAC;IACJ,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC1C,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,mBAAmB,CACjC,KAA2C;IAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE;QAClB,OAAO,SAAS,CAAC;KAClB;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IACvC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;QACpB,iEAAiE;QACjE,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC;QAC1C,iEAAiE;QACjE,gFAAgF;QAChF,8BAA8B;QAC9B,IAAI,WAAW,EAAE;YACf,8EAA8E;YAC9E,0BAA0B;YAC1B,OAAO,CACL,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;gBAClE,SAAS,CACV,CAAC;SACH;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,KAAgB,EAChB,EAAE,OAAO,EAAE,GAAG,KAAK,KAA2B,EAAE;IAEhD,OAAO,CACL,oBAAC,MAAM;IACL,gDAAgD;;QAAhD,gDAAgD;QAChD,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,KAC7B,KAAK,EACT,IAAI,EAAE,KAAK,CAAC,KAAK,EACjB,GAAG,EAAE,KAAK,CAAC,KAAK,EAChB,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAChB,uCAAuC;YACvC,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS;gBACnC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,aAAa;gBAClC,CAAC,CAAC,IAAI,CAAC;YACT,MAAM,YAAY,GAChB,OAAO,aAAa,KAAK,UAAU;gBACjC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC;gBACrB,CAAC,CAAC,aAAa,CAAC;YACpB,MAAM,aAAa,GACjB,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC5D,OAAO;gBACL,GAAG,YAAY;gBACf,GAAG,aAAa;aACjB,CAAC;QACJ,CAAC,EACD,YAAY,EAAE,GAAG,EAAE,CAAC,0BAA0B,CAAC,KAAK,CAAC,GACrD,CACH,CAAC;AACJ,CAAC","sourcesContent":["import React from \"react\";\n\nimport { Route, RouteNode, sortRoutes, useRouteNode } from \"./Route\";\nimport { Screen } from \"./primitives\";\nimport { Try } from \"./views/Try\";\n\nexport type ScreenProps<\n TOptions extends Record<string, any> = Record<string, any>\n> = {\n /** Name is required when used inside a Layout component. */\n name?: string;\n /**\n * Redirect to the nearest or provided sibling route.\n * If all children are redirect={true}, the layout will render `null` as there are no children to render.\n */\n redirect?: boolean | string;\n initialParams?: { [key: string]: any };\n options?: TOptions;\n};\n\nfunction getSortedChildren(\n children: RouteNode[],\n order?: ScreenProps[]\n): { route: RouteNode; props: any }[] {\n if (!order?.length) {\n return children.sort(sortRoutes).map((route) => ({ route, props: {} }));\n }\n const entries = [...children];\n\n const ordered = order\n .map(({ name, redirect, initialParams, options }) => {\n if (!entries.length) {\n console.warn(\n `[Layout children]: Too many screens defined. Route \"${name}\" is extraneous.`\n );\n return null;\n }\n const matchIndex = entries.findIndex((child) => child.route === name);\n if (matchIndex === -1) {\n console.warn(\n `[Layout children]: No route named \"${name}\" exists in nested children:`,\n children.map(({ route }) => route)\n );\n return null;\n } else {\n // Get match and remove from entries\n const match = entries[matchIndex];\n entries.splice(matchIndex, 1);\n\n // Ensure to return null after removing from entries.\n if (redirect) {\n if (typeof redirect === \"string\") {\n throw new Error(\n `Redirecting to a specific route is not supported yet.`\n );\n }\n return null;\n }\n\n return { route: match, props: { initialParams, options } };\n }\n })\n .filter(Boolean) as {\n route: RouteNode;\n props: Partial<ScreenProps>;\n }[];\n\n // Add any remaining children\n ordered.push(\n ...entries.sort(sortRoutes).map((route) => ({ route, props: {} }))\n );\n\n return ordered;\n}\n\n/**\n * @returns React Navigation screens sorted by the `route` property.\n */\nexport function useSortedScreens(order: ScreenProps[]): React.ReactNode[] {\n const node = useRouteNode();\n\n const sorted = node?.children?.length\n ? getSortedChildren(node.children, order)\n : [];\n return React.useMemo(\n () => sorted.map((value) => routeToScreen(value.route, value.props)),\n [sorted]\n );\n}\n\n// TODO: Maybe there's a more React-y way to do this?\n// Without this store, the process enters a recursive loop.\nconst qualifiedStore = new WeakMap<RouteNode, React.ComponentType<any>>();\n\n/** Wrap the component with various enhancements and add access to child routes. */\nexport function getQualifiedRouteComponent(value: RouteNode) {\n if (qualifiedStore.has(value)) {\n return qualifiedStore.get(value)!;\n }\n\n const { default: Component, ErrorBoundary } = value.loadRoute();\n\n const QualifiedRoute = React.forwardRef(\n (props: { route: any; navigation: any }, ref: any) => {\n // Surface dynamic name as props to the view\n const children = React.createElement(Component, {\n ...props,\n ref,\n });\n\n const errorBoundary = ErrorBoundary ? (\n <Try catch={ErrorBoundary}>{children}</Try>\n ) : (\n children\n );\n\n return <Route node={value}>{errorBoundary}</Route>;\n }\n );\n\n QualifiedRoute.displayName = `Route(${\n Component.displayName || Component.name || value.route\n })`;\n qualifiedStore.set(value, QualifiedRoute);\n return QualifiedRoute;\n}\n\n/** @returns a function which provides a screen id that matches the dynamic route name in params. */\nexport function createGetIdForRoute(\n route: Pick<RouteNode, \"dynamic\" | \"route\">\n) {\n if (!route.dynamic) {\n return undefined;\n }\n const dynamicName = route.dynamic.name;\n const routeName = route.route;\n return ({ params }) => {\n // Params can be undefined when there are no params in the route.\n const preferredId = params?.[dynamicName];\n // If the route has a dynamic segment, use the matching parameter\n // as the screen id. This enables pushing a screen like `/[user]` multiple times\n // when the user is different.\n if (preferredId) {\n // Deep dynamic routes will return as an array, so we'll join them to create a\n // fully qualified string.\n return (\n (Array.isArray(preferredId) ? preferredId.join(\"/\") : preferredId) ||\n routeName\n );\n }\n return routeName;\n };\n}\n\nfunction routeToScreen(\n route: RouteNode,\n { options, ...props }: Partial<ScreenProps> = {}\n) {\n return (\n <Screen\n // Users can override the screen getId function.\n getId={createGetIdForRoute(route)}\n {...props}\n name={route.route}\n key={route.route}\n options={(args) => {\n // Only eager load generated components\n const staticOptions = route.generated\n ? route.loadRoute()?.getNavOptions\n : null;\n const staticResult =\n typeof staticOptions === \"function\"\n ? staticOptions(args)\n : staticOptions;\n const dynamicResult =\n typeof options === \"function\" ? options?.(args) : options;\n return {\n ...staticResult,\n ...dynamicResult,\n };\n }}\n getComponent={() => getQualifiedRouteComponent(route)}\n />\n );\n}\n"]}
|