@amazon-devices/react-navigation__react-native-tab-view 8.0.9000000000 → 8.0.9000000002

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 (39) hide show
  1. package/SystemModules/amzn__react-navigation__react-native-tab-view-8.private.modules.txt +35 -29
  2. package/kepler-compatibility.json +4 -2
  3. package/lib/module/index.js +0 -7
  4. package/oss-attribution/attribution.txt +0 -0
  5. package/oss-attribution/licenseInfos.json +1 -0
  6. package/package.json +1 -1
  7. package/src/index.tsx +1 -15
  8. package/SystemBundles/6f915df16edbc21a601928d99e844a99397b9428146027dcf0d86b2a798f21f4.bundle +0 -8563
  9. package/SystemBundles/6f915df16edbc21a601928d99e844a99397b9428146027dcf0d86b2a798f21f4.map +0 -3217
  10. package/lib/module/Pager.android.js +0 -4
  11. package/lib/module/Pager.ios.js +0 -4
  12. package/lib/module/Pager.js +0 -4
  13. package/lib/module/PagerViewAdapter.js +0 -130
  14. package/lib/module/PanResponderAdapter.js +0 -209
  15. package/lib/module/PlatformPressable.js +0 -61
  16. package/lib/module/SceneMap.js +0 -24
  17. package/lib/module/SceneView.js +0 -72
  18. package/lib/module/TabBar.js +0 -472
  19. package/lib/module/TabBarIndicator.js +0 -122
  20. package/lib/module/TabBarItem.js +0 -217
  21. package/lib/module/TabBarItemLabel.js +0 -33
  22. package/lib/module/TabView.js +0 -141
  23. package/lib/module/types.js +0 -4
  24. package/lib/module/useAnimatedValue.js +0 -12
  25. package/src/Pager.android.tsx +0 -1
  26. package/src/Pager.ios.tsx +0 -1
  27. package/src/Pager.tsx +0 -1
  28. package/src/PagerViewAdapter.tsx +0 -185
  29. package/src/PanResponderAdapter.tsx +0 -344
  30. package/src/PlatformPressable.tsx +0 -91
  31. package/src/SceneMap.tsx +0 -30
  32. package/src/SceneView.tsx +0 -106
  33. package/src/TabBar.tsx +0 -728
  34. package/src/TabBarIndicator.tsx +0 -190
  35. package/src/TabBarItem.tsx +0 -308
  36. package/src/TabBarItemLabel.tsx +0 -42
  37. package/src/TabView.tsx +0 -198
  38. package/src/types.tsx +0 -87
  39. package/src/useAnimatedValue.tsx +0 -12
@@ -1,217 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { Animated, Platform, StyleSheet, View } from 'react-native';
5
- import useLatestCallback from 'use-latest-callback';
6
- import { PlatformPressable } from "./PlatformPressable.js";
7
- import { TabBarItemLabel } from "./TabBarItemLabel.js";
8
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
- const DEFAULT_ACTIVE_COLOR = 'rgba(255, 255, 255, 1)';
10
- const DEFAULT_INACTIVE_COLOR = 'rgba(255, 255, 255, 0.7)';
11
- const ICON_SIZE = 24;
12
- const getActiveOpacity = (position, routesLength, tabIndex) => {
13
- if (routesLength > 1) {
14
- const inputRange = Array.from({
15
- length: routesLength
16
- }, (_, i) => i);
17
- return position.interpolate({
18
- inputRange,
19
- outputRange: inputRange.map(i => i === tabIndex ? 1 : 0)
20
- });
21
- } else {
22
- return 1;
23
- }
24
- };
25
- const getInactiveOpacity = (position, routesLength, tabIndex) => {
26
- if (routesLength > 1) {
27
- const inputRange = Array.from({
28
- length: routesLength
29
- }, (_, i) => i);
30
- return position.interpolate({
31
- inputRange,
32
- outputRange: inputRange.map(i => i === tabIndex ? 0 : 1)
33
- });
34
- } else {
35
- return 0;
36
- }
37
- };
38
- const ANDROID_RIPPLE_DEFAULT = {
39
- borderless: true
40
- };
41
- const TabBarItemInternal = ({
42
- accessibilityLabel,
43
- accessible,
44
- label: customlabel,
45
- testID,
46
- onLongPress,
47
- onPress,
48
- isFocused,
49
- position,
50
- style,
51
- inactiveColor: inactiveColorCustom,
52
- activeColor: activeColorCustom,
53
- labelStyle,
54
- onLayout,
55
- index: tabIndex,
56
- pressColor,
57
- pressOpacity,
58
- defaultTabWidth,
59
- icon: customIcon,
60
- badge: customBadge,
61
- href,
62
- labelText,
63
- routesLength,
64
- android_ripple = ANDROID_RIPPLE_DEFAULT,
65
- labelAllowFontScaling,
66
- route
67
- }) => {
68
- const labelColorFromStyle = StyleSheet.flatten(labelStyle || {}).color;
69
- const activeColor = activeColorCustom !== undefined ? activeColorCustom : typeof labelColorFromStyle === 'string' ? labelColorFromStyle : DEFAULT_ACTIVE_COLOR;
70
- const inactiveColor = inactiveColorCustom !== undefined ? inactiveColorCustom : typeof labelColorFromStyle === 'string' ? labelColorFromStyle : DEFAULT_INACTIVE_COLOR;
71
- const activeOpacity = getActiveOpacity(position, routesLength, tabIndex);
72
- const inactiveOpacity = getInactiveOpacity(position, routesLength, tabIndex);
73
- const icon = React.useMemo(() => {
74
- if (!customIcon) {
75
- return null;
76
- }
77
- const inactiveIcon = customIcon({
78
- focused: false,
79
- color: inactiveColor,
80
- size: ICON_SIZE,
81
- route
82
- });
83
- const activeIcon = customIcon({
84
- focused: true,
85
- color: activeColor,
86
- size: ICON_SIZE,
87
- route
88
- });
89
- return /*#__PURE__*/_jsxs(View, {
90
- style: styles.icon,
91
- children: [/*#__PURE__*/_jsx(Animated.View, {
92
- style: {
93
- opacity: inactiveOpacity
94
- },
95
- children: inactiveIcon
96
- }), /*#__PURE__*/_jsx(Animated.View, {
97
- style: [StyleSheet.absoluteFill, {
98
- opacity: activeOpacity
99
- }],
100
- children: activeIcon
101
- })]
102
- });
103
- }, [activeColor, activeOpacity, customIcon, inactiveColor, inactiveOpacity, route]);
104
- const renderLabel = React.useCallback(focused => customlabel ? customlabel({
105
- focused,
106
- color: focused ? activeColor : inactiveColor,
107
- style: labelStyle,
108
- labelText,
109
- allowFontScaling: labelAllowFontScaling,
110
- route
111
- }) : /*#__PURE__*/_jsx(TabBarItemLabel, {
112
- color: focused ? activeColor : inactiveColor,
113
- icon: icon,
114
- label: labelText,
115
- style: labelStyle
116
- }), [customlabel, activeColor, labelStyle, labelText, labelAllowFontScaling, route, inactiveColor, icon]);
117
- const tabStyle = StyleSheet.flatten(style);
118
- const isWidthSet = tabStyle?.width !== undefined;
119
- const tabContainerStyle = isWidthSet ? null : {
120
- width: defaultTabWidth
121
- };
122
- const ariaLabel = typeof accessibilityLabel !== 'undefined' ? accessibilityLabel : labelText;
123
- return /*#__PURE__*/_jsx(PlatformPressable, {
124
- android_ripple: android_ripple,
125
- testID: testID,
126
- accessible: accessible,
127
- role: "tab",
128
- "aria-label": ariaLabel,
129
- "aria-selected": isFocused,
130
- pressColor: pressColor,
131
- pressOpacity: pressOpacity,
132
- unstable_pressDelay: 0,
133
- onLayout: onLayout,
134
- onPress: onPress,
135
- onLongPress: onLongPress,
136
- href: href,
137
- style: [styles.pressable, tabContainerStyle],
138
- children: /*#__PURE__*/_jsxs(View, {
139
- pointerEvents: "none",
140
- style: [styles.item, tabStyle],
141
- children: [icon, /*#__PURE__*/_jsxs(View, {
142
- children: [/*#__PURE__*/_jsx(Animated.View, {
143
- style: {
144
- opacity: inactiveOpacity
145
- },
146
- children: renderLabel(false)
147
- }), /*#__PURE__*/_jsx(Animated.View, {
148
- style: [StyleSheet.absoluteFill, {
149
- opacity: activeOpacity
150
- }],
151
- children: renderLabel(true)
152
- })]
153
- }), customBadge != null ? /*#__PURE__*/_jsx(View, {
154
- style: styles.badge,
155
- children: customBadge({
156
- route
157
- })
158
- }) : null]
159
- })
160
- });
161
- };
162
- const MemoizedTabBarItemInternal = /*#__PURE__*/React.memo(TabBarItemInternal);
163
- export function TabBarItem(props) {
164
- const {
165
- onPress,
166
- onLongPress,
167
- onLayout,
168
- navigationState,
169
- route,
170
- ...rest
171
- } = props;
172
- const onPressLatest = useLatestCallback(onPress);
173
- const onLongPressLatest = useLatestCallback(onLongPress);
174
- const onLayoutLatest = useLatestCallback(onLayout ? onLayout : () => {});
175
- const tabIndex = navigationState.routes.indexOf(route);
176
- return /*#__PURE__*/_jsx(MemoizedTabBarItemInternal, {
177
- ...rest,
178
- onPress: onPressLatest,
179
- onLayout: onLayoutLatest,
180
- onLongPress: onLongPressLatest,
181
- isFocused: navigationState.index === tabIndex,
182
- route: route,
183
- index: tabIndex,
184
- routesLength: navigationState.routes.length
185
- });
186
- }
187
- const styles = StyleSheet.create({
188
- icon: {
189
- margin: 2
190
- },
191
- item: {
192
- flex: 1,
193
- alignItems: 'center',
194
- justifyContent: 'center',
195
- padding: 10,
196
- minHeight: 48
197
- },
198
- badge: {
199
- position: 'absolute',
200
- top: 0,
201
- end: 0
202
- },
203
- pressable: {
204
- // The label is not pressable on Windows
205
- // Adding backgroundColor: 'transparent' seems to fix it
206
- backgroundColor: 'transparent',
207
- ...Platform.select({
208
- // Roundness for iPad hover effect
209
- ios: {
210
- borderRadius: 10,
211
- borderCurve: 'continuous'
212
- },
213
- default: null
214
- })
215
- }
216
- });
217
- //# sourceMappingURL=TabBarItem.js.map
@@ -1,33 +0,0 @@
1
- "use strict";
2
-
3
- import React from 'react';
4
- import { Animated, StyleSheet } from 'react-native';
5
- import { jsx as _jsx } from "react/jsx-runtime";
6
- export const TabBarItemLabel = /*#__PURE__*/React.memo(({
7
- color,
8
- label,
9
- style,
10
- icon
11
- }) => {
12
- if (!label) {
13
- return null;
14
- }
15
- return /*#__PURE__*/_jsx(Animated.Text, {
16
- style: [styles.label, icon ? {
17
- marginTop: 0
18
- } : null, style, {
19
- color: color
20
- }],
21
- children: label
22
- });
23
- });
24
- TabBarItemLabel.displayName = 'TabBarItemLabel';
25
- const styles = StyleSheet.create({
26
- label: {
27
- margin: 4,
28
- fontSize: 14,
29
- fontWeight: '500',
30
- backgroundColor: 'transparent'
31
- }
32
- });
33
- //# sourceMappingURL=TabBarItemLabel.js.map
@@ -1,141 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { I18nManager, Platform, StyleSheet, View } from 'react-native';
5
- import { Pager } from './Pager';
6
- import { SceneView } from "./SceneView.js";
7
- import { TabBar } from "./TabBar.js";
8
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
- const renderLazyPlaceholderDefault = () => null;
10
- export function TabView({
11
- onIndexChange,
12
- onTabSelect,
13
- navigationState,
14
- renderScene,
15
- initialLayout,
16
- keyboardDismissMode = 'auto',
17
- lazy = false,
18
- lazyPreloadDistance = 0,
19
- onSwipeStart,
20
- onSwipeEnd,
21
- renderLazyPlaceholder = renderLazyPlaceholderDefault,
22
- // eslint-disable-next-line @eslint-react/no-unstable-default-props
23
- renderTabBar = props => /*#__PURE__*/_jsx(TabBar, {
24
- ...props
25
- }),
26
- pagerStyle,
27
- style,
28
- direction = I18nManager.getConstants().isRTL ? 'rtl' : 'ltr',
29
- swipeEnabled = true,
30
- tabBarPosition = 'top',
31
- animationEnabled = true,
32
- overScrollMode,
33
- options: sceneOptions,
34
- commonOptions
35
- }) {
36
- if (Platform.OS !== 'web' && direction !== (I18nManager.getConstants().isRTL ? 'rtl' : 'ltr')) {
37
- console.warn(`The 'direction' prop is set to '${direction}' but the effective value is '${I18nManager.getConstants().isRTL ? 'rtl' : 'ltr'}'. This is not supported. Make sure to match the 'direction' prop with the writing direction of the app.`);
38
- }
39
- const [layout, setLayout] = React.useState({
40
- width: 0,
41
- height: 0,
42
- ...initialLayout
43
- });
44
- const jumpToIndex = index => {
45
- if (index !== navigationState.index) {
46
- onIndexChange(index);
47
- }
48
- };
49
- const handleLayout = e => {
50
- const {
51
- height,
52
- width
53
- } = e.nativeEvent.layout;
54
- setLayout(prevLayout => {
55
- if (prevLayout.width === width && prevLayout.height === height) {
56
- return prevLayout;
57
- }
58
- return {
59
- height,
60
- width
61
- };
62
- });
63
- };
64
- const options = Object.fromEntries(navigationState.routes.map(route => [route.key, {
65
- ...commonOptions,
66
- ...sceneOptions?.[route.key]
67
- }]));
68
- return /*#__PURE__*/_jsx(View, {
69
- onLayout: handleLayout,
70
- style: [styles.pager, style],
71
- children: /*#__PURE__*/_jsx(Pager, {
72
- layout: layout,
73
- navigationState: navigationState,
74
- keyboardDismissMode: keyboardDismissMode,
75
- swipeEnabled: swipeEnabled,
76
- onSwipeStart: onSwipeStart,
77
- onSwipeEnd: onSwipeEnd,
78
- onIndexChange: jumpToIndex,
79
- onTabSelect: onTabSelect,
80
- animationEnabled: animationEnabled,
81
- overScrollMode: overScrollMode,
82
- style: pagerStyle,
83
- layoutDirection: direction,
84
- children: ({
85
- position,
86
- render,
87
- addEnterListener,
88
- jumpTo
89
- }) => {
90
- // All the props here must not change between re-renders
91
- // This is crucial to optimizing the routes with PureComponent
92
- const sceneRendererProps = {
93
- position,
94
- layout,
95
- jumpTo
96
- };
97
- return /*#__PURE__*/_jsxs(React.Fragment, {
98
- children: [tabBarPosition === 'top' && renderTabBar({
99
- ...sceneRendererProps,
100
- options,
101
- navigationState
102
- }), render(navigationState.routes.map((route, i) => {
103
- const {
104
- sceneStyle
105
- } = options?.[route.key] ?? {};
106
- return /*#__PURE__*/_jsx(SceneView, {
107
- ...sceneRendererProps,
108
- addEnterListener: addEnterListener,
109
- index: i,
110
- lazy: typeof lazy === 'function' ? lazy({
111
- route
112
- }) : lazy,
113
- lazyPreloadDistance: lazyPreloadDistance,
114
- navigationState: navigationState,
115
- style: sceneStyle,
116
- children: ({
117
- loading
118
- }) => loading ? renderLazyPlaceholder({
119
- route
120
- }) : renderScene({
121
- ...sceneRendererProps,
122
- route
123
- })
124
- }, route.key);
125
- })), tabBarPosition === 'bottom' && renderTabBar({
126
- ...sceneRendererProps,
127
- options,
128
- navigationState
129
- })]
130
- });
131
- }
132
- })
133
- });
134
- }
135
- const styles = StyleSheet.create({
136
- pager: {
137
- flex: 1,
138
- overflow: 'hidden'
139
- }
140
- });
141
- //# sourceMappingURL=TabView.js.map
@@ -1,4 +0,0 @@
1
- "use strict";
2
-
3
- export {};
4
- //# sourceMappingURL=types.js.map
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- import * as React from 'react';
4
- import { Animated } from 'react-native';
5
- export function useAnimatedValue(initialValue) {
6
- const lazyRef = React.useRef(undefined);
7
- if (lazyRef.current === undefined) {
8
- lazyRef.current = new Animated.Value(initialValue);
9
- }
10
- return lazyRef.current;
11
- }
12
- //# sourceMappingURL=useAnimatedValue.js.map
@@ -1 +0,0 @@
1
- export { PagerViewAdapter as Pager } from './PagerViewAdapter';
package/src/Pager.ios.tsx DELETED
@@ -1 +0,0 @@
1
- export { PagerViewAdapter as Pager } from './PagerViewAdapter';
package/src/Pager.tsx DELETED
@@ -1 +0,0 @@
1
- export { PanResponderAdapter as Pager } from './PanResponderAdapter';
@@ -1,185 +0,0 @@
1
- import * as React from 'react';
2
- import { Animated, Keyboard, Platform, StyleSheet } from 'react-native';
3
- import ViewPager, {
4
- type PageScrollStateChangedNativeEvent,
5
- } from 'react-native-pager-view';
6
- import useLatestCallback from 'use-latest-callback';
7
-
8
- import type {
9
- EventEmitterProps,
10
- Listener,
11
- NavigationState,
12
- PagerProps,
13
- Route,
14
- } from './types';
15
- import { useAnimatedValue } from './useAnimatedValue';
16
-
17
- const AnimatedViewPager = Animated.createAnimatedComponent(ViewPager);
18
-
19
- type Props<T extends Route> = PagerProps & {
20
- onIndexChange: (index: number) => void;
21
- onTabSelect?: (props: { index: number }) => void;
22
- navigationState: NavigationState<T>;
23
- children: (
24
- props: EventEmitterProps & {
25
- // Animated value which represents the state of current index
26
- // It can include fractional digits as it represents the intermediate value
27
- position: Animated.AnimatedInterpolation<number>;
28
- // Function to actually render the content of the pager
29
- // The parent component takes care of rendering
30
- render: (children: React.ReactNode) => React.ReactNode;
31
- // Callback to call when switching the tab
32
- // The tab switch animation is performed even if the index in state is unchanged
33
- jumpTo: (key: string) => void;
34
- }
35
- ) => React.ReactElement;
36
- };
37
-
38
- const useNativeDriver = Platform.OS !== 'web';
39
-
40
- export function PagerViewAdapter<T extends Route>({
41
- keyboardDismissMode = 'auto',
42
- swipeEnabled = true,
43
- navigationState,
44
- onIndexChange,
45
- onTabSelect,
46
- onSwipeStart,
47
- onSwipeEnd,
48
- children,
49
- style,
50
- animationEnabled,
51
- ...rest
52
- }: Props<T>) {
53
- const { index } = navigationState;
54
-
55
- const listenersRef = React.useRef<Listener[]>([]);
56
-
57
- const pagerRef = React.useRef<ViewPager>(null);
58
- const indexRef = React.useRef<number>(index);
59
- const navigationStateRef = React.useRef(navigationState);
60
-
61
- const position = useAnimatedValue(index);
62
- const offset = useAnimatedValue(0);
63
-
64
- React.useEffect(() => {
65
- navigationStateRef.current = navigationState;
66
- });
67
-
68
- const jumpTo = useLatestCallback((key: string) => {
69
- const index = navigationStateRef.current.routes.findIndex(
70
- (route: { key: string }) => route.key === key
71
- );
72
-
73
- if (animationEnabled) {
74
- pagerRef.current?.setPage(index);
75
- } else {
76
- pagerRef.current?.setPageWithoutAnimation(index);
77
- position.setValue(index);
78
- }
79
-
80
- onIndexChange(index);
81
- });
82
-
83
- React.useEffect(() => {
84
- if (keyboardDismissMode === 'auto') {
85
- Keyboard.dismiss();
86
- }
87
-
88
- if (indexRef.current !== index) {
89
- if (animationEnabled) {
90
- pagerRef.current?.setPage(index);
91
- } else {
92
- pagerRef.current?.setPageWithoutAnimation(index);
93
- position.setValue(index);
94
- }
95
- }
96
- }, [keyboardDismissMode, index, animationEnabled, position]);
97
-
98
- const onPageScrollStateChanged = (
99
- state: PageScrollStateChangedNativeEvent
100
- ) => {
101
- const { pageScrollState } = state.nativeEvent;
102
-
103
- switch (pageScrollState) {
104
- case 'idle':
105
- onSwipeEnd?.();
106
- return;
107
- case 'dragging': {
108
- const subscription = offset.addListener(({ value }) => {
109
- const next =
110
- index + (value > 0 ? Math.ceil(value) : Math.floor(value));
111
-
112
- if (next !== index) {
113
- listenersRef.current.forEach((listener) => listener(next));
114
- }
115
-
116
- offset.removeListener(subscription);
117
- });
118
-
119
- onSwipeStart?.();
120
- return;
121
- }
122
- }
123
- };
124
-
125
- const addEnterListener = useLatestCallback((listener: Listener) => {
126
- listenersRef.current.push(listener);
127
-
128
- return () => {
129
- const index = listenersRef.current.indexOf(listener);
130
-
131
- if (index > -1) {
132
- listenersRef.current.splice(index, 1);
133
- }
134
- };
135
- });
136
-
137
- const memoizedPosition = React.useMemo(
138
- () => Animated.add(position, offset),
139
- [offset, position]
140
- );
141
-
142
- return children({
143
- position: memoizedPosition,
144
- addEnterListener,
145
- jumpTo,
146
- render: (children) => (
147
- <AnimatedViewPager
148
- {...rest}
149
- ref={pagerRef}
150
- style={[styles.container, style]}
151
- initialPage={index}
152
- keyboardDismissMode={
153
- keyboardDismissMode === 'auto' ? 'on-drag' : keyboardDismissMode
154
- }
155
- onPageScroll={Animated.event(
156
- [
157
- {
158
- nativeEvent: {
159
- position: position,
160
- offset: offset,
161
- },
162
- },
163
- ],
164
- { useNativeDriver }
165
- )}
166
- onPageSelected={(e) => {
167
- const index = e.nativeEvent.position;
168
- indexRef.current = index;
169
- onIndexChange(index);
170
- onTabSelect?.({ index });
171
- }}
172
- onPageScrollStateChanged={onPageScrollStateChanged}
173
- scrollEnabled={swipeEnabled}
174
- >
175
- {children}
176
- </AnimatedViewPager>
177
- ),
178
- });
179
- }
180
-
181
- const styles = StyleSheet.create({
182
- container: {
183
- flex: 1,
184
- },
185
- });