@@ -126,6 +126,10 @@ export default function useAlign(
126126 const doc = popupElement . ownerDocument ;
127127 const win = getWin ( popupElement ) ;
128128
129+ // Placement
130+ const placementInfo : AlignType =
131+ builtinPlacements [ placement ] || popupAlign || { } ;
132+
129133 // Reset first
130134 popupElement . style . left = '0' ;
131135 popupElement . style . top = '0' ;
@@ -150,18 +154,34 @@ export default function useAlign(
150154 }
151155 const popupRect = popupElement . getBoundingClientRect ( ) ;
152156 const { width, height } = win . getComputedStyle ( popupElement ) ;
153- const { clientWidth, clientHeight } = doc . documentElement ;
157+ const {
158+ clientWidth,
159+ clientHeight,
160+ scrollWidth,
161+ scrollHeight,
162+ scrollTop,
163+ scrollLeft,
164+ } = doc . documentElement ;
154165
155166 const popupHeight = popupRect . height ;
156167 const popupWidth = popupRect . width ;
157168
158169 // Get bounding of visible area
159- const visibleArea = {
160- left : 0 ,
161- top : 0 ,
162- right : clientWidth ,
163- bottom : clientHeight ,
164- } ;
170+ const visibleArea =
171+ placementInfo . htmlRegion === 'scroll'
172+ ? // Scroll region should take scrollLeft & scrollTop into account
173+ {
174+ left : - scrollLeft ,
175+ top : - scrollTop ,
176+ right : scrollWidth - scrollLeft ,
177+ bottom : scrollHeight - scrollTop ,
178+ }
179+ : {
180+ left : 0 ,
181+ top : 0 ,
182+ right : clientWidth ,
183+ bottom : clientHeight ,
184+ } ;
165185
166186 ( scrollerList || [ ] ) . forEach ( ( ele ) => {
167187 const eleRect = ele . getBoundingClientRect ( ) ;
@@ -179,10 +199,10 @@ export default function useAlign(
179199 Math . round ( ( eleRect . height / eleOutHeight ) * 1000 ) / 1000 ,
180200 ) ;
181201
182- const scrollWidth = ( eleOutWidth - eleInnerWidth ) * scaleX ;
183- const scrollHeight = ( eleOutHeight - eleInnerHeight ) * scaleY ;
184- const eleRight = eleRect . x + eleRect . width - scrollWidth ;
185- const eleBottom = eleRect . y + eleRect . height - scrollHeight ;
202+ const eleScrollWidth = ( eleOutWidth - eleInnerWidth ) * scaleX ;
203+ const eleScrollHeight = ( eleOutHeight - eleInnerHeight ) * scaleY ;
204+ const eleRight = eleRect . x + eleRect . width - eleScrollWidth ;
205+ const eleBottom = eleRect . y + eleRect . height - eleScrollHeight ;
186206
187207 visibleArea . left = Math . max ( visibleArea . left , eleRect . left ) ;
188208 visibleArea . top = Math . max ( visibleArea . top , eleRect . top ) ;
@@ -202,10 +222,6 @@ export default function useAlign(
202222 Math . round ( ( popupHeight / parseFloat ( height ) ) * 1000 ) / 1000 ,
203223 ) ;
204224
205- // Placement
206- const placementInfo : AlignType =
207- builtinPlacements [ placement ] || popupAlign || { } ;
208-
209225 // Offset
210226 const { offset, targetOffset } = placementInfo ;
211227 const [ popupOffsetX = 0 , popupOffsetY = 0 ] = offset || [ ] ;
0 commit comments