UNPKG

react-native-reanimated-dnd

Version:

A powerful drag-and-drop library for React Native using Reanimated 3

1 lines 3.08 kB
import{useRef,useEffect,useContext,useCallback,useMemo}from"react";import{StyleSheet}from"react-native";import{useAnimatedRef,measure,runOnUI,runOnJS}from"react-native-reanimated";import{SlotsContext}from"../types/context";import{_getUniqueDroppableId}from"../components/Droppable";export const useDroppable=options=>{const{onDrop,dropDisabled,onActiveChange,dropAlignment,dropOffset,activeStyle,droppableId,capacity}=options;const animatedViewRef=useAnimatedRef();const id=useRef(_getUniqueDroppableId()).current;const stringId=useRef(droppableId||`droppable-${id}`).current;const instanceId=useRef(`droppable-${id}-${Math.random().toString(36).substr(2,9)}`).current;const{register,unregister,isRegistered,activeHoverSlotId:contextActiveHoverSlotId,registerPositionUpdateListener,unregisterPositionUpdateListener}=useContext(SlotsContext);const isActive=contextActiveHoverSlotId===id;const{processedActiveStyle,activeTransforms}=useMemo((()=>{if(!isActive||!activeStyle){return{processedActiveStyle:null,activeTransforms:[]}}const flattenedStyle=StyleSheet.flatten(activeStyle);let processedStyle={...flattenedStyle};let transforms=[];if(flattenedStyle.transform){if(Array.isArray(flattenedStyle.transform)){transforms=[...flattenedStyle.transform]}delete processedStyle.transform}return{processedActiveStyle:processedStyle,activeTransforms:transforms}}),[isActive,activeStyle]);const combinedActiveStyle=useMemo((()=>{if(!isActive||!activeStyle){return undefined}if(activeTransforms.length===0){return processedActiveStyle}return{...processedActiveStyle,transform:activeTransforms}}),[isActive,activeStyle,processedActiveStyle,activeTransforms]);useEffect((()=>{onActiveChange===null||onActiveChange===void 0?void 0:onActiveChange(isActive)}),[isActive,onActiveChange]);useEffect((()=>{console.log(`Droppable ${id} using string ID: ${stringId}, provided ID: ${droppableId||"none"}`)}),[id,stringId,droppableId]);const updateDroppablePosition=useCallback((()=>{runOnUI((()=>{"worklet";const measurement=measure(animatedViewRef);if(measurement===null){return}if(measurement.width>0&&measurement.height>0){runOnJS(register)(id,{id:droppableId||`droppable-${id}`,x:measurement.pageX,y:measurement.pageY,width:measurement.width,height:measurement.height,onDrop,dropAlignment:dropAlignment||"center",dropOffset:dropOffset||{x:0,y:0},capacity})}}))()}),[id,droppableId,onDrop,register,animatedViewRef,dropAlignment,dropOffset,capacity]);const handleLayoutHandler=useCallback((_event=>{updateDroppablePosition()}),[updateDroppablePosition]);useEffect((()=>{registerPositionUpdateListener(instanceId,updateDroppablePosition);return()=>{unregisterPositionUpdateListener(instanceId)}}),[instanceId,registerPositionUpdateListener,unregisterPositionUpdateListener,updateDroppablePosition]);useEffect((()=>{if(dropDisabled){unregister(id)}else{updateDroppablePosition()}}),[dropDisabled,id,unregister,updateDroppablePosition]);useEffect((()=>()=>{unregister(id)}),[id,unregister]);return{viewProps:{onLayout:handleLayoutHandler,style:combinedActiveStyle},isActive,activeStyle,animatedViewRef}};