@gorhom/bottom-sheet
Version:
A performant interactive bottom sheet with fully configurable options 🚀
70 lines (61 loc) • 2.06 kB
text/typescript
import { type RefObject, useCallback, useRef } from 'react';
import { type NodeHandle, findNodeHandle } from 'react-native';
import { useSharedValue } from 'react-native-reanimated';
import { SCROLLABLE_STATE, SCROLLABLE_TYPE } from '../constants';
import type { Scrollable, ScrollableRef } from '../types';
export const useScrollable = () => {
// refs
const scrollableRef = useRef<ScrollableRef>(null);
const previousScrollableRef = useRef<ScrollableRef>(null);
// variables
const animatedScrollableType = useSharedValue<SCROLLABLE_TYPE>(
SCROLLABLE_TYPE.UNDETERMINED
);
const animatedScrollableContentOffsetY = useSharedValue<number>(0);
const animatedScrollableOverrideState = useSharedValue<SCROLLABLE_STATE>(
SCROLLABLE_STATE.UNDETERMINED
);
const isScrollableRefreshable = useSharedValue<boolean>(false);
// callbacks
const setScrollableRef = useCallback((ref: ScrollableRef) => {
// get current node handle id
const currentRefId = scrollableRef.current?.id ?? null;
if (currentRefId !== ref.id) {
if (scrollableRef.current) {
// @ts-ignore
previousScrollableRef.current = scrollableRef.current;
}
// @ts-ignore
scrollableRef.current = ref;
}
}, []);
const removeScrollableRef = useCallback((ref: RefObject<Scrollable>) => {
// find node handle id
let id: NodeHandle | null;
try {
id = findNodeHandle(ref.current);
} catch {
return;
}
// get current node handle id
const currentRefId = scrollableRef.current?.id ?? null;
/**
* @DEV
* when the incoming node is actually the current node, we reset
* the current scrollable ref to the previous one.
*/
if (id === currentRefId) {
// @ts-ignore
scrollableRef.current = previousScrollableRef.current;
}
}, []);
return {
scrollableRef,
animatedScrollableType,
animatedScrollableContentOffsetY,
animatedScrollableOverrideState,
isScrollableRefreshable,
setScrollableRef,
removeScrollableRef,
};
};