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.
- package/lib/commonjs/PlatformPressable.js +13 -15
- package/lib/commonjs/PlatformPressable.js.map +1 -1
- package/lib/commonjs/SceneView.js.map +1 -1
- package/lib/commonjs/TabBar.js +8 -10
- package/lib/commonjs/TabBar.js.map +1 -1
- package/lib/commonjs/TabView.js +13 -3
- package/lib/commonjs/TabView.js.map +1 -1
- package/lib/module/PlatformPressable.js +13 -15
- package/lib/module/PlatformPressable.js.map +1 -1
- package/lib/module/SceneView.js.map +1 -1
- package/lib/module/TabBar.js +7 -9
- package/lib/module/TabBar.js.map +1 -1
- package/lib/module/TabView.js +13 -3
- package/lib/module/TabView.js.map +1 -1
- package/lib/typescript/commonjs/src/PlatformPressable.d.ts +1 -5
- package/lib/typescript/commonjs/src/PlatformPressable.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TabBar.d.ts +1 -2
- package/lib/typescript/commonjs/src/TabBar.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/TabView.d.ts +5 -3
- package/lib/typescript/commonjs/src/TabView.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/types.d.ts +2 -1
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
- package/lib/typescript/module/src/PlatformPressable.d.ts +1 -5
- package/lib/typescript/module/src/PlatformPressable.d.ts.map +1 -1
- package/lib/typescript/module/src/TabBar.d.ts +1 -2
- package/lib/typescript/module/src/TabBar.d.ts.map +1 -1
- package/lib/typescript/module/src/TabView.d.ts +5 -3
- package/lib/typescript/module/src/TabView.d.ts.map +1 -1
- package/lib/typescript/module/src/types.d.ts +2 -1
- package/lib/typescript/module/src/types.d.ts.map +1 -1
- package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/PlatformPressable.tsx +15 -14
- package/src/SceneView.tsx +1 -1
- package/src/TabBar.tsx +2 -8
- package/src/TabView.tsx +24 -4
- 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
|
|
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
|
-
|
|
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.
|
|
44
|
-
|
|
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:
|
|
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:
|
|
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 & {
|
|
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={
|
|
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';
|