1.7.0 • Published 7 months ago

rn-tinder-card v1.7.0

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

rn-tinder-card ⚡️

https://user-images.githubusercontent.com/68515357/233647214-47fbf6fc-3c66-478d-8ce8-d4e3ea08ad9a.mp4

⚡ Lightning fast and customizable tinder-like swipe card for React Native

Installation ⚙️

yarn add rn-tinder-card

rn-tinder-card needs react-native-reanimated and react-native-gesture-handler package 💎

yarn add react-native-reanimated react-native-gesture-handler

👇 You also need to complete installations of these packages for more information use the links below 👇

Overview

  • Rotation animation
  • Swipe event callbacks
  • Scale animation
  • Overlay labels
  • Swipe back to previous card with a custom animation
  • More swipe events callbacks
  • Integrating and using a single card with flatlist (coming soon)

Props ✏️

Card Props

Propstypedescriptiondefault
cardWidthnumberThe width of the cardwindowWidth
cardHeightnumberThe height of the cardwindowHeight
translateXRangearrayThe range for card translation along the X-axis-windowWidth / 2, 0, windowWidth / 2
translateYRangearrayThe range for card translation along the Y-axis-windowHeight / 2, 0, windowHeight / 2
cardStyleobjectThe style properties applied to the card{}
scaleValuenumberThe scale factor for card animation1
childrenReact.ReactNodeThe scale factor for card animation1

Event callbacks

Propstypedescriptiondefault
onSwipedLeftfuncfunction to be called when a card is swiped left() => {}
onSwipedRightfuncfunction to be called when a card is swiped right() => {}
onSwipedTopfuncfunction to be called when a card is swiped top() => {}

Swipe Animation Props

propstypedescriptiondefault
disableLeftSwipebooldisable left swipefalse
disableRightSwipebooldisable right swipefalse
disableTopSwipebooldisable top swipefalse

Rotation Animation Props

propstypedescriptiondefault
inputRotationRangearrayx values range for the rotation output-width, 0, width
outputRotationRangearrayrotation values for the x values in inputRotationRange-10, 0, 10

Overlay Labels Animation Props

propstypedescriptiondefault
inputOverlayLabelRightOpacityRangearrayInput range for the right overlay label opacity animation0, windowWidth / 2
outputOverlayLabelRightOpacityRangearrayOutput range for the right overlay label opacity animation0, 1
inputOverlayLabelLeftOpacityRangearrayInput range for the left overlay label opacity animation0, -windowWidth / 2
outputOverlayLabelLeftOpacityRangearrayOutput range for the left overlay label opacity animation0, 1
inputOverlayLabelTopOpacityRangearrayInput range for the top overlay label opacity animation0, -windowHeight / 2
outputOverlayLabelTopOpacityRangearrayOutput range for the top overlay label opacity animation0, 1
OverlayRight() => JSX.ElementComponent for the right swipe overlay label
OverlayLeft() => JSX.ElementComponent for the left swipe overlay label
OverlayTop() => JSX.ElementComponent for the top swipe overlay label

Swipe methods

propstypedescription
swipeBackcallbackResets the card position after a swipe event
swipeRightcallbackAnimates the card to fling to the right and calls onSwipeRight
swipeLeftcallbackAnimates the card to fling to the left and calls onSwipeLeft
swipeTopcallbackAnimates the card to fling to the top and calls onSwipeTop

Usage 🧑‍💻

import * as React from 'react';
import { Alert, Image, StyleSheet, Text, View } from 'react-native';
import { TinderCard } from 'rn-tinder-card';

const data = [
  'https://images.unsplash.com/photo-1681896616404-6568bf13b022?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1335&q=80',
  'https://images.unsplash.com/photo-1681871197336-0250ed2fe23d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1287&q=80',
  'https://images.unsplash.com/photo-1681238091934-10fbb34b497a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1282&q=80',
];

export default function App() {
  const OverlayRight = () => {
    return (
      <View
        style={[
          styles.overlayLabelContainer,
          {
            backgroundColor: 'green',
          },
        ]}
      >
        <Text style={styles.overlayLabelText}>Like</Text>
      </View>
    );
  };
  const OverlayLeft = () => {
    return (
      <View
        style={[
          styles.overlayLabelContainer,
          {
            backgroundColor: 'red',
          },
        ]}
      >
        <Text style={styles.overlayLabelText}>Nope</Text>
      </View>
    );
  };
  const OverlayTop = () => {
    return (
      <View
        style={[
          styles.overlayLabelContainer,
          {
            backgroundColor: 'blue',
          },
        ]}
      >
        <Text style={styles.overlayLabelText}>Super Like</Text>
      </View>
    );
  };

  return (
    <View style={styles.wrapper}>
      {data.map((item, index) => {
        return (
          <View
            style={styles.cardContainer}
            pointerEvents="box-none"
            key={index}
          >
            <TinderCard
              cardWidth={380}
              cardHeight={730}
              OverlayLabelRight={OverlayRight}
              OverlayLabelLeft={OverlayLeft}
              OverlayLabelTop={OverlayTop}
              cardStyle={styles.card}
              onSwipedRight={() => {
                Alert.alert('Swiped right');
              }}
              onSwipedTop={() => {
                Alert.alert('Swiped Top');
              }}
              onSwipedLeft={() => {
                Alert.alert('Swiped left');
              }}
            >
              <Image source={{ uri: item }} style={styles.image} />
            </TinderCard>
          </View>
        );
      })}
    </View>
  );
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1,
  },
  cardContainer: {
    ...StyleSheet.absoluteFillObject,
    justifyContent: 'center',
    alignItems: 'center',
  },
  card: {
    borderRadius: 48,
  },
  image: {
    width: '100%',
    height: '100%',
    borderRadius: 48,
  },
  overlayLabelContainer: {
    width: '100%',
    height: '100%',
    borderRadius: 48,
    justifyContent: 'center',
    alignItems: 'center',
  },
  overlayLabelText: { color: 'white', fontSize: 32, fontWeight: 'bold' },
});

For more examples check out the example folder 📂

Types 🏷️

export type CardItemHandle = {
  swipeBack: () => void;
};

export type TinderCardOptions = PropsWithChildren<{
  /*
  The width of the card.
  */
  cardWidth?: number;

  /*
  The width of the card.
  */
  cardHeight?: number;

  /* 
  The x coordinate range for card translation.
  */
  translateXRange?: number[];

  /*
  The y coordinate range for card translation.
  */
  translateYRange?: number[];

  /*
  The input and output ranges for card rotation.
  */
  inputRotationRange?: number[];
  outputRotationRange?: number[];

  /*
  The input and output ranges for swipe direction overlay label opacity.
  */

  inputOverlayLabelRightOpacityRange?: number[];
  outputOverlayLabelRightOpacityRange?: number[];

  inputOverlayLabelLeftOpacityRange?: number[];
  outputOverlayLabelLeftOpacityRange?: number[];

  inputOverlayLabelTopOpacityRange?: number[];
  outputOverlayLabelTopOpacityRange?: number[];

  /*
  Disable right, left, and top swipes.
  */
  disableRightSwipe?: boolean;
  disableLeftSwipe?: boolean;
  disableTopSwipe?: boolean;

  /*
  The style of the card.
  */
  cardStyle?: StyleProp<ViewStyle>;
  /*
  Callbacks for swipe events.
  */
  onSwipedRight?: () => void;
  onSwipedLeft?: () => void;
  onSwipedTop?: () => void;

  /*
  The scale value for card animation.
  */
  scaleValue?: number;

  /*  
  Swipe direction overlay label components.
  */
  OverlayLabelRight?: () => JSX.Element;
  OverlayLabelLeft?: () => JSX.Element;
  OverlayLabelTop?: () => JSX.Element;
}>;

Contributing 🔖

See the contributing guide to learn how to contribute to the repository and the development workflow.

License 📰

MIT