Skip to content

Commit 60d6e42

Browse files
committed
#67 Auto adjust placement enhance
1 parent 7661e62 commit 60d6e42

File tree

2 files changed

+37
-21
lines changed

2 files changed

+37
-21
lines changed

src/docs/pages/PopoverDoc.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@
162162
},
163163
{
164164
name: 'auto-placement',
165-
desc: 'Try to auto adjust the placement if the set one does not have enough space to show. Try order: top -> right -> bottom -> left, and use the set one if none of these matched',
165+
desc: 'Try to auto adjust the placement if the set one does not have enough space to show. Try order: right -> bottom -> left -> top, and use the set one if none of these matched',
166166
type: 'Boolean',
167167
'default': 'true'
168168
},

src/utils/domUtils.js

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,28 +148,33 @@ export default {
148148
let triggerRect = trigger.getBoundingClientRect()
149149
let popupRect = popup.getBoundingClientRect()
150150
let viewPortSize = getViewportSize()
151-
let available
151+
let top = true
152+
let right = true
153+
let bottom = true
154+
let left = true
152155
switch (placement) {
153156
case PLACEMENTS.TOP:
154-
available = triggerRect.top >= popupRect.height
157+
top = triggerRect.top >= popupRect.height
158+
left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
159+
right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
155160
break
156-
case PLACEMENTS.RIGHT: {
157-
let widthAvailable = triggerRect.right + popupRect.width <= viewPortSize.width
158-
let heightAvailable = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
159-
available = widthAvailable && heightAvailable
160-
break
161-
}
162161
case PLACEMENTS.BOTTOM:
163-
available = triggerRect.bottom + popupRect.height <= viewPortSize.height
162+
bottom = triggerRect.bottom + popupRect.height <= viewPortSize.height
163+
left = triggerRect.left + triggerRect.width / 2 >= popupRect.width / 2
164+
right = triggerRect.right - triggerRect.width / 2 + popupRect.width / 2 <= viewPortSize.width
164165
break
165-
case PLACEMENTS.LEFT: {
166-
let widthAvailable = triggerRect.left - popupRect.width >= 0
167-
let heightAvailable = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
168-
available = widthAvailable && heightAvailable
166+
case PLACEMENTS.RIGHT:
167+
right = triggerRect.right + popupRect.width <= viewPortSize.width
168+
top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
169+
bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
170+
break
171+
case PLACEMENTS.LEFT:
172+
left = triggerRect.left >= popupRect.width
173+
top = triggerRect.top + triggerRect.height / 2 >= popupRect.height / 2
174+
bottom = triggerRect.bottom - triggerRect.height / 2 + popupRect.height / 2 <= viewPortSize.height
169175
break
170-
}
171176
}
172-
return available
177+
return top && right && bottom && left
173178
},
174179
setTooltipPosition (tooltip, trigger, placement, auto, appendToSelector) {
175180
let container
@@ -187,18 +192,29 @@ export default {
187192
}
188193
// auto adjust placement
189194
if (auto) {
190-
let placements = [PLACEMENTS.TOP, PLACEMENTS.RIGHT, PLACEMENTS.BOTTOM, PLACEMENTS.LEFT]
195+
// Try: right -> bottom -> left -> top
196+
// Cause the default placement is top
197+
let placements = [PLACEMENTS.RIGHT, PLACEMENTS.BOTTOM, PLACEMENTS.LEFT, PLACEMENTS.TOP]
198+
// The class switch helper function
199+
const changePlacementClass = (placement) => {
200+
// console.log(placement)
201+
placements.forEach(placement => {
202+
this.removeClass(tooltip, placement)
203+
})
204+
this.addClass(tooltip, placement)
205+
}
206+
// No need to adjust if the default placement fits
191207
if (!this.isAvailableAtPosition(trigger, tooltip, placement)) {
192208
for (let i = 0, l = placements.length; i < l; i++) {
193-
for (let j = 0; j < l; j++) {
194-
this.removeClass(tooltip, placements[j])
195-
}
196-
this.addClass(tooltip, placements[i])
209+
// Re-assign placement class
210+
changePlacementClass(placements[i])
211+
// Break if new placement fits
197212
if (this.isAvailableAtPosition(trigger, tooltip, placements[i])) {
198213
placement = placements[i]
199214
break
200215
}
201216
}
217+
changePlacementClass(placement)
202218
}
203219
}
204220
// fix left and top for tooltip

0 commit comments

Comments
 (0)