A package based on @brentvatne's awesome example.
npm install --save react-native-swipe-cards
- Create a module e.g.
SwipeCards.js
- Import it
import SwipeCards from './SwipeCards.js'
- Render it
<SwipeCards style={{flex: 1}} />
// SwipeCards.js
import React, { Component } from 'react';
import {StyleSheet, Text, View, Image} from 'react-native';
import SwipeCards from 'react-native-swipe-cards';
const Card = ({ backgroundColor, text }) => {
return (
<View style={[styles.card, {backgroundColor}]}>
<Text>{text}</Text>
</View>
)
}
const NoMoreCards = () => {
return (
<View>
<Text style={styles.noMoreCardsText}>No more cards</Text>
</View>
)
}
const Cards = [
{text: 'Tomato', backgroundColor: 'red'},
{text: 'Aubergine', backgroundColor: 'purple'},
{text: 'Courgette', backgroundColor: 'green'},
{text: 'Blueberry', backgroundColor: 'blue'},
{text: 'Umm...', backgroundColor: 'cyan'},
{text: 'orange', backgroundColor: 'orange'},
]
export default class extends Component {
state = {
cards: Cards
}
onRightSwipe (card) {
console.log(`Right for ${card.text}`)
}
onLeftSwipe (card) {
console.log(`Left for ${card.text}`)
}
onUpSwipe (card) {
console.log(`Up for ${card.text}`)
}
render() {
return (
<SwipeCards
cards={this.state.cards}
renderCard={(cardData) => <Card {...cardData} />}
renderNoMoreCards={() => <NoMoreCards />}
onRightSwipe={this.onRightSwipe}
onLeftSwipe={this.onLeftSwipe}
onUpSwipe={this.onUpSwipe}
hasUpAction
// If you want a stack of cards instead of one-per-one view, activate stack mode
// stack={true}
/>
)
}
}
const styles = StyleSheet.create({
card: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width: 300,
height: 300,
},
noMoreCardsText: {
fontSize: 22,
}
})
import React from 'react';
import {StyleSheet, Text, View, Image} from 'react-native';
import SwipeCards from 'react-native-swipe-cards';
const Card = ({ image, name }) => {
return (
<View style={styles.card}>
<Image style={styles.thumbnail} source={{uri: image}} />
<Text style={styles.text}>This is card {name}</Text>
</View>
)
}
const NoMoreCards = () => {
return (
<View>
<Text style={styles.noMoreCardsText}>No more cards</Text>
</View>
)
}
const Cards = [
{name: '1', image: 'https://media.giphy.com/media/GfXFVHUzjlbOg/giphy.gif'},
{name: '2', image: 'https://media.giphy.com/media/irTuv1L1T34TC/giphy.gif'},
{name: '3', image: 'https://media.giphy.com/media/LkLL0HJerdXMI/giphy.gif'},
{name: '4', image: 'https://media.giphy.com/media/fFBmUMzFL5zRS/giphy.gif'},
{name: '5', image: 'https://media.giphy.com/media/oDLDbBgf0dkis/giphy.gif'},
{name: '6', image: 'https://media.giphy.com/media/7r4g8V2UkBUcw/giphy.gif'},
{name: '7', image: 'https://media.giphy.com/media/K6Q7ZCdLy8pCE/giphy.gif'},
{name: '8', image: 'https://media.giphy.com/media/hEwST9KM0UGti/giphy.gif'},
{name: '9', image: 'https://media.giphy.com/media/3oEduJbDtIuA2VrtS0/giphy.gif'},
]
const Cards2 = [
{name: '10', image: 'https://media.giphy.com/media/12b3E4U9aSndxC/giphy.gif'},
{name: '11', image: 'https://media4.giphy.com/media/6csVEPEmHWhWg/200.gif'},
{name: '12', image: 'https://media4.giphy.com/media/AA69fOAMCPa4o/200.gif'},
{name: '13', image: 'https://media.giphy.com/media/OVHFny0I7njuU/giphy.gif'},
]
export default class extends Component {
state = {
cards: Cards,
outOfCards: false
}
onRightSwipe (card) {
console.log("right")
}
onLeftSwipe (card) {
console.log("left")
}
onCardRemoved (index) {
console.log(`The index is ${index}`);
const CARD_REFRESH_LIMIT = 3
if (this.state.cards.length - index <= CARD_REFRESH_LIMIT + 1) {
console.log(`There are only ${this.state.cards.length - index - 1} cards left.`);
if (!this.state.outOfCards) {
console.log(`Adding ${Cards2.length} more cards`)
this.setState({
cards: this.state.cards.concat(Cards2),
outOfCards: true
})
}
}
}
render() {
return (
<SwipeCards
cards={this.state.cards}
loop={false}
renderCard={(cardData) => <Card {...cardData} />}
renderNoMoreCards={() => <NoMoreCards />}
showRight={true}
showLeft={true}
onRightSwipe={this.onRightSwipe}
onLeftSwipe={this.onLeftSwipe}
onCardRemoved={this.onCardRemoved}
/>
)
}
})
const styles = StyleSheet.create({
card: {
alignItems: 'center',
borderRadius: 5,
overflow: 'hidden',
borderColor: 'grey',
backgroundColor: 'white',
borderWidth: 1,
elevation: 1,
},
thumbnail: {
flex: 1,
width: 300,
height: 300,
},
text: {
fontSize: 20,
paddingTop: 10,
paddingBottom: 10
},
noMoreCards: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
})
Prop name | Type | Default | Description |
---|---|---|---|
cardKey | (card: T) => Key | React key to be used to for each card | |
cards | Array | Data that will be provided as props for the cards | |
containerStyle | style | Override default style | |
dragY | Boolean | true |
Allows dragging cards vertically |
draggingDisabled | Boolean | false |
Allows dragging or not |
hasUpAction | Boolean | false |
Includes the possibility to swipe up and its components |
leftStyle | style | Override default style | |
leftText | string | Nope! |
Text to render on left swipe |
leftTextStyle | style | Override default style | |
leftView | ReactNode | React component to render on a left swipe | |
loop | Boolean | false |
If true, start again when run out of cards |
onCardRemoved | () => void | A callback passing the card reference that just got removed | |
onLeftSwipe | SwipeHandler | Called when card is swiped left. Return true to cancel the animation. | |
onLoop | () => void | Called when card list returns to the beginning | |
onRightSwipe | SwipeHandler | Called when card is swiped right. Return true to cancel the animation. | |
onSwipeCancelled | (card: T) => boolean | Called after a card swipe is cancelled. | |
onUpSwipe | SwipeHandler | Called when card is swiped up. Return true to cancel the animation. | |
renderCard | StatelessComponent | Renders the card with the current data | |
renderLeft | (pan: Animated.ValueXY) => ReactNode | Renders Left | |
renderLeftButton | ButtonRenderer | Renders Left button. Takes onPress and disabled props |
|
renderNoMoreCards | StatelessComponent | Renders what is shown after swiped last card | |
renderRight | (pan: Animated.ValueXY) => ReactNode | Renders Right | |
renderRightButton | ButtonRenderer | Renders Right Button. Takes onPress and disabled props |
|
renderUp | (pan: Animated.ValueXY) => ReactNode | Renders Up | |
renderUpButton | ButtonRenderer | Renders Up Button. Takes onPress and disabled props |
|
rightStyle | style | Override default style | |
rightText | string | Yup! |
Text to render on right swipe |
rightTextStyle | style | Override default style | |
rightView | ReactNode | React component to render on a right swipe | |
showLeft | Boolean | true |
Shows the 'Left' label |
showRight | Boolean | true |
Shows the 'Right' label |
showUp | Boolean | true |
Shows the 'Up' label |
smoothTransition | Boolean | false |
Disables a slow transition fading the current card out |
stack | Boolean | false |
Enables the stack mode |
stackOffsetX | Number | 25 | Horizontal offset between cards in stack |
stackOffsetY | Number | 0 | Vertical offset between cards in stack |
upStyle | style | Override default style | |
upText | string | Maybe! |
Text to render on Up swipe |
upTextStyle | style | Override default style | |
upView | ReactNode | React component to render on a Up swipe |
- Testing