react-native-tab-view 4.0.0-rc.8 → 4.0.0

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 (38) hide show
  1. package/lib/commonjs/PlatformPressable.js +13 -15
  2. package/lib/commonjs/PlatformPressable.js.map +1 -1
  3. package/lib/commonjs/SceneView.js.map +1 -1
  4. package/lib/commonjs/TabBar.js +8 -10
  5. package/lib/commonjs/TabBar.js.map +1 -1
  6. package/lib/commonjs/TabView.js +13 -3
  7. package/lib/commonjs/TabView.js.map +1 -1
  8. package/lib/module/PlatformPressable.js +13 -15
  9. package/lib/module/PlatformPressable.js.map +1 -1
  10. package/lib/module/SceneView.js.map +1 -1
  11. package/lib/module/TabBar.js +7 -9
  12. package/lib/module/TabBar.js.map +1 -1
  13. package/lib/module/TabView.js +13 -3
  14. package/lib/module/TabView.js.map +1 -1
  15. package/lib/typescript/commonjs/src/PlatformPressable.d.ts +1 -5
  16. package/lib/typescript/commonjs/src/PlatformPressable.d.ts.map +1 -1
  17. package/lib/typescript/commonjs/src/TabBar.d.ts +1 -2
  18. package/lib/typescript/commonjs/src/TabBar.d.ts.map +1 -1
  19. package/lib/typescript/commonjs/src/TabView.d.ts +5 -3
  20. package/lib/typescript/commonjs/src/TabView.d.ts.map +1 -1
  21. package/lib/typescript/commonjs/src/types.d.ts +2 -1
  22. package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
  23. package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
  24. package/lib/typescript/module/src/PlatformPressable.d.ts +1 -5
  25. package/lib/typescript/module/src/PlatformPressable.d.ts.map +1 -1
  26. package/lib/typescript/module/src/TabBar.d.ts +1 -2
  27. package/lib/typescript/module/src/TabBar.d.ts.map +1 -1
  28. package/lib/typescript/module/src/TabView.d.ts +5 -3
  29. package/lib/typescript/module/src/TabView.d.ts.map +1 -1
  30. package/lib/typescript/module/src/types.d.ts +2 -1
  31. package/lib/typescript/module/src/types.d.ts.map +1 -1
  32. package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
  33. package/package.json +6 -4
  34. package/src/PlatformPressable.tsx +15 -14
  35. package/src/SceneView.tsx +1 -1
  36. package/src/TabBar.tsx +2 -8
  37. package/src/TabView.tsx +24 -4
  38. package/src/types.tsx +2 -1
@@ -18,11 +18,7 @@ const ANDROID_SUPPORTS_RIPPLE =
18
18
  Platform.OS === 'android' && Platform.Version >= ANDROID_VERSION_LOLLIPOP;
19
19
 
20
20
  /**
21
- * PlatformPressable provides an abstraction on top of TouchableNativeFeedback and
22
- * TouchableOpacity to handle platform differences.
23
- *
24
- * On Android, you can pass the props of TouchableNativeFeedback.
25
- * On other platforms, you can pass the props of TouchableOpacity.
21
+ * PlatformPressable provides an abstraction on top of Pressable to handle platform differences.
26
22
  */
27
23
  export function PlatformPressable({
28
24
  disabled,
@@ -34,16 +30,16 @@ export function PlatformPressable({
34
30
  ...rest
35
31
  }: Props) {
36
32
  const handlePress = (e: GestureResponderEvent) => {
37
- // @ts-expect-error: these properties exist on web, but not in React Native
38
- const hasModifierKey = e.metaKey || e.altKey || e.ctrlKey || e.shiftKey; // ignore clicks with modifier keys
39
- // @ts-expect-error: these properties exist on web, but not in React Native
40
- const isLeftClick = e.button == null || e.button === 0; // only handle left clicks
41
- const isSelfTarget = [undefined, null, '', 'self'].includes(
33
+ if (Platform.OS === 'web' && rest.href !== null) {
42
34
  // @ts-expect-error: these properties exist on web, but not in React Native
43
- e.currentTarget?.target
44
- ); // let browser handle "target=_blank" etc.
35
+ const hasModifierKey = e.metaKey || e.altKey || e.ctrlKey || e.shiftKey; // ignore clicks with modifier keys
36
+ // @ts-expect-error: these properties exist on web, but not in React Native
37
+ const isLeftClick = e.button === null || e.button === 0; // only handle left clicks
38
+ const isSelfTarget = [undefined, null, '', 'self'].includes(
39
+ // @ts-expect-error: these properties exist on web, but not in React Native
40
+ e.currentTarget?.target
41
+ ); // let browser handle "target=_blank" etc.
45
42
 
46
- if (Platform.OS === 'web' && rest.href != null) {
47
43
  if (!hasModifierKey && isLeftClick && isSelfTarget) {
48
44
  e.preventDefault();
49
45
  onPress?.(e);
@@ -62,7 +58,12 @@ export function PlatformPressable({
62
58
  }
63
59
  style={({ pressed }) => [
64
60
  {
65
- cursor: 'pointer', // Add hover effect on iPad and VisionOS,
61
+ cursor:
62
+ Platform.OS === 'web' || Platform.OS === 'ios'
63
+ ? // Pointer cursor on web
64
+ // Hover effect on iPad and visionOS
65
+ 'pointer'
66
+ : 'auto',
66
67
  opacity: pressed && !ANDROID_SUPPORTS_RIPPLE ? pressOpacity : 1,
67
68
  },
68
69
  typeof style === 'function' ? style({ pressed }) : style,
package/src/SceneView.tsx CHANGED
@@ -54,7 +54,7 @@ export function SceneView<T extends Route>({
54
54
  };
55
55
 
56
56
  let unsubscribe: (() => void) | undefined;
57
- let timer: NodeJS.Timeout | undefined;
57
+ let timer: ReturnType<typeof setTimeout> | undefined;
58
58
 
59
59
  if (lazy && isLoading) {
60
60
  // If lazy mode is enabled, listen to when we enter screens
package/src/TabBar.tsx CHANGED
@@ -43,7 +43,6 @@ export type Props<T extends Route> = SceneRendererProps & {
43
43
  pressColor?: string;
44
44
  pressOpacity?: number;
45
45
  options?: Record<string, TabDescriptor<T>>;
46
- commonOptions?: TabDescriptor<T>;
47
46
  renderIndicator?: (props: IndicatorProps<T>) => React.ReactNode;
48
47
  renderTabBarItem?: (
49
48
  props: TabBarItemProps<T> & { key: string }
@@ -358,7 +357,6 @@ export function TabBar<T extends Route>({
358
357
  testID,
359
358
  android_ripple,
360
359
  options,
361
- commonOptions,
362
360
  }: Props<T>) {
363
361
  const [layout, setLayout] = React.useState<Layout>(
364
362
  propLayout ?? { width: 0, height: 0 }
@@ -455,10 +453,7 @@ export function TabBar<T extends Route>({
455
453
  accessible = getAccessibleDefault({ route }),
456
454
  accessibilityLabel = getAccessibilityLabelDefault({ route }),
457
455
  ...rest
458
- } = {
459
- ...commonOptions,
460
- ...options?.[route.key],
461
- };
456
+ } = options?.[route.key] ?? {};
462
457
 
463
458
  const onLayout = isWidthDynamic
464
459
  ? (e: LayoutChangeEvent) => {
@@ -553,7 +548,7 @@ export function TabBar<T extends Route>({
553
548
  {renderTabBarItem ? (
554
549
  renderTabBarItem(props)
555
550
  ) : (
556
- <TabBarItem {...props} />
551
+ <TabBarItem {...props} key={props.key} />
557
552
  )}
558
553
  </>
559
554
  );
@@ -561,7 +556,6 @@ export function TabBar<T extends Route>({
561
556
  [
562
557
  position,
563
558
  navigationState,
564
- commonOptions,
565
559
  options,
566
560
  activeColor,
567
561
  inactiveColor,
package/src/TabView.tsx CHANGED
@@ -19,6 +19,7 @@ import type {
19
19
  PagerProps,
20
20
  Route,
21
21
  SceneRendererProps,
22
+ TabDescriptor,
22
23
  } from './types';
23
24
 
24
25
  export type Props<T extends Route> = Omit<PagerProps, 'layoutDirection'> & {
@@ -26,17 +27,21 @@ export type Props<T extends Route> = Omit<PagerProps, 'layoutDirection'> & {
26
27
  navigationState: NavigationState<T>;
27
28
  renderLazyPlaceholder?: (props: { route: T }) => React.ReactNode;
28
29
  renderTabBar?: (
29
- props: SceneRendererProps & { navigationState: NavigationState<T> }
30
+ props: SceneRendererProps & {
31
+ navigationState: NavigationState<T>;
32
+ options: Record<string, TabDescriptor<T>> | undefined;
33
+ }
30
34
  ) => React.ReactNode;
31
35
  tabBarPosition?: 'top' | 'bottom';
32
36
  initialLayout?: Partial<Layout>;
33
37
  lazy?: ((props: { route: T }) => boolean) | boolean;
34
38
  lazyPreloadDistance?: number;
35
- sceneContainerStyle?: StyleProp<ViewStyle>;
36
39
  direction?: LocaleDirection;
37
40
  pagerStyle?: StyleProp<ViewStyle>;
38
41
  style?: StyleProp<ViewStyle>;
39
42
  renderScene: (props: SceneRendererProps & { route: T }) => React.ReactNode;
43
+ options?: Record<string, TabDescriptor<T>>;
44
+ commonOptions?: TabDescriptor<T>;
40
45
  };
41
46
 
42
47
  const renderLazyPlaceholderDefault = () => null;
@@ -54,7 +59,6 @@ export function TabView<T extends Route>({
54
59
  renderLazyPlaceholder = renderLazyPlaceholderDefault,
55
60
  // eslint-disable-next-line @eslint-react/no-unstable-default-props
56
61
  renderTabBar = (props) => <TabBar {...props} />,
57
- sceneContainerStyle,
58
62
  pagerStyle,
59
63
  style,
60
64
  direction = I18nManager.getConstants().isRTL ? 'rtl' : 'ltr',
@@ -62,6 +66,8 @@ export function TabView<T extends Route>({
62
66
  tabBarPosition = 'top',
63
67
  animationEnabled = true,
64
68
  overScrollMode,
69
+ options: sceneOptions,
70
+ commonOptions,
65
71
  }: Props<T>) {
66
72
  if (
67
73
  Platform.OS !== 'web' &&
@@ -98,6 +104,16 @@ export function TabView<T extends Route>({
98
104
  });
99
105
  };
100
106
 
107
+ const options = Object.fromEntries(
108
+ navigationState.routes.map((route) => [
109
+ route.key,
110
+ {
111
+ ...commonOptions,
112
+ ...sceneOptions?.[route.key],
113
+ },
114
+ ])
115
+ );
116
+
101
117
  return (
102
118
  <View onLayout={handleLayout} style={[styles.pager, style]}>
103
119
  <Pager
@@ -127,10 +143,13 @@ export function TabView<T extends Route>({
127
143
  {tabBarPosition === 'top' &&
128
144
  renderTabBar({
129
145
  ...sceneRendererProps,
146
+ options,
130
147
  navigationState,
131
148
  })}
132
149
  {render(
133
150
  navigationState.routes.map((route, i) => {
151
+ const { sceneStyle } = options?.[route.key] ?? {};
152
+
134
153
  return (
135
154
  <SceneView
136
155
  {...sceneRendererProps}
@@ -140,7 +159,7 @@ export function TabView<T extends Route>({
140
159
  lazy={typeof lazy === 'function' ? lazy({ route }) : lazy}
141
160
  lazyPreloadDistance={lazyPreloadDistance}
142
161
  navigationState={navigationState}
143
- style={sceneContainerStyle}
162
+ style={sceneStyle}
144
163
  >
145
164
  {({ loading }) =>
146
165
  loading
@@ -157,6 +176,7 @@ export function TabView<T extends Route>({
157
176
  {tabBarPosition === 'bottom' &&
158
177
  renderTabBar({
159
178
  ...sceneRendererProps,
179
+ options,
160
180
  navigationState,
161
181
  })}
162
182
  </React.Fragment>
package/src/types.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import type { Animated, StyleProp, TextStyle } from 'react-native';
1
+ import type { Animated, StyleProp, TextStyle, ViewStyle } from 'react-native';
2
2
  import type { PagerViewProps } from 'react-native-pager-view';
3
3
 
4
4
  export type TabDescriptor<T extends Route> = {
@@ -23,6 +23,7 @@ export type TabDescriptor<T extends Route> = {
23
23
  size: number;
24
24
  }) => React.ReactElement;
25
25
  badge?: (props: { route: T }) => React.ReactElement;
26
+ sceneStyle?: StyleProp<ViewStyle>;
26
27
  };
27
28
 
28
29
  export type LocaleDirection = 'ltr' | 'rtl';