Creating a Draggable Component in React Native/Expo with NativeWind

Creating a Draggable Component in React Native/Expo with NativeWind cover

If you're building a React Native or Expo app and need to create a draggable component, you're in the right place. Draggable components are useful for things like sliders, custom UI elements, or even games. In this guide, we'll walk through how to create a draggable component using React Native and Expo, and we'll style it with NativeWind for a clean and modern look.

Prerequisites

Before we start, make sure you have the following set up:

  1. Node.js installed on your machine.
  2. Expo CLI installed (npm install -g expo-cli).
  3. A new Expo project created (expo init DraggableComponent).
  4. NativeWind installed and configured in your project. If you haven't set it up yet, follow the NativeWind installation guide.

Step 1: Set Up Your Project

First, navigate to your project directory and install the necessary dependencies:

npx create-expo-app@latest DraggableComponent
cd DraggableComponent

npm install react-native-gesture-handler react-native-reanimated

These libraries will help us handle gestures and animations for the draggable component.

Step 2: Create the Draggable Component

Now, let's create the draggable component. We'll use react-native-gesture-handler for gesture detection and react-native-reanimated for smooth animations.

Import Required Libraries:

Open your App.js or the file where you want to create the draggable component and add the following imports:

import React, { useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
  useAnimatedGestureHandler,
  useSharedValue,
  useAnimatedStyle,
  withSpring,
} from 'react-native-reanimated';

Create the Draggable Component:

Define the draggable component using the PanGestureHandler and Animated components:

const DraggableComponent = () => {
  const translateX = useSharedValue(0);
  const translateY = useSharedValue(0);

  const onGestureEvent = useAnimatedGestureHandler({
    onStart: (_, ctx) => {
      ctx.startX = translateX.value;
      ctx.startY = translateY.value;
    },
    onActive: (event, ctx) => {
      translateX.value = ctx.startX + event.translationX;
      translateY.value = ctx.startY + event.translationY;
    },
    onEnd: () => {
      translateX.value = withSpring(0);
      translateY.value = withSpring(0);
    },
  });

  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [
        { translateX: translateX.value },
        { translateY: translateY.value },
      ],
    };
  });

  return (
    <View style={styles.container}>
      <PanGestureHandler onGestureEvent={onGestureEvent}>
        <Animated.View style={[styles.box, animatedStyle]} />
      </PanGestureHandler>
    </View>
  );
};

Add Styles:

Define the styles for the container and the draggable box:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: 'blue',
    borderRadius: 10,
  },
});

Step 3: Style with NativeWind

If you prefer using NativeWind for styling, you can replace the StyleSheet styles with NativeWind classes. Here's how:

Install NativeWind (if not already installed):

npm install nativewind

Update the Component:

Replace the styles object with NativeWind classes:

const DraggableComponent = () => {
  // ... (same code as above)

  return (
    <View className="flex-1 justify-center items-center">
      <PanGestureHandler onGestureEvent={onGestureEvent}>
        <Animated.View
          className="w-24 h-24 bg-blue-500 rounded-lg"
          style={animatedStyle}
        />
      </PanGestureHandler>
    </View>
  );
};

NativeWind makes it easy to apply Tailwind-like utility classes directly to your components.

Step 4: Test Your Draggable Component

Now, run your app to see the draggable component in action:

expo start

You should see a blue square in the center of the screen. Try dragging it around—it should move smoothly and snap back to the center when you release it.

Step 5: Customize Further

You can customize the draggable component further by:

  • Adding boundaries to restrict movement.
  • Changing the spring animation behavior.
  • Adding additional gestures or interactions.

For example, to restrict movement within the screen bounds, you can add logic to clamp the translateX and translateY values.

Conclusion

And that's it! You've successfully created a draggable component in React Native/Expo using react-native-gesture-handler, react-native-reanimated, and NativeWind for styling. This component can now be used in your app for various interactive features.

Feel free to experiment and expand on this example to suit your specific needs. Happy coding! 🚀

Recent Guides

Hestia Kit Premium

You have to be signed in to favorite this

Share

Hestia Kit Premium

This is Hestia Kit premium component