expo-router 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app.plugin.js +1 -0
- package/babel.js +7 -1
- package/build/ExpoRoot.d.ts.map +1 -1
- package/build/fork/getStateFromPath.d.ts.map +1 -1
- package/build/fork/useLinking.native.d.ts.map +1 -1
- package/build/layouts/Tabs.d.ts.map +1 -1
- package/build/link/Link.d.ts.map +1 -1
- package/build/link/linking.d.ts +1 -1
- package/build/link/linking.d.ts.map +1 -1
- package/build/link/useHref.d.ts.map +1 -1
- package/build/link/useLinkToPath.d.ts.map +1 -1
- package/build/link/useRouter.d.ts.map +1 -1
- package/build/navigationStore/index.d.ts.map +1 -1
- package/build/navigationStore/initialState.d.ts.map +1 -1
- package/build/testing-library/expect.d.ts +2 -0
- package/build/testing-library/expect.d.ts.map +1 -0
- package/build/testing-library/index.d.ts +19 -0
- package/build/testing-library/index.d.ts.map +1 -0
- package/build/testing-library/mocks.d.ts +2 -0
- package/build/testing-library/mocks.d.ts.map +1 -0
- package/build/testing-library/require-context-ponyfill.d.ts +3 -0
- package/build/testing-library/require-context-ponyfill.d.ts.map +1 -0
- package/build/useScreens.d.ts +1 -1
- package/build/useScreens.d.ts.map +1 -1
- package/build/views/ErrorBoundary.d.ts.map +1 -1
- package/build/views/SuspenseFallback.d.ts.map +1 -1
- package/entry.js +1 -2
- package/head.ts +5 -2
- package/package.json +9 -2
- package/plugin/build/index.d.ts +12 -0
- package/plugin/build/index.js +18 -0
- package/plugin/options.json +48 -0
- package/plugin/src/index.ts +30 -0
- package/plugin/tsconfig.json +9 -0
- package/src/ExpoRoot.tsx +1 -0
- package/src/fork/getStateFromPath.ts +2 -2
- package/src/fork/useLinking.native.ts +2 -1
- package/src/layouts/Tabs.tsx +1 -1
- package/src/link/Link.tsx +1 -1
- package/src/link/linking.ts +5 -1
- package/src/link/useHref.ts +1 -1
- package/src/link/useLinkToPath.ts +1 -1
- package/src/link/useLinkToPathProps.tsx +1 -1
- package/src/link/useRouter.ts +1 -1
- package/src/navigationStore/index.ts +11 -3
- package/src/navigationStore/initialState.ts +6 -4
- package/src/static/renderStaticContent.tsx +2 -2
- package/src/testing-library/expect.ts +15 -0
- package/src/testing-library/index.tsx +159 -0
- package/src/testing-library/mocks.ts +15 -0
- package/src/testing-library/require-context-ponyfill.ts +44 -0
- package/src/views/EmptyRoute.tsx +1 -1
- package/src/views/ErrorBoundary.tsx +1 -1
- package/src/views/Navigator.tsx +1 -1
- package/src/views/SuspenseFallback.tsx +1 -1
- package/types/expect.d.ts +4 -0
- package/types/jest.d.ts +9 -0
- package/build/head/Head.d.ts +0 -7
- package/build/head/Head.d.ts.map +0 -1
- package/build/head/Head.native.d.ts +0 -11
- package/build/head/Head.native.d.ts.map +0 -1
- package/src/head/Head.native.tsx +0 -78
- package/src/head/Head.tsx +0 -12
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("./plugin/build");
|
package/babel.js
CHANGED
|
@@ -41,7 +41,7 @@ function getExpoRouterImportMode(projectRoot, platform) {
|
|
|
41
41
|
|
|
42
42
|
if (env === "production" && mode === "lazy") {
|
|
43
43
|
throw new Error(
|
|
44
|
-
"Async routes are not supported in production yet. Set `
|
|
44
|
+
"Async routes are not supported in production yet. Set the `expo-router` Config Plugin prop `asyncRoutes` to `development`, `false`, or `undefined`."
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -189,6 +189,12 @@ module.exports = function (api) {
|
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
// Skip loading the app root in tests.
|
|
193
|
+
// This is handled by the testing-library utils
|
|
194
|
+
if (process.env.NODE_ENV === "test") {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
192
198
|
parent.replaceWith(
|
|
193
199
|
// This is defined in Expo CLI when using Metro. It points to the relative path for the project app directory.
|
|
194
200
|
t.stringLiteral(getExpoRouterAppRoot(projectRoot))
|
package/build/ExpoRoot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoRoot.d.ts","sourceRoot":"","sources":["../src/ExpoRoot.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAwBzC,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"ExpoRoot.d.ts","sourceRoot":"","sources":["../src/ExpoRoot.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAwBzC,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,eAchE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getStateFromPath.d.ts","sourceRoot":"","sources":["../../src/fork/getStateFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"getStateFromPath.d.ts","sourceRoot":"","sources":["../../src/fork/getStateFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAEV,eAAe,EACf,YAAY,EACb,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAKrC,KAAK,OAAO,CAAC,SAAS,SAAS,MAAM,IAAI;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,GAAG,CAAC,CAAC;AAe1D,KAAK,kBAAkB,GAAG;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG;IACxD,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAkBF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,SAAS,SAAS,MAAM,EAC/D,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAC3B,WAAW,GAAG,SAAS,CAIzB;AAED,wBAAgB,wBAAwB,CAAC,SAAS,SAAS,MAAM,EAC/D,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC;;;;;;;;;;;;;;EA+C7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLinking.native.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.native.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,sBAAsB,EACtB,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,KAAK,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;AAI7C,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,EAC3D,EAGE,MAAM,EACN,MAAM,EACN,aAQI,EACJ,SAUC,EACD,gBAA0C,EAC1C,kBAA8C,GAC/C,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useLinking.native.d.ts","sourceRoot":"","sources":["../../src/fork/useLinking.native.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,sBAAsB,EACtB,aAAa,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,KAAK,OAAO,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;AAI7C,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,EAC3D,EAGE,MAAM,EACN,MAAM,EACN,aAQI,EACJ,SAUC,EACD,gBAA0C,EAC1C,kBAA8C,GAC/C,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4KX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/layouts/Tabs.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAE3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/layouts/Tabs.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAE3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAMpC,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Cf,CAAC;AAEH,eAAe,IAAI,CAAC"}
|
package/build/link/Link.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAQ,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAQ,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAY,MAAM,cAAc,CAAC;AAG/D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI3C,MAAM,WAAW,SAAU,SAAQ,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACvE,wBAAwB;IACxB,IAAI,EAAE,IAAI,CAAC;IAGX,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,OAAO,CAAC,EAAE,CACR,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,EAAE,UAAU,CAAC,GAAG,qBAAqB,KACvE,IAAI,CAAC;CACX;AAED,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,QAMhD;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,KAAK,EAAE,KAAK,CAAC,iBAAiB,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;IACzD,6DAA6D;IAC7D,WAAW,EAAE,OAAO,WAAW,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,eAEY,CAAC"}
|
package/build/link/linking.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import getPathFromState from "../fork/getPathFromState";
|
|
2
2
|
import getStateFromPath from "../fork/getStateFromPath";
|
|
3
|
-
export declare function getInitialURL(): Promise<string
|
|
3
|
+
export declare function getInitialURL(): Promise<string | null> | string;
|
|
4
4
|
export declare function getRootURL(): string;
|
|
5
5
|
export declare function addEventListener(listener: (url: string) => void): () => void;
|
|
6
6
|
export { getStateFromPath, getPathFromState };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"AAKA,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AAOxD,
|
|
1
|
+
{"version":3,"file":"linking.d.ts","sourceRoot":"","sources":["../../src/link/linking.ts"],"names":[],"mappings":"AAKA,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AACxD,OAAO,gBAAgB,MAAM,0BAA0B,CAAC;AAOxD,wBAAgB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,MAAM,CAiD/D;AAID,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,cA8B/D;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useHref.d.ts","sourceRoot":"","sources":["../../src/link/useHref.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLinkToPath.d.ts","sourceRoot":"","sources":["../../src/link/useLinkToPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"useLinkToPath.d.ts","sourceRoot":"","sources":["../../src/link/useLinkToPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,EAKL,cAAc,EACf,MAAM,mBAAmB,CAAC;AAc3B,wBAAgB,aAAa,WAIlB,MAAM,UAAU,MAAM,UAmHhC;AAED,uGAAuG;AACvG,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,GAC5C,MAAM,IAAI,cAAc,CAqB1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRouter.d.ts","sourceRoot":"","sources":["../../src/link/useRouter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useRouter.d.ts","sourceRoot":"","sources":["../../src/link/useRouter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAe,MAAM,QAAQ,CAAC;AAK3C,wBAAgB,OAAO,WAGtB;AAED,KAAK,MAAM,GAAG;IACZ,qCAAqC;IACrC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC3B,0DAA0D;IAC1D,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,8BAA8B;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CACtD,CAAC;AAEF,wBAAgB,SAAS,IAAI,MAAM,CA6BlC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigationStore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigationStore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,YAAY,EAIb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,gBAEN,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C,eAAO,MAAM,aAAa,+FAC+B,CAAC;AAE1D,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAEtD,KAAK,SAAS,GAAG;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,qBAAa,eAAe;IAC1B,eAAe,wBAA6B,IAAI,GAI7C;IAEH,WAAW,EAAE,GAAG,GAAG,SAAS,CAAC;IAE7B,aAAa,gGAAiB;IAC9B,SAAS,EAAG,SAAS,CAAC;IACtB,OAAO,EAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,EAAE,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;IACvE,gBAAgB,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,GAAG,EAAG,GAAG,CAAC;IACV,SAAS,EAAG,SAAS,CAAC;IAEtB,kBAAkB,UAAS;IAC3B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;gBAEV,WAAW,CAAC,EAAE,GAAG;IAI7B,UAAU,YAAa,cAAc,WAAW,MAAM,IAAI,UAoBxD;IAEF,qBAAqB,UACZ,eAAe,GAAG,aAAa,eAAe,CAAC,UA6BtD;IAEF,OAAO,aAWL;IAEF,kBAAkB,UAAW,MAAM,UAIjC;IAEF,gBAAgB,QAAS,MAAM,gBACX,MAAM,IAAI,gBAM5B;IAEF,kBAAkB,aARE,MAAM,IAAI,gBAQ0B;IACxD,kBAAkB,aATE,MAAM,IAAI,gBAS0B;CACzD;AAED,eAAO,MAAM,sBAAsB,gCAElC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc;;EAezD;AAED,wBAAgB,iBAAiB,kGAEhC;AAED,wBAAgB,iBAAiB;sBASX,uBAAuB;EAE5C;AAED,wBAAgB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAOrC;AAED,wBAAgB,YAAY,cAO3B;AAED,wBAAgB,WAAW,aAE1B;AAED,wBAAgB,WAAW,WAE1B;AAED,wBAAgB,eAAe,iBAE9B;AAED,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,YAAY,GAAG,YAAY,KACxC,OAAO,CAAC,OAAO,CAAC,CAEpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialState.d.ts","sourceRoot":"","sources":["../../src/navigationStore/initialState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,WAAW,CAAC,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"initialState.d.ts","sourceRoot":"","sources":["../../src/navigationStore/initialState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,wBAAgB,eAAe,CAC7B,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,EAC/B,WAAW,CAAC,EAAE,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAoBlB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/testing-library/expect.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import "./mocks";
|
|
2
|
+
import "./expect";
|
|
3
|
+
import { render } from "@testing-library/react-native";
|
|
4
|
+
import React from "react";
|
|
5
|
+
export * from "@testing-library/react-native";
|
|
6
|
+
type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
7
|
+
initialUrl?: string;
|
|
8
|
+
};
|
|
9
|
+
type RouteOverrideFunction = () => React.ReactElement<any, any> | null;
|
|
10
|
+
type RouteOverride = {
|
|
11
|
+
default: RouteOverrideFunction;
|
|
12
|
+
} | RouteOverrideFunction;
|
|
13
|
+
export declare function renderRouter(context?: string, options?: RenderRouterOptions): ReturnType<typeof render>;
|
|
14
|
+
export declare function renderRouter(context: Record<string, RouteOverride>, options?: RenderRouterOptions): ReturnType<typeof render>;
|
|
15
|
+
export declare function renderRouter(context: {
|
|
16
|
+
appDir: string;
|
|
17
|
+
overrides: Record<string, RouteOverride>;
|
|
18
|
+
}, options?: RenderRouterOptions): ReturnType<typeof render>;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing-library/index.tsx"],"names":[],"mappings":"AACA,OAAO,SAAS,CAAC;AACjB,OAAO,UAAU,CAAC;AAGlB,OAAO,EAAE,MAAM,EAAgB,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,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,qBAAqB,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;AAEvE,KAAK,aAAa,GAAG;IAAE,OAAO,EAAE,qBAAqB,CAAA;CAAE,GAAG,qBAAqB,CAAC;AAoChF,wBAAgB,YAAY,CAC1B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AAC7B,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACtC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AAC7B,wBAAgB,YAAY,CAC1B,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;CAAE,EACrE,OAAO,CAAC,EAAE,mBAAmB,GAC5B,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocks.d.ts","sourceRoot":"","sources":["../../src/testing-library/mocks.ts"],"names":[],"mappings":"AAAA,OAAO,4CAA4C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-context-ponyfill.d.ts","sourceRoot":"","sources":["../../src/testing-library/require-context-ponyfill.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,IAAI,SAAM,EACV,kBAAkB,UAAO,EACzB,iBAAiB,SAAe,kBAmCjC"}
|
package/build/useScreens.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export type ScreenProps<TOptions extends Record<string, any> = Record<string, an
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function useSortedScreens(order: ScreenProps[]): React.ReactNode[];
|
|
21
21
|
/** Wrap the component with various enhancements and add access to child routes. */
|
|
22
|
-
export declare function getQualifiedRouteComponent(value: RouteNode): React.ComponentType<any> | React.ForwardRefExoticComponent<
|
|
22
|
+
export declare function getQualifiedRouteComponent(value: RouteNode): React.ComponentType<any> | React.ForwardRefExoticComponent<Pick<any, string | number | symbol> & React.RefAttributes<unknown>>;
|
|
23
23
|
/** @returns a function which provides a screen id that matches the dynamic route name in params. */
|
|
24
24
|
export declare function createGetIdForRoute(route: Pick<RouteNode, "dynamic" | "route">): (({ params }: {
|
|
25
25
|
params?: Record<string, any> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAMjB,MAAM,MAAM,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,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAGnB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,CAAC;AA8DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AA6BD,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,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAMjB,MAAM,MAAM,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,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAGnB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,CAAC;AA8DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AA6BD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,kIAuE1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;;sCA0B5C"}
|
|
@@ -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":";AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAE3C,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,kBAAkB,eAkEjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuspenseFallback.d.ts","sourceRoot":"","sources":["../../src/views/SuspenseFallback.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SuspenseFallback.d.ts","sourceRoot":"","sources":["../../src/views/SuspenseFallback.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,eAM/D"}
|
package/entry.js
CHANGED
package/head.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-ignore: TODO -- monorepo issue
|
|
2
|
+
import { Head } from "expo-head";
|
|
2
3
|
|
|
3
|
-
export default Head
|
|
4
|
+
export default Head as unknown as React.FC<{ children?: React.ReactNode }> & {
|
|
5
|
+
Provider: React.FC<{ children?: React.ReactNode; context: any }>;
|
|
6
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-router",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"main": "src/index.tsx",
|
|
5
5
|
"types": "build/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"stack.ts",
|
|
22
22
|
"tabs.ts",
|
|
23
23
|
"types",
|
|
24
|
+
"plugin",
|
|
25
|
+
"app.plugin.js",
|
|
24
26
|
"!**/__tests__"
|
|
25
27
|
],
|
|
26
28
|
"repository": {
|
|
@@ -70,6 +72,9 @@
|
|
|
70
72
|
},
|
|
71
73
|
"@react-navigation/drawer": {
|
|
72
74
|
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"@testing-library/jest-native": {
|
|
77
|
+
"optional": true
|
|
73
78
|
}
|
|
74
79
|
},
|
|
75
80
|
"devDependencies": {
|
|
@@ -93,14 +98,16 @@
|
|
|
93
98
|
},
|
|
94
99
|
"dependencies": {
|
|
95
100
|
"@bacons/react-views": "^1.1.3",
|
|
96
|
-
"@expo/metro-runtime": "2.1.
|
|
101
|
+
"@expo/metro-runtime": "2.1.1",
|
|
97
102
|
"@radix-ui/react-slot": "^1.0.0",
|
|
98
103
|
"@react-navigation/bottom-tabs": "~6.5.7",
|
|
99
104
|
"@react-navigation/native": "~6.1.6",
|
|
100
105
|
"@react-navigation/native-stack": "~6.9.12",
|
|
106
|
+
"expo-head": "0.0.2",
|
|
101
107
|
"expo-splash-screen": "*",
|
|
102
108
|
"query-string": "7.1.3",
|
|
103
109
|
"react-helmet-async": "^1.3.0",
|
|
110
|
+
"schema-utils": "^4.0.1",
|
|
104
111
|
"url": "^0.11.0"
|
|
105
112
|
}
|
|
106
113
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
declare const withRouter: ConfigPlugin<{
|
|
3
|
+
/** Production origin URL where assets in the public folder are hosted. The fetch function is polyfilled to support relative requests from this origin in production, development origin is inferred using the Expo CLI development server. */
|
|
4
|
+
origin: string;
|
|
5
|
+
/** A more specific origin URL used in the `expo-router/head` module for iOS handoff. Defaults to `origin`. */
|
|
6
|
+
headOrigin?: string;
|
|
7
|
+
/** Changes the routes directory from `app` to another value. Defaults to `app`. Avoid using this property. */
|
|
8
|
+
unstable_src?: string;
|
|
9
|
+
/** Should Async Routes be enabled, currently only `development` is supported. */
|
|
10
|
+
asyncRoutes?: string;
|
|
11
|
+
}>;
|
|
12
|
+
export default withRouter;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const schema_utils_1 = require("schema-utils");
|
|
4
|
+
const schema = require("../options.json");
|
|
5
|
+
const withRouter = (config, props) => {
|
|
6
|
+
(0, schema_utils_1.validate)(schema, props);
|
|
7
|
+
return {
|
|
8
|
+
...config,
|
|
9
|
+
extra: {
|
|
10
|
+
...config.extra,
|
|
11
|
+
router: {
|
|
12
|
+
...config.extra?.router,
|
|
13
|
+
...props,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
exports.default = withRouter;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "expo-router config plugin options",
|
|
3
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
|
+
"$ref": "#/definitions/Props",
|
|
5
|
+
"definitions": {
|
|
6
|
+
"Props": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"origin": {
|
|
10
|
+
"description": "Production origin URL where assets in the public folder are hosted. The fetch function is polyfilled to support relative requests from this origin in production, development origin is inferred using the Expo CLI development server.",
|
|
11
|
+
"oneOf": [
|
|
12
|
+
{
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"type": "boolean"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"headOrigin": {
|
|
21
|
+
"description": "A more specific origin URL used in the `expo-router/head` module for iOS handoff. Defaults to `origin`.",
|
|
22
|
+
"type": "string"
|
|
23
|
+
},
|
|
24
|
+
"unstable_src": {
|
|
25
|
+
"description": "Changes the routes directory from `app` to another value. Defaults to `app`. Avoid using this property.",
|
|
26
|
+
"type": "string"
|
|
27
|
+
},
|
|
28
|
+
"asyncRoutes": {
|
|
29
|
+
"description": "Should Async Routes be enabled, currently only `development` is supported.",
|
|
30
|
+
"oneOf": [
|
|
31
|
+
{
|
|
32
|
+
"type": "string",
|
|
33
|
+
"enum": [
|
|
34
|
+
"development",
|
|
35
|
+
"production"
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "boolean"
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"required": ["origin"],
|
|
45
|
+
"additionalProperties": false
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConfigPlugin } from "expo/config-plugins";
|
|
2
|
+
import { validate } from "schema-utils";
|
|
3
|
+
|
|
4
|
+
const schema = require("../options.json");
|
|
5
|
+
|
|
6
|
+
const withRouter: ConfigPlugin<{
|
|
7
|
+
/** Production origin URL where assets in the public folder are hosted. The fetch function is polyfilled to support relative requests from this origin in production, development origin is inferred using the Expo CLI development server. */
|
|
8
|
+
origin: string;
|
|
9
|
+
/** A more specific origin URL used in the `expo-router/head` module for iOS handoff. Defaults to `origin`. */
|
|
10
|
+
headOrigin?: string;
|
|
11
|
+
/** Changes the routes directory from `app` to another value. Defaults to `app`. Avoid using this property. */
|
|
12
|
+
unstable_src?: string;
|
|
13
|
+
/** Should Async Routes be enabled, currently only `development` is supported. */
|
|
14
|
+
asyncRoutes?: string;
|
|
15
|
+
}> = (config, props) => {
|
|
16
|
+
validate(schema, props);
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
...config,
|
|
20
|
+
extra: {
|
|
21
|
+
...config.extra,
|
|
22
|
+
router: {
|
|
23
|
+
...config.extra?.router,
|
|
24
|
+
...props,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default withRouter;
|
package/src/ExpoRoot.tsx
CHANGED
|
@@ -7,10 +7,10 @@ import type {
|
|
|
7
7
|
import escape from "escape-string-regexp";
|
|
8
8
|
import * as queryString from "query-string";
|
|
9
9
|
|
|
10
|
-
import { findFocusedRoute } from "./findFocusedRoute";
|
|
11
|
-
import validatePathConfig from "./validatePathConfig";
|
|
12
10
|
import { RouteNode } from "../Route";
|
|
13
11
|
import { matchGroupName, stripGroupSegmentsFromPath } from "../matchers";
|
|
12
|
+
import { findFocusedRoute } from "./findFocusedRoute";
|
|
13
|
+
import validatePathConfig from "./validatePathConfig";
|
|
14
14
|
|
|
15
15
|
type Options<ParamList extends object> = {
|
|
16
16
|
initialRouteName?: string;
|
|
@@ -156,7 +156,8 @@ export default function useLinking(
|
|
|
156
156
|
|
|
157
157
|
const thenable = {
|
|
158
158
|
then(onfulfilled?: (state: ResultState | undefined) => void) {
|
|
159
|
-
|
|
159
|
+
onfulfilled?.(state);
|
|
160
|
+
return thenable;
|
|
160
161
|
},
|
|
161
162
|
catch() {
|
|
162
163
|
return thenable;
|
package/src/layouts/Tabs.tsx
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { Platform } from "react-native";
|
|
8
8
|
|
|
9
|
-
import { withLayoutContext } from "./withLayoutContext";
|
|
10
9
|
import { Link } from "../link/Link";
|
|
11
10
|
import { Href } from "../link/href";
|
|
11
|
+
import { withLayoutContext } from "./withLayoutContext";
|
|
12
12
|
|
|
13
13
|
// This is the only way to access the navigator.
|
|
14
14
|
const BottomTabNavigator = createBottomTabNavigator().Navigator;
|
package/src/link/Link.tsx
CHANGED
|
@@ -5,10 +5,10 @@ import { Slot } from "@radix-ui/react-slot";
|
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { GestureResponderEvent, Platform } from "react-native";
|
|
7
7
|
|
|
8
|
+
import { useFocusEffect } from "../useFocusEffect";
|
|
8
9
|
import { Href, resolveHref } from "./href";
|
|
9
10
|
import useLinkToPathProps from "./useLinkToPathProps";
|
|
10
11
|
import { useRouter } from "./useRouter";
|
|
11
|
-
import { useFocusEffect } from "../useFocusEffect";
|
|
12
12
|
|
|
13
13
|
export interface LinkProps extends Omit<TextProps, "href" | "hoverStyle"> {
|
|
14
14
|
/** Path to route to. */
|
package/src/link/linking.ts
CHANGED
|
@@ -11,7 +11,11 @@ import getStateFromPath from "../fork/getStateFromPath";
|
|
|
11
11
|
// This helps keep the native functionality working like the web functionality.
|
|
12
12
|
// For example, if you had a root navigator where the first screen was `/settings` and the second was `/index`
|
|
13
13
|
// then `/index` would be used on web and `/settings` would be used on native.
|
|
14
|
-
export
|
|
14
|
+
export function getInitialURL(): Promise<string | null> | string {
|
|
15
|
+
if (process.env.NODE_ENV === "test") {
|
|
16
|
+
return Linking.getInitialURL();
|
|
17
|
+
}
|
|
18
|
+
|
|
15
19
|
if (Platform.OS === "web") {
|
|
16
20
|
if (typeof window === "undefined") {
|
|
17
21
|
return "";
|
package/src/link/useHref.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { TabActions } from "@react-navigation/routers";
|
|
|
7
7
|
import * as Linking from "expo-linking";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
|
|
10
|
+
import { navigationRef, useLinkingContext } from "../navigationStore";
|
|
10
11
|
import { resolve } from "./path";
|
|
11
12
|
import {
|
|
12
13
|
findTopRouteForTarget,
|
|
@@ -15,7 +16,6 @@ import {
|
|
|
15
16
|
isMovingToSiblingRoute,
|
|
16
17
|
NavigateAction,
|
|
17
18
|
} from "./stateOperations";
|
|
18
|
-
import { navigationRef, useLinkingContext } from "../navigationStore";
|
|
19
19
|
|
|
20
20
|
type NavStateParams = {
|
|
21
21
|
params?: NavStateParams;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { GestureResponderEvent, Platform } from "react-native";
|
|
3
3
|
|
|
4
|
-
import { useLinkToPath } from "./useLinkToPath";
|
|
5
4
|
import { stripGroupSegmentsFromPath } from "../matchers";
|
|
5
|
+
import { useLinkToPath } from "./useLinkToPath";
|
|
6
6
|
|
|
7
7
|
function eventShouldPreventDefault(
|
|
8
8
|
e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent
|
package/src/link/useRouter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useCallback } from "react";
|
|
2
2
|
|
|
3
|
+
import { navigationRef } from "../navigationStore";
|
|
3
4
|
import { Href, resolveHref } from "./href";
|
|
4
5
|
import { useLinkToPath } from "./useLinkToPath";
|
|
5
6
|
import { useLoadedNavigation } from "./useLoadedNavigation";
|
|
6
|
-
import { navigationRef } from "../navigationStore";
|
|
7
7
|
|
|
8
8
|
// Wraps useLinkTo to provide an API which is similar to the Link component.
|
|
9
9
|
export function useLink() {
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
ParamListBase,
|
|
5
5
|
PartialState,
|
|
6
6
|
createNavigationContainerRef,
|
|
7
|
-
|
|
7
|
+
NavigationRouteContext,
|
|
8
|
+
RouteProp,
|
|
8
9
|
} from "@react-navigation/native";
|
|
9
10
|
import React from "react";
|
|
10
11
|
|
|
11
|
-
import { getInitialState } from "./initialState";
|
|
12
12
|
import { compareRouteInfo, getRouteInfoFromState } from "../LocationProvider";
|
|
13
13
|
import { RouteNode } from "../Route";
|
|
14
14
|
import getPathFromState, {
|
|
@@ -18,6 +18,7 @@ import { ResultState } from "../fork/getStateFromPath";
|
|
|
18
18
|
import { getLinkingConfig } from "../getLinkingConfig";
|
|
19
19
|
import { getRoutes } from "../getRoutes";
|
|
20
20
|
import { RequireContext } from "../types";
|
|
21
|
+
import { getInitialState } from "./initialState";
|
|
21
22
|
|
|
22
23
|
export const navigationRef =
|
|
23
24
|
createNavigationContainerRef<Record<string, unknown>>();
|
|
@@ -211,5 +212,12 @@ export function useSearchParams() {
|
|
|
211
212
|
export function useLocalSearchParams<
|
|
212
213
|
TParams extends SearchParams = SearchParams
|
|
213
214
|
>(): Partial<TParams> {
|
|
214
|
-
return (
|
|
215
|
+
return (useOptionalLocalRoute()?.params ?? ({} as any)) as Partial<TParams>;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function useOptionalLocalRoute<T extends RouteProp<ParamListBase>>():
|
|
219
|
+
| T
|
|
220
|
+
| undefined {
|
|
221
|
+
const route = React.useContext(NavigationRouteContext);
|
|
222
|
+
return route as T | undefined;
|
|
215
223
|
}
|
|
@@ -14,10 +14,12 @@ export function getInitialState(
|
|
|
14
14
|
ssrLocation.pathname + ssrLocation.search,
|
|
15
15
|
linking.config
|
|
16
16
|
);
|
|
17
|
+
} else if (typeof window.location !== "undefined") {
|
|
18
|
+
return linking.getStateFromPath?.(
|
|
19
|
+
window.location.pathname + window.location.search,
|
|
20
|
+
linking.config
|
|
21
|
+
);
|
|
17
22
|
}
|
|
18
23
|
|
|
19
|
-
return
|
|
20
|
-
window.location.pathname + window.location.search,
|
|
21
|
-
linking.config
|
|
22
|
-
);
|
|
24
|
+
return undefined;
|
|
23
25
|
}
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
import { ServerContainer, ServerContainerRef } from "@react-navigation/native";
|
|
9
9
|
import App, { getManifest } from "expo-router/_entry";
|
|
10
|
+
import Head from "expo-router/head";
|
|
10
11
|
import React from "react";
|
|
11
12
|
import ReactDOMServer from "react-dom/server";
|
|
12
13
|
import { AppRegistry } from "react-native-web";
|
|
13
14
|
|
|
14
|
-
import { getRootComponent } from "./getRootComponent";
|
|
15
|
-
import Head from "../head/Head";
|
|
16
15
|
import { NavigationStore, NavigationStoreContext } from "../navigationStore";
|
|
16
|
+
import { getRootComponent } from "./getRootComponent";
|
|
17
17
|
|
|
18
18
|
AppRegistry.registerComponent("App", () => App);
|
|
19
19
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import matchers from "expect/build/matchers";
|
|
2
|
+
|
|
3
|
+
matchers.customTesters = [];
|
|
4
|
+
|
|
5
|
+
expect.extend({
|
|
6
|
+
toHavePathname(screen, expected) {
|
|
7
|
+
return matchers.toEqual(screen.getPathname(), expected);
|
|
8
|
+
},
|
|
9
|
+
toHaveSearchParams(screen, expected) {
|
|
10
|
+
return matchers.toEqual(
|
|
11
|
+
Object.fromEntries(screen.getSearchParams().entries()),
|
|
12
|
+
expected
|
|
13
|
+
);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/// <reference types="../../types/jest.d.ts" />
|
|
2
|
+
import "./mocks";
|
|
3
|
+
import "./expect";
|
|
4
|
+
|
|
5
|
+
import { BaseNavigationContainer } from "@react-navigation/core";
|
|
6
|
+
import { render, RenderResult } from "@testing-library/react-native";
|
|
7
|
+
import { findAll } from "@testing-library/react-native/build/helpers/findAll";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import React from "react";
|
|
10
|
+
|
|
11
|
+
import { ExpoRoot } from "../ExpoRoot";
|
|
12
|
+
import { RequireContext } from "../types";
|
|
13
|
+
import requireContext from "./require-context-ponyfill";
|
|
14
|
+
|
|
15
|
+
// re-export everything
|
|
16
|
+
export * from "@testing-library/react-native";
|
|
17
|
+
|
|
18
|
+
type RenderRouterOptions = Parameters<typeof render>[1] & {
|
|
19
|
+
initialUrl?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type RouteOverrideFunction = () => React.ReactElement<any, any> | null;
|
|
23
|
+
|
|
24
|
+
type RouteOverride = { default: RouteOverrideFunction } | RouteOverrideFunction;
|
|
25
|
+
|
|
26
|
+
const initialUrlRef = {
|
|
27
|
+
value: "/",
|
|
28
|
+
then(onfulfilled: (v: string) => string) {
|
|
29
|
+
const nextValue = onfulfilled?.(this.value);
|
|
30
|
+
if (nextValue !== undefined) {
|
|
31
|
+
this.value = nextValue;
|
|
32
|
+
}
|
|
33
|
+
return this;
|
|
34
|
+
},
|
|
35
|
+
catch() {
|
|
36
|
+
return this;
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
jest.mock("expo-linking", () => {
|
|
41
|
+
const module: typeof import("expo-linking") = {
|
|
42
|
+
...jest.requireActual("expo-linking"),
|
|
43
|
+
addEventListener() {
|
|
44
|
+
return { remove() {} } as any;
|
|
45
|
+
},
|
|
46
|
+
getInitialURL() {
|
|
47
|
+
return initialUrlRef as unknown as Promise<string>;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return module;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
function isOverrideContext(
|
|
55
|
+
context: object
|
|
56
|
+
): context is { appDir: string; overrides: Record<string, RouteOverride> } {
|
|
57
|
+
return Boolean(typeof context === "object" && "appDir" in context);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function renderRouter(
|
|
61
|
+
context?: string,
|
|
62
|
+
options?: RenderRouterOptions
|
|
63
|
+
): ReturnType<typeof render>;
|
|
64
|
+
export function renderRouter(
|
|
65
|
+
context: Record<string, RouteOverride>,
|
|
66
|
+
options?: RenderRouterOptions
|
|
67
|
+
): ReturnType<typeof render>;
|
|
68
|
+
export function renderRouter(
|
|
69
|
+
context: { appDir: string; overrides: Record<string, RouteOverride> },
|
|
70
|
+
options?: RenderRouterOptions
|
|
71
|
+
): ReturnType<typeof render>;
|
|
72
|
+
export function renderRouter(
|
|
73
|
+
context:
|
|
74
|
+
| string
|
|
75
|
+
| { appDir: string; overrides: Record<string, RouteOverride> }
|
|
76
|
+
| Record<string, RouteOverride> = "./app",
|
|
77
|
+
{ initialUrl = "/", ...options }: RenderRouterOptions = {}
|
|
78
|
+
): ReturnType<typeof render> {
|
|
79
|
+
jest.useFakeTimers();
|
|
80
|
+
|
|
81
|
+
let ctx: RequireContext;
|
|
82
|
+
|
|
83
|
+
// Reset the initial URL
|
|
84
|
+
initialUrlRef.value = initialUrl;
|
|
85
|
+
|
|
86
|
+
if (typeof context === "string") {
|
|
87
|
+
ctx = requireContext(path.resolve(process.cwd(), context));
|
|
88
|
+
} else if (isOverrideContext(context)) {
|
|
89
|
+
const existingContext = requireContext(
|
|
90
|
+
path.resolve(process.cwd(), context.appDir)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
ctx = Object.assign(
|
|
94
|
+
function (id: string) {
|
|
95
|
+
if (id in context.overrides) {
|
|
96
|
+
const route = context.overrides[id];
|
|
97
|
+
return typeof route === "function" ? { default: route } : route;
|
|
98
|
+
} else {
|
|
99
|
+
return existingContext(id);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
keys: () => [
|
|
104
|
+
...Object.keys(context.overrides),
|
|
105
|
+
...existingContext.keys(),
|
|
106
|
+
],
|
|
107
|
+
resolve: (key: string) => key,
|
|
108
|
+
id: "0",
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
} else {
|
|
112
|
+
ctx = Object.assign(
|
|
113
|
+
function (id: string) {
|
|
114
|
+
return typeof context[id] === "function"
|
|
115
|
+
? { default: context[id] }
|
|
116
|
+
: context[id];
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
keys: () => Object.keys(context),
|
|
120
|
+
resolve: (key: string) => key,
|
|
121
|
+
id: "0",
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const result = render(<ExpoRoot context={ctx} />, {
|
|
127
|
+
...options,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
Object.assign(result, {
|
|
131
|
+
getPathname(this: RenderResult): string {
|
|
132
|
+
const containers = findAll(this.root, (node) => {
|
|
133
|
+
return node.type === BaseNavigationContainer;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
"/" +
|
|
138
|
+
containers
|
|
139
|
+
.flatMap((route) => {
|
|
140
|
+
return route.props.initialState.routes.map((r: any) => r.name);
|
|
141
|
+
})
|
|
142
|
+
.join("/")
|
|
143
|
+
);
|
|
144
|
+
},
|
|
145
|
+
getSearchParams(this: RenderResult): URLSearchParams {
|
|
146
|
+
const containers = findAll(this.root, (node) => {
|
|
147
|
+
return node.type === BaseNavigationContainer;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const params = containers.reduce<Record<string, string>>((acc, route) => {
|
|
151
|
+
return { ...acc, ...route.props.initialState.routes[0].params };
|
|
152
|
+
}, {});
|
|
153
|
+
|
|
154
|
+
return new URLSearchParams(params);
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "@testing-library/jest-native/extend-expect";
|
|
2
|
+
|
|
3
|
+
// include this section and the NativeAnimatedHelper section for mocking react-native-reanimated
|
|
4
|
+
jest.mock("react-native-reanimated", () => {
|
|
5
|
+
const Reanimated = require("react-native-reanimated/mock");
|
|
6
|
+
|
|
7
|
+
// The mock for `call` immediately calls the callback which is incorrect
|
|
8
|
+
// So we override it with a no-op
|
|
9
|
+
Reanimated.default.call = () => {};
|
|
10
|
+
|
|
11
|
+
return Reanimated;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
|
|
15
|
+
jest.mock("react-native/Libraries/Animated/NativeAnimatedHelper");
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
import { RequireContext } from "../types";
|
|
5
|
+
|
|
6
|
+
export default function requireContext(
|
|
7
|
+
base = ".",
|
|
8
|
+
scanSubDirectories = true,
|
|
9
|
+
regularExpression = /\.[tj]sx?$/
|
|
10
|
+
) {
|
|
11
|
+
const files: Record<string, unknown> = {};
|
|
12
|
+
|
|
13
|
+
function readDirectory(directory: string) {
|
|
14
|
+
fs.readdirSync(directory).forEach((file: string) => {
|
|
15
|
+
const fullPath = path.resolve(directory, file);
|
|
16
|
+
const relativePath = `./${path.relative(base, fullPath)}`;
|
|
17
|
+
|
|
18
|
+
if (fs.statSync(fullPath).isDirectory()) {
|
|
19
|
+
if (scanSubDirectories) readDirectory(fullPath);
|
|
20
|
+
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!regularExpression.test(fullPath)) return;
|
|
25
|
+
|
|
26
|
+
files[relativePath] = true;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
readDirectory(base);
|
|
31
|
+
|
|
32
|
+
const context: RequireContext = Object.assign(
|
|
33
|
+
function Module(file: string) {
|
|
34
|
+
return require(path.join(base, file));
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
keys: () => Object.keys(files),
|
|
38
|
+
resolve: (key: string) => key,
|
|
39
|
+
id: "0",
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
return context;
|
|
44
|
+
}
|
package/src/views/EmptyRoute.tsx
CHANGED
|
@@ -3,8 +3,8 @@ import React from "react";
|
|
|
3
3
|
import { Platform, ScrollView, TouchableOpacity } from "react-native";
|
|
4
4
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
5
5
|
|
|
6
|
-
import { ErrorBoundaryProps } from "./Try";
|
|
7
6
|
import { Link } from "../link/Link";
|
|
7
|
+
import { ErrorBoundaryProps } from "./Try";
|
|
8
8
|
|
|
9
9
|
export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
|
|
10
10
|
return (
|
package/src/views/Navigator.tsx
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
} from "@react-navigation/native";
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
|
|
8
|
-
import { Screen } from "./Screen";
|
|
9
8
|
import { useContextKey } from "../Route";
|
|
10
9
|
import { useFilterScreenChildren } from "../layouts/withLayoutContext";
|
|
11
10
|
import { useSortedScreens } from "../useScreens";
|
|
11
|
+
import { Screen } from "./Screen";
|
|
12
12
|
|
|
13
13
|
type NavigatorTypes = ReturnType<typeof useNavigationBuilder>;
|
|
14
14
|
|
package/types/jest.d.ts
ADDED
package/build/head/Head.d.ts
DELETED
package/build/head/Head.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Head.d.ts","sourceRoot":"","sources":["../../src/head/Head.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAU,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE5D,QAAA,MAAM,IAAI;cAGE,qBAAqB;CAChC,CAAC;AAIF,eAAe,IAAI,CAAC"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
declare function Head({ children, }: {
|
|
3
|
-
children?: React.ReactNode;
|
|
4
|
-
}): React.ReactElement;
|
|
5
|
-
declare namespace Head {
|
|
6
|
-
var Provider: React.ExoticComponent<{
|
|
7
|
-
children?: React.ReactNode;
|
|
8
|
-
}>;
|
|
9
|
-
}
|
|
10
|
-
export default Head;
|
|
11
|
-
//# sourceMappingURL=Head.native.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Head.native.d.ts","sourceRoot":"","sources":["../../src/head/Head.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA6B1B,iBAAS,IAAI,CAAC,EACZ,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,GAAG,KAAK,CAAC,YAAY,CAwCrB;kBA5CQ,IAAI;;;;;AAgDb,eAAe,IAAI,CAAC"}
|
package/src/head/Head.native.tsx
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
3
|
-
import { useNavigation } from "../useNavigation";
|
|
4
|
-
|
|
5
|
-
function formatLikeConsoleLog(args: any) {
|
|
6
|
-
if (typeof args === "string") {
|
|
7
|
-
return args;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let str = "";
|
|
11
|
-
if (Array.isArray(args)) {
|
|
12
|
-
for (const arg of args) {
|
|
13
|
-
if (str.length > 0) {
|
|
14
|
-
str += " ";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (typeof arg === "string") {
|
|
18
|
-
str += arg;
|
|
19
|
-
} else if (Array.isArray(arg)) {
|
|
20
|
-
str += formatLikeConsoleLog(arg);
|
|
21
|
-
} else {
|
|
22
|
-
str += JSON.stringify(arg);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return str;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function Head({
|
|
31
|
-
children,
|
|
32
|
-
}: {
|
|
33
|
-
children?: React.ReactNode;
|
|
34
|
-
}): React.ReactElement {
|
|
35
|
-
const navigation = useNavigation();
|
|
36
|
-
|
|
37
|
-
const { renderableChildren, metaChildren } = React.useMemo(() => {
|
|
38
|
-
const renderableChildren: any[] = [];
|
|
39
|
-
const metaChildren: any[] = [];
|
|
40
|
-
|
|
41
|
-
React.Children.forEach(children, (child) => {
|
|
42
|
-
if (!React.isValidElement(child)) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
if (typeof child.type === "string") {
|
|
46
|
-
metaChildren.push(child);
|
|
47
|
-
} else {
|
|
48
|
-
renderableChildren.push(child);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return { renderableChildren, metaChildren };
|
|
53
|
-
}, [children]);
|
|
54
|
-
|
|
55
|
-
const title = React.useMemo(() => {
|
|
56
|
-
for (const child of metaChildren) {
|
|
57
|
-
if (child.type === "title") {
|
|
58
|
-
return child.props.children;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return undefined;
|
|
63
|
-
}, [metaChildren]);
|
|
64
|
-
|
|
65
|
-
React.useEffect(() => {
|
|
66
|
-
if (title !== undefined) {
|
|
67
|
-
navigation.setOptions({
|
|
68
|
-
title: formatLikeConsoleLog(title),
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}, [title]);
|
|
72
|
-
|
|
73
|
-
return <>{renderableChildren}</>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
Head.Provider = React.Fragment;
|
|
77
|
-
|
|
78
|
-
export default Head;
|
package/src/head/Head.tsx
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { Helmet, HelmetProvider } from "react-helmet-async";
|
|
3
|
-
|
|
4
|
-
const Head = (({ children }: { children?: React.ReactNode }) => {
|
|
5
|
-
return <Helmet>{children}</Helmet>;
|
|
6
|
-
}) as React.FC & {
|
|
7
|
-
Provider: typeof HelmetProvider;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
Head.Provider = HelmetProvider;
|
|
11
|
-
|
|
12
|
-
export default Head;
|