@@ -9,7 +9,15 @@ import CONST from '@src/CONST';
99import AutoCompleteSuggestionsPortal from './AutoCompleteSuggestionsPortal' ;
1010import type { AutoCompleteSuggestionsProps , MeasureParentContainerAndCursor } from './types' ;
1111
12- const measureHeightOfSuggestionRows = ( numRows : number , canBeBig : boolean ) : number => {
12+ const measureHeightOfSuggestionRows = ( numRows : number , canBeBig : boolean , isInLandscapeMode : boolean ) : number => {
13+ if ( isInLandscapeMode ) {
14+ if ( numRows > 1 ) {
15+ // In landscape mode, we display a scrollable window with a height of 1.5 items, indicating that there are more items available beyond what is currently visible
16+ return CONST . AUTO_COMPLETE_SUGGESTER . SMALL_CONTAINER_HEIGHT_FACTOR_LANDSCAPE_MODE * CONST . AUTO_COMPLETE_SUGGESTER . SUGGESTION_ROW_HEIGHT ;
17+ }
18+
19+ return numRows * CONST . AUTO_COMPLETE_SUGGESTER . SUGGESTION_ROW_HEIGHT ;
20+ }
1321 if ( canBeBig ) {
1422 if ( numRows > CONST . AUTO_COMPLETE_SUGGESTER . MAX_AMOUNT_OF_VISIBLE_SUGGESTIONS_IN_CONTAINER ) {
1523 // On large screens, if there are more than 5 suggestions, we display a scrollable window with a height of 5 items, indicating that there are more items available
@@ -42,6 +50,13 @@ const initialContainerState = {
4250 cursorCoordinates : { x : 0 , y : 0 } ,
4351} ;
4452
53+ function getLeftOffset ( x : number , leftInset : number , bigScreenLeftOffset : number , shouldUseNarrowLayout : boolean , isInLandscapeMode : boolean ) : number {
54+ if ( shouldUseNarrowLayout ) {
55+ return isInLandscapeMode ? x - leftInset : x ;
56+ }
57+ return bigScreenLeftOffset ;
58+ }
59+
4560/**
4661 * On the mobile-web platform, when long-pressing on auto-complete suggestions,
4762 * we need to prevent focus shifting to avoid blurring the main input (which makes the suggestions picker close and fires the onSelect callback).
@@ -55,13 +70,15 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
5570 const leftValue = React . useRef < number > ( 0 ) ;
5671 const prevLeftValue = React . useRef < number > ( 0 ) ;
5772 const { height : windowHeight , width : windowWidth } = useWindowDimensionsForAutoCompleteSuggestions ( ) ;
58- const { shouldUseNarrowLayout} = useResponsiveLayout ( ) ;
73+ const { shouldUseNarrowLayout, isInLandscapeMode} = useResponsiveLayout ( ) ;
74+ const prevIsInLandscapeModeValue = React . useRef ( isInLandscapeMode ) ;
5975 const [ suggestionHeight , setSuggestionHeight ] = React . useState ( 0 ) ;
6076 const [ containerState , setContainerState ] = React . useState ( initialContainerState ) ;
6177 const StyleUtils = useStyleUtils ( ) ;
6278 const insets = useSafeAreaInsets ( ) ;
6379 const { keyboardHeight, isKeyboardAnimatingRef} = useKeyboardState ( ) ;
6480 const { paddingBottom : bottomInset , paddingTop : topInset } = StyleUtils . getPlatformSafeAreaPadding ( insets ?? undefined ) ;
81+ const { left : leftInset } = insets ;
6582
6683 useEffect ( ( ) => {
6784 const container = containerRef . current ;
@@ -95,8 +112,8 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
95112 xCoordinatesOfCursor + CONST . AUTO_COMPLETE_SUGGESTER . BIG_SCREEN_SUGGESTION_WIDTH > windowWidth
96113 ? windowWidth - CONST . AUTO_COMPLETE_SUGGESTER . BIG_SCREEN_SUGGESTION_WIDTH
97114 : xCoordinatesOfCursor ;
98- const contentMaxHeight = measureHeightOfSuggestionRows ( suggestionsLength , true ) ;
99- const contentMinHeight = measureHeightOfSuggestionRows ( suggestionsLength , false ) ;
115+ const contentMaxHeight = measureHeightOfSuggestionRows ( suggestionsLength , true , isInLandscapeMode ) ;
116+ const contentMinHeight = measureHeightOfSuggestionRows ( suggestionsLength , false , isInLandscapeMode ) ;
100117 let bottomValue = windowHeight - ( cursorCoordinates . y - scrollValue + y ) - keyboardHeight ;
101118 const widthValue = shouldUseNarrowLayout ? width : CONST . AUTO_COMPLETE_SUGGESTER . BIG_SCREEN_SUGGESTION_WIDTH ;
102119
@@ -107,34 +124,39 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
107124 contentHeight : contentMaxHeight ,
108125 topInset,
109126 } ) ;
110- const isEnoughSpaceToRenderMenuAboveForSmall = isEnoughSpaceToRenderMenuAboveCursor ( {
111- y,
112- cursorCoordinates,
113- scrollValue,
114- contentHeight : contentMinHeight ,
115- topInset,
116- } ) ;
117127
118- const newLeftOffset = shouldUseNarrowLayout ? x : bigScreenLeftOffset ;
128+ // In landscape mode, we always render the menu above the cursor
129+ const isEnoughSpaceToRenderMenuAboveForSmall =
130+ isInLandscapeMode ||
131+ isEnoughSpaceToRenderMenuAboveCursor ( {
132+ y,
133+ cursorCoordinates,
134+ scrollValue,
135+ contentHeight : contentMinHeight ,
136+ topInset,
137+ } ) ;
138+
139+ const newLeftOffset = getLeftOffset ( x , leftInset , bigScreenLeftOffset , shouldUseNarrowLayout , isInLandscapeMode ) ;
119140 // If the suggested word is longer than 150 (approximately half the width of the suggestion popup), then adjust a new position of popup
120141 const isAdjustmentNeeded = Math . abs ( prevLeftValue . current - bigScreenLeftOffset ) > 150 ;
121- if ( isInitialRender . current || isAdjustmentNeeded ) {
142+ if ( isInitialRender . current || isAdjustmentNeeded || prevIsInLandscapeModeValue . current !== isInLandscapeMode ) {
122143 isSuggestionMenuAboveRef . current = isSuggestionMenuRenderedAbove ( isEnoughSpaceToRenderMenuAboveForBig , isEnoughSpaceToRenderMenuAboveForSmall ) ;
123144 leftValue . current = newLeftOffset ;
124145 isInitialRender . current = false ;
125146 prevLeftValue . current = newLeftOffset ;
147+ prevIsInLandscapeModeValue . current = isInLandscapeMode ;
126148 }
127149
128150 let measuredHeight = 0 ;
129151 if ( isSuggestionMenuAboveRef . current && isEnoughSpaceToRenderMenuAboveForBig ) {
130152 // calculation for big suggestion box above the cursor
131- measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , true ) ;
153+ measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , true , isInLandscapeMode ) ;
132154 } else if ( isSuggestionMenuAboveRef . current && isEnoughSpaceToRenderMenuAboveForSmall ) {
133155 // calculation for small suggestion box above the cursor
134- measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , false ) ;
156+ measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , false , isInLandscapeMode ) ;
135157 } else {
136158 // calculation for big suggestion box below the cursor
137- measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , true ) ;
159+ measuredHeight = measureHeightOfSuggestionRows ( suggestionsLength , true , isInLandscapeMode ) ;
138160 bottomValue = windowHeight - y - cursorCoordinates . y + scrollValue - measuredHeight - CONST . AUTO_COMPLETE_SUGGESTER . SUGGESTION_ROW_HEIGHT - keyboardHeight ;
139161 }
140162
@@ -146,7 +168,19 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
146168 cursorCoordinates,
147169 } ) ;
148170 } ) ;
149- } , [ measureParentContainerAndReportCursor , windowHeight , windowWidth , keyboardHeight , shouldUseNarrowLayout , suggestionsLength , bottomInset , topInset , isKeyboardAnimatingRef ] ) ;
171+ } , [
172+ measureParentContainerAndReportCursor ,
173+ windowHeight ,
174+ windowWidth ,
175+ keyboardHeight ,
176+ shouldUseNarrowLayout ,
177+ suggestionsLength ,
178+ bottomInset ,
179+ topInset ,
180+ isKeyboardAnimatingRef ,
181+ isInLandscapeMode ,
182+ leftInset ,
183+ ] ) ;
150184
151185 // Prevent rendering if container dimensions are not set or if we have no suggestions
152186 if ( ( containerState . width === 0 && containerState . left === 0 && containerState . bottom === 0 ) || ! suggestionsLength ) {
@@ -161,6 +195,7 @@ function AutoCompleteSuggestions<TSuggestion>({measureParentContainerAndReportCu
161195 width = { containerState . width }
162196 bottom = { containerState . bottom }
163197 measuredHeightOfSuggestionRows = { suggestionHeight }
198+ isInLandscapeMode = { isInLandscapeMode }
164199 />
165200 ) ;
166201}
0 commit comments