properly center user popovers

This commit is contained in:
Henry Jameson 2022-06-15 03:50:57 +03:00
parent 7c633aa952
commit d3b5d27f29
1 changed files with 40 additions and 28 deletions

View File

@ -79,9 +79,10 @@ const Popover = {
x: anchorScreenBox.left + anchorWidth * 0.5, x: anchorScreenBox.left + anchorWidth * 0.5,
y: anchorScreenBox.top + anchorHeight * 0.5 y: anchorScreenBox.top + anchorHeight * 0.5
} }
const content = this.overlayCentersSelector const content = this.$refs.content
const overlayCenter = this.overlayCentersSelector
? this.$refs.content.querySelector(this.overlayCentersSelector) ? this.$refs.content.querySelector(this.overlayCentersSelector)
: this.$refs.content : null
// Minor optimization, don't call a slow reflow call if we don't have to // Minor optimization, don't call a slow reflow call if we don't have to
const parentScreenBox = this.boundTo && const parentScreenBox = this.boundTo &&
@ -108,8 +109,20 @@ const Popover = {
max: window.innerHeight - (margin.bottom || 5) max: window.innerHeight - (margin.bottom || 5)
} }
if (!this.overlayCenters) { let horizOffset = 0
let horizOffset = content.offsetWidth * -0.5 let vertOffset = 0
if (overlayCenter) {
const box = content.getBoundingClientRect()
const overlayCenterScreenBox = overlayCenter.getBoundingClientRect()
const leftInnerOffset = overlayCenterScreenBox.left - box.left
const topInnerOffset = overlayCenterScreenBox.top - box.top
horizOffset = -leftInnerOffset - overlayCenter.offsetWidth * 0.5
vertOffset = -topInnerOffset - overlayCenter.offsetWidth * 0.5
} else {
horizOffset = content.offsetWidth * -0.5
vertOffset = content.offsetWidth * -0.5
}
const leftBorder = origin.x + horizOffset const leftBorder = origin.x + horizOffset
const rightBorder = origin.x - horizOffset const rightBorder = origin.x - horizOffset
// If overflowing from left, move it so that it doesn't // If overflowing from left, move it so that it doesn't
@ -122,6 +135,13 @@ const Popover = {
horizOffset -= rightBorder - xBounds.max horizOffset -= rightBorder - xBounds.max
} }
let translateX = 0
let translateY = 0
if (overlayCenter) {
translateX = origin.x + horizOffset
translateY = origin.y + vertOffset
} else {
// Default to whatever user wished with placement prop // Default to whatever user wished with placement prop
let usingTop = this.placement !== 'bottom' let usingTop = this.placement !== 'bottom'
@ -134,26 +154,18 @@ const Popover = {
if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false
const yOffset = (this.offset && this.offset.y) || 0 const yOffset = (this.offset && this.offset.y) || 0
const translateY = usingTop translateY = usingTop
? topBoundary - yOffset - content.offsetHeight ? topBoundary - yOffset - content.offsetHeight
: bottomBoundary + yOffset : bottomBoundary + yOffset
const xOffset = (this.offset && this.offset.x) || 0 const xOffset = (this.offset && this.offset.x) || 0
const translateX = origin.x + horizOffset + xOffset translateX = origin.x + horizOffset + xOffset
}
this.styles = { this.styles = {
left: `${Math.round(translateX)}px`, left: `${Math.round(translateX)}px`,
top: `${Math.round(translateY)}px` top: `${Math.round(translateY)}px`
} }
} else {
const translateY = origin.y - content.offsetHeight
const translateX = origin.x - content.offsetWidth
this.styles = {
left: `${Math.round(translateX)}px`,
top: `${Math.round(translateY)}px`
}
}
if (parentScreenBox) { if (parentScreenBox) {
this.styles.maxWidth = `${Math.round(parentScreenBox.width)}px` this.styles.maxWidth = `${Math.round(parentScreenBox.width)}px`