1 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
2 |
|
3 | import * as React from 'react';
|
4 | import { Animated, StyleSheet, View } from 'react-native';
|
5 | import PlatformPressable from './PlatformPressable';
|
6 | const DEFAULT_ACTIVE_COLOR = 'rgba(255, 255, 255, 1)';
|
7 | const DEFAULT_INACTIVE_COLOR = 'rgba(255, 255, 255, 0.7)';
|
8 | export default class TabBarItem extends React.Component {
|
9 | constructor(...args) {
|
10 | super(...args);
|
11 |
|
12 | _defineProperty(this, "getActiveOpacity", (position, routes, tabIndex) => {
|
13 | if (routes.length > 1) {
|
14 | const inputRange = routes.map((_, i) => i);
|
15 | return position.interpolate({
|
16 | inputRange,
|
17 | outputRange: inputRange.map(i => i === tabIndex ? 1 : 0)
|
18 | });
|
19 | } else {
|
20 | return 1;
|
21 | }
|
22 | });
|
23 |
|
24 | _defineProperty(this, "getInactiveOpacity", (position, routes, tabIndex) => {
|
25 | if (routes.length > 1) {
|
26 | const inputRange = routes.map((_, i) => i);
|
27 | return position.interpolate({
|
28 | inputRange,
|
29 | outputRange: inputRange.map(i => i === tabIndex ? 0 : 1)
|
30 | });
|
31 | } else {
|
32 | return 0;
|
33 | }
|
34 | });
|
35 | }
|
36 |
|
37 | render() {
|
38 | const {
|
39 | route,
|
40 | position,
|
41 | navigationState,
|
42 | renderLabel: renderLabelCustom,
|
43 | renderIcon,
|
44 | renderBadge,
|
45 | getLabelText,
|
46 | getTestID,
|
47 | getAccessibilityLabel,
|
48 | getAccessible,
|
49 | activeColor: activeColorCustom,
|
50 | inactiveColor: inactiveColorCustom,
|
51 | pressColor,
|
52 | pressOpacity,
|
53 | labelStyle,
|
54 | style,
|
55 | onLayout,
|
56 | onPress,
|
57 | onLongPress
|
58 | } = this.props;
|
59 | const tabIndex = navigationState.routes.indexOf(route);
|
60 | const isFocused = navigationState.index === tabIndex;
|
61 | const labelColorFromStyle = StyleSheet.flatten(labelStyle || {}).color;
|
62 | const activeColor = activeColorCustom !== undefined ? activeColorCustom : typeof labelColorFromStyle === 'string' ? labelColorFromStyle : DEFAULT_ACTIVE_COLOR;
|
63 | const inactiveColor = inactiveColorCustom !== undefined ? inactiveColorCustom : typeof labelColorFromStyle === 'string' ? labelColorFromStyle : DEFAULT_INACTIVE_COLOR;
|
64 | const activeOpacity = this.getActiveOpacity(position, navigationState.routes, tabIndex);
|
65 | const inactiveOpacity = this.getInactiveOpacity(position, navigationState.routes, tabIndex);
|
66 | let icon = null;
|
67 | let label = null;
|
68 |
|
69 | if (renderIcon) {
|
70 | const activeIcon = renderIcon({
|
71 | route,
|
72 | focused: true,
|
73 | color: activeColor
|
74 | });
|
75 | const inactiveIcon = renderIcon({
|
76 | route,
|
77 | focused: false,
|
78 | color: inactiveColor
|
79 | });
|
80 |
|
81 | if (inactiveIcon != null && activeIcon != null) {
|
82 | icon = React.createElement(View, {
|
83 | style: styles.icon
|
84 | }, React.createElement(Animated.View, {
|
85 | style: {
|
86 | opacity: inactiveOpacity
|
87 | }
|
88 | }, inactiveIcon), React.createElement(Animated.View, {
|
89 | style: [StyleSheet.absoluteFill, {
|
90 | opacity: activeOpacity
|
91 | }]
|
92 | }, activeIcon));
|
93 | }
|
94 | }
|
95 |
|
96 | const renderLabel = renderLabelCustom !== undefined ? renderLabelCustom : ({
|
97 | route,
|
98 | color
|
99 | }) => {
|
100 | const labelText = getLabelText({
|
101 | route
|
102 | });
|
103 |
|
104 | if (typeof labelText === 'string') {
|
105 | return React.createElement(Animated.Text, {
|
106 | style: [styles.label, icon ? {
|
107 | marginTop: 0
|
108 | } : null, labelStyle, {
|
109 | color
|
110 | }]
|
111 | }, labelText);
|
112 | }
|
113 |
|
114 | return labelText;
|
115 | };
|
116 |
|
117 | if (renderLabel) {
|
118 | const activeLabel = renderLabel({
|
119 | route,
|
120 | focused: true,
|
121 | color: activeColor
|
122 | });
|
123 | const inactiveLabel = renderLabel({
|
124 | route,
|
125 | focused: false,
|
126 | color: inactiveColor
|
127 | });
|
128 | label = React.createElement(View, null, React.createElement(Animated.View, {
|
129 | style: {
|
130 | opacity: inactiveOpacity
|
131 | }
|
132 | }, inactiveLabel), React.createElement(Animated.View, {
|
133 | style: [StyleSheet.absoluteFill, {
|
134 | opacity: activeOpacity
|
135 | }]
|
136 | }, activeLabel));
|
137 | }
|
138 |
|
139 | const tabStyle = StyleSheet.flatten(style);
|
140 | const isWidthSet = (tabStyle === null || tabStyle === void 0 ? void 0 : tabStyle.width) !== undefined;
|
141 | const tabContainerStyle = isWidthSet ? null : {
|
142 | flex: 1
|
143 | };
|
144 | const scene = {
|
145 | route
|
146 | };
|
147 | let accessibilityLabel = getAccessibilityLabel(scene);
|
148 | accessibilityLabel = typeof accessibilityLabel !== 'undefined' ? accessibilityLabel : getLabelText(scene);
|
149 | const badge = renderBadge ? renderBadge(scene) : null;
|
150 | return React.createElement(PlatformPressable, {
|
151 | android_ripple: {
|
152 | borderless: true
|
153 | },
|
154 | testID: getTestID(scene),
|
155 | accessible: getAccessible(scene),
|
156 | accessibilityLabel: accessibilityLabel,
|
157 | accessibilityRole: "tab",
|
158 | accessibilityState: {
|
159 | selected: isFocused
|
160 | }
|
161 | ,
|
162 | accessibilityStates: isFocused ? ['selected'] : [],
|
163 | pressColor: pressColor,
|
164 | pressOpacity: pressOpacity,
|
165 | delayPressIn: 0,
|
166 | onLayout: onLayout,
|
167 | onPress: onPress,
|
168 | onLongPress: onLongPress,
|
169 | style: [styles.pressable, tabContainerStyle]
|
170 | }, React.createElement(View, {
|
171 | pointerEvents: "none",
|
172 | style: [styles.item, tabStyle]
|
173 | }, icon, label, badge != null ? React.createElement(View, {
|
174 | style: styles.badge
|
175 | }, badge) : null));
|
176 | }
|
177 |
|
178 | }
|
179 | const styles = StyleSheet.create({
|
180 | label: {
|
181 | margin: 4,
|
182 | backgroundColor: 'transparent',
|
183 | textTransform: 'uppercase'
|
184 | },
|
185 | icon: {
|
186 | margin: 2
|
187 | },
|
188 | item: {
|
189 | flex: 1,
|
190 | alignItems: 'center',
|
191 | justifyContent: 'center',
|
192 | padding: 10,
|
193 | minHeight: 48
|
194 | },
|
195 | badge: {
|
196 | position: 'absolute',
|
197 | top: 0,
|
198 | right: 0
|
199 | },
|
200 | pressable: {
|
201 |
|
202 |
|
203 | backgroundColor: 'transparent'
|
204 | }
|
205 | });
|
206 |
|
\ | No newline at end of file |