UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

88 lines (87 loc) 3.52 kB
"use strict"; import React from "react"; import { useCallback, useEffect, useRef } from 'react'; import { runOnJS, useAnimatedReaction } from 'react-native-reanimated'; import { useStableCallback } from '../../../hooks'; import { useMutableValue } from '../../../integrations/reanimated'; import { CommonValuesContext, ItemContextProvider, useItemNode, usePortalContext } from '../../../providers'; import { getContextProvider } from '../../../utils'; import TeleportedItemCell from './TeleportedItemCell'; import { jsx as _jsx } from "react/jsx-runtime"; const CommonValuesContextProvider = getContextProvider(CommonValuesContext); export default function ActiveItemPortal({ activationAnimationProgress, baseStyle, commonValuesContext, gesture, isActive, itemKey, onTeleport }) { const node = useItemNode(itemKey); const { isTeleported, measurePortalOutlet, teleport } = usePortalContext() ?? {}; const teleportEnabled = useMutableValue(false); const isFirstUpdateRef = useRef(true); const renderTeleportedItemCell = useCallback(() => /*#__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: /*#__PURE__*/_jsx(ItemContextProvider, { activationAnimationProgress: activationAnimationProgress, gesture: gesture, isActive: isActive, itemKey: itemKey, children: /*#__PURE__*/_jsx(TeleportedItemCell, { activationAnimationProgress: activationAnimationProgress, baseStyle: baseStyle, isActive: isActive, itemKey: itemKey, children: node }) }) }), [activationAnimationProgress, baseStyle, commonValuesContext, gesture, isActive, node, itemKey]); const teleportedItemId = `${commonValuesContext.containerId}-${itemKey}`; const enableTeleport = useStableCallback(() => { isFirstUpdateRef.current = true; teleport?.(teleportedItemId, renderTeleportedItemCell()); onTeleport(true); }); const disableTeleport = useCallback(() => { teleport?.(teleportedItemId, null); onTeleport(false); }, [teleport, teleportedItemId, onTeleport]); useEffect(() => disableTeleport, [disableTeleport]); useEffect(() => { const checkTeleported = () => isTeleported?.(teleportedItemId); if (!checkTeleported()) return; const update = () => checkTeleported() && teleport?.(teleportedItemId, renderTeleportedItemCell()); if (isFirstUpdateRef.current) { isFirstUpdateRef.current = false; // Needed for proper collapsible items behavior setTimeout(update); } else { update(); } }, [isTeleported, renderTeleportedItemCell, teleport, teleportedItemId]); useAnimatedReaction(() => activationAnimationProgress.value, (progress, prevProgress) => { if (prevProgress !== null && progress > prevProgress && !teleportEnabled.value) { // We have to ensure that the portal outlet ref is measured before the // teleported item is rendered within it because portal outlet position // must be known to calculate the teleported item position measurePortalOutlet?.(); teleportEnabled.value = true; runOnJS(enableTeleport)(); } else if (progress === 0 && teleportEnabled.value) { teleportEnabled.value = false; runOnJS(disableTeleport)(); } }); return null; } //# sourceMappingURL=ActiveItemPortal.js.map