expo-router 5.2.0-canary-20250811-5c940c0 → 6.0.0-beta.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 (136) hide show
  1. package/assets/native-tabs.module.css +109 -0
  2. package/build/ExpoRoot.d.ts.map +1 -1
  3. package/build/ExpoRoot.js +0 -2
  4. package/build/ExpoRoot.js.map +1 -1
  5. package/build/fork/NavigationContainer.d.ts.map +1 -1
  6. package/build/fork/NavigationContainer.js +2 -0
  7. package/build/fork/NavigationContainer.js.map +1 -1
  8. package/build/global-state/routing.d.ts +6 -5
  9. package/build/global-state/routing.d.ts.map +1 -1
  10. package/build/global-state/routing.js +8 -11
  11. package/build/global-state/routing.js.map +1 -1
  12. package/build/head/ExpoHead.android.d.ts +1 -3
  13. package/build/imperative-api.d.ts +3 -1
  14. package/build/imperative-api.d.ts.map +1 -1
  15. package/build/imperative-api.js +4 -4
  16. package/build/imperative-api.js.map +1 -1
  17. package/build/layouts/DrawerClient.d.ts +2 -12
  18. package/build/layouts/DrawerClient.d.ts.map +1 -1
  19. package/build/layouts/Stack.web.d.ts +1 -1
  20. package/build/layouts/Stack.web.d.ts.map +1 -1
  21. package/build/layouts/Stack.web.js +3 -3
  22. package/build/layouts/Stack.web.js.map +1 -1
  23. package/build/layouts/StackClient.d.ts +2 -12
  24. package/build/layouts/StackClient.d.ts.map +1 -1
  25. package/build/layouts/StackClient.js +7 -8
  26. package/build/layouts/StackClient.js.map +1 -1
  27. package/build/layouts/TabsClient.d.ts +3 -18
  28. package/build/layouts/TabsClient.d.ts.map +1 -1
  29. package/build/layouts/withLayoutContext.d.ts +5 -1
  30. package/build/layouts/withLayoutContext.d.ts.map +1 -1
  31. package/build/layouts/withLayoutContext.js +21 -8
  32. package/build/layouts/withLayoutContext.js.map +1 -1
  33. package/build/link/LinkWithPreview.d.ts.map +1 -1
  34. package/build/link/LinkWithPreview.js +13 -4
  35. package/build/link/LinkWithPreview.js.map +1 -1
  36. package/build/link/elements.d.ts +17 -17
  37. package/build/link/elements.js +4 -4
  38. package/build/link/elements.js.map +1 -1
  39. package/build/link/preview/HrefPreview.d.ts.map +1 -1
  40. package/build/link/preview/HrefPreview.js +22 -4
  41. package/build/link/preview/HrefPreview.js.map +1 -1
  42. package/build/link/preview/native.d.ts.map +1 -1
  43. package/build/link/preview/native.js +1 -1
  44. package/build/link/preview/native.js.map +1 -1
  45. package/build/link/preview/useNextScreenId.d.ts.map +1 -1
  46. package/build/link/preview/useNextScreenId.js +0 -1
  47. package/build/link/preview/useNextScreenId.js.map +1 -1
  48. package/build/modal/ModalsRenderer.web.js +4 -4
  49. package/build/modal/ModalsRenderer.web.js.map +1 -1
  50. package/build/modal/web/{ModalStack.web.d.ts → ModalStack.d.ts} +1 -1
  51. package/build/modal/web/ModalStack.d.ts.map +1 -0
  52. package/build/modal/web/{ModalStack.web.js → ModalStack.js} +5 -5
  53. package/build/modal/web/ModalStack.js.map +1 -0
  54. package/build/modal/web/{ModalStackRouteDrawer.web.d.ts → ModalStackRouteDrawer.d.ts} +1 -1
  55. package/build/modal/web/ModalStackRouteDrawer.d.ts.map +1 -0
  56. package/build/modal/web/{ModalStackRouteDrawer.web.js → ModalStackRouteDrawer.js} +1 -1
  57. package/build/modal/web/ModalStackRouteDrawer.js.map +1 -0
  58. package/build/modal/web/{TransparentModalStackRouteDrawer.web.d.ts → TransparentModalStackRouteDrawer.d.ts} +1 -1
  59. package/build/modal/web/TransparentModalStackRouteDrawer.d.ts.map +1 -0
  60. package/build/modal/web/{TransparentModalStackRouteDrawer.web.js → TransparentModalStackRouteDrawer.js} +1 -1
  61. package/build/modal/web/TransparentModalStackRouteDrawer.js.map +1 -0
  62. package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.d.ts +4 -12
  63. package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.d.ts.map +1 -1
  64. package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.js +17 -4
  65. package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.js.map +1 -1
  66. package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.d.ts +47 -0
  67. package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.d.ts.map +1 -0
  68. package/build/native-tabs/NativeBottomTabs/{TabOptions.js → NativeTabTrigger.js} +57 -7
  69. package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js.map +1 -0
  70. package/build/native-tabs/NativeBottomTabs/NativeTabs.d.ts +22 -5
  71. package/build/native-tabs/NativeBottomTabs/NativeTabs.d.ts.map +1 -1
  72. package/build/native-tabs/NativeBottomTabs/NativeTabs.js +20 -2
  73. package/build/native-tabs/NativeBottomTabs/NativeTabs.js.map +1 -1
  74. package/build/native-tabs/NativeBottomTabs/NativeTabsView.d.ts +1 -100
  75. package/build/native-tabs/NativeBottomTabs/NativeTabsView.d.ts.map +1 -1
  76. package/build/native-tabs/NativeBottomTabs/NativeTabsView.js +61 -23
  77. package/build/native-tabs/NativeBottomTabs/NativeTabsView.js.map +1 -1
  78. package/build/native-tabs/NativeBottomTabs/NativeTabsView.web.d.ts +4 -0
  79. package/build/native-tabs/NativeBottomTabs/NativeTabsView.web.d.ts.map +1 -0
  80. package/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js +128 -0
  81. package/build/native-tabs/NativeBottomTabs/NativeTabsView.web.js.map +1 -0
  82. package/build/native-tabs/NativeBottomTabs/types.d.ts +193 -0
  83. package/build/native-tabs/NativeBottomTabs/types.d.ts.map +1 -0
  84. package/build/native-tabs/NativeBottomTabs/types.js +3 -0
  85. package/build/native-tabs/NativeBottomTabs/types.js.map +1 -0
  86. package/build/native-tabs/NativeBottomTabs/utils.d.ts +2 -2
  87. package/build/native-tabs/NativeBottomTabs/utils.d.ts.map +1 -1
  88. package/build/native-tabs/NativeBottomTabs/utils.js.map +1 -1
  89. package/build/native-tabs/common/elements.d.ts +21 -6
  90. package/build/native-tabs/common/elements.d.ts.map +1 -1
  91. package/build/native-tabs/common/elements.js +6 -0
  92. package/build/native-tabs/common/elements.js.map +1 -1
  93. package/build/native-tabs/index.d.ts +3 -1
  94. package/build/native-tabs/index.d.ts.map +1 -1
  95. package/build/native-tabs/index.js +18 -5
  96. package/build/native-tabs/index.js.map +1 -1
  97. package/build/rsc/middleware.d.ts +1 -1
  98. package/build/rsc/middleware.d.ts.map +1 -1
  99. package/build/rsc/middleware.js.map +1 -1
  100. package/build/rsc/router/client.d.ts +1 -3
  101. package/build/rsc/router/client.d.ts.map +1 -1
  102. package/build/testing-library/mocks.js +0 -7
  103. package/build/testing-library/mocks.js.map +1 -1
  104. package/build/ui/TabContext.d.ts +11 -21
  105. package/build/ui/TabContext.d.ts.map +1 -1
  106. package/build/ui/TabRouter.d.ts +7 -0
  107. package/build/ui/TabRouter.d.ts.map +1 -1
  108. package/build/ui/Tabs.d.ts +14 -23
  109. package/build/ui/Tabs.d.ts.map +1 -1
  110. package/build/useScreens.d.ts +1 -1
  111. package/build/useScreens.d.ts.map +1 -1
  112. package/build/useScreens.js +6 -4
  113. package/build/useScreens.js.map +1 -1
  114. package/build/views/Sitemap.d.ts.map +1 -1
  115. package/build/views/Sitemap.js +66 -36
  116. package/build/views/Sitemap.js.map +1 -1
  117. package/ios/LinkPreview/LinkPreviewNativeModule.swift +7 -1
  118. package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +0 -1
  119. package/ios/LinkPreview/LinkPreviewNativeTriggerView.swift +1 -1
  120. package/ios/LinkPreview/LinkPreviewNativeView.swift +4 -3
  121. package/package.json +23 -21
  122. package/plugin/build/index.js +1 -1
  123. package/plugin/src/index.ts +1 -1
  124. package/plugin/tsconfig.tsbuildinfo +1 -0
  125. package/server.d.ts +2 -2
  126. package/unstable-native-tabs.d.ts +1 -0
  127. package/unstable-native-tabs.js +1 -0
  128. package/build/modal/web/ModalStack.web.d.ts.map +0 -1
  129. package/build/modal/web/ModalStack.web.js.map +0 -1
  130. package/build/modal/web/ModalStackRouteDrawer.web.d.ts.map +0 -1
  131. package/build/modal/web/ModalStackRouteDrawer.web.js.map +0 -1
  132. package/build/modal/web/TransparentModalStackRouteDrawer.web.d.ts.map +0 -1
  133. package/build/modal/web/TransparentModalStackRouteDrawer.web.js.map +0 -1
  134. package/build/native-tabs/NativeBottomTabs/TabOptions.d.ts +0 -40
  135. package/build/native-tabs/NativeBottomTabs/TabOptions.d.ts.map +0 -1
  136. package/build/native-tabs/NativeBottomTabs/TabOptions.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"NativeBottomTabsNavigator.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,aAAa,EAIb,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAGjD,OAAO,EAAE,gBAAgB,EAAkB,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAG9F,MAAM,WAAW,wBACf,SAAQ,iBAAiB,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAC/D;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;CACpD;AAKD,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,YAAkC,EAClC,GAAG,IAAI,EACR,EAAE,wBAAwB,qBAa1B;AAID,eAAO,MAAM,8BAA8B;;;;;;;;;;;CAOzC,CAAC"}
1
+ {"version":3,"file":"NativeBottomTabsNavigator.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,aAAa,EAIb,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAOjE,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,YAAkC,EAClC,GAAG,IAAI,EACR,EAAE,eAAe,qBA+BjB;AAID,eAAO,MAAM,8BAA8B;;;;;;;;;;;CAKa,CAAC"}
@@ -11,6 +11,8 @@ const react_1 = __importDefault(require("react"));
11
11
  const NativeBottomTabsRouter_1 = require("./NativeBottomTabsRouter");
12
12
  const NativeTabsView_1 = require("./NativeTabsView");
13
13
  const __1 = require("../..");
14
+ const utils_1 = require("./utils");
15
+ const linking_1 = require("../../link/linking");
14
16
  // In Jetpack Compose, the default back behavior is to go back to the initial route.
15
17
  const defaultBackBehavior = 'initialRoute';
16
18
  function NativeTabsNavigator({ children, backBehavior = defaultBackBehavior, ...rest }) {
@@ -18,10 +20,21 @@ function NativeTabsNavigator({ children, backBehavior = defaultBackBehavior, ...
18
20
  children,
19
21
  backBehavior,
20
22
  });
21
- return <NativeTabsView_1.NativeTabsView builder={builder} {...rest}/>;
23
+ const { state, descriptors } = builder;
24
+ const { routes } = state;
25
+ let focusedIndex = state.index;
26
+ const isAnyRouteFocused = routes[focusedIndex].key &&
27
+ descriptors[routes[focusedIndex].key] &&
28
+ (0, utils_1.shouldTabBeVisible)(descriptors[routes[focusedIndex].key].options);
29
+ if (!isAnyRouteFocused) {
30
+ if (process.env.NODE_ENV !== 'production') {
31
+ throw new Error(`The focused tab in NativeTabsView cannot be displayed. Make sure path is correct and the route is not hidden. Path: "${(0, linking_1.getPathFromState)(state)}"`);
32
+ }
33
+ // Set focusedIndex to the first visible tab
34
+ focusedIndex = routes.findIndex((route) => (0, utils_1.shouldTabBeVisible)(descriptors[route.key].options));
35
+ }
36
+ return <NativeTabsView_1.NativeTabsView builder={builder} {...rest} focusedIndex={focusedIndex}/>;
22
37
  }
23
38
  const createNativeTabNavigator = (0, native_1.createNavigatorFactory)(NativeTabsNavigator);
24
- exports.NativeTabsNavigatorWithContext = (0, __1.withLayoutContext)(createNativeTabNavigator().Navigator, (screens) => {
25
- return screens;
26
- });
39
+ exports.NativeTabsNavigatorWithContext = (0, __1.withLayoutContext)(createNativeTabNavigator().Navigator, undefined, true);
27
40
  //# sourceMappingURL=NativeBottomTabsNavigator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeBottomTabsNavigator.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;AA8Bb,kDAiBC;AA7CD,qDAQkC;AAClC,kDAAiD;AAEjD,qEAAkE;AAClE,qDAA8F;AAC9F,6BAA0C;AAY1C,oFAAoF;AACpF,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAE3C,SAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,YAAY,GAAG,mBAAmB,EAClC,GAAG,IAAI,EACkB;IACzB,MAAM,OAAO,GAAG,IAAA,6BAAoB,EAMlC,+CAAsB,EAAE;QACxB,QAAQ;QACR,YAAY;KACb,CAAC,CAAC;IAEH,OAAO,CAAC,+BAAc,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,EAAG,CAAC;AACxD,CAAC;AAED,MAAM,wBAAwB,GAAG,IAAA,+BAAsB,EAAC,mBAAmB,CAAC,CAAC;AAEhE,QAAA,8BAA8B,GAAG,IAAA,qBAAiB,EAK7D,wBAAwB,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;IAClD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC,CAAC","sourcesContent":["'use client';\n\nimport {\n createNavigatorFactory,\n NavigationState,\n ParamListBase,\n TabNavigationState,\n TabRouterOptions,\n useNavigationBuilder,\n type EventMapBase,\n} from '@react-navigation/native';\nimport React, { PropsWithChildren } from 'react';\n\nimport { NativeBottomTabsRouter } from './NativeBottomTabsRouter';\nimport { NativeTabOptions, NativeTabsView, type NativeTabsViewProps } from './NativeTabsView';\nimport { withLayoutContext } from '../..';\n\nexport interface NativeTabsNavigatorProps\n extends PropsWithChildren<Omit<NativeTabsViewProps, 'builder'>> {\n /**\n * The behavior when navigating back with the back button.\n *\n * @platform android\n */\n backBehavior?: 'none' | 'initialRoute' | 'history';\n}\n\n// In Jetpack Compose, the default back behavior is to go back to the initial route.\nconst defaultBackBehavior = 'initialRoute';\n\nexport function NativeTabsNavigator({\n children,\n backBehavior = defaultBackBehavior,\n ...rest\n}: NativeTabsNavigatorProps) {\n const builder = useNavigationBuilder<\n TabNavigationState<ParamListBase>,\n TabRouterOptions,\n Record<string, (...args: any) => void>,\n NativeTabOptions,\n Record<string, any>\n >(NativeBottomTabsRouter, {\n children,\n backBehavior,\n });\n\n return <NativeTabsView builder={builder} {...rest} />;\n}\n\nconst createNativeTabNavigator = createNavigatorFactory(NativeTabsNavigator);\n\nexport const NativeTabsNavigatorWithContext = withLayoutContext<\n NativeTabOptions,\n typeof NativeTabsNavigator,\n NavigationState,\n EventMapBase\n>(createNativeTabNavigator().Navigator, (screens) => {\n return screens;\n});\n"]}
1
+ {"version":3,"file":"NativeBottomTabsNavigator.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;;;AAuBb,kDAmCC;AAxDD,qDAQkC;AAClC,kDAA0B;AAE1B,qEAAkE;AAClE,qDAAkD;AAClD,6BAA0C;AAE1C,mCAA6C;AAC7C,gDAAsD;AAEtD,oFAAoF;AACpF,MAAM,mBAAmB,GAAG,cAAc,CAAC;AAE3C,SAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,YAAY,GAAG,mBAAmB,EAClC,GAAG,IAAI,EACS;IAChB,MAAM,OAAO,GAAG,IAAA,6BAAoB,EAMlC,+CAAsB,EAAE;QACxB,QAAQ;QACR,YAAY;KACb,CAAC,CAAC;IAEH,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACvC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,IAAI,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC;IAC/B,MAAM,iBAAiB,GACrB,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG;QACxB,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC;QACrC,IAAA,0BAAkB,EAAC,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEpE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,wHAAwH,IAAA,0BAAgB,EAAC,KAAK,CAAC,GAAG,CACnJ,CAAC;QACJ,CAAC;QACD,4CAA4C;QAC5C,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,0BAAkB,EAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,CAAC,+BAAc,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,EAAG,CAAC;AACpF,CAAC;AAED,MAAM,wBAAwB,GAAG,IAAA,+BAAsB,EAAC,mBAAmB,CAAC,CAAC;AAEhE,QAAA,8BAA8B,GAAG,IAAA,qBAAiB,EAK7D,wBAAwB,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC","sourcesContent":["'use client';\n\nimport {\n createNavigatorFactory,\n NavigationState,\n ParamListBase,\n TabNavigationState,\n TabRouterOptions,\n useNavigationBuilder,\n type EventMapBase,\n} from '@react-navigation/native';\nimport React from 'react';\n\nimport { NativeBottomTabsRouter } from './NativeBottomTabsRouter';\nimport { NativeTabsView } from './NativeTabsView';\nimport { withLayoutContext } from '../..';\nimport type { NativeTabOptions, NativeTabsProps } from './types';\nimport { shouldTabBeVisible } from './utils';\nimport { getPathFromState } from '../../link/linking';\n\n// In Jetpack Compose, the default back behavior is to go back to the initial route.\nconst defaultBackBehavior = 'initialRoute';\n\nexport function NativeTabsNavigator({\n children,\n backBehavior = defaultBackBehavior,\n ...rest\n}: NativeTabsProps) {\n const builder = useNavigationBuilder<\n TabNavigationState<ParamListBase>,\n TabRouterOptions,\n Record<string, (...args: any) => void>,\n NativeTabOptions,\n Record<string, any>\n >(NativeBottomTabsRouter, {\n children,\n backBehavior,\n });\n\n const { state, descriptors } = builder;\n const { routes } = state;\n let focusedIndex = state.index;\n const isAnyRouteFocused =\n routes[focusedIndex].key &&\n descriptors[routes[focusedIndex].key] &&\n shouldTabBeVisible(descriptors[routes[focusedIndex].key].options);\n\n if (!isAnyRouteFocused) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The focused tab in NativeTabsView cannot be displayed. Make sure path is correct and the route is not hidden. Path: \"${getPathFromState(state)}\"`\n );\n }\n // Set focusedIndex to the first visible tab\n focusedIndex = routes.findIndex((route) => shouldTabBeVisible(descriptors[route.key].options));\n }\n\n return <NativeTabsView builder={builder} {...rest} focusedIndex={focusedIndex} />;\n}\n\nconst createNativeTabNavigator = createNavigatorFactory(NativeTabsNavigator);\n\nexport const NativeTabsNavigatorWithContext = withLayoutContext<\n NativeTabOptions,\n typeof NativeTabsNavigator,\n NavigationState,\n EventMapBase\n>(createNativeTabNavigator().Navigator, undefined, true);\n"]}
@@ -0,0 +1,47 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ import type { ExtendedNativeTabOptions, NativeTabTriggerProps } from './types';
3
+ /**
4
+ * The component used to customize the native tab options both in the _layout file and from the tab screen.
5
+ *
6
+ * When used in the _layout file, you need to provide a `name` prop.
7
+ * When used in the tab screen, the `name` prop takes no effect.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // In _layout file
12
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
13
+ *
14
+ * export default function Layout() {
15
+ * return (
16
+ * <NativeTabs>
17
+ * <NativeTabs.Trigger name="home" />
18
+ * <NativeTabs.Trigger name="settings" />
19
+ * </NativeTabs>
20
+ * );
21
+ * }
22
+ * ```
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * // In a tab screen
27
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
28
+ *
29
+ * export default function HomeScreen() {
30
+ * return (
31
+ * <View>
32
+ * <NativeTabs.Trigger>
33
+ * <Label>Home</Label>
34
+ * </NativeTabs.Trigger>
35
+ * <Text>This is home screen!</Text>
36
+ * </View>
37
+ * );
38
+ * }
39
+ *
40
+ * **Note:** You can use the alias `NativeTabs.Trigger` for this component.
41
+ */
42
+ export declare function NativeTabTrigger(props: NativeTabTriggerProps): null;
43
+ export declare function convertTabPropsToOptions({ options, hidden, children, disablePopToTop, disableScrollToTop, }: NativeTabTriggerProps): ExtendedNativeTabOptions;
44
+ export declare function isNativeTabTrigger(child: ReactNode, contextKey?: string): child is ReactElement<NativeTabTriggerProps & {
45
+ name: string;
46
+ }>;
47
+ //# sourceMappingURL=NativeTabTrigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTabTrigger.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabTrigger.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAK/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,QAqB5D;AAED,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,GACnB,EAAE,qBAAqB,4BAgEvB;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,EAChB,UAAU,CAAC,EAAE,MAAM,GAClB,KAAK,IAAI,YAAY,CAAC,qBAAqB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BjE"}
@@ -1,15 +1,54 @@
1
1
  "use strict";
2
2
  'use client';
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.TabTrigger = TabTrigger;
4
+ exports.NativeTabTrigger = NativeTabTrigger;
5
5
  exports.convertTabPropsToOptions = convertTabPropsToOptions;
6
- exports.isTab = isTab;
6
+ exports.isNativeTabTrigger = isNativeTabTrigger;
7
7
  const native_1 = require("@react-navigation/native");
8
8
  const react_1 = require("react");
9
9
  const utils_1 = require("./utils");
10
10
  const useSafeLayoutEffect_1 = require("../../views/useSafeLayoutEffect");
11
11
  const elements_1 = require("../common/elements");
12
- function TabTrigger(props) {
12
+ /**
13
+ * The component used to customize the native tab options both in the _layout file and from the tab screen.
14
+ *
15
+ * When used in the _layout file, you need to provide a `name` prop.
16
+ * When used in the tab screen, the `name` prop takes no effect.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * // In _layout file
21
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
22
+ *
23
+ * export default function Layout() {
24
+ * return (
25
+ * <NativeTabs>
26
+ * <NativeTabs.Trigger name="home" />
27
+ * <NativeTabs.Trigger name="settings" />
28
+ * </NativeTabs>
29
+ * );
30
+ * }
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * // In a tab screen
36
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
37
+ *
38
+ * export default function HomeScreen() {
39
+ * return (
40
+ * <View>
41
+ * <NativeTabs.Trigger>
42
+ * <Label>Home</Label>
43
+ * </NativeTabs.Trigger>
44
+ * <Text>This is home screen!</Text>
45
+ * </View>
46
+ * );
47
+ * }
48
+ *
49
+ * **Note:** You can use the alias `NativeTabs.Trigger` for this component.
50
+ */
51
+ function NativeTabTrigger(props) {
13
52
  const route = (0, native_1.useRoute)();
14
53
  const navigation = (0, native_1.useNavigation)();
15
54
  const isFocused = navigation.isFocused();
@@ -44,9 +83,20 @@ function convertTabPropsToOptions({ options, hidden, children, disablePopToTop,
44
83
  if (child.props.children) {
45
84
  acc.badgeValue = String(child.props.children);
46
85
  }
86
+ else if (!child.props.hidden) {
87
+ // If no value is provided, we set it to a space to show the badge
88
+ // Otherwise, the `react-native-screens` will interpret it as a hidden badge
89
+ // https://github.com/software-mansion/react-native-screens/blob/b4358fd95dd0736fc54df6bb97f210dc89edf24c/ios/bottom-tabs/RNSBottomTabsScreenComponentView.mm#L172
90
+ acc.badgeValue = ' ';
91
+ }
47
92
  }
48
93
  else if ((0, utils_1.isChildOfType)(child, elements_1.Label)) {
49
- acc.title = child.props.children;
94
+ if (child.props.hidden) {
95
+ acc.title = '';
96
+ }
97
+ else {
98
+ acc.title = child.props.children;
99
+ }
50
100
  }
51
101
  else if ((0, utils_1.isChildOfType)(child, elements_1.Icon)) {
52
102
  if ('src' in child.props || 'selectedSrc' in child.props) {
@@ -83,8 +133,8 @@ function convertTabPropsToOptions({ options, hidden, children, disablePopToTop,
83
133
  return acc;
84
134
  }, { ...initialOptions });
85
135
  }
86
- function isTab(child, contextKey) {
87
- if ((0, react_1.isValidElement)(child) && child && child.type === TabTrigger) {
136
+ function isNativeTabTrigger(child, contextKey) {
137
+ if ((0, react_1.isValidElement)(child) && child && child.type === NativeTabTrigger) {
88
138
  if (typeof child.props === 'object' &&
89
139
  child.props &&
90
140
  'name' in child.props &&
@@ -100,4 +150,4 @@ function isTab(child, contextKey) {
100
150
  }
101
151
  return false;
102
152
  }
103
- //# sourceMappingURL=TabOptions.js.map
153
+ //# sourceMappingURL=NativeTabTrigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTabTrigger.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabTrigger.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAiDb,4CAqBC;AAED,4DAsEC;AAED,gDAgCC;AA9KD,qDAAmE;AACnE,iCAA0E;AAG1E,mCAAuE;AACvE,yEAAsE;AACtE,iDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,SAAgB,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,KAAK,GAAG,IAAA,iBAAQ,GAAE,CAAC;IACzB,MAAM,UAAU,GAAG,IAAA,sBAAa,GAAE,CAAC;IACnC,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;IAEzC,IAAA,yCAAmB,EAAC,GAAG,EAAE;QACvB,6DAA6D;QAC7D,yEAAyE;QACzE,iDAAiD;QACjD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,UAAU,CAAC,QAAQ,EAAE,EAAE,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CACb,wEAAwE,KAAK,CAAC,IAAI,EAAE,CACrF,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;YAChD,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAEvB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,MAAM,EACN,QAAQ,EACR,eAAe,EACf,kBAAkB,GACI;IACtB,MAAM,cAAc,GAA6B;QAC/C,GAAG,OAAO;QACV,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,cAAc,EAAE;YACd,oBAAoB,EAAE;gBACpB,SAAS,EAAE,CAAC,eAAe;gBAC3B,WAAW,EAAE,CAAC,kBAAkB;aACjC;SACF;KACF,CAAC;IACF,MAAM,eAAe,GAAG,IAAA,qCAA6B,EAAC,QAAQ,EAAE,CAAC,gBAAK,EAAE,gBAAK,EAAE,eAAI,CAAC,CAAC,CAAC;IACtF,OAAO,eAAe,CAAC,MAAM,CAC3B,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QACb,IAAI,IAAA,qBAAa,EAAC,KAAK,EAAE,gBAAK,CAAC,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACzB,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAChD,CAAC;iBAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC/B,kEAAkE;gBAClE,4EAA4E;gBAC5E,kKAAkK;gBAClK,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACvB,CAAC;QACH,CAAC;aAAM,IAAI,IAAA,qBAAa,EAAC,KAAK,EAAE,gBAAK,CAAC,EAAE,CAAC;YACvC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;YACnC,CAAC;QACH,CAAC;aAAM,IAAI,IAAA,qBAAa,EAAC,KAAK,EAAE,eAAI,CAAC,EAAE,CAAC;YACtC,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,aAAa,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBACzD,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG;oBACxB,CAAC,CAAC;wBACE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG;qBACrB;oBACH,CAAC,CAAC,SAAS,CAAC;gBACd,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW;oBACxC,CAAC,CAAC;wBACE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW;qBAC7B;oBACH,CAAC,CAAC,SAAS,CAAC;YAChB,CAAC;iBAAM,IAAI,IAAI,IAAI,KAAK,CAAC,KAAK,IAAI,YAAY,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC9D,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;oBAClC,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE;wBACvB,CAAC,CAAC;4BACE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE;yBACnB;wBACH,CAAC,CAAC,SAAS,CAAC;oBACd,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU;wBACvC,CAAC,CAAC;4BACE,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU;yBAC3B;wBACH,CAAC,CAAC,SAAS,CAAC;gBAChB,CAAC;YACH,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACtC,GAAG,CAAC,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC9C,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EACD,EAAE,GAAG,cAAc,EAAE,CACtB,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB,CAChC,KAAgB,EAChB,UAAmB;IAEnB,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACtE,IACE,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;YAC/B,KAAK,CAAC,KAAK;YACX,MAAM,IAAI,KAAK,CAAC,KAAK;YACrB,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EACjB,CAAC;YACD,MAAM,IAAI,KAAK,CACb,uDAAuD,UAAU,8EAA8E,CAChJ,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC1C,IACE,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,IAAI,CAChC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,GAAG,IAAI,KAAK,CAAC,KAAK,CAC9E,EACD,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,uDAAuD,UAAU,0GAA0G,CAC5K,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["'use client';\n\nimport { useNavigation, useRoute } from '@react-navigation/native';\nimport { isValidElement, type ReactElement, type ReactNode } from 'react';\n\nimport type { ExtendedNativeTabOptions, NativeTabTriggerProps } from './types';\nimport { filterAllowedChildrenElements, isChildOfType } from './utils';\nimport { useSafeLayoutEffect } from '../../views/useSafeLayoutEffect';\nimport { Icon, Badge, Label } from '../common/elements';\n\n/**\n * The component used to customize the native tab options both in the _layout file and from the tab screen.\n *\n * When used in the _layout file, you need to provide a `name` prop.\n * When used in the tab screen, the `name` prop takes no effect.\n *\n * @example\n * ```tsx\n * // In _layout file\n * import { NativeTabs } from 'expo-router/unstable-native-tabs';\n *\n * export default function Layout() {\n * return (\n * <NativeTabs>\n * <NativeTabs.Trigger name=\"home\" />\n * <NativeTabs.Trigger name=\"settings\" />\n * </NativeTabs>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // In a tab screen\n * import { NativeTabs } from 'expo-router/unstable-native-tabs';\n *\n * export default function HomeScreen() {\n * return (\n * <View>\n * <NativeTabs.Trigger>\n * <Label>Home</Label>\n * </NativeTabs.Trigger>\n * <Text>This is home screen!</Text>\n * </View>\n * );\n * }\n *\n * **Note:** You can use the alias `NativeTabs.Trigger` for this component.\n */\nexport function NativeTabTrigger(props: NativeTabTriggerProps) {\n const route = useRoute();\n const navigation = useNavigation();\n const isFocused = navigation.isFocused();\n\n useSafeLayoutEffect(() => {\n // This will cause the tab to update only when it is focused.\n // As long as all tabs are loaded at the start, we don't need this check.\n // It is here to ensure similar behavior to stack\n if (isFocused) {\n if (navigation.getState()?.type !== 'tab') {\n throw new Error(\n `Trigger component can only be used in the tab screen. Current route: ${route.name}`\n );\n }\n const options = convertTabPropsToOptions(props);\n navigation.setOptions(options);\n }\n }, [isFocused, props]);\n\n return null;\n}\n\nexport function convertTabPropsToOptions({\n options,\n hidden,\n children,\n disablePopToTop,\n disableScrollToTop,\n}: NativeTabTriggerProps) {\n const initialOptions: ExtendedNativeTabOptions = {\n ...options,\n hidden: !!hidden,\n specialEffects: {\n repeatedTabSelection: {\n popToRoot: !disablePopToTop,\n scrollToTop: !disableScrollToTop,\n },\n },\n };\n const allowedChildren = filterAllowedChildrenElements(children, [Badge, Label, Icon]);\n return allowedChildren.reduce<ExtendedNativeTabOptions>(\n (acc, child) => {\n if (isChildOfType(child, Badge)) {\n if (child.props.children) {\n acc.badgeValue = String(child.props.children);\n } else if (!child.props.hidden) {\n // If no value is provided, we set it to a space to show the badge\n // Otherwise, the `react-native-screens` will interpret it as a hidden badge\n // https://github.com/software-mansion/react-native-screens/blob/b4358fd95dd0736fc54df6bb97f210dc89edf24c/ios/bottom-tabs/RNSBottomTabsScreenComponentView.mm#L172\n acc.badgeValue = ' ';\n }\n } else if (isChildOfType(child, Label)) {\n if (child.props.hidden) {\n acc.title = '';\n } else {\n acc.title = child.props.children;\n }\n } else if (isChildOfType(child, Icon)) {\n if ('src' in child.props || 'selectedSrc' in child.props) {\n acc.icon = child.props.src\n ? {\n src: child.props.src,\n }\n : undefined;\n acc.selectedIcon = child.props.selectedSrc\n ? {\n src: child.props.selectedSrc,\n }\n : undefined;\n } else if ('sf' in child.props || 'selectedSf' in child.props) {\n if (process.env.EXPO_OS === 'ios') {\n acc.icon = child.props.sf\n ? {\n sf: child.props.sf,\n }\n : undefined;\n acc.selectedIcon = child.props.selectedSf\n ? {\n sf: child.props.selectedSf,\n }\n : undefined;\n }\n }\n if (process.env.EXPO_OS === 'android') {\n acc.icon = { drawable: child.props.drawable };\n acc.selectedIcon = undefined;\n }\n }\n return acc;\n },\n { ...initialOptions }\n );\n}\n\nexport function isNativeTabTrigger(\n child: ReactNode,\n contextKey?: string\n): child is ReactElement<NativeTabTriggerProps & { name: string }> {\n if (isValidElement(child) && child && child.type === NativeTabTrigger) {\n if (\n typeof child.props === 'object' &&\n child.props &&\n 'name' in child.props &&\n !child.props.name\n ) {\n throw new Error(\n `<Trigger /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must have a \\`name\\` prop when used as a child of a Layout Route.`\n );\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (\n ['component', 'getComponent'].some(\n (key) => child.props && typeof child.props === 'object' && key in child.props\n )\n ) {\n throw new Error(\n `<Trigger /> component in \\`default export\\` at \\`app${contextKey}/_layout\\` must not have a \\`component\\` or \\`getComponent\\` prop when used as a child of a Layout Route`\n );\n }\n }\n\n return true;\n }\n\n return false;\n}\n"]}
@@ -1,7 +1,24 @@
1
- import type { ComponentProps } from 'react';
2
- import { type NativeTabsNavigator } from './NativeBottomTabsNavigator';
3
- import { TabTrigger } from './TabOptions';
4
- export declare const NativeTabs: ((props: ComponentProps<typeof NativeTabsNavigator>) => import("react").JSX.Element) & {
5
- Trigger: typeof TabTrigger;
1
+ import { NativeTabTrigger } from './NativeTabTrigger';
2
+ import type { NativeTabsProps } from './types';
3
+ /**
4
+ * The component used to create native tabs layout.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * // In _layout file
9
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
10
+ *
11
+ * export default function Layout() {
12
+ * return (
13
+ * <NativeTabs>
14
+ * <NativeTabs.Trigger name="home" />
15
+ * <NativeTabs.Trigger name="settings" />
16
+ * </NativeTabs>
17
+ * );
18
+ * }
19
+ * ```
20
+ */
21
+ export declare const NativeTabs: ((props: NativeTabsProps) => import("react").JSX.Element) & {
22
+ Trigger: typeof NativeTabTrigger;
6
23
  };
7
24
  //# sourceMappingURL=NativeTabs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeTabs.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,eAAO,MAAM,UAAU,WACb,cAAc,CAAC,OAAO,mBAAmB,CAAC;;CAInD,CAAC"}
1
+ {"version":3,"file":"NativeTabs.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabs.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,WACb,eAAe;;CAIxB,CAAC"}
@@ -2,8 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NativeTabs = void 0;
4
4
  const NativeBottomTabsNavigator_1 = require("./NativeBottomTabsNavigator");
5
- const TabOptions_1 = require("./TabOptions");
5
+ const NativeTabTrigger_1 = require("./NativeTabTrigger");
6
+ /**
7
+ * The component used to create native tabs layout.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // In _layout file
12
+ * import { NativeTabs } from 'expo-router/unstable-native-tabs';
13
+ *
14
+ * export default function Layout() {
15
+ * return (
16
+ * <NativeTabs>
17
+ * <NativeTabs.Trigger name="home" />
18
+ * <NativeTabs.Trigger name="settings" />
19
+ * </NativeTabs>
20
+ * );
21
+ * }
22
+ * ```
23
+ */
6
24
  exports.NativeTabs = Object.assign((props) => {
7
25
  return <NativeBottomTabsNavigator_1.NativeTabsNavigatorWithContext {...props}/>;
8
- }, { Trigger: TabOptions_1.TabTrigger });
26
+ }, { Trigger: NativeTabTrigger_1.NativeTabTrigger });
9
27
  //# sourceMappingURL=NativeTabs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeTabs.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabs.tsx"],"names":[],"mappings":";;;AAEA,2EAGqC;AACrC,6CAA0C;AAE7B,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,KAAiD,EAAE,EAAE;IACpD,OAAO,CAAC,0DAA8B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACvD,CAAC,EACD,EAAE,OAAO,EAAE,uBAAU,EAAE,CACxB,CAAC","sourcesContent":["import type { ComponentProps } from 'react';\n\nimport {\n NativeTabsNavigatorWithContext,\n type NativeTabsNavigator,\n} from './NativeBottomTabsNavigator';\nimport { TabTrigger } from './TabOptions';\n\nexport const NativeTabs = Object.assign(\n (props: ComponentProps<typeof NativeTabsNavigator>) => {\n return <NativeTabsNavigatorWithContext {...props} />;\n },\n { Trigger: TabTrigger }\n);\n"]}
1
+ {"version":3,"file":"NativeTabs.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabs.tsx"],"names":[],"mappings":";;;AAAA,2EAA6E;AAC7E,yDAAsD;AAGtD;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CACrC,CAAC,KAAsB,EAAE,EAAE;IACzB,OAAO,CAAC,0DAA8B,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACvD,CAAC,EACD,EAAE,OAAO,EAAE,mCAAgB,EAAE,CAC9B,CAAC","sourcesContent":["import { NativeTabsNavigatorWithContext } from './NativeBottomTabsNavigator';\nimport { NativeTabTrigger } from './NativeTabTrigger';\nimport type { NativeTabsProps } from './types';\n\n/**\n * The component used to create native tabs layout.\n *\n * @example\n * ```tsx\n * // In _layout file\n * import { NativeTabs } from 'expo-router/unstable-native-tabs';\n *\n * export default function Layout() {\n * return (\n * <NativeTabs>\n * <NativeTabs.Trigger name=\"home\" />\n * <NativeTabs.Trigger name=\"settings\" />\n * </NativeTabs>\n * );\n * }\n * ```\n */\nexport const NativeTabs = Object.assign(\n (props: NativeTabsProps) => {\n return <NativeTabsNavigatorWithContext {...props} />;\n },\n { Trigger: NativeTabTrigger }\n);\n"]}
@@ -1,103 +1,4 @@
1
- import { DefaultRouterOptions, ParamListBase, TabNavigationState, TabRouterOptions, useNavigationBuilder } from '@react-navigation/native';
2
1
  import React from 'react';
3
- import { type ColorValue, type ImageSourcePropType, type TextStyle } from 'react-native';
4
- import { type BottomTabsProps, type BottomTabsScreenProps, type TabBarItemLabelVisibilityMode } from 'react-native-screens';
5
- import type { SFSymbol } from 'sf-symbols-typescript';
6
- type BaseNativeTabOptions = Omit<BottomTabsScreenProps, 'children' | 'placeholder' | 'onWillAppear' | 'onDidAppear' | 'onWillDisappear' | 'onDidDisappear' | 'isFocused' | 'tabKey' | 'icon' | 'selectedIcon' | 'iconResourceName'> & DefaultRouterOptions;
7
- type SfSymbolOrImageSource = {
8
- /**
9
- * The name of the SF Symbol to use as an icon.
10
- * @platform iOS
11
- */
12
- sf?: SFSymbol;
13
- } | {
14
- /**
15
- * The image source to use as an icon.
16
- * @platform iOS
17
- */
18
- src?: ImageSourcePropType;
19
- };
20
- export interface NativeTabOptions extends BaseNativeTabOptions {
21
- /**
22
- * If true, the tab will be hidden from the tab bar.
23
- */
24
- hidden?: boolean;
25
- /**
26
- * The icon to display in the tab bar.
27
- */
28
- icon?: SfSymbolOrImageSource & {
29
- /**
30
- * The name of the drawable resource to use as an icon.
31
- * @platform android
32
- */
33
- drawable?: string;
34
- };
35
- /**
36
- * The icon to display when the tab is selected.
37
- */
38
- selectedIcon?: SfSymbolOrImageSource;
39
- }
40
- export interface NativeTabsViewProps {
41
- style?: {
42
- fontFamily?: TextStyle['fontFamily'];
43
- fontSize?: TextStyle['fontSize'];
44
- fontWeight?: TextStyle['fontWeight'];
45
- fontStyle?: TextStyle['fontStyle'];
46
- color?: TextStyle['color'];
47
- iconColor?: ColorValue;
48
- backgroundColor?: ColorValue;
49
- blurEffect?: BottomTabsScreenProps['tabBarBlurEffect'];
50
- tintColor?: ColorValue;
51
- badgeBackgroundColor?: ColorValue;
52
- /**
53
- * @platform android
54
- */
55
- rippleColor?: ColorValue;
56
- /**
57
- * @platform android
58
- */
59
- labelVisibilityMode?: TabBarItemLabelVisibilityMode;
60
- '&:active'?: {
61
- /**
62
- * @platform android
63
- */
64
- color?: ColorValue;
65
- /**
66
- * @platform android
67
- */
68
- fontSize?: TextStyle['fontSize'];
69
- /**
70
- * @platform android
71
- */
72
- iconColor?: ColorValue;
73
- /**
74
- * @platform android
75
- */
76
- indicatorColor?: ColorValue;
77
- };
78
- };
79
- /**
80
- * https://developer.apple.com/documentation/uikit/uitabbarcontroller/tabbarminimizebehavior
81
- *
82
- * Supported values:
83
- * - `none` - The tab bar does not minimize.
84
- * - `onScrollUp` - The tab bar minimizes when scrolling up, and expands when scrolling back down. Recommended if the scroll view content is aligned to the bottom.
85
- * - `onScrollDown` - The tab bar minimizes when scrolling down, and expands when scrolling back up.
86
- * - `automatic` - Resolves to the system default minimize behavior.
87
- *
88
- * @default automatic
89
- *
90
- * @platform iOS 26
91
- */
92
- minimizeBehavior?: BottomTabsProps['tabBarMinimizeBehavior'];
93
- /**
94
- * Disables the active indicator for the tab bar.
95
- *
96
- * @platform android
97
- */
98
- disableIndicator?: boolean;
99
- builder: ReturnType<typeof useNavigationBuilder<TabNavigationState<ParamListBase>, TabRouterOptions, Record<string, (...args: any) => void>, NativeTabOptions, Record<string, any>>>;
100
- }
2
+ import type { NativeTabsViewProps } from './types';
101
3
  export declare function NativeTabsView(props: NativeTabsViewProps): React.JSX.Element;
102
- export {};
103
4
  //# sourceMappingURL=NativeTabsView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NativeTabsView.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabsView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NativeTabsView.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabsView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAQtC,OAAO,KAAK,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAOrE,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,qBA6FxD"}
@@ -1,46 +1,83 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
5
35
  Object.defineProperty(exports, "__esModule", { value: true });
6
36
  exports.NativeTabsView = NativeTabsView;
7
- const react_1 = __importDefault(require("react"));
37
+ const react_1 = __importStar(require("react"));
8
38
  const react_native_screens_1 = require("react-native-screens");
9
39
  const utils_1 = require("./utils");
10
- const linking_1 = require("../../link/linking");
11
40
  // We let native tabs to control the changes. This requires freeze to be disabled for tab bar.
12
41
  // Otherwise user may see glitches when switching between tabs.
13
42
  react_native_screens_1.featureFlags.experiment.controlledBottomTabs = false;
14
- // TODO: ENG-16896: Enable freeze globally and disable only for NativeTabsView
15
- (0, react_native_screens_1.enableFreeze)(false);
16
- // TODO: Add support for dynamic params inside a route
17
43
  function NativeTabsView(props) {
18
- const { builder, style, minimizeBehavior, disableIndicator } = props;
44
+ const { builder, style, minimizeBehavior, disableIndicator, focusedIndex } = props;
19
45
  const { state, descriptors, navigation } = builder;
20
46
  const { routes } = state;
21
- let focusedIndex = state.index;
22
- const isAnyRouteFocused = routes[focusedIndex].key &&
23
- descriptors[routes[focusedIndex].key] &&
24
- (0, utils_1.shouldTabBeVisible)(descriptors[routes[focusedIndex].key].options);
25
- if (!isAnyRouteFocused) {
26
- if (process.env.NODE_ENV !== 'production') {
27
- throw new Error(`The focused tab in NativeTabsView cannot be displayed. Make sure path is correct and the route is not hidden. Path: "${(0, linking_1.getPathFromState)(state)}"`);
28
- }
29
- // Set focusedIndex to the first visible tab
30
- focusedIndex = routes.findIndex((route) => (0, utils_1.shouldTabBeVisible)(descriptors[route.key].options));
47
+ // This is flag that is set to true, when the transition is executed by native tab change
48
+ // In this case we don't need to change the isFocused of the screens, because the transition will happen on native side
49
+ const isDuringNativeTransition = (0, react_1.useRef)(false);
50
+ // This is the last index that was not part of a native transition, e.g navigation from link
51
+ const lastNotNativeTransitionIndex = (0, react_1.useRef)(focusedIndex);
52
+ // If the flag was set in the onNativeFocusChange handler, it will be still true here
53
+ // It is set to false, later in this function
54
+ // Thus if it is false, we know that the transition was not triggered by a native tab change
55
+ // and we need to reset the lastNotNativeTransitionIndex
56
+ if (!isDuringNativeTransition.current) {
57
+ lastNotNativeTransitionIndex.current = focusedIndex;
31
58
  }
32
59
  const children = routes
33
60
  .map((route, index) => ({ route, index }))
34
61
  .filter(({ route: { key } }) => (0, utils_1.shouldTabBeVisible)(descriptors[key].options))
35
62
  .map(({ route, index }) => {
36
63
  const descriptor = descriptors[route.key];
37
- const isFocused = state.index === index;
64
+ // In case of native transition we want to keep the last focused index
65
+ // Otherwise the lastNotNativeTransitionIndex is set to focusedIndex in the if above this statement
66
+ const isFocused = index === focusedIndex;
67
+ // TODO: Find a proper fix, that allows for proper JS navigation
68
+ //lastNotNativeTransitionIndex.current;
38
69
  const title = descriptor.options.title ?? route.name;
39
- return (<react_native_screens_1.BottomTabsScreen key={route.key} {...descriptor.options} iconResourceName={descriptor.options.icon?.drawable} icon={convertOptionsIconToPropsIcon(descriptor.options.icon)} selectedIcon={convertOptionsIconToPropsIcon(descriptor.options.selectedIcon)} title={title} tabKey={route.key} isFocused={isFocused}>
70
+ return (<react_native_screens_1.BottomTabsScreen key={route.key} {...descriptor.options} tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor} tabBarItemBadgeTextColor={style?.badgeTextColor} tabBarItemTitlePositionAdjustment={style?.titlePositionAdjustment} iconResourceName={descriptor.options.icon?.drawable} icon={convertOptionsIconToPropsIcon(descriptor.options.icon)} selectedIcon={convertOptionsIconToPropsIcon(descriptor.options.selectedIcon)} title={title} freezeContents={false} tabKey={route.key} isFocused={isFocused}>
40
71
  {descriptor.render()}
41
72
  </react_native_screens_1.BottomTabsScreen>);
42
73
  });
43
- return (<react_native_screens_1.BottomTabs tabBarItemTitleFontColor={style?.color} tabBarItemTitleFontFamily={style?.fontFamily} tabBarItemTitleFontSize={style?.fontSize} tabBarItemTitleFontWeight={style?.fontWeight} tabBarItemTitleFontStyle={style?.fontStyle} tabBarBackgroundColor={style?.backgroundColor} tabBarBlurEffect={style?.blurEffect} tabBarTintColor={style?.tintColor} tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor} tabBarItemRippleColor={style?.rippleColor} tabBarItemLabelVisibilityMode={style?.labelVisibilityMode} tabBarItemIconColor={style?.iconColor} tabBarItemIconColorActive={style?.['&:active']?.iconColor ?? style?.tintColor} tabBarItemTitleFontColorActive={style?.['&:active']?.color ?? style?.tintColor} tabBarItemTitleFontSizeActive={style?.['&:active']?.fontSize} tabBarItemActiveIndicatorColor={style?.['&:active']?.indicatorColor} tabBarItemActiveIndicatorEnabled={!disableIndicator} tabBarMinimizeBehavior={minimizeBehavior} onNativeFocusChange={({ nativeEvent: { tabKey } }) => {
74
+ // The native render is over, we can reset the flag
75
+ isDuringNativeTransition.current = false;
76
+ return (<react_native_screens_1.BottomTabs tabBarItemTitleFontColor={style?.color} tabBarItemTitleFontFamily={style?.fontFamily} tabBarItemTitleFontSize={style?.fontSize}
77
+ // Only string values are accepted by screens
78
+ tabBarItemTitleFontWeight={style?.fontWeight
79
+ ? String(style.fontWeight)
80
+ : undefined} tabBarItemTitleFontStyle={style?.fontStyle} tabBarBackgroundColor={style?.backgroundColor} tabBarBlurEffect={style?.blurEffect} tabBarTintColor={style?.tintColor} tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor} tabBarItemRippleColor={style?.rippleColor} tabBarItemLabelVisibilityMode={style?.labelVisibilityMode} tabBarItemIconColor={style?.iconColor} tabBarItemIconColorActive={style?.['&:active']?.iconColor ?? style?.tintColor} tabBarItemTitleFontColorActive={style?.['&:active']?.color ?? style?.tintColor} tabBarItemTitleFontSizeActive={style?.['&:active']?.fontSize} tabBarItemActiveIndicatorColor={style?.['&:active']?.indicatorColor} tabBarItemActiveIndicatorEnabled={!disableIndicator} tabBarMinimizeBehavior={minimizeBehavior} onNativeFocusChange={({ nativeEvent: { tabKey } }) => {
44
81
  const descriptor = descriptors[tabKey];
45
82
  const route = descriptor.route;
46
83
  navigation.dispatch({
@@ -50,6 +87,7 @@ function NativeTabsView(props) {
50
87
  name: route.name,
51
88
  },
52
89
  });
90
+ isDuringNativeTransition.current = true;
53
91
  }}>
54
92
  {children}
55
93
  </react_native_screens_1.BottomTabs>);
@@ -62,7 +100,7 @@ function convertOptionsIconToPropsIcon(icon) {
62
100
  return { sfSymbolName: icon.sf };
63
101
  }
64
102
  else if ('src' in icon && icon.src) {
65
- return { imageSource: icon.src };
103
+ return { templateSource: icon.src };
66
104
  }
67
105
  return undefined;
68
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NativeTabsView.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabsView.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n DefaultRouterOptions,\n ParamListBase,\n TabNavigationState,\n TabRouterOptions,\n useNavigationBuilder,\n} from '@react-navigation/native';\nimport React from 'react';\nimport { type ColorValue, type ImageSourcePropType, type TextStyle } from 'react-native';\nimport {\n BottomTabs,\n BottomTabsScreen,\n enableFreeze,\n featureFlags,\n type BottomTabsProps,\n type BottomTabsScreenProps,\n type TabBarItemLabelVisibilityMode,\n} from 'react-native-screens';\nimport type { SFSymbol } from 'sf-symbols-typescript';\n\nimport { shouldTabBeVisible } from './utils';\nimport { getPathFromState } from '../../link/linking';\n\n// We let native tabs to control the changes. This requires freeze to be disabled for tab bar.\n// Otherwise user may see glitches when switching between tabs.\nfeatureFlags.experiment.controlledBottomTabs = false;\n\n// TODO: ENG-16896: Enable freeze globally and disable only for NativeTabsView\nenableFreeze(false);\n\ntype BaseNativeTabOptions = Omit<\n BottomTabsScreenProps,\n | 'children'\n | 'placeholder'\n | 'onWillAppear'\n | 'onDidAppear'\n | 'onWillDisappear'\n | 'onDidDisappear'\n | 'isFocused'\n | 'tabKey'\n | 'icon'\n | 'selectedIcon'\n | 'iconResourceName'\n> &\n DefaultRouterOptions;\n\ntype SfSymbolOrImageSource =\n | {\n /**\n * The name of the SF Symbol to use as an icon.\n * @platform iOS\n */\n sf?: SFSymbol;\n }\n | {\n /**\n * The image source to use as an icon.\n * @platform iOS\n */\n src?: ImageSourcePropType;\n };\nexport interface NativeTabOptions extends BaseNativeTabOptions {\n /**\n * If true, the tab will be hidden from the tab bar.\n */\n hidden?: boolean;\n /**\n * The icon to display in the tab bar.\n */\n icon?: SfSymbolOrImageSource & {\n /**\n * The name of the drawable resource to use as an icon.\n * @platform android\n */\n drawable?: string;\n };\n /**\n * The icon to display when the tab is selected.\n */\n selectedIcon?: SfSymbolOrImageSource;\n}\n\nexport interface NativeTabsViewProps {\n style?: {\n fontFamily?: TextStyle['fontFamily'];\n fontSize?: TextStyle['fontSize'];\n fontWeight?: TextStyle['fontWeight'];\n fontStyle?: TextStyle['fontStyle'];\n color?: TextStyle['color'];\n iconColor?: ColorValue;\n backgroundColor?: ColorValue;\n blurEffect?: BottomTabsScreenProps['tabBarBlurEffect'];\n tintColor?: ColorValue;\n badgeBackgroundColor?: ColorValue;\n /**\n * @platform android\n */\n rippleColor?: ColorValue;\n /**\n * @platform android\n */\n labelVisibilityMode?: TabBarItemLabelVisibilityMode;\n '&:active'?: {\n /**\n * @platform android\n */\n color?: ColorValue;\n /**\n * @platform android\n */\n fontSize?: TextStyle['fontSize'];\n /**\n * @platform android\n */\n iconColor?: ColorValue;\n /**\n * @platform android\n */\n indicatorColor?: ColorValue;\n };\n };\n /**\n * https://developer.apple.com/documentation/uikit/uitabbarcontroller/tabbarminimizebehavior\n *\n * Supported values:\n * - `none` - The tab bar does not minimize.\n * - `onScrollUp` - The tab bar minimizes when scrolling up, and expands when scrolling back down. Recommended if the scroll view content is aligned to the bottom.\n * - `onScrollDown` - The tab bar minimizes when scrolling down, and expands when scrolling back up.\n * - `automatic` - Resolves to the system default minimize behavior.\n *\n * @default automatic\n *\n * @platform iOS 26\n */\n minimizeBehavior?: BottomTabsProps['tabBarMinimizeBehavior'];\n /**\n * Disables the active indicator for the tab bar.\n *\n * @platform android\n */\n disableIndicator?: boolean;\n builder: ReturnType<\n typeof useNavigationBuilder<\n TabNavigationState<ParamListBase>,\n TabRouterOptions,\n Record<string, (...args: any) => void>,\n NativeTabOptions,\n Record<string, any>\n >\n >;\n}\n\n// TODO: Add support for dynamic params inside a route\nexport function NativeTabsView(props: NativeTabsViewProps) {\n const { builder, style, minimizeBehavior, disableIndicator } = props;\n const { state, descriptors, navigation } = builder;\n const { routes } = state;\n\n let focusedIndex = state.index;\n const isAnyRouteFocused =\n routes[focusedIndex].key &&\n descriptors[routes[focusedIndex].key] &&\n shouldTabBeVisible(descriptors[routes[focusedIndex].key].options);\n\n if (!isAnyRouteFocused) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n `The focused tab in NativeTabsView cannot be displayed. Make sure path is correct and the route is not hidden. Path: \"${getPathFromState(state)}\"`\n );\n }\n // Set focusedIndex to the first visible tab\n focusedIndex = routes.findIndex((route) => shouldTabBeVisible(descriptors[route.key].options));\n }\n\n const children = routes\n .map((route, index) => ({ route, index }))\n .filter(({ route: { key } }) => shouldTabBeVisible(descriptors[key].options))\n .map(({ route, index }) => {\n const descriptor = descriptors[route.key];\n const isFocused = state.index === index;\n const title = descriptor.options.title ?? route.name;\n\n return (\n <BottomTabsScreen\n key={route.key}\n {...descriptor.options}\n iconResourceName={descriptor.options.icon?.drawable}\n icon={convertOptionsIconToPropsIcon(descriptor.options.icon)}\n selectedIcon={convertOptionsIconToPropsIcon(descriptor.options.selectedIcon)}\n title={title}\n tabKey={route.key}\n isFocused={isFocused}>\n {descriptor.render()}\n </BottomTabsScreen>\n );\n });\n\n return (\n <BottomTabs\n tabBarItemTitleFontColor={style?.color}\n tabBarItemTitleFontFamily={style?.fontFamily}\n tabBarItemTitleFontSize={style?.fontSize}\n tabBarItemTitleFontWeight={style?.fontWeight}\n tabBarItemTitleFontStyle={style?.fontStyle}\n tabBarBackgroundColor={style?.backgroundColor}\n tabBarBlurEffect={style?.blurEffect}\n tabBarTintColor={style?.tintColor}\n tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor}\n tabBarItemRippleColor={style?.rippleColor}\n tabBarItemLabelVisibilityMode={style?.labelVisibilityMode}\n tabBarItemIconColor={style?.iconColor}\n tabBarItemIconColorActive={style?.['&:active']?.iconColor ?? style?.tintColor}\n tabBarItemTitleFontColorActive={style?.['&:active']?.color ?? style?.tintColor}\n tabBarItemTitleFontSizeActive={style?.['&:active']?.fontSize}\n tabBarItemActiveIndicatorColor={style?.['&:active']?.indicatorColor}\n tabBarItemActiveIndicatorEnabled={!disableIndicator}\n tabBarMinimizeBehavior={minimizeBehavior}\n onNativeFocusChange={({ nativeEvent: { tabKey } }) => {\n const descriptor = descriptors[tabKey];\n const route = descriptor.route;\n navigation.dispatch({\n type: 'JUMP_TO',\n target: state.key,\n payload: {\n name: route.name,\n },\n });\n }}>\n {children}\n </BottomTabs>\n );\n}\n\nfunction convertOptionsIconToPropsIcon(\n icon: NativeTabOptions['icon']\n): BottomTabsScreenProps['icon'] {\n if (!icon) {\n return undefined;\n }\n if ('sf' in icon && icon.sf) {\n return { sfSymbolName: icon.sf };\n } else if ('src' in icon && icon.src) {\n return { imageSource: icon.src };\n }\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"NativeTabsView.js","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabsView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useRef } from 'react';\nimport {\n BottomTabs,\n BottomTabsScreen,\n featureFlags,\n type BottomTabsScreenProps,\n} from 'react-native-screens';\n\nimport type { NativeTabOptions, NativeTabsViewProps } from './types';\nimport { shouldTabBeVisible } from './utils';\n\n// We let native tabs to control the changes. This requires freeze to be disabled for tab bar.\n// Otherwise user may see glitches when switching between tabs.\nfeatureFlags.experiment.controlledBottomTabs = false;\n\nexport function NativeTabsView(props: NativeTabsViewProps) {\n const { builder, style, minimizeBehavior, disableIndicator, focusedIndex } = props;\n const { state, descriptors, navigation } = builder;\n const { routes } = state;\n\n // This is flag that is set to true, when the transition is executed by native tab change\n // In this case we don't need to change the isFocused of the screens, because the transition will happen on native side\n const isDuringNativeTransition = useRef<boolean>(false);\n // This is the last index that was not part of a native transition, e.g navigation from link\n const lastNotNativeTransitionIndex = useRef<number>(focusedIndex);\n\n // If the flag was set in the onNativeFocusChange handler, it will be still true here\n // It is set to false, later in this function\n // Thus if it is false, we know that the transition was not triggered by a native tab change\n // and we need to reset the lastNotNativeTransitionIndex\n if (!isDuringNativeTransition.current) {\n lastNotNativeTransitionIndex.current = focusedIndex;\n }\n\n const children = routes\n .map((route, index) => ({ route, index }))\n .filter(({ route: { key } }) => shouldTabBeVisible(descriptors[key].options))\n .map(({ route, index }) => {\n const descriptor = descriptors[route.key];\n // In case of native transition we want to keep the last focused index\n // Otherwise the lastNotNativeTransitionIndex is set to focusedIndex in the if above this statement\n const isFocused = index === focusedIndex;\n // TODO: Find a proper fix, that allows for proper JS navigation\n //lastNotNativeTransitionIndex.current;\n const title = descriptor.options.title ?? route.name;\n\n return (\n <BottomTabsScreen\n key={route.key}\n {...descriptor.options}\n tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor}\n tabBarItemBadgeTextColor={style?.badgeTextColor}\n tabBarItemTitlePositionAdjustment={style?.titlePositionAdjustment}\n iconResourceName={descriptor.options.icon?.drawable}\n icon={convertOptionsIconToPropsIcon(descriptor.options.icon)}\n selectedIcon={convertOptionsIconToPropsIcon(descriptor.options.selectedIcon)}\n title={title}\n freezeContents={false}\n tabKey={route.key}\n isFocused={isFocused}>\n {descriptor.render()}\n </BottomTabsScreen>\n );\n });\n\n // The native render is over, we can reset the flag\n isDuringNativeTransition.current = false;\n\n return (\n <BottomTabs\n tabBarItemTitleFontColor={style?.color}\n tabBarItemTitleFontFamily={style?.fontFamily}\n tabBarItemTitleFontSize={style?.fontSize}\n // Only string values are accepted by screens\n tabBarItemTitleFontWeight={\n style?.fontWeight\n ? (String(style.fontWeight) as `${NonNullable<(typeof style)['fontWeight']>}`)\n : undefined\n }\n tabBarItemTitleFontStyle={style?.fontStyle}\n tabBarBackgroundColor={style?.backgroundColor}\n tabBarBlurEffect={style?.blurEffect}\n tabBarTintColor={style?.tintColor}\n tabBarItemBadgeBackgroundColor={style?.badgeBackgroundColor}\n tabBarItemRippleColor={style?.rippleColor}\n tabBarItemLabelVisibilityMode={style?.labelVisibilityMode}\n tabBarItemIconColor={style?.iconColor}\n tabBarItemIconColorActive={style?.['&:active']?.iconColor ?? style?.tintColor}\n tabBarItemTitleFontColorActive={style?.['&:active']?.color ?? style?.tintColor}\n tabBarItemTitleFontSizeActive={style?.['&:active']?.fontSize}\n tabBarItemActiveIndicatorColor={style?.['&:active']?.indicatorColor}\n tabBarItemActiveIndicatorEnabled={!disableIndicator}\n tabBarMinimizeBehavior={minimizeBehavior}\n onNativeFocusChange={({ nativeEvent: { tabKey } }) => {\n const descriptor = descriptors[tabKey];\n const route = descriptor.route;\n navigation.dispatch({\n type: 'JUMP_TO',\n target: state.key,\n payload: {\n name: route.name,\n },\n });\n isDuringNativeTransition.current = true;\n }}>\n {children}\n </BottomTabs>\n );\n}\n\nfunction convertOptionsIconToPropsIcon(\n icon: NativeTabOptions['icon']\n): BottomTabsScreenProps['icon'] {\n if (!icon) {\n return undefined;\n }\n if ('sf' in icon && icon.sf) {\n return { sfSymbolName: icon.sf };\n } else if ('src' in icon && icon.src) {\n return { templateSource: icon.src };\n }\n return undefined;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { NativeTabsViewProps } from './types';
3
+ export declare function NativeTabsView(props: NativeTabsViewProps): React.JSX.Element;
4
+ //# sourceMappingURL=NativeTabsView.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTabsView.web.d.ts","sourceRoot":"","sources":["../../../src/native-tabs/NativeBottomTabs/NativeTabsView.web.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAInD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,qBAuDxD"}