Skip to content

Commit

Permalink
fix: handle relative html offset clipping rect (#3097)
Browse files Browse the repository at this point in the history
  • Loading branch information
atomiks authored Oct 30, 2024
1 parent dcca804 commit d93e718
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-humans-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@floating-ui/dom": patch
---

fix: handle relative html offset clipping rect
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {

import {getBoundingClientRect} from '../utils/getBoundingClientRect';
import {getScale} from './getScale';
import {getHTMLOffset} from '../utils/getHTMLOffset';

export function convertOffsetParentRelativeRectToViewportRelativeRect({
elements,
Expand Down Expand Up @@ -52,10 +53,16 @@ export function convertOffsetParentRelativeRectToViewportRelativeRect({
}
}

const htmlOffset =
documentElement && !isOffsetParentAnElement && !isFixed
? getHTMLOffset(documentElement, scroll, true)
: createCoords(0);

return {
width: rect.width * scale.x,
height: rect.height * scale.y,
x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y,
x:
rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,
y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y,
};
}
23 changes: 23 additions & 0 deletions packages/dom/src/utils/getHTMLOffset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {NodeScroll} from '../types';
import {getWindowScrollBarX} from './getWindowScrollBarX';

export function getHTMLOffset(
documentElement: HTMLElement,
scroll: NodeScroll,
ignoreScrollbarX = false,
) {
const htmlRect = documentElement.getBoundingClientRect();
const x =
htmlRect.left +
scroll.scrollLeft -
(ignoreScrollbarX
? 0
: // RTL <body> scrollbar.
getWindowScrollBarX(documentElement, htmlRect));
const y = htmlRect.top + scroll.scrollTop;

return {
x,
y,
};
}
21 changes: 7 additions & 14 deletions packages/dom/src/utils/getRectRelativeToOffsetParent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {VirtualElement} from '../types';
import {getDocumentElement} from '../platform/getDocumentElement';
import {getBoundingClientRect} from './getBoundingClientRect';
import {getWindowScrollBarX} from './getWindowScrollBarX';
import {getHTMLOffset} from './getHTMLOffset';

export function getRectRelativeToOffsetParent(
element: Element | VirtualElement,
Expand Down Expand Up @@ -49,21 +50,13 @@ export function getRectRelativeToOffsetParent(
}
}

let htmlX = 0;
let htmlY = 0;
const htmlOffset =
documentElement && !isOffsetParentAnElement && !isFixed
? getHTMLOffset(documentElement, scroll)
: createCoords(0);

if (documentElement && !isOffsetParentAnElement && !isFixed) {
const htmlRect = documentElement.getBoundingClientRect();
htmlY = htmlRect.top + scroll.scrollTop;
htmlX =
htmlRect.left +
scroll.scrollLeft -
// RTL <body> scrollbar.
getWindowScrollBarX(documentElement, htmlRect);
}

const x = rect.left + scroll.scrollLeft - offsets.x - htmlX;
const y = rect.top + scroll.scrollTop - offsets.y - htmlY;
const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;

return {
x,
Expand Down

0 comments on commit d93e718

Please sign in to comment.