Skip to content

Commit 9a0c7c1

Browse files
committed
Use absolute positioning only when iOS virtual keyboard is present
1 parent ef671e1 commit 9a0c7c1

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/internal/components/dropdown/index.tsx

+21-9
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,20 @@ const Dropdown = ({
233233

234234
// Position normal overflow dropdowns with fixed positioning relative to viewport
235235
if (expandToViewport && !interior) {
236-
target.style.position = 'absolute';
236+
const isIOSVirtualKeyboardPresent =
237+
window.visualViewport?.height && window.visualViewport.height < window.innerHeight;
238+
target.style.position = isIOSVirtualKeyboardPresent ? 'absolute' : 'fixed';
239+
const verticalScrollOffset = isIOSVirtualKeyboardPresent ? document.documentElement.scrollTop : 0;
240+
const horizontalScrollOffset = isIOSVirtualKeyboardPresent ? document.documentElement.scrollLeft : 0;
237241
if (position.dropBlockStart) {
238-
target.style.insetBlockEnd = `calc(100% - ${document.documentElement.scrollTop + triggerBox.top}px)`;
242+
target.style.insetBlockEnd = `calc(100% - ${verticalScrollOffset + triggerBox.top}px)`;
239243
} else {
240-
target.style.insetBlockStart = `${document.documentElement.scrollTop + triggerBox.bottom}px`;
244+
target.style.insetBlockStart = `${verticalScrollOffset + triggerBox.bottom}px`;
241245
}
242246
if (position.dropInlineStart) {
243-
target.style.insetInlineStart = `calc(${triggerBox.right}px - ${position.inlineSize})`;
247+
target.style.insetInlineStart = `calc(${horizontalScrollOffset + triggerBox.right}px - ${position.inlineSize})`;
244248
} else {
245-
target.style.insetInlineStart = `${triggerBox.left}px`;
249+
target.style.insetInlineStart = `${horizontalScrollOffset + triggerBox.left}px`;
246250
}
247251
// Keep track of the initial dropdown position and direction.
248252
// Dropdown direction doesn't need to change as the user scrolls, just needs to stay attached to the trigger.
@@ -391,18 +395,26 @@ const Dropdown = ({
391395
}
392396
const updateDropdownPosition = () => {
393397
if (triggerRef.current && dropdownRef.current && verticalContainerRef.current) {
398+
const isIOSVirtualKeyboardPresent =
399+
window.visualViewport?.height && window.visualViewport.height < window.innerHeight;
400+
401+
dropdownRef.current.style.position = isIOSVirtualKeyboardPresent ? 'absolute' : 'fixed';
402+
403+
const verticalScrollOffset = isIOSVirtualKeyboardPresent ? document.documentElement.scrollTop : 0;
404+
const horizontalScrollOffset = isIOSVirtualKeyboardPresent ? document.documentElement.scrollLeft : 0;
405+
394406
const triggerRect = getLogicalBoundingClientRect(triggerRef.current);
395407
const target = dropdownRef.current;
396408
if (fixedPosition.current) {
397409
if (fixedPosition.current.dropBlockStart) {
398-
dropdownRef.current.style.insetBlockEnd = `calc(100% - ${document.documentElement.scrollTop + triggerRect.insetBlockStart}px)`;
410+
dropdownRef.current.style.insetBlockEnd = `calc(100% - ${verticalScrollOffset + triggerRect.insetBlockStart}px)`;
399411
} else {
400-
target.style.insetBlockStart = `${document.documentElement.scrollTop + triggerRect.insetBlockEnd}px`;
412+
target.style.insetBlockStart = `${verticalScrollOffset + triggerRect.insetBlockEnd}px`;
401413
}
402414
if (fixedPosition.current.dropInlineStart) {
403-
target.style.insetInlineStart = `calc(${triggerRect.insetInlineEnd}px - ${fixedPosition.current.inlineSize})`;
415+
target.style.insetInlineStart = `calc(${horizontalScrollOffset + triggerRect.insetInlineEnd}px - ${fixedPosition.current.inlineSize})`;
404416
} else {
405-
target.style.insetInlineStart = `${triggerRect.insetInlineStart}px`;
417+
target.style.insetInlineStart = `${horizontalScrollOffset + triggerRect.insetInlineStart}px`;
406418
}
407419
}
408420
}

0 commit comments

Comments
 (0)