From 8f44db6255a71a0c14dbccda359c5c0bd23c807f Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Thu, 2 Apr 2026 14:27:26 -0400 Subject: [PATCH 1/3] Replace polyfill with `useAnchoredPosition` --- packages/react/package.json | 1 - .../src/AnchoredOverlay/AnchoredOverlay.tsx | 26 +++++-------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/packages/react/package.json b/packages/react/package.json index d4ae30e6638..21c1ee30aa9 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -78,7 +78,6 @@ "@github/relative-time-element": "^4.5.0", "@github/tab-container-element": "^4.8.2", "@lit-labs/react": "1.2.1", - "@oddbird/css-anchor-positioning": "^0.9.0", "@oddbird/popover-polyfill": "^0.5.2", "@primer/behaviors": "^1.10.2", "@primer/live-region-element": "^0.7.1", diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx index 65af71b83dd..30502f672cd 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx @@ -125,17 +125,6 @@ export type AnchoredOverlayProps = AnchoredOverlayBaseProps & (AnchoredOverlayPropsWithAnchor | AnchoredOverlayPropsWithoutAnchor) & Partial> -const applyAnchorPositioningPolyfill = async () => { - if (typeof window !== 'undefined' && !('anchorName' in document.documentElement.style)) { - try { - await import('@oddbird/css-anchor-positioning') - } catch (e) { - // eslint-disable-next-line no-console - console.warn('Failed to load CSS anchor positioning polyfill:', e) - } - } -} - const defaultVariant = { regular: 'anchored', narrow: 'anchored', @@ -173,7 +162,9 @@ export const AnchoredOverlay: React.FC { - const cssAnchorPositioning = useFeatureFlag('primer_react_css_anchor_positioning') + const cssAnchorPositioningFlag = useFeatureFlag('primer_react_css_anchor_positioning') + const supportsNativeCSSAnchorPositioning = useRef(false) + const cssAnchorPositioning = cssAnchorPositioningFlag && supportsNativeCSSAnchorPositioning.current const anchorRef = useProvidedRefOrCreate(externalAnchorRef) const [overlayRef, updateOverlayRef] = useRenderForcingRef() const anchorId = useId(externalAnchorId) @@ -232,19 +223,14 @@ export const AnchoredOverlay: React.FC { + supportsNativeCSSAnchorPositioning.current = 'anchorName' in document.documentElement.style + // ensure overlay ref gets cleared when closed, so position can reset between closing/re-opening if (!open && overlayRef.current) { updateOverlayRef(null) } - - if (cssAnchorPositioning && !hasLoadedAnchorPositioningPolyfill.current) { - applyAnchorPositioningPolyfill() - hasLoadedAnchorPositioningPolyfill.current = true - } - }, [open, overlayRef, updateOverlayRef, cssAnchorPositioning]) + }, [open, overlayRef, updateOverlayRef]) useFocusZone({ containerRef: overlayRef, From 0c2f9992721c8759063fb19c599b00d2c12d6dd1 Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Thu, 2 Apr 2026 19:44:14 -0400 Subject: [PATCH 2/3] Adjust CSS --- packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css b/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css index 5edbdb0a043..8b503bfa74c 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css @@ -35,23 +35,27 @@ /* stylelint-disable primer/spacing */ top: calc(anchor(bottom) + var(--base-size-4)); left: anchor(left); + max-height: calc(100dvh - anchor(bottom) - var(--base-size-4)); } &[data-side='outside-top'] { margin-bottom: var(--base-size-4); bottom: anchor(top); left: anchor(left); + max-height: calc(anchor(top) - var(--base-size-4)); } &[data-side='outside-left'] { right: anchor(left); top: anchor(top); margin-right: var(--base-size-4); + max-height: calc(100dvh - anchor(top)); } &[data-side='outside-right'] { left: anchor(right); top: anchor(top); margin-left: var(--base-size-4); + max-height: calc(100dvh - anchor(top)); } } From 5b1285bae4c20305a6e477b7a59eb9bee445f55c Mon Sep 17 00:00:00 2001 From: Tyler Jones Date: Mon, 6 Apr 2026 11:56:13 -0400 Subject: [PATCH 3/3] Add some JS --- .../AnchoredOverlay.module.css | 11 ++++++++ .../src/AnchoredOverlay/AnchoredOverlay.tsx | 26 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css b/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css index 8b503bfa74c..a20a216393a 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.module.css @@ -19,6 +19,7 @@ flip-inline, flip-block flip-inline; position-visibility: anchors-visible; + position-try-order: most-inline-size; z-index: 100; position: fixed !important; @@ -36,6 +37,11 @@ top: calc(anchor(bottom) + var(--base-size-4)); left: anchor(left); max-height: calc(100dvh - anchor(bottom) - var(--base-size-4)); + + &[data-align='left'] { + left: auto; + right: anchor(right); + } } &[data-side='outside-top'] { @@ -43,6 +49,11 @@ bottom: anchor(top); left: anchor(left); max-height: calc(anchor(top) - var(--base-size-4)); + + &[data-align='left'] { + left: auto; + right: anchor(right); + } } &[data-side='outside-left'] { diff --git a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx index 30502f672cd..810b4d9ec2c 100644 --- a/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx +++ b/packages/react/src/AnchoredOverlay/AnchoredOverlay.tsx @@ -268,6 +268,13 @@ export const AnchoredOverlay: React.FC= space.top ? 'bottom' : 'top' + const horizontal = space.right >= space.left ? 'right' : 'left' + + return {vertical, horizontal} +} + function assignRef( ref: React.MutableRefObject | ((instance: T | null) => void) | null | undefined, value: T | null,