react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
123 lines (118 loc) • 4.43 kB
JavaScript
"use strict";
import React from "react";
import { Fragment, memo, useEffect } from 'react';
import { GestureDetector } from 'react-native-gesture-handler';
import { LayoutAnimationConfig, useDerivedValue, useSharedValue } from 'react-native-reanimated';
import { CommonValuesContext, ItemContextProvider, useCommonValuesContext, useItemDecorationStyles, useItemLayoutStyles, useItemPanGesture, useMeasurementsContext, usePortalContext } from '../../../providers';
import { ItemPortalState } from '../../../types';
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 {
activeItemKey,
componentId,
customHandle,
itemsOverridesStyle
} = commonValuesContext;
const activationAnimationProgress = useSharedValue(0);
const isActive = useDerivedValue(() => activeItemKey.value === key);
const portalState = useSharedValue(ItemPortalState.IDLE);
const layoutStyles = useItemLayoutStyles(key, activationAnimationProgress);
const decorationStyles = useItemDecorationStyles(key, isActive, activationAnimationProgress, portalState);
const gesture = useItemPanGesture(key, activationAnimationProgress);
useEffect(() => {
return () => removeItemMeasurements(key);
}, [key, removeItemMeasurements]);
const withItemContext = component => /*#__PURE__*/_jsx(ItemContextProvider, {
activationAnimationProgress: activationAnimationProgress,
gesture: gesture,
isActive: isActive,
itemKey: key,
children: component
});
const renderItemCell = onMeasure => {
const innerComponent = /*#__PURE__*/_jsx(ItemCell, {
...layoutAnimations,
cellStyle: [style, layoutStyles],
decorationStyles: decorationStyles,
itemsOverridesStyle: itemsOverridesStyle,
onMeasure: onMeasure,
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((width, height) => handleItemMeasurement(key, {
height,
width
}));
}
// PORTAL CASE
const teleportedItemId = `${componentId}-${key}`;
const onMeasureItem = (width, height) => {
const state = portalState.value;
if (state === ItemPortalState.EXITING) {
if (height > 0 && width > 0) {
portalContext.teleport(teleportedItemId, null);
portalState.value = ItemPortalState.IDLE;
}
} else if (state !== ItemPortalState.TELEPORTED) {
handleItemMeasurement(key, {
height,
width
});
}
};
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, {
activationAnimationProgress: activationAnimationProgress,
baseCellStyle: style,
isActive: isActive,
itemKey: key,
itemsOverridesStyle: itemsOverridesStyle,
teleportedItemId: teleportedItemId,
onMeasure: onMeasureItem,
children: children
}))
});
return /*#__PURE__*/_jsxs(Fragment, {
children: [renderItemCell(onMeasureItem), /*#__PURE__*/_jsx(ActiveItemPortal, {
activationAnimationProgress: activationAnimationProgress,
portalState: portalState,
renderTeleportedItemCell: renderTeleportedItemCell,
teleportedItemId: teleportedItemId,
children: children
})]
});
}
export default /*#__PURE__*/memo(DraggableView);
//# sourceMappingURL=DraggableView.js.map