UNPKG

@kietpt2003/react-native-core-ui

Version:
147 lines (146 loc) 6.93 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx } from "react/jsx-runtime"; import React from "react"; import { findNodeHandle, } from "react-native"; import Animated, { runOnUI, useAnimatedStyle, useSharedValue, } from "react-native-reanimated"; import { typedMemo } from "../utils/DraggableFlatList/typedMemo"; import { WEB } from "../utils"; import { CellProvider } from "../context/DraggableFlatList/cellContext"; import { useRefs } from "../context/DraggableFlatList/refContext"; import { useDraggableFlatListContext } from "../context/DraggableFlatList/draggableFlatListContext"; import { useAnimatedValues } from "../context/DraggableFlatList/animatedValueContext"; import { useStableCallback } from "../hooks/DraggableFlatList/useStableCallback"; import { useCellTranslate } from "../hooks/DraggableFlatList/useCellTranslate"; function CellRendererComponent(props) { const { item, index, onLayout, children } = props, rest = __rest(props, ["item", "index", "onLayout", "children"]); const viewRef = React.useRef(null); const { cellDataRef, propsRef, containerRef } = useRefs(); const { horizontalAnim, scrollOffset } = useAnimatedValues(); const { activeKey, keyExtractor, horizontal, layoutAnimationDisabled } = useDraggableFlatListContext(); const key = keyExtractor(item, index); const offset = useSharedValue(-1); const size = useSharedValue(-1); const heldTanslate = useSharedValue(0); const translate = useCellTranslate({ cellOffset: offset, cellSize: size, cellIndex: index, }); const isActive = activeKey === key; const animStyle = useAnimatedStyle(() => { // When activeKey becomes null at the end of a drag and the list reorders, // the animated style may apply before the next paint, causing a flicker. // Solution is to hold over the last animated value until the next onLayout. // (Not required in web) if (translate.value && !WEB) { heldTanslate.value = translate.value; } const t = activeKey ? translate.value : heldTanslate.value; return { transform: [horizontalAnim.value ? { translateX: t } : { translateY: t }], }; }, [translate, activeKey]); const updateCellMeasurements = useStableCallback(() => { const onSuccess = (x, y, w, h) => { if (WEB && horizontal) x += scrollOffset.value; const cellOffset = horizontal ? x : y; const cellSize = horizontal ? w : h; cellDataRef.current.set(key, { measurements: { size: cellSize, offset: cellOffset }, }); size.value = cellSize; offset.value = cellOffset; }; const onFail = () => { var _a; if ((_a = propsRef.current) === null || _a === void 0 ? void 0 : _a.debug) { console.log(`## on measure fail, index: ${index}`); } }; const containerNode = containerRef.current; const viewNode = viewRef.current; const nodeHandle = containerNode; if (viewNode && nodeHandle) { //@ts-ignore viewNode.measureLayout(nodeHandle, onSuccess, onFail); } }); const onCellLayout = useStableCallback((e) => { heldTanslate.value = 0; updateCellMeasurements(); if (onLayout && e) onLayout(e); }); React.useEffect(() => { if (WEB) { // onLayout isn't called on web when the cell index changes, so we manually re-measure requestAnimationFrame(() => { onCellLayout(); }); } }, [index, onCellLayout]); const baseStyle = React.useMemo(() => { return { elevation: isActive ? 1 : 0, zIndex: isActive ? 999 : 0, flexDirection: horizontal ? "row" : "column", }; }, [isActive, horizontal]); const { itemEnteringAnimation, itemExitingAnimation, itemLayoutAnimation } = propsRef.current; React.useEffect(() => { // NOTE: Keep an eye on reanimated LayoutAnimation refactor: // https://github.com/software-mansion/react-native-reanimated/pull/3332/files // We might have to change the way we register/unregister LayouAnimations: // - get native module: https://github.com/software-mansion/react-native-reanimated/blob/cf59766460d05eb30357913455318d8a95909468/src/reanimated2/NativeReanimated/NativeReanimated.ts#L18 // - register layout animation for tag: https://github.com/software-mansion/react-native-reanimated/blob/cf59766460d05eb30357913455318d8a95909468/src/reanimated2/NativeReanimated/NativeReanimated.ts#L99 if (!propsRef.current.enableLayoutAnimationExperimental) return; const tag = findNodeHandle(viewRef.current); runOnUI((t, _layoutDisabled) => { "worklet"; if (!t) return; const config = global.LayoutAnimationRepository.configs[t]; if (config) stashConfig(t, config); const stashedConfig = getStashedConfig(t); if (_layoutDisabled) { global.LayoutAnimationRepository.removeConfig(t); } else if (stashedConfig) { global.LayoutAnimationRepository.registerConfig(t, stashedConfig); } })(tag, layoutAnimationDisabled); }, [layoutAnimationDisabled]); return (_jsx(Animated.View, Object.assign({}, rest, { ref: viewRef, onLayout: onCellLayout, entering: itemEnteringAnimation, exiting: itemExitingAnimation, layout: propsRef.current.enableLayoutAnimationExperimental ? itemLayoutAnimation : undefined, style: [props.style, baseStyle, animStyle], pointerEvents: activeKey ? "none" : "auto", children: _jsx(CellProvider, { isActive: isActive, children: children }) }))); } export default typedMemo(CellRendererComponent); runOnUI(() => { "worklet"; global.RNDFLLayoutAnimationConfigStash = {}; })(); function stashConfig(tag, config) { "worklet"; if (!global.RNDFLLayoutAnimationConfigStash) global.RNDFLLayoutAnimationConfigStash = {}; global.RNDFLLayoutAnimationConfigStash[tag] = config; } function getStashedConfig(tag) { "worklet"; if (!global.RNDFLLayoutAnimationConfigStash) return null; return global.RNDFLLayoutAnimationConfigStash[tag]; }