DEV Community

Cover image for React Native: Swipeable Row component with actions
Sergei
Sergei

Posted on

React Native: Swipeable Row component with actions

In this tutorial I will explain how to implement a UI element popular on iOS devices - swipeable row with actions. We will use the react-native-gesture-handler library.

ShoppingList

ShoppingListSwipe

Let's look at a singular row component:

Row

<View style={styles.container}>
        <TouchableOpacity style={styles.cardContainer} activeOpacity={1}>
          <Image
            source={{
              uri: product?.images?.length
                ? product.images[0]
                : settings.PRODUCT_IMAGE_PLACEHOLDER,
            }}
            style={styles.imageMini}
          />

          <View style={styles.rightSide}>
            <Text style={styles.title} numberOfLines={2}>
              {product.title}
            </Text>

            <View style={styles.buttonAndPriceContainer}>
              <MiniProductButton
                quantity={
                  product.inCartCount ? (product.inCartCount as number) : 0
                }
                onPressAdd={() => {}}
                onPressRemove={() => {}}
              />

              <Text style={styles.priceText} numberOfLines={1}>
                {formatPrice(product)}
              </Text>
            </View>
          </View>
        </TouchableOpacity>
      </View>
Enter fullscreen mode Exit fullscreen mode

The view should have a background color (or obscure the background in some other way), otherwise left and right actions will be visible on the screen the moment the user starts swiping!

No background color

container: {
    alignSelf: 'stretch',
    padding: 12,
    flex: 1,
    backgroundColor: palette.screenBackground,
  },
Enter fullscreen mode Exit fullscreen mode

First, we need to wrap this view in <Swipeable>.
Then, we need to create a function that will return a view that will be rendered when the user swipes to the left.

Right actions

const renderRightActions = () => {
    return (
      <View style={styles.rightActions}>
        <TouchableOpacity
          style={styles.favoriteButton}
          onPress={onFavoritePressed}>
          <IconFavoriteBig />
          <Text style={styles.textInSwipe}>Favorite</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.deleteButton}
          onPress={onDeleteItemPressed}>
          <IconDelete />
          <Text style={styles.textInSwipe}>Remove</Text>
        </TouchableOpacity>
      </View>
    );
  };
Enter fullscreen mode Exit fullscreen mode

Now, we need to pass this function to <Swipeable> as renderRightActions prop. The complete code of the component:

return (
    <Swipeable renderRightActions={renderRightActions}>
      <View style={styles.container}>
        <TouchableOpacity style={styles.cardContainer} activeOpacity={1}>
          <Image
            source={{
              uri: product?.images?.length
                ? product.images[0]
                : settings.PRODUCT_IMAGE_PLACEHOLDER,
            }}
            style={styles.imageMini}
          />

          <View style={styles.rightSide}>
            <Text style={styles.title} numberOfLines={2}>
              {product.title}
            </Text>

            <View style={styles.buttonAndPriceContainer}>
              <MiniProductButton
                quantity={
                  product.inCartCount ? (product.inCartCount as number) : 0
                }
                onPressAdd={() => {}}
                onPressRemove={() => {}}
              />

              <Text style={styles.priceText} numberOfLines={1}>
                {formatPrice(product)}
              </Text>
            </View>
          </View>
        </TouchableOpacity>
      </View>
    </Swipeable>
Enter fullscreen mode Exit fullscreen mode

This is it! The actions will appear after the user swipes the component:

Right actions row

You can create left actions in the same way and pass them as renderLeftActions.

There are also some useful props and methods that you should check out, such as friction or overshootLeft/Right.

Information about all available props and methods can be found here.

If you have any suggestions on how to improve this article, I'd love to hear them in the comments!

Top comments (0)