import * as React from 'react'; import { useWindowDimensions } from 'react-native'; import type { TabPageProps, TabPageRef } from './TabPage'; import type { TabPageBodyRef, TabPageHeaderRef } from './types'; export const calculateIndex = (params: { width: number; contentOffsetX: number; }) => { const { width, contentOffsetX } = params; if (Number.isInteger(width) && Number.isInteger(contentOffsetX)) { return Math.floor(contentOffsetX / width); } else { const w = Math.round(width); const c = Math.round(contentOffsetX); return Math.round(c / w); } }; export const useHeaderStartScrolling = ( count: number, headerRef?: React.RefObject, initIndex?: number ) => { const currentIndex = React.useRef(initIndex ?? 0); return { headerStartScrolling: (width: number, x: number) => { const index = calculateIndex({ width: width, contentOffsetX: x, }); const current = index; const pre = currentIndex.current; const c = Math.abs(current - pre); currentIndex.current = current; if (current > pre) { if (current < count) { headerRef?.current?.toRight(c); } } else if (current < pre) { if (current >= 0) { headerRef?.current?.toLeft(c); } } }, }; }; export function useTabPageAPI( props: TabPageProps, ref?: React.ForwardedRef ) { const { header, width: initWidth, initIndex = 0 } = props; const { HeaderProps } = header; const { titles: headerTitles } = HeaderProps; const headerRef = React.useRef({} as any); const bodyRef = React.useRef({} as any); const count = headerTitles.length; const { width: winWidth } = useWindowDimensions(); const width = initWidth ?? winWidth; const { headerStartScrolling } = useHeaderStartScrolling( count, headerRef, initIndex ); React.useImperativeHandle(ref, () => { return { changeIndex: (index: number, animated?: boolean) => { bodyRef.current?.scrollTo(index, animated); headerStartScrolling(width, width * index); }, }; }, [headerStartScrolling, width]); return { headerRef, bodyRef, headerStartScrolling, }; }