Skip to content

Commit 3fd5193

Browse files
committed
Refactor usePopoverPositioning internal hook with options
1 parent 513ba2d commit 3fd5193

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

src/components/feedback/Popover.tsx

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,34 @@ type PopoverCSSProps =
2525
| 'bottom'
2626
| 'marginTop';
2727

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+
2842
/**
2943
* Manages the popover position manually to make sure it renders "next" to the
3044
* anchor element (above or below). This is mainly needed when using the
3145
* popover API, as that makes it render in the top layer, making it impossible
3246
* 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
3747
*/
3848
function usePopoverPositioning(
39-
anchorElementRef: RefObject<HTMLElement | undefined>,
4049
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,
4552
) {
4653
const adjustPopoverPositioning = useCallback(() => {
4754
const popoverEl = popoverRef.current!;
48-
const anchorEl = anchorElementRef.current!;
55+
const anchorEl = anchorRef.current!;
4956

5057
/**
5158
* Set the positioning styles synchronously (not via <div style={computedStyles} />),
@@ -131,10 +138,10 @@ function usePopoverPositioning(
131138
: `calc(${absBodyTop + anchorElDistanceToTop + anchorElHeight}px + ${POPOVER_ANCHOR_EL_GAP})`,
132139
left: `${Math.max(POPOVER_VIEWPORT_HORIZONTAL_GAP, left)}px`,
133140
});
134-
}, [asNativePopover, anchorElementRef, popoverRef, alignToRight, placement]);
141+
}, [asNativePopover, anchorRef, popoverRef, alignToRight, placement]);
135142

136143
useLayoutEffect(() => {
137-
if (!popoverOpen) {
144+
if (!open) {
138145
return () => {};
139146
}
140147

@@ -171,7 +178,7 @@ function usePopoverPositioning(
171178
listeners.removeAll();
172179
observer.disconnect();
173180
};
174-
}, [adjustPopoverPositioning, asNativePopover, popoverOpen, popoverRef]);
181+
}, [adjustPopoverPositioning, asNativePopover, open, popoverRef]);
175182
}
176183

177184
/**
@@ -355,14 +362,12 @@ export default function Popover({
355362
}: PopoverProps) {
356363
const popoverRef = useSyncedRef<HTMLElement>(elementRef);
357364

358-
usePopoverPositioning(
359-
anchorElementRef,
360-
popoverRef,
365+
usePopoverPositioning(popoverRef, anchorElementRef, {
361366
open,
362-
asNativePopover,
363-
align === 'right',
364367
placement,
365-
);
368+
alignToRight: align === 'right',
369+
asNativePopover,
370+
});
366371
useOnClose(popoverRef, anchorElementRef, onClose, open, asNativePopover);
367372
useRestoreFocusOnClose({
368373
open,

0 commit comments

Comments
 (0)