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.
Files changed (63) hide show
  1. package/app.plugin.js +1 -0
  2. package/babel.js +7 -1
  3. package/build/ExpoRoot.d.ts.map +1 -1
  4. package/build/fork/getStateFromPath.d.ts.map +1 -1
  5. package/build/fork/useLinking.native.d.ts.map +1 -1
  6. package/build/layouts/Tabs.d.ts.map +1 -1
  7. package/build/link/Link.d.ts.map +1 -1
  8. package/build/link/linking.d.ts +1 -1
  9. package/build/link/linking.d.ts.map +1 -1
  10. package/build/link/useHref.d.ts.map +1 -1
  11. package/build/link/useLinkToPath.d.ts.map +1 -1
  12. package/build/link/useRouter.d.ts.map +1 -1
  13. package/build/navigationStore/index.d.ts.map +1 -1
  14. package/build/navigationStore/initialState.d.ts.map +1 -1
  15. package/build/testing-library/expect.d.ts +2 -0
  16. package/build/testing-library/expect.d.ts.map +1 -0
  17. package/build/testing-library/index.d.ts +19 -0
  18. package/build/testing-library/index.d.ts.map +1 -0
  19. package/build/testing-library/mocks.d.ts +2 -0
  20. package/build/testing-library/mocks.d.ts.map +1 -0
  21. package/build/testing-library/require-context-ponyfill.d.ts +3 -0
  22. package/build/testing-library/require-context-ponyfill.d.ts.map +1 -0
  23. package/build/useScreens.d.ts +1 -1
  24. package/build/useScreens.d.ts.map +1 -1
  25. package/build/views/ErrorBoundary.d.ts.map +1 -1
  26. package/build/views/SuspenseFallback.d.ts.map +1 -1
  27. package/entry.js +1 -2
  28. package/head.ts +5 -2
  29. package/package.json +9 -2
  30. package/plugin/build/index.d.ts +12 -0
  31. package/plugin/build/index.js +18 -0
  32. package/plugin/options.json +48 -0
  33. package/plugin/src/index.ts +30 -0
  34. package/plugin/tsconfig.json +9 -0
  35. package/src/ExpoRoot.tsx +1 -0
  36. package/src/fork/getStateFromPath.ts +2 -2
  37. package/src/fork/useLinking.native.ts +2 -1
  38. package/src/layouts/Tabs.tsx +1 -1
  39. package/src/link/Link.tsx +1 -1
  40. package/src/link/linking.ts +5 -1
  41. package/src/link/useHref.ts +1 -1
  42. package/src/link/useLinkToPath.ts +1 -1
  43. package/src/link/useLinkToPathProps.tsx +1 -1
  44. package/src/link/useRouter.ts +1 -1
  45. package/src/navigationStore/index.ts +11 -3
  46. package/src/navigationStore/initialState.ts +6 -4
  47. package/src/static/renderStaticContent.tsx +2 -2
  48. package/src/testing-library/expect.ts +15 -0
  49. package/src/testing-library/index.tsx +159 -0
  50. package/src/testing-library/mocks.ts +15 -0
  51. package/src/testing-library/require-context-ponyfill.ts +44 -0
  52. package/src/views/EmptyRoute.tsx +1 -1
  53. package/src/views/ErrorBoundary.tsx +1 -1
  54. package/src/views/Navigator.tsx +1 -1
  55. package/src/views/SuspenseFallback.tsx +1 -1
  56. package/types/expect.d.ts +4 -0
  57. package/types/jest.d.ts +9 -0
  58. package/build/head/Head.d.ts +0 -7
  59. package/build/head/Head.d.ts.map +0 -1
  60. package/build/head/Head.native.d.ts +0 -11
  61. package/build/head/Head.native.d.ts.map +0 -1
  62. package/src/head/Head.native.tsx +0 -78
  63. 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 `extra.router.asyncRoutes` to `development`, `false`, or `undefined`."
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))
@@ -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,eAahE"}
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;AAMnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,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
+ {"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2KX"}
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;AAK1B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAKpC,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Cf,CAAC;AAEH,eAAe,IAAI,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"}
@@ -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;AAE/D,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAK3C,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"}
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"}
@@ -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,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CA6CrD;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
+ {"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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGpC,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
+ {"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;AAMhC,OAAO,EAKL,cAAc,EACf,MAAM,mBAAmB,CAAC;AAe3B,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
+ {"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":"AAEA,OAAO,EAAE,IAAI,EAAe,MAAM,QAAQ,CAAC;AAM3C,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
+ {"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,EAGb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,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;AAE1C,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
+ {"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAkBlB"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=expect.d.ts.map
@@ -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,2 @@
1
+ import "@testing-library/jest-native/extend-expect";
2
+ //# sourceMappingURL=mocks.d.ts.map
@@ -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,3 @@
1
+ import { RequireContext } from "../types";
2
+ export default function requireContext(base?: string, scanSubDirectories?: boolean, regularExpression?: RegExp): RequireContext;
3
+ //# sourceMappingURL=require-context-ponyfill.d.ts.map
@@ -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"}
@@ -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<Omit<any, "ref"> & React.RefAttributes<unknown>>;
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,+GAuE1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;;sCA0B5C"}
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":";AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAG3C,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,kBAAkB,eAkEjE"}
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":";AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,eAM/D"}
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
@@ -1,7 +1,6 @@
1
- import "@expo/metro-runtime";
2
-
3
1
  import { ExpoRoot } from "expo-router";
4
2
  import Head from "expo-router/head";
3
+ import "@expo/metro-runtime";
5
4
  import { renderRootComponent } from "expo-router/src/renderRootComponent";
6
5
 
7
6
  const ctx = require.context(
package/head.ts CHANGED
@@ -1,3 +1,6 @@
1
- import Head from "./src/head/Head";
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.6.0",
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.0",
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;
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "expo-module-scripts/tsconfig.plugin",
3
+ "compilerOptions": {
4
+ "outDir": "build",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["./src"],
8
+ "exclude": ["**/__mocks__/*", "**/__tests__/*"]
9
+ }
package/src/ExpoRoot.tsx CHANGED
@@ -32,6 +32,7 @@ export function ExpoRoot({ context }: { context: RequireContext }) {
32
32
  return (
33
33
  <GestureHandlerRootView>
34
34
  <SafeAreaProvider
35
+ testID="test"
35
36
  // SSR support
36
37
  initialMetrics={INITIAL_METRICS}
37
38
  >
@@ -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
- return Promise.resolve(onfulfilled ? onfulfilled(state) : state);
159
+ onfulfilled?.(state);
160
+ return thenable;
160
161
  },
161
162
  catch() {
162
163
  return thenable;
@@ -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. */
@@ -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 async function getInitialURL(): Promise<string> {
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 "";
@@ -1,5 +1,5 @@
1
- import { HrefObject } from "./href";
2
1
  import { usePathname, useSearchParams, useSegments } from "../navigationStore";
2
+ import { HrefObject } from "./href";
3
3
 
4
4
  /** @deprecated */
5
5
  type RouteInfo = Omit<Required<HrefObject>, "query"> & {
@@ -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
@@ -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
- useRoute,
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 (useRoute()?.params ?? ({} as any)) as Partial<TParams>;
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 linking.getStateFromPath?.(
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
+ }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { Toast, ToastWrapper } from "./Toast";
4
3
  import { useRouteNode } from "../Route";
4
+ import { Toast, ToastWrapper } from "./Toast";
5
5
 
6
6
  export function EmptyRoute() {
7
7
  const route = useRouteNode();
@@ -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 (
@@ -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
 
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { Toast, ToastWrapper } from "./Toast";
4
3
  import { RouteNode } from "../Route";
4
+ import { Toast, ToastWrapper } from "./Toast";
5
5
 
6
6
  export function SuspenseFallback({ route }: { route: RouteNode }) {
7
7
  return (
@@ -0,0 +1,4 @@
1
+ declare module "expect/build/matchers" {
2
+ const matchers: any;
3
+ export default matchers;
4
+ }
@@ -0,0 +1,9 @@
1
+ export {};
2
+ declare global {
3
+ namespace jest {
4
+ interface Matchers<R> {
5
+ toHavePathname(pathname: string): R;
6
+ toHaveSearchParams(params: Record<string, string>): R;
7
+ }
8
+ }
9
+ }
@@ -1,7 +0,0 @@
1
- import React from "react";
2
- import { HelmetProvider } from "react-helmet-async";
3
- declare const Head: React.FC<{}> & {
4
- Provider: typeof HelmetProvider;
5
- };
6
- export default Head;
7
- //# sourceMappingURL=Head.d.ts.map
@@ -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"}
@@ -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;