@@ -19,15 +19,7 @@ import classNames from "classnames";
19
19
import * as React from "react" ;
20
20
import { Manager , Modifier , Popper , PopperChildrenProps , Reference , ReferenceChildrenProps } from "react-popper" ;
21
21
22
- import {
23
- AbstractPureComponent ,
24
- Classes ,
25
- DISPLAYNAME_PREFIX ,
26
- HTMLDivProps ,
27
- mergeRefs ,
28
- refHandler ,
29
- Utils ,
30
- } from "../../common" ;
22
+ import { AbstractPureComponent , Classes , DISPLAYNAME_PREFIX , HTMLDivProps , refHandler , Utils } from "../../common" ;
31
23
import * as Errors from "../../common/errors" ;
32
24
import { Overlay } from "../overlay/overlay" ;
33
25
import { ResizeSensor } from "../resize-sensor/resizeSensor" ;
@@ -174,17 +166,20 @@ export class Popover<
174
166
* DOM element that contains the popover.
175
167
* When `usePortal={true}`, this element will be portaled outside the usual DOM flow,
176
168
* so this reference can be very useful for testing.
169
+ *
170
+ * @public for testing
177
171
*/
178
172
public popoverElement : HTMLElement | null = null ;
179
173
180
- /** DOM element that contains the target. */
181
- public targetElement : HTMLElement | null = null ;
182
-
183
174
/** Popover ref handler */
184
175
private popoverRef : React . Ref < HTMLDivElement > = refHandler ( this , "popoverElement" , this . props . popoverRef ) ;
185
176
186
- /** Target ref handler */
187
- private targetRef : React . Ref < HTMLElement > = el => ( this . targetElement = el ) ;
177
+ /**
178
+ * Target DOM element ref.
179
+ *
180
+ * @public for testing
181
+ */
182
+ public targetRef = React . createRef < HTMLElement > ( ) ;
188
183
189
184
private cancelOpenTimeout ?: ( ) => void ;
190
185
@@ -243,7 +238,7 @@ export class Popover<
243
238
244
239
return (
245
240
< Manager >
246
- < Reference > { this . renderTarget } </ Reference >
241
+ < Reference innerRef = { this . targetRef } > { this . renderTarget } </ Reference >
247
242
< Popper
248
243
innerRef = { this . popoverRef }
249
244
placement = { placement ?? positionToPlacement ( position ) }
@@ -319,7 +314,7 @@ export class Popover<
319
314
*/
320
315
public reposition = ( ) => this . popperScheduleUpdate ?.( ) ;
321
316
322
- private renderTarget = ( { ref : popperChildRef } : ReferenceChildrenProps ) => {
317
+ private renderTarget = ( { ref } : ReferenceChildrenProps ) => {
323
318
const { children, className, fill, openOnTargetFocus, renderTarget } = this . props ;
324
319
const { isOpen } = this . state ;
325
320
const isControlled = this . isControlled ( ) ;
@@ -330,8 +325,6 @@ export class Popover<
330
325
targetTagName = "div" ;
331
326
}
332
327
333
- const ref = mergeRefs ( popperChildRef , this . targetRef ) ;
334
-
335
328
const targetEventHandlers : PopoverHoverTargetHandlers < T > | PopoverClickTargetHandlers < T > =
336
329
isHoverInteractionKind
337
330
? {
@@ -412,8 +405,10 @@ export class Popover<
412
405
target = wrappedTarget ;
413
406
}
414
407
408
+ // N.B. we must attach the ref ('wrapped' with react-popper functionality) to the DOM element here and
409
+ // let ResizeSensor know about it
415
410
return (
416
- < ResizeSensor targetRef = { ref } onResize = { this . reposition } >
411
+ < ResizeSensor targetRef = { this . targetRef } onResize = { this . reposition } >
417
412
{ target }
418
413
</ ResizeSensor >
419
414
) ;
@@ -670,14 +665,14 @@ export class Popover<
670
665
} ;
671
666
672
667
private handleOverlayClose = ( e ?: React . SyntheticEvent < HTMLElement > ) => {
673
- if ( this . targetElement = == null || e === undefined ) {
668
+ if ( this . targetRef . current == null || e === undefined ) {
674
669
return ;
675
670
}
676
671
677
672
const event = ( e . nativeEvent ?? e ) as Event ;
678
673
const eventTarget = ( event . composed ? event . composedPath ( ) [ 0 ] : event . target ) as HTMLElement ;
679
674
// if click was in target, target event listener will handle things, so don't close
680
- if ( ! Utils . elementIsOrContains ( this . targetElement , eventTarget ) || e . nativeEvent instanceof KeyboardEvent ) {
675
+ if ( ! Utils . elementIsOrContains ( this . targetRef . current , eventTarget ) || e . nativeEvent instanceof KeyboardEvent ) {
681
676
this . setOpenState ( false , e ) ;
682
677
}
683
678
} ;
@@ -716,7 +711,8 @@ export class Popover<
716
711
717
712
private updateDarkParent ( ) {
718
713
if ( this . props . usePortal && this . state . isOpen ) {
719
- const hasDarkParent = this . targetElement != null && this . targetElement . closest ( `.${ Classes . DARK } ` ) != null ;
714
+ const hasDarkParent =
715
+ this . targetRef . current != null && this . targetRef . current . closest ( `.${ Classes . DARK } ` ) != null ;
720
716
this . setState ( { hasDarkParent } ) ;
721
717
}
722
718
}
0 commit comments