Hoist minimumHeaderHeight and expose collapsedHeaderHeight in PagerWithHeader

Move minimumHeaderHeight state from PagerTabBar up to PagerWithHeader so it
can be shared with child tabs. Compute collapsedHeaderHeight as
minimumHeaderHeight + tabBarHeight and pass it through PagerWithHeaderChildParams
alongside headerHeight. This gives each tab access to the collapsed header
offset for scroll indicator positioning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-02-17 11:47:57 +02:00
parent 13b453e506
commit 8672740833
2 changed files with 17 additions and 2 deletions
+15 -2
View File
@@ -30,8 +30,9 @@ import {TabBar} from './TabBar'
export interface PagerWithHeaderChildParams { export interface PagerWithHeaderChildParams {
headerHeight: number headerHeight: number
collapsedHeaderHeight: number
isFocused: boolean isFocused: boolean
scrollElRef: React.MutableRefObject<ListMethods | ScrollView | null> scrollElRef: React.RefObject<ListMethods | ScrollView | null>
} }
export interface PagerWithHeaderProps { export interface PagerWithHeaderProps {
@@ -67,6 +68,7 @@ export function PagerWithHeader({
const [currentPage, setCurrentPage] = useState(0) const [currentPage, setCurrentPage] = useState(0)
const [tabBarHeight, setTabBarHeight] = useState(0) const [tabBarHeight, setTabBarHeight] = useState(0)
const [headerOnlyHeight, setHeaderOnlyHeight] = useState(0) const [headerOnlyHeight, setHeaderOnlyHeight] = useState(0)
const [minimumHeaderHeight, setMinimumHeaderHeight] = useState(0)
const scrollY = useSharedValue(0) const scrollY = useSharedValue(0)
const headerHeight = headerOnlyHeight + tabBarHeight const headerHeight = headerOnlyHeight + tabBarHeight
@@ -91,6 +93,8 @@ export function PagerWithHeader({
<PagerHeaderProvider scrollY={scrollY} headerHeight={headerOnlyHeight}> <PagerHeaderProvider scrollY={scrollY} headerHeight={headerOnlyHeight}>
<PagerTabBar <PagerTabBar
headerOnlyHeight={headerOnlyHeight} headerOnlyHeight={headerOnlyHeight}
minimumHeaderHeight={minimumHeaderHeight}
setMinimumHeaderHeight={setMinimumHeaderHeight}
items={items} items={items}
isHeaderReady={isHeaderReady} isHeaderReady={isHeaderReady}
renderHeader={renderHeader} renderHeader={renderHeader}
@@ -110,6 +114,8 @@ export function PagerWithHeader({
}, },
[ [
headerOnlyHeight, headerOnlyHeight,
minimumHeaderHeight,
setMinimumHeaderHeight,
items, items,
isHeaderReady, isHeaderReady,
renderHeader, renderHeader,
@@ -202,6 +208,7 @@ export function PagerWithHeader({
<View key={i} collapsable={false}> <View key={i} collapsable={false}>
<PagerItem <PagerItem
headerHeight={headerHeight} headerHeight={headerHeight}
collapsedHeaderHeight={minimumHeaderHeight + tabBarHeight}
index={i} index={i}
isReady={isReady} isReady={isReady}
isFocused={i === currentPage} isFocused={i === currentPage}
@@ -219,6 +226,8 @@ export function PagerWithHeader({
let PagerTabBar = ({ let PagerTabBar = ({
currentPage, currentPage,
headerOnlyHeight, headerOnlyHeight,
minimumHeaderHeight,
setMinimumHeaderHeight,
isHeaderReady, isHeaderReady,
items, items,
scrollY, scrollY,
@@ -234,6 +243,8 @@ let PagerTabBar = ({
}: { }: {
currentPage: number currentPage: number
headerOnlyHeight: number headerOnlyHeight: number
minimumHeaderHeight: number
setMinimumHeaderHeight: (height: number) => void
isHeaderReady: boolean isHeaderReady: boolean
items: string[] items: string[]
testID?: string testID?: string
@@ -252,7 +263,6 @@ let PagerTabBar = ({
dragState: SharedValue<'idle' | 'dragging' | 'settling'> dragState: SharedValue<'idle' | 'dragging' | 'settling'>
}): React.ReactNode => { }): React.ReactNode => {
const t = useTheme() const t = useTheme()
const [minimumHeaderHeight, setMinimumHeaderHeight] = useState(0)
const headerTransform = useAnimatedStyle(() => { const headerTransform = useAnimatedStyle(() => {
const translateY = const translateY =
Math.min( Math.min(
@@ -344,6 +354,7 @@ PagerTabBar = memo(PagerTabBar)
function PagerItem({ function PagerItem({
headerHeight, headerHeight,
collapsedHeaderHeight,
index, index,
isReady, isReady,
isFocused, isFocused,
@@ -352,6 +363,7 @@ function PagerItem({
registerRef, registerRef,
}: { }: {
headerHeight: number headerHeight: number
collapsedHeaderHeight: number
index: number index: number
isFocused: boolean isFocused: boolean
isReady: boolean isReady: boolean
@@ -376,6 +388,7 @@ function PagerItem({
<ScrollProvider onScroll={onScrollWorklet}> <ScrollProvider onScroll={onScrollWorklet}>
{renderTab({ {renderTab({
headerHeight, headerHeight,
collapsedHeaderHeight,
isFocused, isFocused,
scrollElRef: scrollElRef as React.MutableRefObject< scrollElRef: scrollElRef as React.MutableRefObject<
ListMethods | ScrollView | null ListMethods | ScrollView | null
@@ -15,6 +15,7 @@ import {TabBar} from './TabBar'
export interface PagerWithHeaderChildParams { export interface PagerWithHeaderChildParams {
headerHeight: number headerHeight: number
collapsedHeaderHeight: number
isFocused: boolean isFocused: boolean
scrollElRef: React.MutableRefObject<ListMethods | ScrollView | null> scrollElRef: React.MutableRefObject<ListMethods | ScrollView | null>
} }
@@ -177,6 +178,7 @@ function PagerItem({
} }
return renderTab({ return renderTab({
headerHeight: 0, headerHeight: 0,
collapsedHeaderHeight: 0,
isFocused, isFocused,
scrollElRef: scrollElRef as React.MutableRefObject< scrollElRef: scrollElRef as React.MutableRefObject<
ListMethods | ScrollView | null ListMethods | ScrollView | null