react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
89 lines (85 loc) • 2.78 kB
JavaScript
;
import { useCallback } from 'react';
import { measure, runOnUI } from 'react-native-reanimated';
import { HIDDEN_X_OFFSET } from '../../constants';
import { useAnimatedDebounce, useMutableValue } from '../../integrations/reanimated';
import { createProvider } from '../utils';
import { useCommonValuesContext } from './CommonValuesProvider';
const {
CustomHandleProvider,
useCustomHandleContext
} = createProvider('CustomHandle', {
guarded: false
})(() => {
const {
containerRef,
itemPositions
} = useCommonValuesContext();
const debounce = useAnimatedDebounce();
const fixedItemKeys = useMutableValue({});
const handleRefs = useMutableValue({});
const activeHandleMeasurements = useMutableValue(null);
const activeHandleOffset = useMutableValue(null);
const registerHandle = useCallback((key, handleRef, fixed) => {
runOnUI(() => {
'worklet';
handleRefs.value[key] = handleRef;
if (fixed) {
fixedItemKeys.value[key] = true;
debounce.schedule(fixedItemKeys.modify, 100);
}
})();
const unregister = () => {
'worklet';
delete handleRefs.value[key];
if (fixed) {
fixedItemKeys.value[key] = false;
debounce.schedule(fixedItemKeys.modify, 100);
}
};
return runOnUI(unregister);
}, [debounce, fixedItemKeys, handleRefs]);
const updateActiveHandleMeasurements = useCallback(key => {
'worklet';
const handleRef = handleRefs.value[key];
if (!handleRef) {
return;
}
const handleMeasurements = measure(handleRef);
const containerMeasurements = measure(containerRef);
const itemPosition = itemPositions.value[key];
if (!handleMeasurements || !containerMeasurements || !itemPosition) {
return;
}
activeHandleMeasurements.value = handleMeasurements;
const {
x: itemX,
y: itemY
} = itemPosition;
const {
pageX: handleX,
pageY: handleY
} = handleMeasurements;
const {
pageX: containerX,
pageY: containerY
} = containerMeasurements;
activeHandleOffset.value = {
// The handle might be measured when the item is already hidden (put outside
// of the viewport) so we need to adjust the measured x position accordingly
x: (handleX + HIDDEN_X_OFFSET) % HIDDEN_X_OFFSET - containerX - itemX,
y: handleY - containerY - itemY
};
}, [activeHandleMeasurements, activeHandleOffset, containerRef, handleRefs, itemPositions]);
return {
value: {
activeHandleMeasurements,
activeHandleOffset,
fixedItemKeys,
registerHandle,
updateActiveHandleMeasurements
}
};
});
export { CustomHandleProvider, useCustomHandleContext };
//# sourceMappingURL=CustomHandleProvider.js.map