@@ -5,34 +5,22 @@ import {StyleSheet, ScrollView, ViewPropTypes, Platform} from 'react-native';
5
5
import Reanimated , { Easing } from 'react-native-reanimated' ;
6
6
import PropTypes from 'prop-types' ;
7
7
import _ from 'lodash' ;
8
+
8
9
import TabBarContext from './TabBarContext' ;
10
+ import ReanimatedObject from './ReanimatedObject' ;
9
11
import { asBaseComponent , forwardRef } from '../../commons' ;
10
12
import View from '../../components/view' ;
11
13
import Text from '../../components/text' ;
12
14
import { Colors , Spacings } from '../../style' ;
13
15
import { Constants } from '../../helpers' ;
14
16
15
17
const DEFAULT_HEIGHT = 48 ;
16
- const {
17
- Code,
18
- Clock,
19
- Value,
20
- add,
21
- sub,
22
- cond,
23
- eq,
24
- stopClock,
25
- startClock,
26
- clockRunning,
27
- timing,
28
- block,
29
- set,
30
- } = Reanimated ;
18
+ const { Code, Clock, Value, add, sub, cond, eq, stopClock, startClock, clockRunning, timing, block, set} = Reanimated ;
31
19
32
20
/**
33
- * @description : TabController's TabBar component
34
- * @example : https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/incubatorScreens/TabControllerScreen/index.js
35
- */
21
+ * @description : TabController's TabBar component
22
+ * @example : https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/incubatorScreens/TabControllerScreen/index.js
23
+ */
36
24
class TabBar extends PureComponent {
37
25
static displayName = 'TabController.TabBar' ;
38
26
static contextType = TabBarContext ;
@@ -93,23 +81,26 @@ class TabBar extends PureComponent {
93
81
containerWidth : Constants . screenWidth ,
94
82
} ;
95
83
96
- state = {
97
- itemsWidths : undefined ,
98
- } ;
99
-
100
- tabBar = React . createRef ( ) ;
101
- _clock = new Clock ( ) ;
102
- _itemsWidths = _ . times ( React . Children . count ( this . props . children ) , ( ) => null ) ;
103
- _indicatorWidth = new Value ( 0 ) ;
104
- _prevIndicatorWidth = new Value ( 0 ) ;
105
- _prevOffset = new Value ( 0 ) ;
106
- _offset = new Value ( 0 ) ;
107
-
108
84
constructor ( props , context ) {
109
85
super ( props , context ) ;
110
86
const { registerTabItems} = this . context ;
111
87
const itemsCount = React . Children . count ( this . props . children ) ;
112
88
const ignoredItems = [ ] ;
89
+
90
+ this . tabBar = React . createRef ( ) ;
91
+
92
+ this . _itemsWidths = _ . times ( React . Children . count ( this . props . children ) , ( ) => null ) ;
93
+ this . _indicatorOffset = new ReanimatedObject ( { duration : 300 , easing : Easing . bezier ( 0.23 , 1 , 0.32 , 1 ) } ) ;
94
+ this . _indicatorWidth = new ReanimatedObject ( { duration : 300 , easing : Easing . bezier ( 0.23 , 1 , 0.32 , 1 ) } ) ;
95
+ this . _indicatorTransitionStyle = {
96
+ width : this . _indicatorWidth . value ,
97
+ left : this . _indicatorOffset . value ,
98
+ } ;
99
+
100
+ this . state = {
101
+ itemsWidths : undefined ,
102
+ } ;
103
+
113
104
React . Children . toArray ( this . props . children ) . forEach ( ( child , index ) => {
114
105
if ( child . props . ignore ) {
115
106
ignoredItems . push ( index ) ;
@@ -158,14 +149,19 @@ class TabBar extends PureComponent {
158
149
}
159
150
160
151
renderSelectedIndicator ( ) {
152
+ // return null;
161
153
const { itemsWidths} = this . state ;
162
154
const { indicatorStyle} = this . props ;
163
155
if ( itemsWidths ) {
164
- const transitionStyle = {
165
- width : this . runTiming ( this . _indicatorWidth , this . _prevIndicatorWidth , 300 ) ,
166
- left : this . runTiming ( this . _offset , this . _prevOffset , 400 ) ,
167
- } ;
168
- return < Reanimated . View style = { [ styles . selectedIndicator , indicatorStyle , transitionStyle ] } /> ;
156
+ // const transitionStyle = {
157
+ // width: this.runTiming(this._indicatorWidth, this._prevIndicatorWidth, 300),
158
+ // left: this.runTiming(this._offset, this._prevOffset, 400),
159
+ // };
160
+ return (
161
+ < Reanimated . View
162
+ style = { [ styles . selectedIndicator , indicatorStyle /* , transitionStyle */ , this . _indicatorTransitionStyle ] }
163
+ />
164
+ ) ;
169
165
}
170
166
}
171
167
@@ -181,7 +177,12 @@ class TabBar extends PureComponent {
181
177
activeBackgroundColor,
182
178
} = this . props ;
183
179
if ( ! _ . isEmpty ( itemStates ) ) {
184
- return React . Children . map ( this . props . children , ( child , index ) => {
180
+
181
+ if ( this . tabBarItems ) {
182
+ return this . tabBarItems ;
183
+ }
184
+
185
+ this . tabBarItems = React . Children . map ( this . props . children , ( child , index ) => {
185
186
return React . cloneElement ( child , {
186
187
labelColor,
187
188
selectedLabelColor,
@@ -197,6 +198,7 @@ class TabBar extends PureComponent {
197
198
onLayout : this . onItemLayout ,
198
199
} ) ;
199
200
} ) ;
201
+ return this . tabBarItems ;
200
202
}
201
203
}
202
204
@@ -210,8 +212,8 @@ class TabBar extends PureComponent {
210
212
ref = { this . tabBar }
211
213
horizontal
212
214
showsHorizontalScrollIndicator = { false }
213
- style = { { backgroundColor : Colors . white } }
214
- contentContainerStyle = { { minWidth : containerWidth } }
215
+ style = { styles . tabBarScroll }
216
+ contentContainerStyle = { styles . tabBarScrollContent }
215
217
>
216
218
< View style = { [ styles . tabBar , height && { height} ] } > { this . renderTabBarItems ( ) } </ View >
217
219
{ this . renderSelectedIndicator ( ) }
@@ -222,14 +224,23 @@ class TabBar extends PureComponent {
222
224
const indicatorInset = Spacings . s4 ;
223
225
224
226
return block ( [
227
+ // calc indicator current width
225
228
..._ . map ( itemsWidths , ( width , index ) => {
226
229
return cond ( eq ( currentPage , index ) , [
227
- set ( this . _indicatorWidth , sub ( itemsWidths [ index ] , indicatorInset * 2 ) ) ,
230
+ set ( this . _indicatorWidth . nextValue , sub ( itemsWidths [ index ] , indicatorInset * 2 ) ) ,
228
231
] ) ;
229
232
} ) ,
233
+ // calc indicator current position
230
234
..._ . map ( itemsOffsets , ( offset , index ) => {
231
- return cond ( eq ( currentPage , index ) , [ set ( this . _offset , add ( itemsOffsets [ index ] , indicatorInset ) ) ] ) ;
235
+ return cond ( eq ( currentPage , index ) , [
236
+ set ( this . _indicatorOffset . nextValue , add ( itemsOffsets [ index ] , indicatorInset ) ) ,
237
+ ] ) ;
232
238
} ) ,
239
+
240
+ // Offset transition
241
+ this . _indicatorOffset . getTransitionBlock ( ) ,
242
+ // Width transition
243
+ this . _indicatorWidth . getTransitionBlock ( ) ,
233
244
] ) ;
234
245
} }
235
246
</ Code >
@@ -247,6 +258,12 @@ const styles = StyleSheet.create({
247
258
flexDirection : 'row' ,
248
259
justifyContent : 'space-between' ,
249
260
} ,
261
+ tabBarScroll : {
262
+ backgroundColor : Colors . white ,
263
+ } ,
264
+ tabBarScrollContent : {
265
+ minWidth : Constants . screenWidth ,
266
+ } ,
250
267
tab : {
251
268
flex : 1 ,
252
269
alignItems : 'center' ,
@@ -266,13 +283,13 @@ const styles = StyleSheet.create({
266
283
shadowColor : Colors . dark10 ,
267
284
shadowOpacity : 0.05 ,
268
285
shadowRadius : 2 ,
269
- shadowOffset : { height : 6 , width : 0 }
286
+ shadowOffset : { height : 6 , width : 0 } ,
270
287
} ,
271
288
android : {
272
289
elevation : 5 ,
273
- backgroundColor : Colors . white
274
- }
275
- } )
290
+ backgroundColor : Colors . white ,
291
+ } ,
292
+ } ) ,
276
293
} ,
277
294
} ) ;
278
295
0 commit comments