UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

154 lines (151 loc) 5.05 kB
"use strict"; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { cancelAnimation, makeMutable, runOnUI, useAnimatedRef } from 'react-native-reanimated'; import { useDebouncedStableCallback } from '../../hooks'; import { createProvider } from '../../providers/utils'; import { DebugComponentType } from '../../types/debug'; const { DebugProvider, useDebugContext } = createProvider('Debug', { guarded: false })(({ enabled }) => { const debugIdRef = useRef(0); const debugViewsRef = useRef({}); const observersRef = useRef(new Set()); const debugOutletRef = useAnimatedRef(); const getNextKey = useCallback(() => debugIdRef.current++, []); const notifyObservers = useDebouncedStableCallback(() => { const views = debugViewsRef.current; for (const observer of observersRef.current) { observer({ ...views }); } }); const createUpdater = useCallback(type => { const props = makeMutable({ visible: false }); return { hide() { 'worklet'; props.value = { ...props.value, visible: false }; }, props, set(newProps) { 'worklet'; if (typeof newProps === 'function') { const prevProps = props.value; props.value = newProps(prevProps); } else { props.value = newProps; } }, type }; }, []); const addUpdater = useCallback((key, updater) => { debugViewsRef.current[key] = updater; notifyObservers(); return updater; }, [notifyObservers]); const removeUpdater = useCallback(key => { const updater = debugViewsRef.current[key]; if (!updater) { return; } runOnUI(cancelAnimation)(updater.props); delete debugViewsRef.current[key]; notifyObservers(); }, [notifyObservers]); const useDebugComponent = useCallback(type => { const key = useMemo(getNextKey, []); const updater = useMemo(() => addUpdater(key, createUpdater(type)), [type, key]); useEffect(() => { return () => { removeUpdater(key); }; }, [updater, key]); return updater; }, [removeUpdater, createUpdater, addUpdater, getNextKey]); const useDebugComponents = useCallback((type, keysOrCount) => { const isNumber = typeof keysOrCount === 'number'; const [keys] = useState(isNumber ? [] : {}); const [updaters] = useState(() => isNumber ? [] : {}); useEffect(() => { return () => { for (const key of Object.values(keys)) { removeUpdater(key); } }; }, [keys]); if (isNumber && Array.isArray(keys) && Array.isArray(updaters)) { if (keys.length < keysOrCount) { for (let i = keys.length; i < keysOrCount; i++) { const key = getNextKey(); keys.push(key); updaters.push(addUpdater(key, createUpdater(type))); } } else { const removedKeys = keys.splice(keysOrCount); updaters.splice(keysOrCount); removedKeys.forEach(removeUpdater); } } else if (!isNumber && !Array.isArray(keys) && !Array.isArray(updaters)) { const resultKeySet = new Set(keysOrCount); for (const [resultKey, key] of Object.entries(keys)) { if (!resultKeySet.has(resultKey)) { removeUpdater(key); delete keys[resultKey]; delete updaters[resultKey]; } } for (const resultKey of keysOrCount) { if (!updaters[resultKey]) { const key = getNextKey(); keys[resultKey] = key; updaters[resultKey] = addUpdater(key, createUpdater(type)); } } } return Array.isArray(updaters) ? [...updaters] : { ...updaters }; }, [removeUpdater, createUpdater, addUpdater, getNextKey]); const useDebugLine = useCallback(() => useDebugComponent(DebugComponentType.LINE), [useDebugComponent]); const useDebugRect = useCallback(() => useDebugComponent(DebugComponentType.RECT), [useDebugComponent]); const useDebugCross = useCallback(() => useDebugComponent(DebugComponentType.CROSS), [useDebugComponent]); const useDebugLines = useCallback(keysOrCount => useDebugComponents(DebugComponentType.LINE, keysOrCount), [useDebugComponents]); const useDebugRects = useCallback(keysOrCount => useDebugComponents(DebugComponentType.RECT, keysOrCount), [useDebugComponents]); const useObserver = useCallback(observer => { useEffect(() => { const observers = observersRef.current; observers.add(observer); // Notify the observer immediately after adding it observer(debugViewsRef.current); return () => { observers.delete(observer); }; }, [observer]); }, []); return { enabled, value: { debugOutletRef, useDebugCross, useDebugLine, useDebugLines: useDebugLines, useDebugRect, useDebugRects: useDebugRects, useObserver } }; }); export { DebugProvider, useDebugContext }; //# sourceMappingURL=DebugProvider.js.map