Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ AppRegistry.registerComponent('swiper', () => swiper)

| Prop | Default | Type | Description |
| :------------ |:---------------:| :---------------:| :-----|
| index | `0` | `number` | Index number of initial slide. |
| index | | `number` | Show slide in this index. |
| initialIndex | `0` | `number` | Index number of initial slide. Not applicable with `index`.|
| pager | `true` | `boolean` | Show pager. |
| onPageChange | | `function` | Callback when page changes. |
| onPageChange | | `function` | Callback when page changes or change is requested if `index` is set. |
| activeDotColor | `blue` | `string` | CSS color of the dot for the current page. |


Expand Down
37 changes: 31 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,44 @@ import React, {

import Dots from './dots'

const hasValue = v => v != null;

export default class Swiper extends Component {
static propTypes = {
children: React.PropTypes.node.isRequired,
index: React.PropTypes.number,
initialIndex: React.PropTypes.number,
pager: React.PropTypes.bool,
onPageChange: React.PropTypes.func,
activeDotColor: React.PropTypes.string,
}

static defaultProps = {
index: 0,
initialIndex: 0,
pager: true,
onPageChange: () => {},
activeDotColor: 'blue',
}

constructor(props) {
super(props)
this.isControlled = hasValue(props.index);
var initial = this.isControlled ? props.index : props.initialIndex;

this.state = {
index: props.index,
scrollValue: new Animated.Value(props.index),
index: initial,
scrollValue: new Animated.Value(initial),
viewWidth: Dimensions.get('window').width,
}
}

componentWillReceiveProps(nextProps) {
if (this.isControlled && nextProps.index !== this.state.index) {
this.goToPage(nextProps.index);
clearTimeout(this.revertSwipeTimer);
}
}

componentWillMount() {
const release = (e, gestureState) => {
const relativeGestureDistance = gestureState.dx / this.state.viewWidth
Expand All @@ -49,7 +61,18 @@ export default class Swiper extends Component {
newIndex = newIndex - 1
}

this.goToPage(newIndex)
this.props.onPageChange(newIndex);

if (this.isControlled) {
// If the parent does not update this.props.index within 50ms revert
// back to previous index. With 50ms we get nice bouncing effect.
this.revertSwipeTimer = setTimeout(() => {
this.goToPage(this.state.index);
}, 50);
} else {
this.goToPage(newIndex);
}

}

this._panResponder = PanResponder.create({
Expand All @@ -75,6 +98,10 @@ export default class Swiper extends Component {
})
}

componentWillUnmount() {
clearTimeout(this.revertSwipeTimer);
}

goToPage(pageNumber) {
// Don't scroll outside the bounds of the screens
pageNumber = Math.max(0, Math.min(pageNumber, this.props.children.length - 1))
Expand All @@ -83,8 +110,6 @@ export default class Swiper extends Component {
})

Animated.spring(this.state.scrollValue, {toValue: pageNumber, friction: this.props.springFriction, tension: this.props.springTension}).start();

this.props.onPageChange(pageNumber)
}

handleLayout(event) {
Expand Down