diff --git a/src/__tests__/anchored-position.test.ts b/src/__tests__/anchored-position.test.ts index 98707b3..1113b72 100644 --- a/src/__tests__/anchored-position.test.ts +++ b/src/__tests__/anchored-position.test.ts @@ -366,4 +366,18 @@ describe('getAnchoredPosition', () => { expect(top).toEqual(54) // anchorRect.top + anchorRect.height + (settings.anchorOffset ?? 4) - parentRect.top expect(left).toEqual(380) // anchorRect.left + anchorRect.width - parentRect.left - floatingRect.width }) + + // This test runs for values derived from a real use case https://github.com/github/accessibility-audits/issues/4515 as run on a local storybook. + it('should overflow to bottom if the element is too tall to fit on the screen when zoomed', () => { + const parentRect = makeDOMRect(0, 0, 400, 400) + const anchorRect = makeDOMRect(16, 16, 32, 32) // left aligned button + const floatingRect = makeDOMRect(0, 0, 256, 428) + const {float, anchor} = createVirtualDOM(parentRect, anchorRect, floatingRect) + const settings: Partial = {side: 'outside-bottom', align: 'start'} + const {top, left, anchorSide, anchorAlign} = getAnchoredPosition(float, anchor, settings) + expect(anchorSide).toEqual('outside-right') + expect(anchorAlign).toEqual('start') + expect(top).toEqual(0) + expect(left).toEqual(52) + }) }) diff --git a/src/anchored-position.ts b/src/anchored-position.ts index ca7a5a3..d1371f3 100644 --- a/src/anchored-position.ts +++ b/src/anchored-position.ts @@ -370,7 +370,8 @@ function pureCalculateAnchoredPosition( // likely to be able to scroll. if (alternateOrder && positionAttempt < alternateOrder.length) { if (pos.top + floatingRect.height > viewportRect.height + relativeViewportRect.top) { - pos.top = viewportRect.height + relativeViewportRect.top - floatingRect.height + // This prevents top from being a negative value + pos.top = Math.max(viewportRect.height + relativeViewportRect.top - floatingRect.height, 0) } } }