Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hot-phones-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---
Comment thread
TylerJDev marked this conversation as resolved.

AnchoredOverlay: (Behind feature flag) Make popover API usage opt-in
28 changes: 19 additions & 9 deletions packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ interface AnchoredOverlayBaseProps extends Pick<OverlayProps, 'height' | 'width'
* Props to be spread on the close button in the overlay.
*/
closeButtonProps?: Partial<IconButtonProps>
/**
* When enabled (and CSS anchor positioning feature flag is on), uses the Popover API
Comment thread
TylerJDev marked this conversation as resolved.
Outdated
*/
usePopover?: boolean
Comment thread
TylerJDev marked this conversation as resolved.
Outdated
}

export type AnchoredOverlayProps = AnchoredOverlayBaseProps &
Expand Down Expand Up @@ -162,10 +166,13 @@ export const AnchoredOverlay: React.FC<React.PropsWithChildren<AnchoredOverlayPr
onPositionChange,
displayCloseButton = true,
closeButtonProps = defaultCloseButtonProps,
usePopover = false,
}) => {
const cssAnchorPositioningFlag = useFeatureFlag('primer_react_css_anchor_positioning')
const supportsNativeCSSAnchorPositioning = useRef(false)
const cssAnchorPositioning = cssAnchorPositioningFlag && supportsNativeCSSAnchorPositioning.current
// Only use Popover API when both CSS anchor positioning is enabled AND usePopover is true
const shouldUsePopover = cssAnchorPositioning && usePopover
const anchorRef = useProvidedRefOrCreate(externalAnchorRef)
const [overlayRef, updateOverlayRef] = useRenderForcingRef<HTMLDivElement>()
const anchorId = useId(externalAnchorId)
Expand Down Expand Up @@ -282,14 +289,17 @@ export const AnchoredOverlay: React.FC<React.PropsWithChildren<AnchoredOverlayPr
currentOverlay.style.setProperty(`--anchored-overlay-anchor-offset-${result.horizontal}`, `${offset || 0}px`)
}

try {
if (!currentOverlay.matches(':popover-open')) {
currentOverlay.showPopover()
// Only call showPopover when usePopover is enabled
if (shouldUsePopover) {
try {
if (!currentOverlay.matches(':popover-open')) {
currentOverlay.showPopover()
}
} catch {
// Ignore if popover is already showing or not supported
}
} catch {
// Ignore if popover is already showing or not supported
}
}, [cssAnchorPositioning, open, overlayElement, id, overlayRef, anchorRef, width])
}, [cssAnchorPositioning, shouldUsePopover, open, overlayElement, id, overlayRef, anchorRef, width])

const showXIcon = onClose && variant.narrow === 'fullscreen' && displayCloseButton
const XButtonAriaLabelledBy = closeButtonProps['aria-labelledby']
Expand All @@ -308,7 +318,7 @@ export const AnchoredOverlay: React.FC<React.PropsWithChildren<AnchoredOverlayPr
tabIndex: 0,
onClick: onAnchorClick,
onKeyDown: onAnchorKeyDown,
...(cssAnchorPositioning ? {popoverTarget: popoverId} : {}),
...(shouldUsePopover ? {popoverTarget: popoverId} : {}),
})}
{open ? (
<Overlay
Expand All @@ -328,9 +338,9 @@ export const AnchoredOverlay: React.FC<React.PropsWithChildren<AnchoredOverlayPr
preventOverflow={preventOverflow}
data-component="AnchoredOverlay"
_PrivateDisablePortal={_PrivateDisablePortal}
{...(cssAnchorPositioning ? {popover: 'manual'} : {})}
{...(shouldUsePopover ? {popover: 'manual'} : {})}
{...restOverlayProps}
{...(cssAnchorPositioning ? {id: popoverId} : {})}
{...(shouldUsePopover ? {id: popoverId} : {})}
ref={node => {
if (overlayProps?.ref) {
assignRef(overlayProps.ref, node)
Expand Down
Loading