@momo-kits/swipe 0.77.2 → 0.77.4

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/Swiper.js DELETED
@@ -1,845 +0,0 @@
1
- /* eslint-disable react/state-in-constructor */
2
- /* eslint-disable react/static-property-placement */
3
- /* eslint-disable no-multi-assign */
4
- /* eslint-disable brace-style */
5
- /* eslint-disable no-param-reassign */
6
- /* eslint-disable react/no-array-index-key */
7
- /* eslint-disable guard-for-in */
8
- /* eslint-disable default-case */
9
- /* eslint-disable react/destructuring-assignment */
10
- /* eslint-disable no-restricted-syntax */
11
- /**
12
- * react-native-swiper
13
- * @author leecade<leecade@163.com>
14
- */
15
- import React, {Component} from 'react';
16
- import PropTypes from 'prop-types';
17
- import {
18
- Text,
19
- View,
20
- ScrollView,
21
- Dimensions,
22
- TouchableOpacity,
23
- Platform,
24
- ActivityIndicator,
25
- } from 'react-native';
26
- import {ViewPager as ViewPagerAndroid} from '@momo-kits/core-v2';
27
-
28
- /**
29
- * Default styles
30
- * @type {StyleSheetPropType}
31
- */
32
- const styles = {
33
- container: {
34
- backgroundColor: 'transparent',
35
- position: 'relative',
36
- flex: 1,
37
- },
38
-
39
- wrapperIOS: {
40
- backgroundColor: 'transparent',
41
- },
42
-
43
- wrapperAndroid: {
44
- backgroundColor: 'transparent',
45
- flex: 1,
46
- },
47
-
48
- slide: {
49
- backgroundColor: 'transparent',
50
- },
51
-
52
- pagination_x: {
53
- position: 'absolute',
54
- bottom: 25,
55
- left: 0,
56
- right: 0,
57
- flexDirection: 'row',
58
- flex: 1,
59
- justifyContent: 'center',
60
- alignItems: 'center',
61
- backgroundColor: 'transparent',
62
- },
63
-
64
- pagination_y: {
65
- position: 'absolute',
66
- right: 15,
67
- top: 0,
68
- bottom: 0,
69
- flexDirection: 'column',
70
- flex: 1,
71
- justifyContent: 'center',
72
- alignItems: 'center',
73
- backgroundColor: 'transparent',
74
- },
75
-
76
- title: {
77
- height: 30,
78
- justifyContent: 'center',
79
- position: 'absolute',
80
- paddingLeft: 10,
81
- bottom: -30,
82
- left: 0,
83
- flexWrap: 'nowrap',
84
- width: 250,
85
- backgroundColor: 'transparent',
86
- },
87
-
88
- buttonWrapper: {
89
- backgroundColor: 'transparent',
90
- flexDirection: 'row',
91
- position: 'absolute',
92
- top: 0,
93
- left: 0,
94
- flex: 1,
95
- paddingHorizontal: 10,
96
- paddingVertical: 10,
97
- justifyContent: 'space-between',
98
- alignItems: 'center',
99
- },
100
-
101
- buttonText: {
102
- fontSize: 50,
103
- color: '#007aff',
104
- },
105
- };
106
-
107
- // missing `module.exports = exports['default'];` with babel6
108
- // export default React.createClass({
109
- export default class Swiper extends Component {
110
- /**
111
- * Props Validation
112
- * @type {Object}
113
- */
114
- static propTypes = {
115
- horizontal: PropTypes.bool,
116
- children: PropTypes.node.isRequired,
117
- containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
118
- style: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
119
- scrollViewStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
120
- pagingEnabled: PropTypes.bool,
121
- showsHorizontalScrollIndicator: PropTypes.bool,
122
- showsVerticalScrollIndicator: PropTypes.bool,
123
- bounces: PropTypes.bool,
124
- scrollsToTop: PropTypes.bool,
125
- removeClippedSubviews: PropTypes.bool,
126
- automaticallyAdjustContentInsets: PropTypes.bool,
127
- showsPagination: PropTypes.bool,
128
- showsButtons: PropTypes.bool,
129
- disableNextButton: PropTypes.bool,
130
- loadMinimal: PropTypes.bool,
131
- loadMinimalSize: PropTypes.number,
132
- loadMinimalLoader: PropTypes.element,
133
- loop: PropTypes.bool,
134
- autoplay: PropTypes.bool,
135
- autoplayTimeout: PropTypes.number,
136
- autoplayDirection: PropTypes.bool,
137
- index: PropTypes.number,
138
- renderPagination: PropTypes.func,
139
- dotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
140
- activeDotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
141
- dotColor: PropTypes.string,
142
- activeDotColor: PropTypes.string,
143
- /**
144
- * Called when the index has changed because the user swiped.
145
- */
146
- onIndexChanged: PropTypes.func,
147
- };
148
-
149
- /**
150
- * Default props
151
- * @return {object} props
152
- * @see http://facebook.github.io/react-native/docs/scrollview.html
153
- */
154
- static defaultProps = {
155
- horizontal: true,
156
- pagingEnabled: true,
157
- showsHorizontalScrollIndicator: false,
158
- showsVerticalScrollIndicator: false,
159
- bounces: false,
160
- scrollsToTop: false,
161
- removeClippedSubviews: true,
162
- automaticallyAdjustContentInsets: false,
163
- showsPagination: true,
164
- showsButtons: false,
165
- disableNextButton: false,
166
- loop: true,
167
- loadMinimal: false,
168
- loadMinimalSize: 1,
169
- autoplay: false,
170
- autoplayTimeout: 2.5,
171
- autoplayDirection: true,
172
- index: 0,
173
- onIndexChanged: () => null,
174
- };
175
-
176
- /**
177
- * Init states
178
- * @return {object} states
179
- */
180
- state = this.initState(this.props);
181
-
182
- /**
183
- * Initial render flag
184
- * @type {bool}
185
- */
186
- initialRender = true;
187
-
188
- /**
189
- * autoplay timer
190
- * @type {null}
191
- */
192
- autoplayTimer = null;
193
-
194
- loopJumpTimer = null;
195
-
196
- UNSAFE_componentWillReceiveProps(nextProps) {
197
- if (!nextProps.autoplay && this.autoplayTimer) {
198
- clearTimeout(this.autoplayTimer);
199
- }
200
- // Fix render last item first
201
- if (nextProps.index === this.props.index) return;
202
- this.setState(
203
- this.initState(nextProps, this.props.index !== nextProps.index),
204
- );
205
- }
206
-
207
- componentDidMount() {
208
- this.autoplay();
209
- }
210
-
211
- componentWillUnmount() {
212
- this.autoplayTimer && clearTimeout(this.autoplayTimer);
213
- this.loopJumpTimer && clearTimeout(this.loopJumpTimer);
214
- }
215
-
216
- UNSAFE_componentWillUpdate(nextProps, nextState) {
217
- // If the index has changed, we notify the parent via the onIndexChanged callback
218
- if (this.state.index !== nextState.index) {
219
- this.props.onIndexChanged(nextState.index);
220
- }
221
- }
222
-
223
- initState(props, updateIndex = false) {
224
- // set the current state
225
- const state = this.state || {
226
- width: 0,
227
- height: 0,
228
- offset: {
229
- x: 0,
230
- y: 0,
231
- },
232
- };
233
-
234
- const initState = {
235
- autoplayEnd: false,
236
- loopJump: false,
237
- offset: {},
238
- };
239
-
240
- initState.total = props.children ? props.children.length || 1 : 0;
241
-
242
- if (state.total === initState.total && !updateIndex) {
243
- // retain the index
244
- initState.index = state.index;
245
- } else {
246
- initState.index =
247
- initState.total > 1 ? Math.min(props.index, initState.total - 1) : 0;
248
- }
249
-
250
- // Default: horizontal
251
- const {width, height} = Dimensions.get('window');
252
-
253
- initState.dir = props.horizontal === false ? 'y' : 'x';
254
-
255
- if (props.width) {
256
- initState.width = props.width;
257
- } else if (this.state && this.state.width) {
258
- initState.width = this.state.width;
259
- } else {
260
- initState.width = width;
261
- }
262
-
263
- if (props.height) {
264
- initState.height = props.height;
265
- } else if (this.state && this.state.height) {
266
- initState.height = this.state.height;
267
- } else {
268
- initState.height = height;
269
- }
270
-
271
- initState.offset[initState.dir] =
272
- initState.dir === 'y' ? height * props.index : width * props.index;
273
-
274
- this.internals = {
275
- ...this.internals,
276
- isScrolling: false,
277
- };
278
- return initState;
279
- }
280
-
281
- // include internals with state
282
- fullState() {
283
- return {...this.state, ...this.internals};
284
- }
285
-
286
- onLayout = event => {
287
- const {width, height} = event.nativeEvent.layout;
288
- const offset = (this.internals.offset = {});
289
- const state = {
290
- width,
291
- height,
292
- };
293
-
294
- if (this.state.total > 1) {
295
- let setup = this.state.index;
296
- if (this.props.loop) {
297
- setup++;
298
- }
299
- offset[this.state.dir] =
300
- this.state.dir === 'y' ? height * setup : width * setup;
301
- }
302
-
303
- // only update the offset in state if needed, updating offset while swiping
304
- // causes some bad jumping / stuttering
305
- if (
306
- !this.state.offset ||
307
- width !== this.state.width ||
308
- height !== this.state.height
309
- ) {
310
- state.offset = offset;
311
- }
312
-
313
- // related to https://github.com/leecade/react-native-swiper/issues/570
314
- // contentOffset is not working in react 0.48.x so we need to use scrollTo
315
- // to emulate offset.
316
- if (Platform.OS === 'ios') {
317
- if (this.initialRender && this.state.total > 1) {
318
- this.scrollView.scrollTo({
319
- ...offset,
320
- animated: false,
321
- });
322
- this.initialRender = false;
323
- }
324
- }
325
-
326
- this.setState(state);
327
- };
328
-
329
- loopJump = () => {
330
- if (!this.state.loopJump) return;
331
- const i = this.state.index + (this.props.loop ? 1 : 0);
332
- const {scrollView} = this;
333
- this.loopJumpTimer = setTimeout(
334
- () =>
335
- scrollView.setPageWithoutAnimation &&
336
- scrollView.setPageWithoutAnimation(i),
337
- 50,
338
- );
339
- };
340
-
341
- /**
342
- * Automatic rolling
343
- */
344
- autoplay = () => {
345
- if (
346
- !Array.isArray(this?.props?.children) ||
347
- !this.props.autoplay ||
348
- this.internals.isScrolling ||
349
- this.state.autoplayEnd
350
- ) {
351
- return;
352
- }
353
-
354
- this.autoplayTimer && clearTimeout(this.autoplayTimer);
355
- this.autoplayTimer = setTimeout(() => {
356
- if (
357
- !this.props.loop &&
358
- (this.props.autoplayDirection
359
- ? this.state.index === this.state.total - 1
360
- : this.state.index === 0)
361
- ) {
362
- return this.setState({autoplayEnd: true});
363
- }
364
-
365
- this.scrollBy(this.props.autoplayDirection ? 1 : -1);
366
- }, this.props.autoplayTimeout * 1000);
367
- };
368
-
369
- /**
370
- * Scroll begin handle
371
- * @param {object} e native event
372
- */
373
- onScrollBegin = e => {
374
- // update scroll state
375
- this.internals.isScrolling = true;
376
- this.props.onScrollBeginDrag &&
377
- this.props.onScrollBeginDrag(e, this.fullState(), this);
378
- };
379
-
380
- /**
381
- * Scroll end handle
382
- * @param {object} e native event
383
- */
384
- onScrollEnd = e => {
385
- // update scroll state
386
- this.internals.isScrolling = false;
387
-
388
- // making our events coming from android compatible to updateIndex logic
389
- if (!e.nativeEvent.contentOffset) {
390
- if (this.state.dir === 'x') {
391
- e.nativeEvent.contentOffset = {
392
- x: e.nativeEvent.position * this.state.width,
393
- };
394
- } else {
395
- e.nativeEvent.contentOffset = {
396
- y: e.nativeEvent.position * this.state.height,
397
- };
398
- }
399
- }
400
-
401
- this.updateIndex(e.nativeEvent.contentOffset, this.state.dir, () => {
402
- this.autoplay();
403
- this.loopJump();
404
-
405
- // if `onMomentumScrollEnd` registered will be called here
406
- this.props.onMomentumScrollEnd &&
407
- this.props.onMomentumScrollEnd(e, this.fullState(), this);
408
- });
409
- };
410
-
411
- /*
412
- * Drag end handle
413
- * @param {object} e native event
414
- */
415
- onScrollEndDrag = e => {
416
- const {contentOffset} = e.nativeEvent;
417
- const {horizontal, children} = this.props;
418
- const {index} = this.state;
419
- const {offset} = this.internals;
420
- const previousOffset = horizontal ? offset.x : offset.y;
421
- const newOffset = horizontal ? contentOffset.x : contentOffset.y;
422
-
423
- if (
424
- previousOffset === newOffset &&
425
- (index === 0 || index === children.length - 1)
426
- ) {
427
- this.internals.isScrolling = false;
428
- }
429
- };
430
-
431
- /**
432
- * Update index after scroll
433
- * @param {object} offset content offset
434
- * @param {string} dir 'x' || 'y'
435
- */
436
- updateIndex = (offset, dir, cb) => {
437
- const {state} = this;
438
- let {index} = state;
439
- if (!this.internals.offset) {
440
- // Android not setting this onLayout first? https://github.com/leecade/react-native-swiper/issues/582
441
- this.internals.offset = {};
442
- }
443
- const diff = offset[dir] - this.internals.offset[dir];
444
- const step = dir === 'x' ? state.width : state.height;
445
- let loopJump = false;
446
-
447
- // Do nothing if offset no change.
448
- if (!diff) return;
449
-
450
- // Note: if touch very very quickly and continuous,
451
- // the variation of `index` more than 1.
452
- // parseInt() ensures it's always an integer
453
- index = parseInt(index + Math.round(diff / step));
454
-
455
- if (this.props.loop) {
456
- if (index <= -1) {
457
- index = state.total - 1;
458
- offset[dir] = step * state.total;
459
- loopJump = true;
460
- } else if (index >= state.total) {
461
- index = 0;
462
- offset[dir] = step;
463
- loopJump = true;
464
- }
465
- }
466
-
467
- const newState = {};
468
- newState.index = index;
469
- newState.loopJump = loopJump;
470
-
471
- this.internals.offset = offset;
472
-
473
- // only update offset in state if loopJump is true
474
- if (loopJump) {
475
- // when swiping to the beginning of a looping set for the third time,
476
- // the new offset will be the same as the last one set in state.
477
- // Setting the offset to the same thing will not do anything,
478
- // so we increment it by 1 then immediately set it to what it should be,
479
- // after render.
480
- if (offset[dir] === this.internals.offset[dir]) {
481
- newState.offset = {
482
- x: 0,
483
- y: 0,
484
- };
485
- newState.offset[dir] = offset[dir] + 1;
486
- this.setState(newState, () => {
487
- this.setState({offset}, cb);
488
- });
489
- } else {
490
- newState.offset = offset;
491
- this.setState(newState, cb);
492
- }
493
- } else {
494
- this.setState(newState, cb);
495
- }
496
- };
497
-
498
- /**
499
- * Scroll by index
500
- * @param {number} index offset index
501
- * @param {bool} animated
502
- */
503
-
504
- scrollBy = (index, animated = true) => {
505
- if (this.internals.isScrolling || this.state.total < 2) return;
506
- const {state} = this;
507
- const diff = (this.props.loop ? 1 : 0) + index + this.state.index;
508
- let x = 0;
509
- let y = 0;
510
- if (state.dir === 'x') x = diff * state.width;
511
- if (state.dir === 'y') y = diff * state.height;
512
-
513
- if (Platform.OS !== 'ios') {
514
- this.scrollView &&
515
- this.scrollView[animated ? 'setPage' : 'setPageWithoutAnimation'](diff);
516
- } else {
517
- this.scrollView &&
518
- this.scrollView.scrollTo({
519
- x,
520
- y,
521
- animated,
522
- });
523
- }
524
-
525
- // update scroll state
526
- this.internals.isScrolling = true;
527
- this.setState({
528
- autoplayEnd: false,
529
- });
530
-
531
- // trigger onScrollEnd manually in android
532
- if (!animated || Platform.OS !== 'ios') {
533
- setImmediate(() => {
534
- this.onScrollEnd({
535
- nativeEvent: {
536
- position: diff,
537
- },
538
- });
539
- });
540
- }
541
- };
542
-
543
- scrollViewPropOverrides = () => {
544
- const {props} = this;
545
- const overrides = {};
546
-
547
- /*
548
- const scrollResponders = [
549
- 'onMomentumScrollBegin',
550
- 'onTouchStartCapture',
551
- 'onTouchStart',
552
- 'onTouchEnd',
553
- 'onResponderRelease',
554
- ]
555
- */
556
-
557
- for (const prop in props) {
558
- // if(~scrollResponders.indexOf(prop)
559
- if (
560
- typeof props[prop] === 'function' &&
561
- prop !== 'onMomentumScrollEnd' &&
562
- prop !== 'renderPagination' &&
563
- prop !== 'onScrollBeginDrag'
564
- ) {
565
- const originResponder = props[prop];
566
- overrides[prop] = e => originResponder(e, this.fullState(), this);
567
- }
568
- }
569
-
570
- return overrides;
571
- };
572
-
573
- /**
574
- * Render pagination
575
- * @return {object} react-dom
576
- */
577
- renderPagination = () => {
578
- // By default, dots only show when `total` >= 2
579
- if (this.state.total <= 1) return null;
580
-
581
- const dots = [];
582
- const ActiveDot = this.props.activeDot || (
583
- <View
584
- style={[
585
- {
586
- backgroundColor: this.props.activeDotColor || '#007aff',
587
- width: 8,
588
- height: 8,
589
- borderRadius: 4,
590
- marginLeft: 3,
591
- marginRight: 3,
592
- marginTop: 3,
593
- marginBottom: 3,
594
- },
595
- this.props.activeDotStyle,
596
- ]}
597
- />
598
- );
599
- const Dot = this.props.dot || (
600
- <View
601
- style={[
602
- {
603
- backgroundColor: this.props.dotColor || 'rgba(0,0,0,.2)',
604
- width: 8,
605
- height: 8,
606
- borderRadius: 4,
607
- marginLeft: 3,
608
- marginRight: 3,
609
- marginTop: 3,
610
- marginBottom: 3,
611
- },
612
- this.props.dotStyle,
613
- ]}
614
- />
615
- );
616
- for (let i = 0; i < this.state.total; i++) {
617
- dots.push(
618
- i === this.state.index
619
- ? React.cloneElement(ActiveDot, {key: i})
620
- : React.cloneElement(Dot, {key: i}),
621
- );
622
- }
623
-
624
- return (
625
- <View
626
- pointerEvents="none"
627
- style={[
628
- styles[`pagination_${this.state.dir}`],
629
- this.props.paginationStyle,
630
- ]}>
631
- {dots}
632
- </View>
633
- );
634
- };
635
-
636
- renderTitle = () => {
637
- let {children = []} = this.props;
638
- const child = children[this.state.index];
639
- const title = child && child.props && child.props.title;
640
- return !!title ? (
641
- <View style={styles.title}>
642
- {this.props.children?.[this.state.index].props.title}
643
- </View>
644
- ) : null;
645
- };
646
-
647
- renderNextButton = () => {
648
- let button = null;
649
-
650
- if (this.props.loop || this.state.index !== this.state.total - 1) {
651
- button = this.props.nextButton || (
652
- <Text style={styles.buttonText}>›</Text>
653
- );
654
- }
655
-
656
- return (
657
- <TouchableOpacity
658
- onPress={() => button !== null && this.scrollBy(1)}
659
- disabled={this.props.disableNextButton}>
660
- <View>{button}</View>
661
- </TouchableOpacity>
662
- );
663
- };
664
-
665
- renderPrevButton = () => {
666
- let button = null;
667
-
668
- if (this.props.loop || this.state.index !== 0) {
669
- button = this.props.prevButton || (
670
- <Text style={styles.buttonText}>‹</Text>
671
- );
672
- }
673
-
674
- return (
675
- <TouchableOpacity onPress={() => button !== null && this.scrollBy(-1)}>
676
- <View>{button}</View>
677
- </TouchableOpacity>
678
- );
679
- };
680
-
681
- renderButtons = () => (
682
- <View
683
- pointerEvents="box-none"
684
- style={[
685
- styles.buttonWrapper,
686
- {
687
- width: this.state.width,
688
- height: this.state.height,
689
- },
690
- this.props.buttonWrapperStyle,
691
- ]}>
692
- {this.renderPrevButton()}
693
- {this.renderNextButton()}
694
- </View>
695
- );
696
-
697
- refScrollView = view => {
698
- this.scrollView = view;
699
- };
700
-
701
- onPageScrollStateChanged = state => {
702
- switch (state) {
703
- case 'dragging':
704
- return this.onScrollBegin();
705
-
706
- case 'idle':
707
- case 'settling':
708
- if (this.props.onTouchEnd) this.props.onTouchEnd();
709
- }
710
- };
711
-
712
- renderScrollView = pages => {
713
- if (Platform.OS === 'ios') {
714
- return (
715
- <ScrollView
716
- ref={this.refScrollView}
717
- {...this.props}
718
- {...this.scrollViewPropOverrides()}
719
- contentContainerStyle={[styles.wrapperIOS, this.props.style]}
720
- contentOffset={this.state.offset}
721
- onScrollBeginDrag={this.onScrollBegin}
722
- onMomentumScrollEnd={this.onScrollEnd}
723
- onScrollEndDrag={this.onScrollEndDrag}
724
- style={this.props.scrollViewStyle}>
725
- {pages}
726
- </ScrollView>
727
- );
728
- }
729
- return (
730
- <ViewPagerAndroid
731
- ref={this.refScrollView}
732
- {...this.props}
733
- initialPage={this.props.loop ? this.state.index + 1 : this.state.index}
734
- onPageScrollStateChanged={this.onPageScrollStateChanged}
735
- onPageSelected={this.onScrollEnd}
736
- key={pages.length}
737
- style={[styles.wrapperAndroid, this.props.style]}>
738
- {pages}
739
- </ViewPagerAndroid>
740
- );
741
- };
742
-
743
- checkPagesBeforeAfter = children => {
744
- let str = '';
745
- if (children && Array.isArray(children)) {
746
- for (const child in children) {
747
- str += children[child].key || child;
748
- }
749
- }
750
- return str;
751
- };
752
-
753
- /**
754
- * Default render
755
- * @return {object} react-dom
756
- */
757
- render() {
758
- const {index, total, width, height} = this.state;
759
- const {
760
- children,
761
- containerStyle,
762
- loop,
763
- loadMinimal,
764
- loadMinimalSize,
765
- loadMinimalLoader,
766
- renderPagination,
767
- showsButtons,
768
- showsPagination,
769
- } = this.props;
770
- // let dir = state.dir
771
- // let key = 0
772
- const loopVal = loop ? 1 : 0;
773
- let pages = [];
774
-
775
- const pageStyle = [
776
- {
777
- width,
778
- height,
779
- },
780
- styles.slide,
781
- ];
782
- const pageStyleLoading = {
783
- width,
784
- height,
785
- flex: 1,
786
- justifyContent: 'center',
787
- alignItems: 'center',
788
- };
789
-
790
- // For make infinite at least total > 1
791
- if (total > 1) {
792
- // Re-design a loop model for avoid img flickering
793
- pages = Object.keys(children);
794
- // console.log(`checkPagesBeforeAfter children: ${JSON.stringify(this.checkPagesBeforeAfter(pages))}`);
795
-
796
- if (loop) {
797
- pages.unshift(`${total - 1}`);
798
- pages.push('0');
799
- }
800
-
801
- pages = pages.map((page, i) => {
802
- if (loadMinimal) {
803
- if (
804
- i >= index + loopVal - loadMinimalSize &&
805
- i <= index + loopVal + loadMinimalSize
806
- ) {
807
- return (
808
- <View style={pageStyle} key={i}>
809
- {children[page]}
810
- </View>
811
- );
812
- }
813
- return (
814
- <View style={pageStyleLoading} key={i}>
815
- {loadMinimalLoader || <ActivityIndicator />}
816
- </View>
817
- );
818
- }
819
- return (
820
- <View style={pageStyle} key={i}>
821
- {children[page]}
822
- </View>
823
- );
824
- });
825
- } else {
826
- pages = (
827
- <View style={pageStyle} key={0}>
828
- {children}
829
- </View>
830
- );
831
- }
832
-
833
- return (
834
- <View style={[styles.container, containerStyle]} onLayout={this.onLayout}>
835
- {this.renderScrollView(pages)}
836
- {showsPagination &&
837
- (renderPagination
838
- ? renderPagination(index, total, this)
839
- : this.renderPagination())}
840
- {this.renderTitle()}
841
- {showsButtons && this.renderButtons()}
842
- </View>
843
- );
844
- }
845
- }