Skip to content

Commit a96e1f1

Browse files
authored
chore: not flip too much (#334)
1 parent 2df8db2 commit a96e1f1

File tree

2 files changed

+70
-11
lines changed

2 files changed

+70
-11
lines changed

docs/examples/inside.tsx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ const builtinPlacements = {
1212
},
1313
offset: [0, 0],
1414
},
15+
topLeft: {
16+
points: ['bl', 'tl'],
17+
overflow: {
18+
adjustX: true,
19+
adjustY: true,
20+
},
21+
offset: [0, 0],
22+
},
23+
topRight: {
24+
points: ['br', 'tr'],
25+
overflow: {
26+
adjustX: true,
27+
adjustY: true,
28+
},
29+
offset: [0, 0],
30+
},
1531
left: {
1632
points: ['cr', 'cl'],
1733
overflow: {
@@ -20,6 +36,22 @@ const builtinPlacements = {
2036
},
2137
offset: [0, 0],
2238
},
39+
leftTop: {
40+
points: ['tr', 'tl'],
41+
overflow: {
42+
adjustX: true,
43+
adjustY: true,
44+
},
45+
offset: [0, 0],
46+
},
47+
leftBottom: {
48+
points: ['br', 'bl'],
49+
overflow: {
50+
adjustX: true,
51+
adjustY: true,
52+
},
53+
offset: [0, 0],
54+
},
2355
right: {
2456
points: ['cl', 'cr'],
2557
overflow: {
@@ -38,7 +70,7 @@ const builtinPlacements = {
3870
},
3971
};
4072

41-
const popupPlacement = 'top';
73+
const popupPlacement = 'leftBottom';
4274

4375
export default () => {
4476
const containerRef = React.useRef<HTMLDivElement>();

src/hooks/useAlign.ts

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ export default function useAlign(
166166
const popupHeight = popupRect.height;
167167
const popupWidth = popupRect.width;
168168

169+
const targetHeight = targetRect.height;
170+
const targetWidth = targetRect.width;
171+
169172
// Get bounding of visible area
170173
const visibleArea =
171174
placementInfo.htmlRegion === 'scroll'
@@ -274,13 +277,20 @@ export default function useAlign(
274277

275278
const needAdjustY = supportAdjust(adjustY);
276279

280+
const sameTB = popupPoints[0] === targetPoints[0];
281+
277282
// Bottom to Top
278283
if (
279284
needAdjustY &&
280285
popupPoints[0] === 't' &&
281286
nextPopupBottom > visibleArea.bottom
282287
) {
283-
nextOffsetY = targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;
288+
if (sameTB) {
289+
nextOffsetY -= popupHeight - targetHeight;
290+
} else {
291+
nextOffsetY =
292+
targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;
293+
}
284294

285295
nextAlignInfo.points = [
286296
reversePoints(popupPoints, 0),
@@ -294,7 +304,12 @@ export default function useAlign(
294304
popupPoints[0] === 'b' &&
295305
nextPopupY < visibleArea.top
296306
) {
297-
nextOffsetY = targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;
307+
if (sameTB) {
308+
nextOffsetY += popupHeight - targetHeight;
309+
} else {
310+
nextOffsetY =
311+
targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;
312+
}
298313

299314
nextAlignInfo.points = [
300315
reversePoints(popupPoints, 0),
@@ -309,13 +324,20 @@ export default function useAlign(
309324
const needAdjustX = supportAdjust(adjustX);
310325

311326
// >>>>> Flip
327+
const sameLR = popupPoints[1] === targetPoints[1];
328+
312329
// Right to Left
313330
if (
314331
needAdjustX &&
315332
popupPoints[1] === 'l' &&
316333
nextPopupRight > visibleArea.right
317334
) {
318-
nextOffsetX = targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;
335+
if (sameLR) {
336+
nextOffsetX -= popupWidth - targetWidth;
337+
} else {
338+
nextOffsetX =
339+
targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;
340+
}
319341

320342
nextAlignInfo.points = [
321343
reversePoints(popupPoints, 1),
@@ -329,7 +351,12 @@ export default function useAlign(
329351
popupPoints[1] === 'r' &&
330352
nextPopupX < visibleArea.left
331353
) {
332-
nextOffsetX = targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;
354+
if (sameLR) {
355+
nextOffsetX += popupWidth - targetWidth;
356+
} else {
357+
nextOffsetX =
358+
targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;
359+
}
333360

334361
nextAlignInfo.points = [
335362
reversePoints(popupPoints, 1),
@@ -344,9 +371,9 @@ export default function useAlign(
344371
if (nextPopupX < visibleArea.left) {
345372
nextOffsetX -= nextPopupX - visibleArea.left;
346373

347-
if (targetRect.x + targetRect.width < visibleArea.left + numShiftX) {
374+
if (targetRect.x + targetWidth < visibleArea.left + numShiftX) {
348375
nextOffsetX +=
349-
targetRect.x - visibleArea.left + targetRect.width - numShiftX;
376+
targetRect.x - visibleArea.left + targetWidth - numShiftX;
350377
}
351378
}
352379

@@ -366,9 +393,9 @@ export default function useAlign(
366393
if (nextPopupY < visibleArea.top) {
367394
nextOffsetY -= nextPopupY - visibleArea.top;
368395

369-
if (targetRect.y + targetRect.height < visibleArea.top + numShiftY) {
396+
if (targetRect.y + targetHeight < visibleArea.top + numShiftY) {
370397
nextOffsetY +=
371-
targetRect.y - visibleArea.top + targetRect.height - numShiftY;
398+
targetRect.y - visibleArea.top + targetHeight - numShiftY;
372399
}
373400
}
374401

@@ -389,9 +416,9 @@ export default function useAlign(
389416
const popupBottom = popupTop + popupHeight;
390417

391418
const targetLeft = targetRect.x;
392-
const targetRight = targetLeft + targetRect.width;
419+
const targetRight = targetLeft + targetWidth;
393420
const targetTop = targetRect.y;
394-
const targetBottom = targetTop + targetRect.height;
421+
const targetBottom = targetTop + targetHeight;
395422

396423
const maxLeft = Math.max(popupLeft, targetLeft);
397424
const minRight = Math.min(popupRight, targetRight);

0 commit comments

Comments
 (0)