Skip to content

Commit d7b7cf2

Browse files
authored
fix: offsetX/Y on shift logic (#418)
* fix: popupOffset logic * test: add test case
1 parent b6c9af3 commit d7b7cf2

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

docs/examples/inside.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ export const builtinPlacements: BuildInPlacements = {
2323
points: ['bl', 'tl'],
2424
overflow: {
2525
adjustX: true,
26-
adjustY: true,
26+
adjustY: false,
27+
shiftY: true,
2728
},
28-
offset: [0, 0],
29+
offset: [0, -20],
2930
...experimentalConfig,
3031
},
3132
topRight: {
@@ -82,9 +83,19 @@ export const builtinPlacements: BuildInPlacements = {
8283
offset: [0, 0],
8384
...experimentalConfig,
8485
},
86+
bottomLeft: {
87+
points: ['tl', 'bl'],
88+
overflow: {
89+
shiftX: 50,
90+
adjustY: true,
91+
shiftY: true,
92+
},
93+
offset: [0, 20],
94+
...experimentalConfig,
95+
},
8596
};
8697

87-
const popupPlacement = 'top';
98+
const popupPlacement = 'bottomLeft';
8899

89100
export default () => {
90101
const [popupHeight, setPopupHeight] = React.useState(60);

src/hooks/useAlign.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ export default function useAlign(
287287

288288
// Offset
289289
const { offset, targetOffset } = placementInfo;
290-
const [popupOffsetX, popupOffsetY] = getNumberOffset(popupRect, offset);
290+
let [popupOffsetX, popupOffsetY] = getNumberOffset(popupRect, offset);
291291
const [targetOffsetX, targetOffsetY] = getNumberOffset(
292292
targetRect,
293293
targetOffset,
@@ -417,6 +417,7 @@ export default function useAlign(
417417
) {
418418
prevFlipRef.current.bt = true;
419419
nextOffsetY = tmpNextOffsetY;
420+
popupOffsetY = -popupOffsetY;
420421

421422
nextAlignInfo.points = [
422423
reversePoints(popupPoints, 0),
@@ -462,6 +463,7 @@ export default function useAlign(
462463
) {
463464
prevFlipRef.current.tb = true;
464465
nextOffsetY = tmpNextOffsetY;
466+
popupOffsetY = -popupOffsetY;
465467

466468
nextAlignInfo.points = [
467469
reversePoints(popupPoints, 0),
@@ -514,6 +516,7 @@ export default function useAlign(
514516
) {
515517
prevFlipRef.current.rl = true;
516518
nextOffsetX = tmpNextOffsetX;
519+
popupOffsetX = -popupOffsetX;
517520

518521
nextAlignInfo.points = [
519522
reversePoints(popupPoints, 1),
@@ -559,6 +562,7 @@ export default function useAlign(
559562
) {
560563
prevFlipRef.current.lr = true;
561564
nextOffsetX = tmpNextOffsetX;
565+
popupOffsetX = -popupOffsetX;
562566

563567
nextAlignInfo.points = [
564568
reversePoints(popupPoints, 1),
@@ -576,7 +580,7 @@ export default function useAlign(
576580
if (typeof numShiftX === 'number') {
577581
// Left
578582
if (nextPopupX < visibleRegionArea.left) {
579-
nextOffsetX -= nextPopupX - visibleRegionArea.left;
583+
nextOffsetX -= nextPopupX - visibleRegionArea.left - popupOffsetX;
580584

581585
if (targetRect.x + targetWidth < visibleRegionArea.left + numShiftX) {
582586
nextOffsetX +=
@@ -586,7 +590,8 @@ export default function useAlign(
586590

587591
// Right
588592
if (nextPopupRight > visibleRegionArea.right) {
589-
nextOffsetX -= nextPopupRight - visibleRegionArea.right;
593+
nextOffsetX -=
594+
nextPopupRight - visibleRegionArea.right - popupOffsetX;
590595

591596
if (targetRect.x > visibleRegionArea.right - numShiftX) {
592597
nextOffsetX += targetRect.x - visibleRegionArea.right + numShiftX;
@@ -598,8 +603,10 @@ export default function useAlign(
598603
if (typeof numShiftY === 'number') {
599604
// Top
600605
if (nextPopupY < visibleRegionArea.top) {
601-
nextOffsetY -= nextPopupY - visibleRegionArea.top + popupOffsetY;
606+
nextOffsetY -= nextPopupY - visibleRegionArea.top - popupOffsetY;
602607

608+
// When target if far away from visible area
609+
// Stop shift
603610
if (targetRect.y + targetHeight < visibleRegionArea.top + numShiftY) {
604611
nextOffsetY +=
605612
targetRect.y - visibleRegionArea.top + targetHeight - numShiftY;
@@ -608,7 +615,8 @@ export default function useAlign(
608615

609616
// Bottom
610617
if (nextPopupBottom > visibleRegionArea.bottom) {
611-
nextOffsetY -= nextPopupBottom - visibleRegionArea.bottom - popupOffsetY;
618+
nextOffsetY -=
619+
nextPopupBottom - visibleRegionArea.bottom - popupOffsetY;
612620

613621
if (targetRect.y > visibleRegionArea.bottom - numShiftY) {
614622
nextOffsetY += targetRect.y - visibleRegionArea.bottom + numShiftY;

tests/flipShift.test.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,36 @@ describe('Trigger.Flip+Shift', () => {
190190
left: '-900px',
191191
});
192192
});
193+
194+
// https://github.com/ant-design/ant-design/issues/44096
195+
// Note: Safe to modify `top` style compare if refactor
196+
it('flip not shake by offset with shift', async () => {
197+
spanRect.y = -1000;
198+
199+
render(
200+
<Trigger
201+
popupVisible
202+
popupAlign={{
203+
points: ['tl', 'bl'],
204+
overflow: {
205+
adjustY: true,
206+
shiftY: true,
207+
},
208+
offset: [0, 33],
209+
}}
210+
popup={<strong>trigger</strong>}
211+
>
212+
<span className="target" />
213+
</Trigger>,
214+
);
215+
216+
await act(async () => {
217+
await Promise.resolve();
218+
});
219+
220+
// Just need check left < 0
221+
expect(document.querySelector('.rc-trigger-popup')).toHaveStyle({
222+
top: '-867px',
223+
});
224+
});
193225
});

0 commit comments

Comments
 (0)