Add moduleSuffixes to tsconfig (#11146)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
useState,
|
||||
} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type SharedValue, useSharedValue} from 'react-native-reanimated'
|
||||
import {flushSync} from 'react-dom'
|
||||
|
||||
import {s} from '#/lib/styles'
|
||||
@@ -19,7 +20,9 @@ export interface PagerRef {
|
||||
export interface RenderTabBarFnProps {
|
||||
selectedPage: number
|
||||
onSelect?: (index: number) => void
|
||||
tabBarAnchor?: JSX.Element
|
||||
tabBarAnchor?: JSX.Element | null | undefined // Ignored on native.
|
||||
dragProgress: SharedValue<number> // Ignored on web.
|
||||
dragState: SharedValue<'idle' | 'dragging' | 'settling'> // Ignored on web.
|
||||
}
|
||||
export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
|
||||
|
||||
@@ -27,7 +30,17 @@ interface Props {
|
||||
ref?: React.Ref<PagerRef>
|
||||
initialPage?: number
|
||||
renderTabBar: RenderTabBarFn
|
||||
// tab pressed, yet to scroll to page
|
||||
onTabPressed?: (index: number) => void
|
||||
// scroll settled
|
||||
onPageSelected?: (index: number) => void
|
||||
/**
|
||||
* Never fires on web - pages switch instantly, there is no drag gesture.
|
||||
*/
|
||||
onPageScrollStateChanged?: (
|
||||
scrollState: 'idle' | 'dragging' | 'settling',
|
||||
) => void
|
||||
testID?: string
|
||||
}
|
||||
|
||||
export function Pager({
|
||||
@@ -35,12 +48,22 @@ export function Pager({
|
||||
children,
|
||||
initialPage = 0,
|
||||
renderTabBar,
|
||||
onTabPressed,
|
||||
onPageSelected,
|
||||
onPageScrollStateChanged: _onPageScrollStateChanged,
|
||||
testID,
|
||||
}: React.PropsWithChildren<Props>) {
|
||||
const [selectedPage, setSelectedPage] = useState(initialPage)
|
||||
const scrollYs = useRef<Array<number | null>>([])
|
||||
const anchorRef = useRef(null)
|
||||
|
||||
/*
|
||||
* There is no drag gesture on web; these exist to satisfy the shared
|
||||
* RenderTabBarFnProps contract and never change.
|
||||
*/
|
||||
const dragProgress = useSharedValue(selectedPage)
|
||||
const dragState = useSharedValue<'idle' | 'dragging' | 'settling'>('idle')
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
setPage: (index: number) => {
|
||||
onTabBarSelect(index)
|
||||
@@ -59,6 +82,7 @@ export function Pager({
|
||||
: -scrollY // If there's no anchor, treat the top of the page as one.
|
||||
const isSticking = anchorTop <= 5 // This would be 0 if browser scrollTo() was reliable.
|
||||
|
||||
onTabPressed?.(index)
|
||||
if (isSticking) {
|
||||
scrollYs.current[selectedPage] = window.scrollY
|
||||
} else {
|
||||
@@ -77,15 +101,17 @@ export function Pager({
|
||||
}
|
||||
}
|
||||
},
|
||||
[selectedPage, setSelectedPage, onPageSelected],
|
||||
[selectedPage, setSelectedPage, onPageSelected, onTabPressed],
|
||||
)
|
||||
|
||||
return (
|
||||
<View style={s.hContentRegion}>
|
||||
<View testID={testID} style={s.hContentRegion}>
|
||||
{renderTabBar({
|
||||
selectedPage,
|
||||
tabBarAnchor: <View ref={anchorRef} />,
|
||||
onSelect: e => onTabBarSelect(e),
|
||||
dragProgress,
|
||||
dragState,
|
||||
})}
|
||||
{Children.map(children, (child, i) => (
|
||||
<View
|
||||
|
||||
@@ -29,11 +29,12 @@ export interface PagerWithHeaderProps {
|
||||
renderHeader?: ({
|
||||
setMinimumHeight,
|
||||
}: {
|
||||
setMinimumHeight: () => void
|
||||
setMinimumHeight: (height: number) => void
|
||||
}) => JSX.Element
|
||||
initialPage?: number
|
||||
onPageSelected?: (index: number) => void
|
||||
onCurrentPageSelected?: (index: number) => void
|
||||
allowHeaderOverScroll?: boolean // Ignored on web.
|
||||
}
|
||||
export const PagerWithHeader = forwardRef<PagerRef, PagerWithHeaderProps>(
|
||||
function PageWithHeaderImpl(
|
||||
@@ -127,7 +128,7 @@ let PagerTabBar = ({
|
||||
renderHeader?: ({
|
||||
setMinimumHeight,
|
||||
}: {
|
||||
setMinimumHeight: () => void
|
||||
setMinimumHeight: (height: number) => void
|
||||
}) => JSX.Element
|
||||
isHeaderReady: boolean
|
||||
onCurrentPageSelected?: (index: number) => void
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {useCallback, useEffect, useRef} from 'react'
|
||||
import {type ScrollView, StyleSheet, View} from 'react-native'
|
||||
import {type SharedValue} from 'react-native-reanimated'
|
||||
|
||||
import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
|
||||
import {Text} from '#/components/Typography'
|
||||
@@ -15,6 +16,14 @@ export interface TabBarProps {
|
||||
|
||||
onSelect?: (index: number) => void
|
||||
onPressSelected?: (index: number) => void
|
||||
|
||||
/**
|
||||
* The drag-following indicator and transparent background only exist in
|
||||
* the native tab bar - accepted here so shared callers typecheck.
|
||||
*/
|
||||
dragProgress?: SharedValue<number> // Ignored on web.
|
||||
dragState?: SharedValue<'idle' | 'dragging' | 'settling'> // Ignored on web.
|
||||
transparent?: boolean // Ignored on web.
|
||||
}
|
||||
|
||||
// How much of the previous/next item we're showing
|
||||
|
||||
Reference in New Issue
Block a user