From 7612f66586566ec4631efe62502b96c5a1f10347 Mon Sep 17 00:00:00 2001 From: rdlabo Date: Thu, 1 Oct 2026 15:03:40 +0900 Subject: [PATCH 1/2] fix: preserve vertical alignment for horizontal popovers --- src/popover/utils.spec.ts | 5 +++++ src/popover/utils.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/popover/utils.spec.ts b/src/popover/utils.spec.ts index cd7a117..a2385af 100644 --- a/src/popover/utils.spec.ts +++ b/src/popover/utils.spec.ts @@ -3,6 +3,11 @@ import { describe, expect, it } from 'vitest'; import { calculateWindowAdjustment, getIndexOfItem, getNextItem, getPopoverPosition, getPrevItem } from './utils.js'; describe('popover utilities', () => { + it.each(['left', 'right', 'start', 'end'] as const)('preserves the vertical anchor alignment for side=%s', (side) => { + const position = calculateWindowAdjustment(side, 120, 100, 5, 440, 636, 200, 52, 8, 'right', 'center'); + expect(position.top).toBe(120); + }); + it('navigates only relative to ion-item elements', () => { const items = [document.createElement('ion-item'), document.createElement('ion-item')] as HTMLIonItemElement[]; diff --git a/src/popover/utils.ts b/src/popover/utils.ts index ed30ce9..248ea42 100644 --- a/src/popover/utils.ts +++ b/src/popover/utils.ts @@ -616,7 +616,8 @@ export const calculateWindowAdjustment = ( const triggerTop = triggerCoordinates ? triggerCoordinates.top + triggerCoordinates.height : bodyHeight / 2 - contentHeight / 2; const triggerHeight = triggerCoordinates ? triggerCoordinates.height : 0; let left = coordLeft; - let top = !isReplace ? coordTop + POPOVER_IOS_BODY_MARGIN : coordTop - triggerHeight; + const horizontal = side === 'left' || side === 'right' || side === 'start' || side === 'end'; + let top = !isReplace ? coordTop + (horizontal ? 0 : POPOVER_IOS_BODY_MARGIN) : coordTop - triggerHeight; let bottom; let originX = contentOriginX; let originY = contentOriginY; From a03c33d3907d47387c4309d53866a52d8aaa0e81 Mon Sep 17 00:00:00 2001 From: rdlabo Date: Thu, 1 Oct 2026 15:10:39 +0900 Subject: [PATCH 2/2] fix: keep horizontal callouts inside vertical viewport bounds --- src/popover/utils.spec.ts | 2 ++ src/popover/utils.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/src/popover/utils.spec.ts b/src/popover/utils.spec.ts index a2385af..a18137c 100644 --- a/src/popover/utils.spec.ts +++ b/src/popover/utils.spec.ts @@ -6,6 +6,8 @@ describe('popover utilities', () => { it.each(['left', 'right', 'start', 'end'] as const)('preserves the vertical anchor alignment for side=%s', (side) => { const position = calculateWindowAdjustment(side, 120, 100, 5, 440, 636, 200, 52, 8, 'right', 'center'); expect(position.top).toBe(120); + expect(calculateWindowAdjustment(side, -4, 100, 5, 440, 636, 200, 52, 8, 'right', 'center').top).toBe(5); + expect(calculateWindowAdjustment(side, 620, 100, 5, 440, 636, 200, 52, 8, 'right', 'center').top).toBe(579); }); it('navigates only relative to ion-item elements', () => { diff --git a/src/popover/utils.ts b/src/popover/utils.ts index 248ea42..5700079 100644 --- a/src/popover/utils.ts +++ b/src/popover/utils.ts @@ -618,6 +618,7 @@ export const calculateWindowAdjustment = ( let left = coordLeft; const horizontal = side === 'left' || side === 'right' || side === 'start' || side === 'end'; let top = !isReplace ? coordTop + (horizontal ? 0 : POPOVER_IOS_BODY_MARGIN) : coordTop - triggerHeight; + if (horizontal && !isReplace) top = Math.max(bodyPadding, Math.min(top, bodyHeight - bodyPadding - contentHeight)); let bottom; let originX = contentOriginX; let originY = contentOriginY;