@@ -33,19 +33,24 @@ const rootElement =
3333 document . getElementById ! ( 'root' ) ||
3434 document . getElementById ! ( '__next' ) as HTMLElement
3535
36- function getOverlayPosition ( { target } : GetOverlayPositionProps ) : React . CSSProperties {
36+ function getOverlayPosition ( { container , target } : GetOverlayPositionProps ) : React . CSSProperties {
3737 if ( target ) {
3838 const { top : targetTop , left : targetLeft } = target . getBoundingClientRect ( )
3939
40- const top = targetTop - target . clientTop
41- const left = targetLeft - target . clientLeft
40+ const top = container ?
41+ targetTop - target . clientTop - container . getBoundingClientRect ( ) . top + container . scrollTop :
42+ targetTop - target . clientTop
43+ const left = container ?
44+ targetLeft - target . clientLeft - container . getBoundingClientRect ( ) . left + container . scrollLeft :
45+ targetLeft - target . clientLeft
4246
4347 return { top, left }
4448 }
4549 return { }
4650}
4751
4852function getOverlayTranslation ( {
53+ container,
4954 target,
5055 overlay,
5156 placement,
@@ -54,12 +59,13 @@ function getOverlayTranslation({
5459 keepInContainer,
5560} : GetOverlayTranslatationProps ) : React . CSSProperties {
5661 if ( target ) {
62+ const containerElement = container || rootElement as HTMLElement
5763 const {
5864 width : rootWidth ,
5965 height : rootHeight ,
6066 top : rootTop ,
6167 left : rootLeft ,
62- } = rootElement . getBoundingClientRect ( )
68+ } = containerElement . getBoundingClientRect ( )
6369 const { width : targetWidth , height : targetHeight , top : targetTop , left : targetLeft } = target . getBoundingClientRect ( )
6470 const { width : overlayWidth , height : overlayHeight } = overlay . getBoundingClientRect ( )
6571
@@ -134,6 +140,7 @@ function getOverlayTranslation({
134140}
135141
136142function getOverlayStyle ( {
143+ container,
137144 target,
138145 overlay,
139146 placement,
@@ -142,8 +149,16 @@ function getOverlayStyle({
142149 keepInContainer,
143150} : GetOverlayStyleProps ) : React . CSSProperties {
144151 if ( target ) {
145- const overlayPositionStyle = getOverlayPosition ( { target } )
146- const overlayTranslateStyle = getOverlayTranslation ( { target, overlay, placement, marginX, marginY, keepInContainer } )
152+ const overlayPositionStyle = getOverlayPosition ( { container, target } )
153+ const overlayTranslateStyle = getOverlayTranslation ( {
154+ container,
155+ target,
156+ overlay,
157+ placement,
158+ marginX,
159+ marginY,
160+ keepInContainer,
161+ } )
147162
148163 const combinedStyle = {
149164 ...overlayPositionStyle ,
@@ -167,6 +182,7 @@ function Overlay(
167182 style,
168183 containerClassName = '' ,
169184 containerStyle,
185+ container,
170186 target,
171187 placement = OverlayPosition . LeftCenter ,
172188 marginX = 0 ,
@@ -181,7 +197,7 @@ function Overlay(
181197 const [ overlayStyle , setOverlayStyle ] = useState < React . CSSProperties > ( )
182198 const [ isHidden , setIsHidden ] = useState < boolean > ( true )
183199 const overlayRef = useRef < HTMLDivElement > ( null )
184- const [ containerRef , setContainerRef ] = useState < HTMLDivElement | null > ( null )
200+ const containerRef = useRef < HTMLDivElement > ( null )
185201 const mergedRef = useMergeRefs < HTMLDivElement > ( overlayRef , forwardedRef )
186202
187203 const handleBlockMouseWheel = useCallback ( ( event : HTMLElementEventMap [ 'wheel' ] ) => {
@@ -205,14 +221,9 @@ function Overlay(
205221 }
206222 } , [ onHide ] )
207223
208- const overlay = useMemo ( ( ) => (
209- < Container
210- ref = { setContainerRef }
211- className = { containerClassName }
212- style = { containerStyle }
213- data-testid = { containerTestId }
214- >
215- < Wrapper data-testid = { wrapperTestId } >
224+ const overlay = useMemo ( ( ) => {
225+ if ( container ) {
226+ return (
216227 < StyledOverlay
217228 as = { as }
218229 className = { className }
@@ -227,14 +238,40 @@ function Overlay(
227238 >
228239 { children }
229240 </ StyledOverlay >
230- </ Wrapper >
231- </ Container >
232- ) , [
241+ )
242+ }
243+ return (
244+ < Container
245+ ref = { containerRef }
246+ className = { containerClassName }
247+ style = { containerStyle }
248+ data-testid = { containerTestId }
249+ >
250+ < Wrapper data-testid = { wrapperTestId } >
251+ < StyledOverlay
252+ as = { as }
253+ className = { className }
254+ isHidden = { isHidden }
255+ style = { {
256+ ...( style || { } ) ,
257+ ...( overlayStyle || { } ) ,
258+ } }
259+ ref = { mergedRef }
260+ data-testid = { testId }
261+ { ...otherProps }
262+ >
263+ { children }
264+ </ StyledOverlay >
265+ </ Wrapper >
266+ </ Container >
267+ )
268+ } , [
233269 as ,
234270 className ,
235271 style ,
236272 containerClassName ,
237273 containerStyle ,
274+ container ,
238275 isHidden ,
239276 overlayStyle ,
240277 children ,
@@ -248,11 +285,12 @@ function Overlay(
248285 useEventHandler ( document , 'click' , handleHideOverlay , show )
249286 useEventHandler ( document , 'keyup' , handleKeydown , show )
250287 useEventHandler ( target , 'click' , handleClickTarget , show )
251- useEventHandler ( containerRef , 'wheel' , handleBlockMouseWheel , show )
288+ useEventHandler ( containerRef . current , 'wheel' , handleBlockMouseWheel , show )
252289
253290 useEffect ( ( ) => {
254291 if ( show ) {
255292 const tempOverlayStyle = getOverlayStyle ( {
293+ container,
256294 target,
257295 overlay : overlayRef . current as HTMLElement ,
258296 placement,
@@ -269,11 +307,11 @@ function Overlay(
269307 }
270308 }
271309 return noop
272- } , [ show , marginX , marginY , placement , target , keepInContainer ] )
310+ } , [ show , container , marginX , marginY , placement , target , keepInContainer ] )
273311
274312 if ( ! show ) return null
275313
276- return ReactDOM . createPortal ( overlay , rootElement as HTMLElement )
314+ return ReactDOM . createPortal ( overlay , container || rootElement as HTMLElement )
277315}
278316
279317export default forwardRef ( Overlay )
0 commit comments