Skip to content

Commit

Permalink
fix: correct flip (#349)
Browse files Browse the repository at this point in the history
* fix: correct flip

* chore: fix lint

* chore: optimize test

* chore: optimize test

* chore: add test

* chore: update

* chore: update

* test: merge test case

* chore: rename

* chore: merge naming

* chore: merge master

* chore: merge master

---------

Co-authored-by: 二货机器人 <smith3816@gmail.com>
  • Loading branch information
acyza and zombieJ authored Apr 4, 2023
1 parent a699a1d commit 0336525
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 12 deletions.
15 changes: 9 additions & 6 deletions src/hooks/useAlign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,16 +269,19 @@ export default function useAlign(

// ============== Intersection ===============
// Get area by position. Used for check if flip area is better
function getIntersectionVisibleArea(x: number, y: number) {
const r = x + popupWidth;
const b = y + popupHeight;
function getIntersectionVisibleArea(offsetX: number, offsetY: number) {
const l = popupRect.x + offsetX;
const t = popupRect.y + offsetY;

const visibleX = Math.max(x, visibleArea.left);
const visibleY = Math.max(y, visibleArea.top);
const r = l + popupWidth;
const b = t + popupHeight;

const visibleL = Math.max(l, visibleArea.left);
const visibleT = Math.max(t, visibleArea.top);
const visibleR = Math.min(r, visibleArea.right);
const visibleB = Math.min(b, visibleArea.bottom);

return (visibleR - visibleX) * (visibleB - visibleY);
return (visibleR - visibleL) * (visibleB - visibleT);
}

const originIntersectionVisibleArea = getIntersectionVisibleArea(
Expand Down
95 changes: 89 additions & 6 deletions tests/flip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ describe('Trigger.Align', () => {
height: 1,
};

let popupRect = {
x: 0,
y: 0,
width: 100,
height: 100,
};

beforeAll(() => {
spyElementPrototypes(HTMLElement, {
clientWidth: {
Expand All @@ -53,12 +60,7 @@ describe('Trigger.Align', () => {

spyElementPrototypes(HTMLDivElement, {
getBoundingClientRect() {
return {
x: 0,
y: 0,
width: 100,
height: 100,
};
return popupRect;
},
});

Expand All @@ -82,6 +84,12 @@ describe('Trigger.Align', () => {
width: 1,
height: 1,
};
popupRect = {
x: 0,
y: 0,
width: 100,
height: 100,
};
jest.useFakeTimers();
});

Expand Down Expand Up @@ -187,4 +195,79 @@ describe('Trigger.Align', () => {
});
});
});

// `getPopupContainer` sometime makes the popup 0/0 not start at left top.
// We need cal the real visible position
/*
*******************
* Target *
* *************
* * Popup *
* *************
* *
*******************
To:
*******************
* Target *
* ************* *
* * Popup * *
* ************* *
* *
*******************
*/
it('popup start position not at left top', async () => {
spanRect.x = 99;
spanRect.y = 0;

popupRect = {
x: 100,
y: 1,
width: 100,
height: 100,
};

render(
<Trigger
popupVisible
popupPlacement="topLeft"
builtinPlacements={{
topLeft: {
points: ['tl', 'bl'],
overflow: {
adjustX: true,
adjustY: true,
},
},
topRight: {
points: ['tr', 'br'],
overflow: {
adjustX: true,
adjustY: true,
},
},
}}
popup={<strong>trigger</strong>}
>
<span className="target" />
</Trigger>,
);

await act(async () => {
await Promise.resolve();
});

// Flip
expect(
document.querySelector('.rc-trigger-popup-placement-topRight'),
).toBeTruthy();

expect(document.querySelector('.rc-trigger-popup')).toHaveStyle({
left: `-100px`, // (left: 100) - (offset: 100) = 0
top: `0px`,
});
});
});

0 comments on commit 0336525

Please sign in to comment.