react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
134 lines (129 loc) • 4.39 kB
JavaScript
"use strict";
import React from "react";
import { Fragment, memo, useCallback, useEffect, useState } from 'react';
import { GestureDetector } from 'react-native-gesture-handler';
import { LayoutAnimationConfig, runOnUI, useDerivedValue } from 'react-native-reanimated';
import { useMutableValue } from '../../../integrations/reanimated';
import { CommonValuesContext, ItemContextProvider, useCommonValuesContext, useDragContext, useItemPanGesture, useItemStyles, useMeasurementsContext, usePortalContext } from '../../../providers';
import { getContextProvider } from '../../../utils';
import ActiveItemPortal from './ActiveItemPortal';
import ItemCell from './ItemCell';
import TeleportedItemCell from './TeleportedItemCell';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const CommonValuesContextProvider = getContextProvider(CommonValuesContext);
function DraggableView({
children,
itemKey: key,
style,
...layoutAnimations
}) {
const portalContext = usePortalContext();
const commonValuesContext = useCommonValuesContext();
const {
handleItemMeasurement,
removeItemMeasurements
} = useMeasurementsContext();
const {
handleDragEnd
} = useDragContext();
const {
activeItemKey,
containerId,
customHandle
} = commonValuesContext;
const [isTeleported, setIsTeleported] = useState(false);
const activationAnimationProgress = useMutableValue(0);
const isActive = useDerivedValue(() => activeItemKey.value === key);
const itemStyles = useItemStyles(key, isActive, activationAnimationProgress);
const gesture = useItemPanGesture(key, activationAnimationProgress);
useEffect(() => {
return () => {
removeItemMeasurements(key);
runOnUI(() => {
handleDragEnd(key, activationAnimationProgress);
})();
};
}, [activationAnimationProgress, handleDragEnd, key, removeItemMeasurements]);
useEffect(() => {
if (!portalContext) {
setIsTeleported(false);
return;
}
const teleportedItemId = `${containerId}-${key}`;
const unsubscribe = portalContext?.subscribe?.(teleportedItemId, setIsTeleported);
return () => {
portalContext?.teleport?.(teleportedItemId, null);
unsubscribe?.();
};
}, [portalContext, containerId, key]);
const onLayout = useCallback(({
nativeEvent: {
layout: {
height,
width
}
}
}) => handleItemMeasurement(key, {
height,
width
}), [handleItemMeasurement, key]);
const withItemContext = component => /*#__PURE__*/_jsx(ItemContextProvider, {
activationAnimationProgress: activationAnimationProgress,
gesture: gesture,
isActive: isActive,
itemKey: key,
children: component
});
const sharedCellProps = {
activationAnimationProgress,
isActive,
itemKey: key,
onLayout
};
const renderItemCell = (hidden = false) => {
const innerComponent = /*#__PURE__*/_jsx(ItemCell, {
...layoutAnimations,
...sharedCellProps,
cellStyle: [style, itemStyles],
hidden: hidden,
children: /*#__PURE__*/_jsx(LayoutAnimationConfig, {
skipEntering: false,
skipExiting: false,
children: children
})
});
return withItemContext(customHandle ? innerComponent : /*#__PURE__*/_jsx(GestureDetector, {
gesture: gesture,
userSelect: "none",
children: innerComponent
}));
};
// NORMAL CASE (no portal)
if (!portalContext) {
return renderItemCell();
}
// PORTAL CASE
const renderTeleportedItemCell = () =>
/*#__PURE__*/
// We have to wrap the TeleportedItemCell in context providers as they won't
// be accessible otherwise, when the item is rendered in the portal outlet
_jsx(CommonValuesContextProvider, {
value: commonValuesContext,
children: withItemContext(/*#__PURE__*/_jsx(TeleportedItemCell, {
...sharedCellProps,
cellStyle: style,
children: children
}))
});
return /*#__PURE__*/_jsxs(Fragment, {
children: [renderItemCell(isTeleported), /*#__PURE__*/_jsx(ActiveItemPortal, {
activationAnimationProgress: activationAnimationProgress,
commonValuesContext: commonValuesContext,
itemKey: key,
renderTeleportedItemCell: renderTeleportedItemCell,
children: children
})]
});
}
export default /*#__PURE__*/memo(DraggableView);
//# sourceMappingURL=DraggableView.js.map