expo-router 4.0.17 → 4.0.18-canary-20250303-4dba60e

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 (94) hide show
  1. package/build/Route.d.ts +10 -10
  2. package/build/Route.d.ts.map +1 -1
  3. package/build/Route.js +4 -27
  4. package/build/Route.js.map +1 -1
  5. package/build/exports.d.ts +1 -0
  6. package/build/exports.d.ts.map +1 -1
  7. package/build/exports.js +3 -1
  8. package/build/exports.js.map +1 -1
  9. package/build/fast-refresh.d.ts.map +1 -1
  10. package/build/fast-refresh.js +0 -4
  11. package/build/fast-refresh.js.map +1 -1
  12. package/build/fork/getPathFromState.d.ts.map +1 -1
  13. package/build/fork/getPathFromState.js +29 -7
  14. package/build/fork/getPathFromState.js.map +1 -1
  15. package/build/fork/getStateFromPath-forks.d.ts +1 -1
  16. package/build/fork/native-stack/NativeStackView.d.ts +4 -0
  17. package/build/fork/native-stack/NativeStackView.d.ts.map +1 -0
  18. package/build/fork/native-stack/NativeStackView.js +27 -0
  19. package/build/fork/native-stack/NativeStackView.js.map +1 -0
  20. package/build/fork/native-stack/createNativeStackNavigator.d.ts +17 -0
  21. package/build/fork/native-stack/createNativeStackNavigator.d.ts.map +1 -0
  22. package/build/fork/native-stack/createNativeStackNavigator.js +66 -0
  23. package/build/fork/native-stack/createNativeStackNavigator.js.map +1 -0
  24. package/build/fork/useLinking.d.ts +1 -0
  25. package/build/fork/useLinking.d.ts.map +1 -1
  26. package/build/fork/useLinking.js +5 -1
  27. package/build/fork/useLinking.js.map +1 -1
  28. package/build/fork/useLinking.native.d.ts +1 -0
  29. package/build/fork/useLinking.native.d.ts.map +1 -1
  30. package/build/fork/useLinking.native.js +21 -9
  31. package/build/fork/useLinking.native.js.map +1 -1
  32. package/build/getRoutesCore.js +23 -19
  33. package/build/getRoutesCore.js.map +1 -1
  34. package/build/global-state/routing.d.ts +1 -1
  35. package/build/global-state/routing.js.map +1 -1
  36. package/build/hooks.d.ts +23 -8
  37. package/build/hooks.d.ts.map +1 -1
  38. package/build/hooks.js +4 -4
  39. package/build/hooks.js.map +1 -1
  40. package/build/imperative-api.d.ts +2 -2
  41. package/build/imperative-api.js.map +1 -1
  42. package/build/layouts/RootModal.d.ts +13 -0
  43. package/build/layouts/RootModal.d.ts.map +1 -0
  44. package/build/layouts/RootModal.js +26 -0
  45. package/build/layouts/RootModal.js.map +1 -0
  46. package/build/layouts/StackClient.d.ts.map +1 -1
  47. package/build/layouts/StackClient.js +2 -2
  48. package/build/layouts/StackClient.js.map +1 -1
  49. package/build/layouts/withLayoutContext.d.ts +26 -0
  50. package/build/layouts/withLayoutContext.d.ts.map +1 -1
  51. package/build/layouts/withLayoutContext.js +26 -0
  52. package/build/layouts/withLayoutContext.js.map +1 -1
  53. package/build/link/Link.d.ts +1 -1
  54. package/build/link/Link.d.ts.map +1 -1
  55. package/build/link/Link.js.map +1 -1
  56. package/build/link/linking.d.ts.map +1 -1
  57. package/build/link/linking.js +19 -17
  58. package/build/link/linking.js.map +1 -1
  59. package/build/link/useLinkHooks.d.ts +1 -1
  60. package/build/link/useLinkHooks.js.map +1 -1
  61. package/build/link/useLinkToPathProps.d.ts.map +1 -1
  62. package/build/link/useLinkToPathProps.js +2 -2
  63. package/build/link/useLinkToPathProps.js.map +1 -1
  64. package/build/rsc/router/host.d.ts.map +1 -1
  65. package/build/rsc/router/host.js +15 -1
  66. package/build/rsc/router/host.js.map +1 -1
  67. package/build/typed-routes/types.d.ts +40 -16
  68. package/build/typed-routes/types.d.ts.map +1 -1
  69. package/build/typed-routes/types.js.map +1 -1
  70. package/build/ui/TabContext.d.ts +2 -8
  71. package/build/ui/TabContext.d.ts.map +1 -1
  72. package/build/ui/TabContext.js.map +1 -1
  73. package/build/ui/TabRouter.d.ts +1 -1
  74. package/build/ui/TabRouter.d.ts.map +1 -1
  75. package/build/ui/TabRouter.js.map +1 -1
  76. package/build/ui/TabSlot.d.ts +5 -6
  77. package/build/ui/TabSlot.d.ts.map +1 -1
  78. package/build/ui/TabSlot.js +4 -7
  79. package/build/ui/TabSlot.js.map +1 -1
  80. package/build/ui/Tabs.d.ts +13 -8
  81. package/build/ui/Tabs.d.ts.map +1 -1
  82. package/build/ui/Tabs.js +5 -2
  83. package/build/ui/Tabs.js.map +1 -1
  84. package/build/useNavigation.d.ts +2 -2
  85. package/build/useNavigation.js +2 -2
  86. package/build/useNavigation.js.map +1 -1
  87. package/build/useScreens.d.ts +5 -5
  88. package/build/useScreens.d.ts.map +1 -1
  89. package/build/useScreens.js +14 -8
  90. package/build/useScreens.js.map +1 -1
  91. package/expo-module.config.json +2 -3
  92. package/package.json +8 -8
  93. package/plugin/build/index.js +0 -4
  94. package/plugin/src/index.ts +0 -5
@@ -1 +1 @@
1
- {"version":3,"file":"TabSlot.d.ts","sourceRoot":"","sources":["../../src/ui/TabSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAU,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAc,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,MAAM,iBAAiB,GAAG,cAAc,CAAC,OAAO,eAAe,CAAC,GAAG;IACvE;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,qBAAqB,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,+BAsCzD;AAED,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,+BAE1C;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,cAAc,EAC1B,EAAE,SAAS,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,qBAAqB,sCAuBpE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,YAAY,CAAC,YAAY,CAAC,CAEvF"}
1
+ {"version":3,"file":"TabSlot.d.ts","sourceRoot":"","sources":["../../src/ui/TabSlot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAY,MAAM,OAAO,CAAC;AAE/D,OAAO,EAAE,eAAe,EAAU,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAc,cAAc,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,eAAe,CAAC,GAAG;IAClE;;OAEG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,qBAAqB,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,EACzB,qBAAuE,EACvE,KAAK,EACL,QAAgC,GACjC,GAAE,YAAiB,+BA8BnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,+BAE1C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,cAAc,EAC1B,EAAE,SAAS,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,qBAAqB,sCAuBpE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,YAAY,CAAC,YAAY,CAAC,CAEvF"}
@@ -7,11 +7,8 @@ const react_native_screens_1 = require("react-native-screens");
7
7
  const TabContext_1 = require("./TabContext");
8
8
  const Navigator_1 = require("../views/Navigator");
9
9
  /**
10
- *
11
10
  * Returns a `ReactElement` of the current tab.
12
11
  *
13
- * @see [`useTabSlot`](#usetabslotoptions).
14
- *
15
12
  * @example
16
13
  * ```tsx
17
14
  * function MyTabSlot() {
@@ -21,10 +18,7 @@ const Navigator_1 = require("../views/Navigator");
21
18
  * }
22
19
  * ```
23
20
  */
24
- function useTabSlot(options = {}) {
25
- const { detachInactiveScreens = react_native_1.Platform.OS === 'web' ||
26
- react_native_1.Platform.OS === 'android' ||
27
- react_native_1.Platform.OS === 'ios', style, renderFn = defaultTabsSlotRender, } = options;
21
+ function useTabSlot({ detachInactiveScreens = ['android', 'ios', 'web'].includes(react_native_1.Platform.OS), style, renderFn = defaultTabsSlotRender, } = {}) {
28
22
  const { state, descriptors } = (0, Navigator_1.useNavigatorContext)();
29
23
  const focusedRouteKey = state.routes[state.index].key;
30
24
  const [loaded, setLoaded] = (0, react_1.useState)({ [focusedRouteKey]: true });
@@ -65,6 +59,9 @@ function TabSlot(props) {
65
59
  return useTabSlot(props);
66
60
  }
67
61
  exports.TabSlot = TabSlot;
62
+ /**
63
+ * @hidden
64
+ */
68
65
  function defaultTabsSlotRender(descriptor, { isFocused, loaded, detachInactiveScreens }) {
69
66
  const { lazy = true, unmountOnBlur, freezeOnBlur } = descriptor.options;
70
67
  if (unmountOnBlur && !isFocused) {
@@ -1 +1 @@
1
- {"version":3,"file":"TabSlot.js","sourceRoot":"","sources":["../../src/ui/TabSlot.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ComponentProps, ReactElement, useState } from 'react';\nimport { Platform, StyleSheet } from 'react-native';\nimport { ScreenContainer, Screen } from 'react-native-screens';\n\nimport { TabContext, TabsDescriptor } from './TabContext';\nimport { TabListProps } from './TabList';\nimport { useNavigatorContext } from '../views/Navigator';\n\nexport type UseTabSlotOptions = ComponentProps<typeof ScreenContainer> & {\n /**\n * Remove inactive screens.\n */\n detachInactiveScreens?: boolean;\n /**\n * Override how the `Screen` component is rendered.\n */\n renderFn?: typeof defaultTabsSlotRender;\n};\n\n/**\n * Options provided to the `UseTabSlotOptions`.\n */\nexport type TabsSlotRenderOptions = {\n /**\n * Index of screen.\n */\n index: number;\n /**\n * Whether the screen is focused.\n */\n isFocused: boolean;\n /**\n * Whether the screen has been loaded.\n */\n loaded: boolean;\n /**\n * Should the screen be unloaded when inactive.\n */\n detachInactiveScreens: boolean;\n};\n\n/**\n *\n * Returns a `ReactElement` of the current tab.\n *\n * @see [`useTabSlot`](#usetabslotoptions).\n *\n * @example\n * ```tsx\n * function MyTabSlot() {\n * const slot = useTabSlot();\n *\n * return slot;\n * }\n * ```\n */\nexport function useTabSlot(options: UseTabSlotOptions = {}) {\n const {\n detachInactiveScreens = Platform.OS === 'web' ||\n Platform.OS === 'android' ||\n Platform.OS === 'ios',\n style,\n renderFn = defaultTabsSlotRender,\n } = options;\n\n const { state, descriptors } = useNavigatorContext();\n const focusedRouteKey = state.routes[state.index].key;\n const [loaded, setLoaded] = useState({ [focusedRouteKey]: true });\n\n if (!loaded[focusedRouteKey]) {\n setLoaded({ ...loaded, [focusedRouteKey]: true });\n }\n\n return (\n <ScreenContainer\n enabled={detachInactiveScreens}\n hasTwoStates\n style={[styles.screenContainer, style]}>\n {state.routes.map((route, index) => {\n const descriptor = descriptors[route.key] as unknown as TabsDescriptor;\n\n return (\n <TabContext.Provider key={descriptor.route.key} value={descriptor.options}>\n {renderFn(descriptor, {\n index,\n isFocused: state.index === index,\n loaded: loaded[route.key],\n detachInactiveScreens,\n })}\n </TabContext.Provider>\n );\n })}\n </ScreenContainer>\n );\n}\n\nexport type TabSlotProps = UseTabSlotOptions;\n\n/**\n * Renders the current tab.\n *\n * @see [`useTabSlot`](#usetabslot) for a hook version of this component.\n *\n * @example\n * ```tsx\n * <Tabs>\n * <TabSlot />\n * <TabList>\n * <TabTrigger name=\"home\" href=\"/\" />\n * </TabList>\n * </Tabs>\n * ```\n */\nexport function TabSlot(props: TabSlotProps) {\n return useTabSlot(props);\n}\n\nexport function defaultTabsSlotRender(\n descriptor: TabsDescriptor,\n { isFocused, loaded, detachInactiveScreens }: TabsSlotRenderOptions\n) {\n const { lazy = true, unmountOnBlur, freezeOnBlur } = descriptor.options;\n\n if (unmountOnBlur && !isFocused) {\n return null;\n }\n\n if (lazy && !loaded && !isFocused) {\n // Don't render a lazy screen if we've never navigated to it\n return null;\n }\n\n return (\n <Screen\n key={descriptor.route.key}\n enabled={detachInactiveScreens}\n activityState={isFocused ? 2 : 0}\n freezeOnBlur={freezeOnBlur}\n style={[styles.screen, isFocused ? styles.focused : styles.unfocused]}>\n {descriptor.render()}\n </Screen>\n );\n}\n\n/**\n * @hidden\n */\nexport function isTabSlot(child: ReactElement<any>): child is ReactElement<TabListProps> {\n return child.type === TabSlot;\n}\n\nconst styles = StyleSheet.create({\n screen: {\n flex: 1,\n position: 'relative',\n height: '100%',\n },\n screenContainer: {\n flexShrink: 0,\n flexGrow: 1,\n },\n focused: {\n zIndex: 1,\n display: 'flex',\n flexShrink: 0,\n flexGrow: 1,\n },\n unfocused: {\n zIndex: -1,\n display: 'none',\n flexShrink: 1,\n flexGrow: 0,\n },\n});\n"]}
1
+ {"version":3,"file":"TabSlot.js","sourceRoot":"","sources":["../../src/ui/TabSlot.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ComponentProps, ReactElement, useState } from 'react';\nimport { Platform, StyleSheet } from 'react-native';\nimport { ScreenContainer, Screen } from 'react-native-screens';\n\nimport { TabContext, TabsDescriptor } from './TabContext';\nimport { TabListProps } from './TabList';\nimport { useNavigatorContext } from '../views/Navigator';\n\nexport type TabSlotProps = ComponentProps<typeof ScreenContainer> & {\n /**\n * Remove inactive screens.\n */\n detachInactiveScreens?: boolean;\n /**\n * Override how the `Screen` component is rendered.\n */\n renderFn?: typeof defaultTabsSlotRender;\n};\n\n/**\n * Options provided to the `UseTabSlotOptions`.\n */\nexport type TabsSlotRenderOptions = {\n /**\n * Index of screen.\n */\n index: number;\n /**\n * Whether the screen is focused.\n */\n isFocused: boolean;\n /**\n * Whether the screen has been loaded.\n */\n loaded: boolean;\n /**\n * Should the screen be unloaded when inactive.\n */\n detachInactiveScreens: boolean;\n};\n\n/**\n * Returns a `ReactElement` of the current tab.\n *\n * @example\n * ```tsx\n * function MyTabSlot() {\n * const slot = useTabSlot();\n *\n * return slot;\n * }\n * ```\n */\nexport function useTabSlot({\n detachInactiveScreens = ['android', 'ios', 'web'].includes(Platform.OS),\n style,\n renderFn = defaultTabsSlotRender,\n}: TabSlotProps = {}) {\n const { state, descriptors } = useNavigatorContext();\n const focusedRouteKey = state.routes[state.index].key;\n const [loaded, setLoaded] = useState({ [focusedRouteKey]: true });\n\n if (!loaded[focusedRouteKey]) {\n setLoaded({ ...loaded, [focusedRouteKey]: true });\n }\n\n return (\n <ScreenContainer\n enabled={detachInactiveScreens}\n hasTwoStates\n style={[styles.screenContainer, style]}>\n {state.routes.map((route, index) => {\n const descriptor = descriptors[route.key] as unknown as TabsDescriptor;\n\n return (\n <TabContext.Provider key={descriptor.route.key} value={descriptor.options}>\n {renderFn(descriptor, {\n index,\n isFocused: state.index === index,\n loaded: loaded[route.key],\n detachInactiveScreens,\n })}\n </TabContext.Provider>\n );\n })}\n </ScreenContainer>\n );\n}\n\n/**\n * Renders the current tab.\n *\n * @see [`useTabSlot`](#usetabslot) for a hook version of this component.\n *\n * @example\n * ```tsx\n * <Tabs>\n * <TabSlot />\n * <TabList>\n * <TabTrigger name=\"home\" href=\"/\" />\n * </TabList>\n * </Tabs>\n * ```\n */\nexport function TabSlot(props: TabSlotProps) {\n return useTabSlot(props);\n}\n\n/**\n * @hidden\n */\nexport function defaultTabsSlotRender(\n descriptor: TabsDescriptor,\n { isFocused, loaded, detachInactiveScreens }: TabsSlotRenderOptions\n) {\n const { lazy = true, unmountOnBlur, freezeOnBlur } = descriptor.options;\n\n if (unmountOnBlur && !isFocused) {\n return null;\n }\n\n if (lazy && !loaded && !isFocused) {\n // Don't render a lazy screen if we've never navigated to it\n return null;\n }\n\n return (\n <Screen\n key={descriptor.route.key}\n enabled={detachInactiveScreens}\n activityState={isFocused ? 2 : 0}\n freezeOnBlur={freezeOnBlur}\n style={[styles.screen, isFocused ? styles.focused : styles.unfocused]}>\n {descriptor.render()}\n </Screen>\n );\n}\n\n/**\n * @hidden\n */\nexport function isTabSlot(child: ReactElement<any>): child is ReactElement<TabListProps> {\n return child.type === TabSlot;\n}\n\nconst styles = StyleSheet.create({\n screen: {\n flex: 1,\n position: 'relative',\n height: '100%',\n },\n screenContainer: {\n flexShrink: 0,\n flexGrow: 1,\n },\n focused: {\n zIndex: 1,\n display: 'flex',\n flexShrink: 0,\n flexGrow: 1,\n },\n unfocused: {\n zIndex: -1,\n display: 'none',\n flexShrink: 1,\n flexGrow: 0,\n },\n});\n"]}
@@ -1,5 +1,5 @@
1
1
  import { DefaultNavigatorOptions, ParamListBase, TabActionHelpers, TabNavigationState, TabRouterOptions } from '@react-navigation/native';
2
- import { ReactNode } from 'react';
2
+ import { ReactNode, PropsWithChildren } from 'react';
3
3
  import { ViewProps } from 'react-native';
4
4
  import { ExpoTabsScreenOptions, TabNavigationEventMap, TabsContextValue } from './TabContext';
5
5
  import { ScreenTrigger } from './common';
@@ -7,6 +7,7 @@ export * from './TabContext';
7
7
  export * from './TabList';
8
8
  export * from './TabSlot';
9
9
  export * from './TabTrigger';
10
+ export { ExpoTabsResetValue } from './TabRouter';
10
11
  /**
11
12
  * Options to provide to the Tab Router.
12
13
  */
@@ -33,15 +34,16 @@ export type TabsProps = ViewProps & {
33
34
  * ```
34
35
  */
35
36
  export declare function Tabs(props: TabsProps): import("react").JSX.Element;
36
- export type UseTabsWithChildrenOptions = UseTabsOptions & {
37
- children: ReactNode;
38
- };
37
+ export type UseTabsWithChildrenOptions = PropsWithChildren<UseTabsOptions>;
39
38
  export type UseTabsWithTriggersOptions = UseTabsOptions & {
40
39
  triggers: ScreenTrigger[];
41
40
  };
42
41
  /**
43
42
  * Hook version of `Tabs`. The returned NavigationContent component
44
- * should be rendered.
43
+ * should be rendered. Using the hook requires using the `<TabList />`
44
+ * and `<TabTrigger />` components exported from Expo Router.
45
+ *
46
+ * The `useTabsWithTriggers()` hook can be used for custom components.
45
47
  *
46
48
  * @see [`Tabs`](#tabs) for the component version of this hook.
47
49
  * @example
@@ -64,6 +66,9 @@ export declare function useTabsWithChildren(options: UseTabsWithChildrenOptions)
64
66
  }> | ((state: Readonly<Readonly<{
65
67
  key: string;
66
68
  index: number;
69
+ /**
70
+ * Options to provide to the Tab Router.
71
+ */
67
72
  routeNames: string[];
68
73
  history?: unknown[] | undefined;
69
74
  routes: import("@react-navigation/native").NavigationRoute<ParamListBase, string>[];
@@ -75,7 +80,7 @@ export declare function useTabsWithChildren(options: UseTabsWithChildrenOptions)
75
80
  source?: string | undefined;
76
81
  target?: string | undefined;
77
82
  }>)): void;
78
- navigate<RouteName extends string>(...args: [screen: string] | [screen: string, params: object | undefined]): void;
83
+ navigate<RouteName extends string>(...args: [screen: string] | [screen: string, params: object | undefined] | [screen: string, params: object | undefined, merge: boolean]): void;
79
84
  navigate<RouteName_1 extends string>(options: {
80
85
  name: string;
81
86
  params: object | undefined;
@@ -152,7 +157,7 @@ export declare function useTabsWithChildren(options: UseTabsWithChildrenOptions)
152
157
  source?: string | undefined;
153
158
  target?: string | undefined;
154
159
  }>)): void;
155
- navigate<RouteName_6 extends string>(...args: [screen: string] | [screen: string, params: object | undefined]): void;
160
+ navigate<RouteName_6 extends string>(...args: [screen: string] | [screen: string, params: object | undefined] | [screen: string, params: object | undefined, merge: boolean]): void;
156
161
  navigate<RouteName_7 extends string>(options: {
157
162
  name: string;
158
163
  params: object | undefined;
@@ -199,7 +204,7 @@ export declare function useTabsWithChildren(options: UseTabsWithChildrenOptions)
199
204
  source?: string | undefined;
200
205
  target?: string | undefined;
201
206
  }>)): void;
202
- navigate<RouteName_11 extends string>(...args: [screen: string] | [screen: string, params: object | undefined]): void;
207
+ navigate<RouteName_11 extends string>(...args: [screen: string] | [screen: string, params: object | undefined] | [screen: string, params: object | undefined, merge: boolean]): void;
203
208
  navigate<RouteName_12 extends string>(options: {
204
209
  name: string;
205
210
  params: object | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/ui/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAKL,SAAS,EAIV,MAAM,OAAO,CAAC;AACf,OAAO,EAAc,SAAS,EAAQ,MAAM,cAAc,CAAC;AAE3D,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAKtB,OAAO,EAAoB,aAAa,EAAqB,MAAM,UAAU,CAAC;AAQ9E,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,uBAAuB,CACrB,aAAa,EACb,GAAG,EACH,kBAAkB,CAAC,GAAG,CAAC,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,GAAG,CACJ,EACD,UAAU,CACX,GAAG;IACF,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG;IAClC,mGAAmG;IACnG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,+BAepC;AAED,MAAM,MAAM,0BAA0B,GAAG,cAAc,GAAG;IACxD,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,cAAc,GAAG;IACxD,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGtE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,gBAAgB,CAiEzF"}
1
+ {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/ui/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAEjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAKL,SAAS,EAIT,iBAAiB,EAClB,MAAM,OAAO,CAAC;AACf,OAAO,EAAc,SAAS,EAAQ,MAAM,cAAc,CAAC;AAE3D,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AAKtB,OAAO,EAAoB,aAAa,EAAqB,MAAM,UAAU,CAAC;AAQ9E,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAC/B,uBAAuB,CACrB,aAAa,EACb,GAAG,EACH,kBAAkB,CAAC,GAAG,CAAC,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,GAAG,CACJ,EACD,UAAU,CACX,GAAG;IACF,YAAY,CAAC,EAAE,gBAAgB,CAAC,cAAc,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG;IAClC,mGAAmG;IACnG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,+BAepC;AAGD,MAAM,MAAM,0BAA0B,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;AAG3E,MAAM,MAAM,0BAA0B,GAAG,cAAc,GAAG;IACxD,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;;;;;;;;;;;YA/EvE;;eAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgFF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,gBAAgB,CAiEzF"}
package/build/ui/Tabs.js CHANGED
@@ -63,7 +63,10 @@ function Tabs(props) {
63
63
  exports.Tabs = Tabs;
64
64
  /**
65
65
  * Hook version of `Tabs`. The returned NavigationContent component
66
- * should be rendered.
66
+ * should be rendered. Using the hook requires using the `<TabList />`
67
+ * and `<TabTrigger />` components exported from Expo Router.
68
+ *
69
+ * The `useTabsWithTriggers()` hook can be used for custom components.
67
70
  *
68
71
  * @see [`Tabs`](#tabs) for the component version of this hook.
69
72
  * @example
@@ -151,7 +154,7 @@ function parseTriggersFromChildren(children, screenTriggers = [], isInTabList =
151
154
  const { href, name } = child.props;
152
155
  if (!href) {
153
156
  if (process.env.NODE_ENV === 'development') {
154
- console.warn(`<TabTrigger name={${name}}> does not have a 'href' prop. TabTriggers within a <TabList /> are required to have a href.`);
157
+ console.warn(`<TabTrigger name={${name}}> does not have a 'href' prop. TabTriggers within a <TabList /> are required to have an href.`);
155
158
  }
156
159
  return;
157
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../src/ui/Tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DefaultNavigatorOptions,\n LinkingContext,\n ParamListBase,\n TabActionHelpers,\n TabNavigationState,\n TabRouterOptions,\n useNavigationBuilder,\n} from '@react-navigation/native';\nimport {\n Children,\n ComponentProps,\n Fragment,\n ReactElement,\n ReactNode,\n isValidElement,\n useContext,\n useMemo,\n} from 'react';\nimport { StyleSheet, ViewProps, View } from 'react-native';\n\nimport {\n ExpoTabsScreenOptions,\n TabNavigationEventMap,\n TabTriggerMapContext,\n TabsContextValue,\n} from './TabContext';\nimport { isTabList } from './TabList';\nimport { ExpoTabRouter, ExpoTabRouterOptions } from './TabRouter';\nimport { isTabSlot } from './TabSlot';\nimport { isTabTrigger } from './TabTrigger';\nimport { SafeAreaViewSlot, ScreenTrigger, triggersToScreens } from './common';\nimport { useComponent } from './useComponent';\nimport { useRouteNode, useContextKey } from '../Route';\nimport { useRouteInfo } from '../hooks';\nimport { resolveHref } from '../link/href';\nimport { shouldLinkExternally } from '../utils/url';\nimport { NavigatorContext, NavigatorContextValue } from '../views/Navigator';\n\nexport * from './TabContext';\nexport * from './TabList';\nexport * from './TabSlot';\nexport * from './TabTrigger';\n\n/**\n * Options to provide to the Tab Router.\n */\nexport type UseTabsOptions = Omit<\n DefaultNavigatorOptions<\n ParamListBase,\n any,\n TabNavigationState<any>,\n ExpoTabsScreenOptions,\n TabNavigationEventMap,\n any\n >,\n 'children'\n> & {\n backBehavior?: TabRouterOptions['backBehavior'];\n};\n\nexport type TabsProps = ViewProps & {\n /** Forward props to child component and removes the extra `<View>`. Useful for custom wrappers. */\n asChild?: boolean;\n options?: UseTabsOptions;\n};\n\n/**\n * Root component for the headless tabs.\n *\n * @see [`useTabsWithChildren`](#usetabswithchildrenoptions) for a hook version of this component.\n * @example\n * ```tsx\n * <Tabs>\n * <TabSlot />\n * <TabList>\n * <TabTrigger name=\"home\" href=\"/\" />\n * </TabList>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: TabsProps) {\n const { children, asChild, options, ...rest } = props;\n const Comp = asChild ? SafeAreaViewSlot : View;\n\n const { NavigationContent } = useTabsWithChildren({\n // asChild adds an extra layer, so we need to process the child's children\n children: asChild && isValidElement(children) ? children.props.children : children,\n ...options,\n });\n\n return (\n <Comp style={styles.tabsRoot} {...rest}>\n <NavigationContent>{children}</NavigationContent>\n </Comp>\n );\n}\n\nexport type UseTabsWithChildrenOptions = UseTabsOptions & {\n children: ReactNode;\n};\n\nexport type UseTabsWithTriggersOptions = UseTabsOptions & {\n triggers: ScreenTrigger[];\n};\n\n/**\n * Hook version of `Tabs`. The returned NavigationContent component\n * should be rendered.\n *\n * @see [`Tabs`](#tabs) for the component version of this hook.\n * @example\n * ```tsx\n * export function MyTabs({ children }) {\n * const { NavigationContent } = useTabsWithChildren({ children })\n *\n * return <NavigationContent />\n * }\n * ```\n */\nexport function useTabsWithChildren(options: UseTabsWithChildrenOptions) {\n const { children, ...rest } = options;\n return useTabsWithTriggers({ triggers: parseTriggersFromChildren(children), ...rest });\n}\n\n/**\n * Alternative hook version of `Tabs` that uses explicit triggers\n * instead of `children`.\n *\n * @see [`Tabs`](#tabs) for the component version of this hook.\n * @example\n * ```tsx\n * export function MyTabs({ children }) {\n * const { NavigationContent } = useTabsWithChildren({ triggers: [] })\n *\n * return <NavigationContent />\n * }\n * ```\n */\nexport function useTabsWithTriggers(options: UseTabsWithTriggersOptions): TabsContextValue {\n const { triggers, ...rest } = options;\n // Ensure we extend the parent triggers, so we can trigger them as well\n const parentTriggerMap = useContext(TabTriggerMapContext);\n const routeNode = useRouteNode();\n const contextKey = useContextKey();\n const linking = useContext(LinkingContext).options;\n const routeInfo = useRouteInfo();\n\n if (!routeNode || !linking) {\n throw new Error('No RouteNode. This is likely a bug in expo-router.');\n }\n\n const initialRouteName = routeNode.initialRouteName;\n\n const { children, triggerMap } = triggersToScreens(\n triggers,\n routeNode,\n linking,\n initialRouteName,\n parentTriggerMap,\n routeInfo,\n contextKey\n );\n\n const navigatorContext = useNavigationBuilder<\n TabNavigationState<any>,\n ExpoTabRouterOptions,\n TabActionHelpers<ParamListBase>,\n ExpoTabsScreenOptions,\n TabNavigationEventMap\n >(ExpoTabRouter, {\n children,\n ...rest,\n triggerMap,\n id: contextKey,\n initialRouteName,\n });\n\n const {\n state,\n descriptors,\n navigation,\n describe,\n NavigationContent: RNNavigationContent,\n } = navigatorContext;\n\n const navigatorContextValue = useMemo<NavigatorContextValue>(\n () => ({\n ...(navigatorContext as unknown as ReturnType<typeof useNavigationBuilder>),\n contextKey,\n router: ExpoTabRouter,\n }),\n [navigatorContext, contextKey, ExpoTabRouter]\n );\n\n const NavigationContent = useComponent((children: React.ReactNode) => (\n <TabTriggerMapContext.Provider value={triggerMap}>\n <NavigatorContext.Provider value={navigatorContextValue}>\n <RNNavigationContent>{children}</RNNavigationContent>\n </NavigatorContext.Provider>\n </TabTriggerMapContext.Provider>\n )) as TabsContextValue['NavigationContent'];\n\n return { state, descriptors, navigation, NavigationContent, describe };\n}\n\nfunction parseTriggersFromChildren(\n children: ReactNode,\n screenTriggers: ScreenTrigger[] = [],\n isInTabList = false\n) {\n Children.forEach(children, (child) => {\n if (!child || !isValidElement(child) || isTabSlot(child)) {\n return;\n }\n\n if (isFragment(child) && typeof child.props.children !== 'function') {\n return parseTriggersFromChildren(\n child.props.children,\n screenTriggers,\n isInTabList || isTabList(child)\n );\n }\n\n if (isTabList(child) && typeof child.props.children !== 'function') {\n let children = child.props.children;\n\n // <TabList asChild /> adds an extra layer. We need to parse the child's children\n if (child.props.asChild && isValidElement(children)) {\n children = children.props.children;\n }\n\n return parseTriggersFromChildren(children, screenTriggers, isInTabList || isTabList(child));\n }\n\n // We should only process TabTriggers within the TabList. All other components will be ignored\n if (!isInTabList || !isTabTrigger(child)) {\n return;\n }\n\n const { href, name } = child.props;\n\n if (!href) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `<TabTrigger name={${name}}> does not have a 'href' prop. TabTriggers within a <TabList /> are required to have a href.`\n );\n }\n return;\n }\n\n const resolvedHref = resolveHref(href);\n\n if (shouldLinkExternally(resolvedHref)) {\n return screenTriggers.push({\n type: 'external',\n name,\n href: resolvedHref,\n });\n }\n\n if (!name) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `<TabTrigger> does not have a 'name' prop. TabTriggers within a <TabList /> are required to have a name.`\n );\n }\n return;\n }\n\n return screenTriggers.push({ type: 'internal', href: resolvedHref, name });\n });\n\n return screenTriggers;\n}\n\nfunction isFragment(\n child: ReactElement<any>\n): child is ReactElement<ComponentProps<typeof Fragment>> {\n return child.type === Fragment;\n}\n\nconst styles = StyleSheet.create({\n tabsRoot: {\n flex: 1,\n },\n});\n"]}
1
+ {"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../src/ui/Tabs.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DefaultNavigatorOptions,\n LinkingContext,\n ParamListBase,\n TabActionHelpers,\n TabNavigationState,\n TabRouterOptions,\n useNavigationBuilder,\n} from '@react-navigation/native';\nimport {\n Children,\n ComponentProps,\n Fragment,\n ReactElement,\n ReactNode,\n isValidElement,\n useContext,\n useMemo,\n PropsWithChildren,\n} from 'react';\nimport { StyleSheet, ViewProps, View } from 'react-native';\n\nimport {\n ExpoTabsScreenOptions,\n TabNavigationEventMap,\n TabTriggerMapContext,\n TabsContextValue,\n} from './TabContext';\nimport { isTabList } from './TabList';\nimport { ExpoTabRouter, ExpoTabRouterOptions } from './TabRouter';\nimport { isTabSlot } from './TabSlot';\nimport { isTabTrigger } from './TabTrigger';\nimport { SafeAreaViewSlot, ScreenTrigger, triggersToScreens } from './common';\nimport { useComponent } from './useComponent';\nimport { useRouteNode, useContextKey } from '../Route';\nimport { useRouteInfo } from '../hooks';\nimport { resolveHref } from '../link/href';\nimport { shouldLinkExternally } from '../utils/url';\nimport { NavigatorContext, NavigatorContextValue } from '../views/Navigator';\n\nexport * from './TabContext';\nexport * from './TabList';\nexport * from './TabSlot';\nexport * from './TabTrigger';\nexport { ExpoTabsResetValue } from './TabRouter';\n\n/**\n * Options to provide to the Tab Router.\n */\nexport type UseTabsOptions = Omit<\n DefaultNavigatorOptions<\n ParamListBase,\n any,\n TabNavigationState<any>,\n ExpoTabsScreenOptions,\n TabNavigationEventMap,\n any\n >,\n 'children'\n> & {\n backBehavior?: TabRouterOptions['backBehavior'];\n};\n\nexport type TabsProps = ViewProps & {\n /** Forward props to child component and removes the extra `<View>`. Useful for custom wrappers. */\n asChild?: boolean;\n options?: UseTabsOptions;\n};\n\n/**\n * Root component for the headless tabs.\n *\n * @see [`useTabsWithChildren`](#usetabswithchildrenoptions) for a hook version of this component.\n * @example\n * ```tsx\n * <Tabs>\n * <TabSlot />\n * <TabList>\n * <TabTrigger name=\"home\" href=\"/\" />\n * </TabList>\n * </Tabs>\n * ```\n */\nexport function Tabs(props: TabsProps) {\n const { children, asChild, options, ...rest } = props;\n const Comp = asChild ? SafeAreaViewSlot : View;\n\n const { NavigationContent } = useTabsWithChildren({\n // asChild adds an extra layer, so we need to process the child's children\n children: asChild && isValidElement(children) ? children.props.children : children,\n ...options,\n });\n\n return (\n <Comp style={styles.tabsRoot} {...rest}>\n <NavigationContent>{children}</NavigationContent>\n </Comp>\n );\n}\n\n// @docsMissing\nexport type UseTabsWithChildrenOptions = PropsWithChildren<UseTabsOptions>;\n\n// @docsMissing\nexport type UseTabsWithTriggersOptions = UseTabsOptions & {\n triggers: ScreenTrigger[];\n};\n\n/**\n * Hook version of `Tabs`. The returned NavigationContent component\n * should be rendered. Using the hook requires using the `<TabList />`\n * and `<TabTrigger />` components exported from Expo Router.\n *\n * The `useTabsWithTriggers()` hook can be used for custom components.\n *\n * @see [`Tabs`](#tabs) for the component version of this hook.\n * @example\n * ```tsx\n * export function MyTabs({ children }) {\n * const { NavigationContent } = useTabsWithChildren({ children })\n *\n * return <NavigationContent />\n * }\n * ```\n */\nexport function useTabsWithChildren(options: UseTabsWithChildrenOptions) {\n const { children, ...rest } = options;\n return useTabsWithTriggers({ triggers: parseTriggersFromChildren(children), ...rest });\n}\n\n/**\n * Alternative hook version of `Tabs` that uses explicit triggers\n * instead of `children`.\n *\n * @see [`Tabs`](#tabs) for the component version of this hook.\n * @example\n * ```tsx\n * export function MyTabs({ children }) {\n * const { NavigationContent } = useTabsWithChildren({ triggers: [] })\n *\n * return <NavigationContent />\n * }\n * ```\n */\nexport function useTabsWithTriggers(options: UseTabsWithTriggersOptions): TabsContextValue {\n const { triggers, ...rest } = options;\n // Ensure we extend the parent triggers, so we can trigger them as well\n const parentTriggerMap = useContext(TabTriggerMapContext);\n const routeNode = useRouteNode();\n const contextKey = useContextKey();\n const linking = useContext(LinkingContext).options;\n const routeInfo = useRouteInfo();\n\n if (!routeNode || !linking) {\n throw new Error('No RouteNode. This is likely a bug in expo-router.');\n }\n\n const initialRouteName = routeNode.initialRouteName;\n\n const { children, triggerMap } = triggersToScreens(\n triggers,\n routeNode,\n linking,\n initialRouteName,\n parentTriggerMap,\n routeInfo,\n contextKey\n );\n\n const navigatorContext = useNavigationBuilder<\n TabNavigationState<any>,\n ExpoTabRouterOptions,\n TabActionHelpers<ParamListBase>,\n ExpoTabsScreenOptions,\n TabNavigationEventMap\n >(ExpoTabRouter, {\n children,\n ...rest,\n triggerMap,\n id: contextKey,\n initialRouteName,\n });\n\n const {\n state,\n descriptors,\n navigation,\n describe,\n NavigationContent: RNNavigationContent,\n } = navigatorContext;\n\n const navigatorContextValue = useMemo<NavigatorContextValue>(\n () => ({\n ...(navigatorContext as unknown as ReturnType<typeof useNavigationBuilder>),\n contextKey,\n router: ExpoTabRouter,\n }),\n [navigatorContext, contextKey, ExpoTabRouter]\n );\n\n const NavigationContent = useComponent((children: React.ReactNode) => (\n <TabTriggerMapContext.Provider value={triggerMap}>\n <NavigatorContext.Provider value={navigatorContextValue}>\n <RNNavigationContent>{children}</RNNavigationContent>\n </NavigatorContext.Provider>\n </TabTriggerMapContext.Provider>\n )) as TabsContextValue['NavigationContent'];\n\n return { state, descriptors, navigation, NavigationContent, describe };\n}\n\nfunction parseTriggersFromChildren(\n children: ReactNode,\n screenTriggers: ScreenTrigger[] = [],\n isInTabList = false\n) {\n Children.forEach(children, (child) => {\n if (!child || !isValidElement(child) || isTabSlot(child)) {\n return;\n }\n\n if (isFragment(child) && typeof child.props.children !== 'function') {\n return parseTriggersFromChildren(\n child.props.children,\n screenTriggers,\n isInTabList || isTabList(child)\n );\n }\n\n if (isTabList(child) && typeof child.props.children !== 'function') {\n let children = child.props.children;\n\n // <TabList asChild /> adds an extra layer. We need to parse the child's children\n if (child.props.asChild && isValidElement(children)) {\n children = children.props.children;\n }\n\n return parseTriggersFromChildren(children, screenTriggers, isInTabList || isTabList(child));\n }\n\n // We should only process TabTriggers within the TabList. All other components will be ignored\n if (!isInTabList || !isTabTrigger(child)) {\n return;\n }\n\n const { href, name } = child.props;\n\n if (!href) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `<TabTrigger name={${name}}> does not have a 'href' prop. TabTriggers within a <TabList /> are required to have an href.`\n );\n }\n return;\n }\n\n const resolvedHref = resolveHref(href);\n\n if (shouldLinkExternally(resolvedHref)) {\n return screenTriggers.push({\n type: 'external',\n name,\n href: resolvedHref,\n });\n }\n\n if (!name) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `<TabTrigger> does not have a 'name' prop. TabTriggers within a <TabList /> are required to have a name.`\n );\n }\n return;\n }\n\n return screenTriggers.push({ type: 'internal', href: resolvedHref, name });\n });\n\n return screenTriggers;\n}\n\nfunction isFragment(\n child: ReactElement<any>\n): child is ReactElement<ComponentProps<typeof Fragment>> {\n return child.type === Fragment;\n}\n\nconst styles = StyleSheet.create({\n tabsRoot: {\n flex: 1,\n },\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  import { NavigationProp, NavigationState } from '@react-navigation/native';
2
2
  import { Href } from './types';
3
3
  /**
4
- * Returns the underlying React Navigation [`navigation` prop](https://reactnavigation.org/docs/navigation-prop)
4
+ * Returns the underlying React Navigation [`navigation` object](https://reactnavigation.org/docs/navigation-object)
5
5
  * to imperatively access layout-specific functionality like `navigation.openDrawer()` in a
6
6
  * [Drawer](/router/advanced/drawer/) layout.
7
7
  *
@@ -49,7 +49,7 @@ import { Href } from './types';
49
49
  * @param parent Provide an absolute path such as `/(root)` to the parent route or a relative path like `../../` to the parent route.
50
50
  * @returns The navigation object for the current route.
51
51
  *
52
- * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-prop/#navigator-dependent-functions)
52
+ * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-object/#navigator-dependent-functions)
53
53
  * for more information.
54
54
  */
55
55
  export declare function useNavigation<T = Omit<NavigationProp<ReactNavigation.RootParamList>, 'getState'> & {
@@ -11,7 +11,7 @@ const router_store_1 = require("./global-state/router-store");
11
11
  const hooks_1 = require("./hooks");
12
12
  const href_1 = require("./link/href");
13
13
  /**
14
- * Returns the underlying React Navigation [`navigation` prop](https://reactnavigation.org/docs/navigation-prop)
14
+ * Returns the underlying React Navigation [`navigation` object](https://reactnavigation.org/docs/navigation-object)
15
15
  * to imperatively access layout-specific functionality like `navigation.openDrawer()` in a
16
16
  * [Drawer](/router/advanced/drawer/) layout.
17
17
  *
@@ -59,7 +59,7 @@ const href_1 = require("./link/href");
59
59
  * @param parent Provide an absolute path such as `/(root)` to the parent route or a relative path like `../../` to the parent route.
60
60
  * @returns The navigation object for the current route.
61
61
  *
62
- * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-prop/#navigator-dependent-functions)
62
+ * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-object/#navigator-dependent-functions)
63
63
  * for more information.
64
64
  */
65
65
  function useNavigation(parent) {
@@ -1 +1 @@
1
- {"version":3,"file":"useNavigation.js","sourceRoot":"","sources":["../src/useNavigation.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n useNavigation as useUpstreamNavigation,\n NavigationProp,\n NavigationState,\n} from '@react-navigation/native';\nimport React from 'react';\n\nimport { store } from './global-state/router-store';\nimport { useSegments } from './hooks';\nimport { resolveHref } from './link/href';\nimport { Href } from './types';\n\n/**\n * Returns the underlying React Navigation [`navigation` prop](https://reactnavigation.org/docs/navigation-prop)\n * to imperatively access layout-specific functionality like `navigation.openDrawer()` in a\n * [Drawer](/router/advanced/drawer/) layout.\n *\n * @example\n * ```tsx app/index.tsx\n * import { useNavigation } from 'expo-router';\n *\n * export default function Route() {\n * // Access the current navigation object for the current route.\n * const navigation = useNavigation();\n *\n * return (\n * <View>\n * <Text onPress={() => {\n * // Open the drawer view.\n * navigation.openDrawer();\n * }}>\n * Open Drawer\n * </Text>\n * </View>\n * );\n * }\n * ```\n *\n * When using nested layouts, you can access higher-order layouts by passing a secondary argument denoting the layout route.\n * For example, `/menu/_layout.tsx` is nested inside `/app/orders/`, you can use `useNavigation('/orders/menu/')`.\n *\n * @example\n * ```tsx app/orders/menu/index.tsx\n * import { useNavigation } from 'expo-router';\n *\n * export default function MenuRoute() {\n * const rootLayout = useNavigation('/');\n * const ordersLayout = useNavigation('/orders');\n *\n * // Same as the default results of `useNavigation()` when invoked in this route.\n * const parentLayout = useNavigation('/orders/menu');\n * }\n * ```\n *\n * If you attempt to access a layout that doesn't exist, an error such as\n * `Could not find parent navigation with route \"/non-existent\"` is thrown.\n *\n *\n * @param parent Provide an absolute path such as `/(root)` to the parent route or a relative path like `../../` to the parent route.\n * @returns The navigation object for the current route.\n *\n * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-prop/#navigator-dependent-functions)\n * for more information.\n */\nexport function useNavigation<\n T = Omit<NavigationProp<ReactNavigation.RootParamList>, 'getState'> & {\n getState(): NavigationState | undefined;\n },\n>(parent?: string | Href): T {\n let navigation = useUpstreamNavigation<any>();\n const initialNavigation = navigation;\n const segments = useSegments();\n\n const targetNavigatorContextKey = React.useMemo(() => {\n if (!parent) {\n return;\n }\n\n if (typeof parent === 'object') {\n parent = resolveHref(parent);\n }\n\n if (parent === '/') {\n return '';\n }\n\n let state = store.getStateFromPath(parent.startsWith('../') ? segments.join('/') : parent);\n\n // Reconstruct the context key from the state\n let contextKey = '';\n const names: string[] = [];\n\n while (state) {\n const routes = state.routes;\n const route = routes[state.index ?? routes.length - 1];\n\n if (route.state) {\n contextKey = `${contextKey}/${route.name}`;\n names.push(route.name);\n\n if (parent === contextKey) {\n break;\n }\n\n state = route.state;\n } else {\n break;\n }\n }\n\n if (parent.startsWith('../')) {\n const parentSegments = parent.split('/').filter(Boolean);\n\n for (const segment of parentSegments) {\n if (segment === '..') {\n names.pop();\n } else {\n throw new Error(\n \"Relative parent paths may only contain '..' and cannot contain other segments\"\n );\n }\n }\n\n contextKey = names.length > 0 ? `/${names.join('/')}` : '';\n }\n\n return contextKey;\n }, [segments, parent]);\n\n if (targetNavigatorContextKey !== undefined) {\n navigation = navigation.getParent(targetNavigatorContextKey as any);\n }\n\n if (!navigation) {\n const ids: (string | undefined)[] = [];\n\n navigation = initialNavigation;\n\n while (navigation) {\n ids.push(navigation.getId() || '/');\n navigation = navigation.getParent();\n }\n\n throw new Error(\n `Could not find parent navigation with route \"${parent}\". Available routes are: '${ids.join(\"', '\")}'`\n );\n }\n\n return navigation;\n}\n"]}
1
+ {"version":3,"file":"useNavigation.js","sourceRoot":"","sources":["../src/useNavigation.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n useNavigation as useUpstreamNavigation,\n NavigationProp,\n NavigationState,\n} from '@react-navigation/native';\nimport React from 'react';\n\nimport { store } from './global-state/router-store';\nimport { useSegments } from './hooks';\nimport { resolveHref } from './link/href';\nimport { Href } from './types';\n\n/**\n * Returns the underlying React Navigation [`navigation` object](https://reactnavigation.org/docs/navigation-object)\n * to imperatively access layout-specific functionality like `navigation.openDrawer()` in a\n * [Drawer](/router/advanced/drawer/) layout.\n *\n * @example\n * ```tsx app/index.tsx\n * import { useNavigation } from 'expo-router';\n *\n * export default function Route() {\n * // Access the current navigation object for the current route.\n * const navigation = useNavigation();\n *\n * return (\n * <View>\n * <Text onPress={() => {\n * // Open the drawer view.\n * navigation.openDrawer();\n * }}>\n * Open Drawer\n * </Text>\n * </View>\n * );\n * }\n * ```\n *\n * When using nested layouts, you can access higher-order layouts by passing a secondary argument denoting the layout route.\n * For example, `/menu/_layout.tsx` is nested inside `/app/orders/`, you can use `useNavigation('/orders/menu/')`.\n *\n * @example\n * ```tsx app/orders/menu/index.tsx\n * import { useNavigation } from 'expo-router';\n *\n * export default function MenuRoute() {\n * const rootLayout = useNavigation('/');\n * const ordersLayout = useNavigation('/orders');\n *\n * // Same as the default results of `useNavigation()` when invoked in this route.\n * const parentLayout = useNavigation('/orders/menu');\n * }\n * ```\n *\n * If you attempt to access a layout that doesn't exist, an error such as\n * `Could not find parent navigation with route \"/non-existent\"` is thrown.\n *\n *\n * @param parent Provide an absolute path such as `/(root)` to the parent route or a relative path like `../../` to the parent route.\n * @returns The navigation object for the current route.\n *\n * @see React Navigation documentation on [navigation dependent functions](https://reactnavigation.org/docs/navigation-object/#navigator-dependent-functions)\n * for more information.\n */\nexport function useNavigation<\n T = Omit<NavigationProp<ReactNavigation.RootParamList>, 'getState'> & {\n getState(): NavigationState | undefined;\n },\n>(parent?: string | Href): T {\n let navigation = useUpstreamNavigation<any>();\n const initialNavigation = navigation;\n const segments = useSegments();\n\n const targetNavigatorContextKey = React.useMemo(() => {\n if (!parent) {\n return;\n }\n\n if (typeof parent === 'object') {\n parent = resolveHref(parent);\n }\n\n if (parent === '/') {\n return '';\n }\n\n let state = store.getStateFromPath(parent.startsWith('../') ? segments.join('/') : parent);\n\n // Reconstruct the context key from the state\n let contextKey = '';\n const names: string[] = [];\n\n while (state) {\n const routes = state.routes;\n const route = routes[state.index ?? routes.length - 1];\n\n if (route.state) {\n contextKey = `${contextKey}/${route.name}`;\n names.push(route.name);\n\n if (parent === contextKey) {\n break;\n }\n\n state = route.state;\n } else {\n break;\n }\n }\n\n if (parent.startsWith('../')) {\n const parentSegments = parent.split('/').filter(Boolean);\n\n for (const segment of parentSegments) {\n if (segment === '..') {\n names.pop();\n } else {\n throw new Error(\n \"Relative parent paths may only contain '..' and cannot contain other segments\"\n );\n }\n }\n\n contextKey = names.length > 0 ? `/${names.join('/')}` : '';\n }\n\n return contextKey;\n }, [segments, parent]);\n\n if (targetNavigatorContextKey !== undefined) {\n navigation = navigation.getParent(targetNavigatorContextKey as any);\n }\n\n if (!navigation) {\n const ids: (string | undefined)[] = [];\n\n navigation = initialNavigation;\n\n while (navigation) {\n ids.push(navigation.getId() || '/');\n navigation = navigation.getParent();\n }\n\n throw new Error(\n `Could not find parent navigation with route \"${parent}\". Available routes are: '${ids.join(\"', '\")}'`\n );\n }\n\n return navigation;\n}\n"]}
@@ -28,10 +28,10 @@ export type ScreenProps<TOptions extends Record<string, any> = Record<string, an
28
28
  export declare function useSortedScreens(order: ScreenProps[]): React.ReactNode[];
29
29
  /** Wrap the component with various enhancements and add access to child routes. */
30
30
  export declare function getQualifiedRouteComponent(value: RouteNode): React.ComponentType<any> | React.ForwardRefExoticComponent<Omit<any, "ref"> & React.RefAttributes<unknown>>;
31
- /** @returns a function which provides a screen id that matches the dynamic route name in params. */
32
- export declare function createGetIdForRoute(route: Pick<RouteNode, 'dynamic' | 'route' | 'contextKey' | 'children'>): ({ params }?: {
33
- params?: Record<string, any> | undefined;
34
- }) => any;
31
+ /**
32
+ * @param getId Override that will be wrapped to remove __EXPO_ROUTER_key which is added by PUSH
33
+ * @returns a function which provides a screen id that matches the dynamic route name in params. */
34
+ export declare function createGetIdForRoute(route: Pick<RouteNode, 'dynamic' | 'route' | 'contextKey' | 'children'>, getId: ScreenProps['getId']): ScreenProps['getId'];
35
35
  export declare function screenOptionsFactory(route: RouteNode, options?: ScreenProps['options']): RouteConfig<any, any, any, any, any, any>['options'];
36
- export declare function routeToScreen(route: RouteNode, { options, ...props }?: Partial<ScreenProps>): React.JSX.Element;
36
+ export declare function routeToScreen(route: RouteNode, { options, getId, ...props }?: Partial<ScreenProps>): React.JSX.Element;
37
37
  //# sourceMappingURL=useScreens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,WAAW,EACX,SAAS,EACT,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAOjB,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1D,MAAM,SAAS,eAAe,GAAG,eAAe,EAChD,SAAS,SAAS,YAAY,GAAG,YAAY,IAC3C;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,OAAO,CAAC,EACJ,QAAQ,GACR,CAAC,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAAC,UAAU,EAAE,GAAG,CAAA;KAAE,KAAK,QAAQ,CAAC,CAAC;IAEvF,SAAS,CAAC,EACN,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,GAClC,CAAC,CAAC,IAAI,EAAE;QACN,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,EAAE,GAAG,CAAC;KACjB,KAAK,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAE9C,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,KAAK,MAAM,GAAG,SAAS,CAAC;CAC9E,CAAC;AA2DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AAuCD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,+GAgE1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,CAAC;;UAoCxE;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,GAC/B,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAqBtD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,GAAE,OAAO,CAAC,WAAW,CAAM,qBAY/F"}
1
+ {"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,aAAa,EACb,WAAW,EACX,SAAS,EACT,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAOjB,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1D,MAAM,SAAS,eAAe,GAAG,eAAe,EAChD,SAAS,SAAS,YAAY,GAAG,YAAY,IAC3C;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,OAAO,CAAC,EACJ,QAAQ,GACR,CAAC,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAAC,UAAU,EAAE,GAAG,CAAA;KAAE,KAAK,QAAQ,CAAC,CAAC;IAEvF,SAAS,CAAC,EACN,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,GAClC,CAAC,CAAC,IAAI,EAAE;QACN,KAAK,EAAE,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,EAAE,GAAG,CAAC;KACjB,KAAK,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAE9C,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,KAAK,MAAM,GAAG,SAAS,CAAC;CAC9E,CAAC;AA2DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AAuCD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,+GAgE1D;AAED;;mGAEmG;AACnG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,YAAY,GAAG,UAAU,CAAC,EACvE,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAC1B,WAAW,CAAC,OAAO,CAAC,CA0CtB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,GAC/B,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAqBtD;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,GAAE,OAAO,CAAC,WAAW,CAAM,qBAYxD"}
@@ -138,19 +138,27 @@ function getQualifiedRouteComponent(value) {
138
138
  return QualifiedRoute;
139
139
  }
140
140
  exports.getQualifiedRouteComponent = getQualifiedRouteComponent;
141
- /** @returns a function which provides a screen id that matches the dynamic route name in params. */
142
- function createGetIdForRoute(route) {
141
+ /**
142
+ * @param getId Override that will be wrapped to remove __EXPO_ROUTER_key which is added by PUSH
143
+ * @returns a function which provides a screen id that matches the dynamic route name in params. */
144
+ function createGetIdForRoute(route, getId) {
143
145
  const include = new Map();
144
146
  if (route.dynamic) {
145
147
  for (const segment of route.dynamic) {
146
148
  include.set(segment.name, segment);
147
149
  }
148
150
  }
149
- return ({ params = {} } = {}) => {
151
+ return (options = {}) => {
152
+ const { params = {} } = options;
150
153
  if (params.__EXPO_ROUTER_key) {
151
154
  const key = params.__EXPO_ROUTER_key;
152
155
  delete params.__EXPO_ROUTER_key;
153
- return key;
156
+ if (getId == null) {
157
+ return key;
158
+ }
159
+ }
160
+ if (getId != null) {
161
+ return getId(options);
154
162
  }
155
163
  const segments = [];
156
164
  for (const dynamic of include.values()) {
@@ -195,10 +203,8 @@ function screenOptionsFactory(route, options) {
195
203
  };
196
204
  }
197
205
  exports.screenOptionsFactory = screenOptionsFactory;
198
- function routeToScreen(route, { options, ...props } = {}) {
199
- return (<primitives_1.Screen
200
- // Users can override the screen getId function.
201
- getId={createGetIdForRoute(route)} {...props} name={route.route} key={route.route} options={screenOptionsFactory(route, options)} getComponent={() => getQualifiedRouteComponent(route)}/>);
206
+ function routeToScreen(route, { options, getId, ...props } = {}) {
207
+ return (<primitives_1.Screen {...props} getId={createGetIdForRoute(route, getId)} name={route.route} key={route.route} options={screenOptionsFactory(route, options)} getComponent={() => getQualifiedRouteComponent(route)}/>);
202
208
  }
203
209
  exports.routeToScreen = routeToScreen;
204
210
  //# sourceMappingURL=useScreens.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useScreens.js","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport type {\n EventMapBase,\n NavigationState,\n ParamListBase,\n RouteConfig,\n RouteProp,\n ScreenListeners,\n} from '@react-navigation/native';\nimport React from 'react';\n\nimport {\n DynamicConvention,\n LoadedRoute,\n Route,\n RouteNode,\n sortRoutesWithInitial,\n useRouteNode,\n} from './Route';\nimport EXPO_ROUTER_IMPORT_MODE from './import-mode';\nimport { Screen } from './primitives';\nimport { EmptyRoute } from './views/EmptyRoute';\nimport { SuspenseFallback } from './views/SuspenseFallback';\nimport { Try } from './views/Try';\n\nexport type ScreenProps<\n TOptions extends Record<string, any> = Record<string, any>,\n TState extends NavigationState = NavigationState,\n TEventMap extends EventMapBase = EventMapBase,\n> = {\n /** Name is required when used inside a Layout component. */\n name?: string;\n /**\n * Redirect to the nearest sibling route.\n * If all children are `redirect={true}`, the layout will render `null` as there are no children to render.\n */\n redirect?: boolean;\n initialParams?: Record<string, any>;\n options?:\n | TOptions\n | ((prop: { route: RouteProp<ParamListBase, string>; navigation: any }) => TOptions);\n\n listeners?:\n | ScreenListeners<TState, TEventMap>\n | ((prop: {\n route: RouteProp<ParamListBase, string>;\n navigation: any;\n }) => ScreenListeners<TState, TEventMap>);\n\n getId?: ({ params }: { params?: Record<string, any> }) => string | undefined;\n};\n\nfunction getSortedChildren(\n children: RouteNode[],\n order?: ScreenProps[],\n initialRouteName?: string\n): { route: RouteNode; props: Partial<ScreenProps> }[] {\n if (!order?.length) {\n return children\n .sort(sortRoutesWithInitial(initialRouteName))\n .map((route) => ({ route, props: {} }));\n }\n const entries = [...children];\n\n const ordered = order\n .map(({ name, redirect, initialParams, listeners, options, getId }) => {\n if (!entries.length) {\n console.warn(`[Layout children]: Too many screens defined. Route \"${name}\" is extraneous.`);\n return null;\n }\n const matchIndex = entries.findIndex((child) => child.route === name);\n if (matchIndex === -1) {\n console.warn(\n `[Layout children]: No route named \"${name}\" exists in nested children:`,\n children.map(({ route }) => route)\n );\n return null;\n } else {\n // Get match and remove from entries\n const match = entries[matchIndex];\n entries.splice(matchIndex, 1);\n\n // Ensure to return null after removing from entries.\n if (redirect) {\n if (typeof redirect === 'string') {\n throw new Error(`Redirecting to a specific route is not supported yet.`);\n }\n return null;\n }\n\n return {\n route: match,\n props: { initialParams, listeners, options, getId },\n };\n }\n })\n .filter(Boolean) as {\n route: RouteNode;\n props: Partial<ScreenProps>;\n }[];\n\n // Add any remaining children\n ordered.push(\n ...entries.sort(sortRoutesWithInitial(initialRouteName)).map((route) => ({ route, props: {} }))\n );\n\n return ordered;\n}\n\n/**\n * @returns React Navigation screens sorted by the `route` property.\n */\nexport function useSortedScreens(order: ScreenProps[]): React.ReactNode[] {\n const node = useRouteNode();\n\n const sorted = node?.children?.length\n ? getSortedChildren(node.children, order, node.initialRouteName)\n : [];\n return React.useMemo(\n () => sorted.map((value) => routeToScreen(value.route, value.props)),\n [sorted]\n );\n}\n\nfunction fromImport({ ErrorBoundary, ...component }: LoadedRoute) {\n if (ErrorBoundary) {\n return {\n default: React.forwardRef((props: any, ref: any) => {\n const children = React.createElement(component.default || EmptyRoute, {\n ...props,\n ref,\n });\n return <Try catch={ErrorBoundary}>{children}</Try>;\n }),\n };\n }\n if (process.env.NODE_ENV !== 'production') {\n if (\n typeof component.default === 'object' &&\n component.default &&\n Object.keys(component.default).length === 0\n ) {\n return { default: EmptyRoute };\n }\n }\n\n return { default: component.default };\n}\n\nfunction fromLoadedRoute(res: LoadedRoute) {\n if (!(res instanceof Promise)) {\n return fromImport(res);\n }\n\n return res.then(fromImport);\n}\n\n// TODO: Maybe there's a more React-y way to do this?\n// Without this store, the process enters a recursive loop.\nconst qualifiedStore = new WeakMap<RouteNode, React.ComponentType<any>>();\n\n/** Wrap the component with various enhancements and add access to child routes. */\nexport function getQualifiedRouteComponent(value: RouteNode) {\n if (qualifiedStore.has(value)) {\n return qualifiedStore.get(value)!;\n }\n\n let ScreenComponent: React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;\n\n // TODO: This ensures sync doesn't use React.lazy, but it's not ideal.\n if (EXPO_ROUTER_IMPORT_MODE === 'lazy') {\n ScreenComponent = React.lazy(async () => {\n const res = value.loadRoute();\n return fromLoadedRoute(res) as Promise<{\n default: React.ComponentType<any>;\n }>;\n });\n } else {\n const res = value.loadRoute();\n const Component = fromImport(res).default as React.ComponentType<any>;\n ScreenComponent = React.forwardRef((props, ref) => {\n return <Component {...props} ref={ref} />;\n });\n }\n\n const getLoadable = (props: any, ref: any) => (\n <React.Suspense fallback={<SuspenseFallback route={value} />}>\n <ScreenComponent\n {...{\n ...props,\n ref,\n // Expose the template segment path, e.g. `(home)`, `[foo]`, `index`\n // the intention is to make it possible to deduce shared routes.\n segment: value.route,\n }}\n />\n </React.Suspense>\n );\n\n const QualifiedRoute = React.forwardRef(\n (\n {\n // Remove these React Navigation props to\n // enforce usage of expo-router hooks (where the query params are correct).\n route,\n navigation,\n\n // Pass all other props to the component\n ...props\n }: any,\n ref: any\n ) => {\n const loadable = getLoadable(props, ref);\n\n return (\n <Route node={value} route={route}>\n {loadable}\n </Route>\n );\n }\n );\n\n QualifiedRoute.displayName = `Route(${value.route})`;\n\n qualifiedStore.set(value, QualifiedRoute);\n return QualifiedRoute;\n}\n\n/** @returns a function which provides a screen id that matches the dynamic route name in params. */\nexport function createGetIdForRoute(\n route: Pick<RouteNode, 'dynamic' | 'route' | 'contextKey' | 'children'>\n) {\n const include = new Map<string, DynamicConvention>();\n\n if (route.dynamic) {\n for (const segment of route.dynamic) {\n include.set(segment.name, segment);\n }\n }\n\n return ({ params = {} } = {} as { params?: Record<string, any> }) => {\n if (params.__EXPO_ROUTER_key) {\n const key = params.__EXPO_ROUTER_key;\n delete params.__EXPO_ROUTER_key;\n return key;\n }\n\n const segments: string[] = [];\n\n for (const dynamic of include.values()) {\n const value = params?.[dynamic.name];\n if (Array.isArray(value) && value.length > 0) {\n // If we are an array with a value\n segments.push(value.join('/'));\n } else if (value && !Array.isArray(value)) {\n // If we have a value and not an empty array\n segments.push(value);\n } else if (dynamic.deep) {\n segments.push(`[...${dynamic.name}]`);\n } else {\n segments.push(`[${dynamic.name}]`);\n }\n }\n\n return segments.join('/') ?? route.contextKey;\n };\n}\n\nexport function screenOptionsFactory(\n route: RouteNode,\n options?: ScreenProps['options']\n): RouteConfig<any, any, any, any, any, any>['options'] {\n return (args) => {\n // Only eager load generated components\n const staticOptions = route.generated ? route.loadRoute()?.getNavOptions : null;\n const staticResult = typeof staticOptions === 'function' ? staticOptions(args) : staticOptions;\n const dynamicResult = typeof options === 'function' ? options?.(args) : options;\n const output = {\n ...staticResult,\n ...dynamicResult,\n };\n\n // Prevent generated screens from showing up in the tab bar.\n if (route.generated) {\n output.tabBarItemStyle = { display: 'none' };\n output.tabBarButton = () => null;\n // TODO: React Navigation doesn't provide a way to prevent rendering the drawer item.\n output.drawerItemStyle = { height: 0, display: 'none' };\n }\n\n return output;\n };\n}\n\nexport function routeToScreen(route: RouteNode, { options, ...props }: Partial<ScreenProps> = {}) {\n return (\n <Screen\n // Users can override the screen getId function.\n getId={createGetIdForRoute(route)}\n {...props}\n name={route.route}\n key={route.route}\n options={screenOptionsFactory(route, options)}\n getComponent={() => getQualifiedRouteComponent(route)}\n />\n );\n}\n"]}
1
+ {"version":3,"file":"useScreens.js","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport type {\n EventMapBase,\n NavigationState,\n ParamListBase,\n RouteConfig,\n RouteProp,\n ScreenListeners,\n} from '@react-navigation/native';\nimport React from 'react';\n\nimport {\n DynamicConvention,\n LoadedRoute,\n Route,\n RouteNode,\n sortRoutesWithInitial,\n useRouteNode,\n} from './Route';\nimport EXPO_ROUTER_IMPORT_MODE from './import-mode';\nimport { Screen } from './primitives';\nimport { EmptyRoute } from './views/EmptyRoute';\nimport { SuspenseFallback } from './views/SuspenseFallback';\nimport { Try } from './views/Try';\n\nexport type ScreenProps<\n TOptions extends Record<string, any> = Record<string, any>,\n TState extends NavigationState = NavigationState,\n TEventMap extends EventMapBase = EventMapBase,\n> = {\n /** Name is required when used inside a Layout component. */\n name?: string;\n /**\n * Redirect to the nearest sibling route.\n * If all children are `redirect={true}`, the layout will render `null` as there are no children to render.\n */\n redirect?: boolean;\n initialParams?: Record<string, any>;\n options?:\n | TOptions\n | ((prop: { route: RouteProp<ParamListBase, string>; navigation: any }) => TOptions);\n\n listeners?:\n | ScreenListeners<TState, TEventMap>\n | ((prop: {\n route: RouteProp<ParamListBase, string>;\n navigation: any;\n }) => ScreenListeners<TState, TEventMap>);\n\n getId?: ({ params }: { params?: Record<string, any> }) => string | undefined;\n};\n\nfunction getSortedChildren(\n children: RouteNode[],\n order?: ScreenProps[],\n initialRouteName?: string\n): { route: RouteNode; props: Partial<ScreenProps> }[] {\n if (!order?.length) {\n return children\n .sort(sortRoutesWithInitial(initialRouteName))\n .map((route) => ({ route, props: {} }));\n }\n const entries = [...children];\n\n const ordered = order\n .map(({ name, redirect, initialParams, listeners, options, getId }) => {\n if (!entries.length) {\n console.warn(`[Layout children]: Too many screens defined. Route \"${name}\" is extraneous.`);\n return null;\n }\n const matchIndex = entries.findIndex((child) => child.route === name);\n if (matchIndex === -1) {\n console.warn(\n `[Layout children]: No route named \"${name}\" exists in nested children:`,\n children.map(({ route }) => route)\n );\n return null;\n } else {\n // Get match and remove from entries\n const match = entries[matchIndex];\n entries.splice(matchIndex, 1);\n\n // Ensure to return null after removing from entries.\n if (redirect) {\n if (typeof redirect === 'string') {\n throw new Error(`Redirecting to a specific route is not supported yet.`);\n }\n return null;\n }\n\n return {\n route: match,\n props: { initialParams, listeners, options, getId },\n };\n }\n })\n .filter(Boolean) as {\n route: RouteNode;\n props: Partial<ScreenProps>;\n }[];\n\n // Add any remaining children\n ordered.push(\n ...entries.sort(sortRoutesWithInitial(initialRouteName)).map((route) => ({ route, props: {} }))\n );\n\n return ordered;\n}\n\n/**\n * @returns React Navigation screens sorted by the `route` property.\n */\nexport function useSortedScreens(order: ScreenProps[]): React.ReactNode[] {\n const node = useRouteNode();\n\n const sorted = node?.children?.length\n ? getSortedChildren(node.children, order, node.initialRouteName)\n : [];\n return React.useMemo(\n () => sorted.map((value) => routeToScreen(value.route, value.props)),\n [sorted]\n );\n}\n\nfunction fromImport({ ErrorBoundary, ...component }: LoadedRoute) {\n if (ErrorBoundary) {\n return {\n default: React.forwardRef((props: any, ref: any) => {\n const children = React.createElement(component.default || EmptyRoute, {\n ...props,\n ref,\n });\n return <Try catch={ErrorBoundary}>{children}</Try>;\n }),\n };\n }\n if (process.env.NODE_ENV !== 'production') {\n if (\n typeof component.default === 'object' &&\n component.default &&\n Object.keys(component.default).length === 0\n ) {\n return { default: EmptyRoute };\n }\n }\n\n return { default: component.default };\n}\n\nfunction fromLoadedRoute(res: LoadedRoute) {\n if (!(res instanceof Promise)) {\n return fromImport(res);\n }\n\n return res.then(fromImport);\n}\n\n// TODO: Maybe there's a more React-y way to do this?\n// Without this store, the process enters a recursive loop.\nconst qualifiedStore = new WeakMap<RouteNode, React.ComponentType<any>>();\n\n/** Wrap the component with various enhancements and add access to child routes. */\nexport function getQualifiedRouteComponent(value: RouteNode) {\n if (qualifiedStore.has(value)) {\n return qualifiedStore.get(value)!;\n }\n\n let ScreenComponent: React.ForwardRefExoticComponent<React.RefAttributes<unknown>>;\n\n // TODO: This ensures sync doesn't use React.lazy, but it's not ideal.\n if (EXPO_ROUTER_IMPORT_MODE === 'lazy') {\n ScreenComponent = React.lazy(async () => {\n const res = value.loadRoute();\n return fromLoadedRoute(res) as Promise<{\n default: React.ComponentType<any>;\n }>;\n });\n } else {\n const res = value.loadRoute();\n const Component = fromImport(res).default as React.ComponentType<any>;\n ScreenComponent = React.forwardRef((props, ref) => {\n return <Component {...props} ref={ref} />;\n });\n }\n\n const getLoadable = (props: any, ref: any) => (\n <React.Suspense fallback={<SuspenseFallback route={value} />}>\n <ScreenComponent\n {...{\n ...props,\n ref,\n // Expose the template segment path, e.g. `(home)`, `[foo]`, `index`\n // the intention is to make it possible to deduce shared routes.\n segment: value.route,\n }}\n />\n </React.Suspense>\n );\n\n const QualifiedRoute = React.forwardRef(\n (\n {\n // Remove these React Navigation props to\n // enforce usage of expo-router hooks (where the query params are correct).\n route,\n navigation,\n\n // Pass all other props to the component\n ...props\n }: any,\n ref: any\n ) => {\n const loadable = getLoadable(props, ref);\n\n return (\n <Route node={value} route={route}>\n {loadable}\n </Route>\n );\n }\n );\n\n QualifiedRoute.displayName = `Route(${value.route})`;\n\n qualifiedStore.set(value, QualifiedRoute);\n return QualifiedRoute;\n}\n\n/**\n * @param getId Override that will be wrapped to remove __EXPO_ROUTER_key which is added by PUSH\n * @returns a function which provides a screen id that matches the dynamic route name in params. */\nexport function createGetIdForRoute(\n route: Pick<RouteNode, 'dynamic' | 'route' | 'contextKey' | 'children'>,\n getId: ScreenProps['getId']\n): ScreenProps['getId'] {\n const include = new Map<string, DynamicConvention>();\n\n if (route.dynamic) {\n for (const segment of route.dynamic) {\n include.set(segment.name, segment);\n }\n }\n\n return (options = {}) => {\n const { params = {} } = options;\n if (params.__EXPO_ROUTER_key) {\n const key = params.__EXPO_ROUTER_key;\n delete params.__EXPO_ROUTER_key;\n if (getId == null) {\n return key;\n }\n }\n\n if (getId != null) {\n return getId(options);\n }\n\n const segments: string[] = [];\n\n for (const dynamic of include.values()) {\n const value = params?.[dynamic.name];\n if (Array.isArray(value) && value.length > 0) {\n // If we are an array with a value\n segments.push(value.join('/'));\n } else if (value && !Array.isArray(value)) {\n // If we have a value and not an empty array\n segments.push(value);\n } else if (dynamic.deep) {\n segments.push(`[...${dynamic.name}]`);\n } else {\n segments.push(`[${dynamic.name}]`);\n }\n }\n\n return segments.join('/') ?? route.contextKey;\n };\n}\n\nexport function screenOptionsFactory(\n route: RouteNode,\n options?: ScreenProps['options']\n): RouteConfig<any, any, any, any, any, any>['options'] {\n return (args) => {\n // Only eager load generated components\n const staticOptions = route.generated ? route.loadRoute()?.getNavOptions : null;\n const staticResult = typeof staticOptions === 'function' ? staticOptions(args) : staticOptions;\n const dynamicResult = typeof options === 'function' ? options?.(args) : options;\n const output = {\n ...staticResult,\n ...dynamicResult,\n };\n\n // Prevent generated screens from showing up in the tab bar.\n if (route.generated) {\n output.tabBarItemStyle = { display: 'none' };\n output.tabBarButton = () => null;\n // TODO: React Navigation doesn't provide a way to prevent rendering the drawer item.\n output.drawerItemStyle = { height: 0, display: 'none' };\n }\n\n return output;\n };\n}\n\nexport function routeToScreen(\n route: RouteNode,\n { options, getId, ...props }: Partial<ScreenProps> = {}\n) {\n return (\n <Screen\n {...props}\n getId={createGetIdForRoute(route, getId)}\n name={route.route}\n key={route.route}\n options={screenOptionsFactory(route, options)}\n getComponent={() => getQualifiedRouteComponent(route)}\n />\n );\n}\n"]}
@@ -1,8 +1,7 @@
1
1
  {
2
- "platforms": ["ios", "web"],
3
- "ios": {
2
+ "platforms": ["apple", "web"],
3
+ "apple": {
4
4
  "modules": ["ExpoHeadModule"],
5
5
  "appDelegateSubscribers": ["ExpoHeadAppDelegateSubscriber"]
6
6
  }
7
7
  }
8
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "4.0.17",
3
+ "version": "4.0.18-canary-20250303-4dba60e",
4
4
  "description": "Expo Router is a file-based router for React Native and web applications.",
5
5
  "author": "650 Industries, Inc.",
6
6
  "license": "MIT",
@@ -75,9 +75,9 @@
75
75
  ],
76
76
  "peerDependencies": {
77
77
  "@react-navigation/drawer": "^7.1.1",
78
- "expo": "*",
79
- "expo-constants": "*",
80
- "expo-linking": "*",
78
+ "expo": "53.0.0-canary-20250303-4dba60e",
79
+ "expo-constants": "18.0.0-canary-20250303-4dba60e",
80
+ "expo-linking": "7.1.0-canary-20250303-4dba60e",
81
81
  "react-native-reanimated": "*",
82
82
  "react-native-safe-area-context": "*",
83
83
  "react-native-screens": "*"
@@ -97,14 +97,14 @@
97
97
  "@react-navigation/drawer": "^7.1.1",
98
98
  "@testing-library/jest-native": "^5.4.2",
99
99
  "@testing-library/react": "^15.0.7",
100
- "@testing-library/react-native": "^12.5.1",
100
+ "@testing-library/react-native": "^13.1.0",
101
101
  "immer": "^10.1.1",
102
102
  "react-server-dom-webpack": "19.0.0-rc-6230622a1a-20240610",
103
103
  "tsd": "^0.28.1"
104
104
  },
105
105
  "dependencies": {
106
- "@expo/metro-runtime": "4.0.1",
107
- "@expo/server": "^0.5.1",
106
+ "@expo/metro-runtime": "4.0.2-canary-20250303-4dba60e",
107
+ "@expo/server": "0.5.2-canary-20250303-4dba60e",
108
108
  "@radix-ui/react-slot": "1.0.1",
109
109
  "@react-navigation/bottom-tabs": "^7.2.0",
110
110
  "@react-navigation/native": "^7.0.14",
@@ -117,5 +117,5 @@
117
117
  "semver": "~7.6.3",
118
118
  "server-only": "^0.0.1"
119
119
  },
120
- "gitHead": "0a0c6d35a691fc59c0d94675d159ac9e3dfd6f26"
120
+ "gitHead": "4dba60e10b5d44b453073aa4968e9dbf312dea6c"
121
121
  }
@@ -30,10 +30,6 @@ const withRouter = (config, _props) => {
30
30
  extra: {
31
31
  ...config.extra,
32
32
  router: {
33
- // RSC enables location origin by default because it's required for requests.
34
- origin: config.experiments?.reactServerComponentRoutes || config.experiments?.reactServerFunctions
35
- ? undefined
36
- : false,
37
33
  ...config.extra?.router,
38
34
  ...props,
39
35
  },
@@ -49,11 +49,6 @@ const withRouter: ConfigPlugin<
49
49
  extra: {
50
50
  ...config.extra,
51
51
  router: {
52
- // RSC enables location origin by default because it's required for requests.
53
- origin:
54
- config.experiments?.reactServerComponentRoutes || config.experiments?.reactServerFunctions
55
- ? undefined
56
- : false,
57
52
  ...config.extra?.router,
58
53
  ...props,
59
54
  },