@@ -25,27 +25,34 @@ type PopoverCSSProps =
25
25
| 'bottom'
26
26
| 'marginTop' ;
27
27
28
+ type PopoverPositioningOptions = {
29
+ open : boolean ;
30
+ placement : 'above' | 'below' ;
31
+
32
+ /**
33
+ * Whether the popover should be aligned to the right side of the anchor
34
+ * element or not
35
+ */
36
+ alignToRight : boolean ;
37
+
38
+ /** Native popover API is used to toggle the popover */
39
+ asNativePopover : boolean ;
40
+ } ;
41
+
28
42
/**
29
43
* Manages the popover position manually to make sure it renders "next" to the
30
44
* anchor element (above or below). This is mainly needed when using the
31
45
* popover API, as that makes it render in the top layer, making it impossible
32
46
* to position it relative to the anchor element via regular CSS.
33
- *
34
- * @param asNativePopover - Native popover API is used to toggle the popover
35
- * @param alignToRight - Whether the popover should be aligned to the right side
36
- * of the anchor element or not
37
47
*/
38
48
function usePopoverPositioning (
39
- anchorElementRef : RefObject < HTMLElement | undefined > ,
40
49
popoverRef : RefObject < HTMLElement | undefined > ,
41
- popoverOpen : boolean ,
42
- asNativePopover : boolean ,
43
- alignToRight : boolean ,
44
- placement : 'above' | 'below' ,
50
+ anchorRef : RefObject < HTMLElement | undefined > ,
51
+ { open, asNativePopover, alignToRight, placement } : PopoverPositioningOptions ,
45
52
) {
46
53
const adjustPopoverPositioning = useCallback ( ( ) => {
47
54
const popoverEl = popoverRef . current ! ;
48
- const anchorEl = anchorElementRef . current ! ;
55
+ const anchorEl = anchorRef . current ! ;
49
56
50
57
/**
51
58
* Set the positioning styles synchronously (not via <div style={computedStyles} />),
@@ -131,10 +138,10 @@ function usePopoverPositioning(
131
138
: `calc(${ absBodyTop + anchorElDistanceToTop + anchorElHeight } px + ${ POPOVER_ANCHOR_EL_GAP } )` ,
132
139
left : `${ Math . max ( POPOVER_VIEWPORT_HORIZONTAL_GAP , left ) } px` ,
133
140
} ) ;
134
- } , [ asNativePopover , anchorElementRef , popoverRef , alignToRight , placement ] ) ;
141
+ } , [ asNativePopover , anchorRef , popoverRef , alignToRight , placement ] ) ;
135
142
136
143
useLayoutEffect ( ( ) => {
137
- if ( ! popoverOpen ) {
144
+ if ( ! open ) {
138
145
return ( ) => { } ;
139
146
}
140
147
@@ -171,7 +178,7 @@ function usePopoverPositioning(
171
178
listeners . removeAll ( ) ;
172
179
observer . disconnect ( ) ;
173
180
} ;
174
- } , [ adjustPopoverPositioning , asNativePopover , popoverOpen , popoverRef ] ) ;
181
+ } , [ adjustPopoverPositioning , asNativePopover , open , popoverRef ] ) ;
175
182
}
176
183
177
184
/**
@@ -355,14 +362,12 @@ export default function Popover({
355
362
} : PopoverProps ) {
356
363
const popoverRef = useSyncedRef < HTMLElement > ( elementRef ) ;
357
364
358
- usePopoverPositioning (
359
- anchorElementRef ,
360
- popoverRef ,
365
+ usePopoverPositioning ( popoverRef , anchorElementRef , {
361
366
open,
362
- asNativePopover ,
363
- align === 'right' ,
364
367
placement,
365
- ) ;
368
+ alignToRight : align === 'right' ,
369
+ asNativePopover,
370
+ } ) ;
366
371
useOnClose ( popoverRef , anchorElementRef , onClose , open , asNativePopover ) ;
367
372
useRestoreFocusOnClose ( {
368
373
open,
0 commit comments