72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
// DragAndDropCard.tsx
|
|
import React, { useEffect, useRef } from 'react';
|
|
import {Text, TextInput} from 'react-native';
|
|
import Animated, {
|
|
useSharedValue,
|
|
useAnimatedStyle,
|
|
withSpring,
|
|
} from 'react-native-reanimated';
|
|
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
import {AnimatedView} from "react-native-reanimated/src/component/View";
|
|
|
|
|
|
interface DragAndDropCardObject {
|
|
heading: string;
|
|
paragraph: string;
|
|
color: string;
|
|
}
|
|
|
|
const DragAndDropCard: React.FC<DragAndDropCardObject> = ({ heading, paragraph, color }) => {
|
|
const translateX = useSharedValue(0);
|
|
const translateY = useSharedValue(0);
|
|
|
|
const isMounted = useRef(true);
|
|
useEffect(() => {
|
|
return () => {
|
|
isMounted.current = false;
|
|
};
|
|
}, []);
|
|
|
|
// Gesture configuration
|
|
const panGesture = Gesture.Pan()
|
|
.onUpdate((event) => {
|
|
translateX.value = event.translationX;
|
|
translateY.value = event.translationY;
|
|
})
|
|
.onEnd(() => {
|
|
if (isMounted.current) {
|
|
translateX.value = withSpring(0);
|
|
translateY.value = withSpring(0);
|
|
}
|
|
});
|
|
|
|
// Animated styles
|
|
const animatedStyle = useAnimatedStyle(() => ({
|
|
transform: [
|
|
{ translateX: translateX.value },
|
|
{ translateY: translateY.value },
|
|
],
|
|
}));
|
|
|
|
return (
|
|
<GestureDetector gesture={panGesture}>
|
|
<AnimatedView
|
|
className="w-[90%] h-24 rounded-xl p-4 mb-2 shadow-md"
|
|
style={[animatedStyle, {backgroundColor: color}]}
|
|
>
|
|
<TextInput
|
|
className="w-[70%] mb-2 p-2 rounded-xl text-center font-semibold text-black"
|
|
placeholder="Type Heading..."
|
|
/>
|
|
|
|
<TextInput
|
|
className="w-[70%] p-2 rounded-xl text-center font-semibold text-black"
|
|
placeholder="Type Paragraph..."
|
|
/>
|
|
</AnimatedView>
|
|
</GestureDetector>
|
|
);
|
|
};
|
|
|
|
export default DragAndDropCard;
|