@@ -3,13 +3,15 @@ import React, {useEffect, useRef} from 'react';
33import type { LayoutChangeEvent } from 'react-native' ;
44import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller' ;
55import Reanimated , { Easing , useAnimatedReaction , useAnimatedStyle , useSharedValue , withTiming } from 'react-native-reanimated' ;
6+ import useDebounce from '@hooks/useDebounce' ;
67import usePrevious from '@hooks/usePrevious' ;
78import useWindowDimensions from '@hooks/useWindowDimensions' ;
89import isInLandscapeModeUtil from '@libs/isInLandscapeMode' ;
910import type { CollapsibleHeaderOnKeyboardProps } from './types' ;
1011
1112const COLLAPSE_DURATION = 100 ;
1213const RESTORE_DURATION = 300 ;
14+ const HEADER_CONTENT_LAYOUT_STABILIZATION_TIME_ON_ORIENTATION_CHANGE = 300 ;
1315// Assumed vertical space for the focused input field — used to reserve space above the keyboard.
1416const VERTICAL_SPACE_FOR_FOCUSED_INPUT = 120 ;
1517const KEYBOARD_OPENING_PROGRESS_THRESHOLDS = [ 0.5 , 0.7 , 0.8 , 0.85 , 0.9 , 0.95 , 0.99 ] ;
@@ -60,6 +62,13 @@ function CollapsibleHeaderOnKeyboard({children, collapsibleHeaderOffset = 0}: Co
6062 isInLandscapeModeSV . set ( isInLandscapeMode ) ;
6163 } , [ isInLandscapeMode , isInLandscapeModeSV ] ) ;
6264
65+ const debouncedUpdateNaturalHeightRef = useDebounce ( ( height : number ) => {
66+ if ( isInLandscapeMode ) {
67+ return ;
68+ }
69+ naturalHeightRef . current = height ;
70+ } , HEADER_CONTENT_LAYOUT_STABILIZATION_TIME_ON_ORIENTATION_CHANGE ) ;
71+
6372 const onLayout = ( e : LayoutChangeEvent ) => {
6473 const height = e . nativeEvent . layout . height ;
6574
@@ -73,6 +82,10 @@ function CollapsibleHeaderOnKeyboard({children, collapsibleHeaderOffset = 0}: Co
7382 if ( ! isInLandscapeMode && height > naturalHeightRef . current && naturalHeightRef . current !== - 1 ) {
7483 naturalHeight . set ( height ) ;
7584 animatedHeight . set ( withTiming ( height , { duration : RESTORE_DURATION } ) ) ;
85+
86+ // we need to debounce the update of the natural height ref to make sure we don't block height updates
87+ // on landscape -> portrait mode change where header layout might not be stable at first.
88+ debouncedUpdateNaturalHeightRef ( height ) ;
7689 return ;
7790 }
7891
@@ -87,7 +100,7 @@ function CollapsibleHeaderOnKeyboard({children, collapsibleHeaderOffset = 0}: Co
87100
88101 // Restores the header when the screen goes from landscape to portrait mode.
89102 useEffect ( ( ) => {
90- const naturalHeightValue = naturalHeightRef . current ;
103+ const naturalHeightValue = naturalHeight . get ( ) ;
91104 if ( ! isInLandscapeMode && isFocused && naturalHeightValue !== - 1 ) {
92105 animatedHeight . set ( withTiming ( naturalHeightValue , { duration : RESTORE_DURATION } ) ) ;
93106 }
@@ -100,7 +113,7 @@ function CollapsibleHeaderOnKeyboard({children, collapsibleHeaderOffset = 0}: Co
100113 return ;
101114 }
102115
103- const naturalHeightValue = naturalHeightRef . current ;
116+ const naturalHeightValue = naturalHeight . get ( ) ;
104117 if ( naturalHeightValue === - 1 ) {
105118 return ;
106119 }
0 commit comments