Merge branch 'disjointed-popovers' into shigusegubu-vue3
* disjointed-popovers: add stay-on-click prop to solve case of clicking user avatar in status popover fix settings tooltips vertical nudge for popovers, especially for overlay-centers ones
This commit is contained in:
commit
84f2074ea4
5 changed files with 63 additions and 17 deletions
|
@ -40,7 +40,10 @@ const Popover = {
|
||||||
overlayCenters: Boolean,
|
overlayCenters: Boolean,
|
||||||
|
|
||||||
// What selector (witin popover!) to use for determining center of popover
|
// What selector (witin popover!) to use for determining center of popover
|
||||||
overlayCentersSelector: String
|
overlayCentersSelector: String,
|
||||||
|
|
||||||
|
// Lets hover popover stay when clicking inside of it
|
||||||
|
stayOnClick: Boolean
|
||||||
},
|
},
|
||||||
inject: ['popoversZLayer'], // override popover z layer
|
inject: ['popoversZLayer'], // override popover z layer
|
||||||
data () {
|
data () {
|
||||||
|
@ -50,6 +53,7 @@ const Popover = {
|
||||||
// with popovers refusing to be hidden when user wants to interact with something in below popover
|
// with popovers refusing to be hidden when user wants to interact with something in below popover
|
||||||
lockReEntry: false,
|
lockReEntry: false,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
pinned: false,
|
||||||
styles: {},
|
styles: {},
|
||||||
oldSize: { width: 0, height: 0 },
|
oldSize: { width: 0, height: 0 },
|
||||||
scrollable: null,
|
scrollable: null,
|
||||||
|
@ -124,13 +128,17 @@ const Popover = {
|
||||||
const leftInnerOffset = overlayCenterScreenBox.left - box.left
|
const leftInnerOffset = overlayCenterScreenBox.left - box.left
|
||||||
const topInnerOffset = overlayCenterScreenBox.top - box.top
|
const topInnerOffset = overlayCenterScreenBox.top - box.top
|
||||||
horizOffset = -leftInnerOffset - overlayCenter.offsetWidth * 0.5
|
horizOffset = -leftInnerOffset - overlayCenter.offsetWidth * 0.5
|
||||||
vertOffset = -topInnerOffset - overlayCenter.offsetWidth * 0.5
|
vertOffset = -topInnerOffset - overlayCenter.offsetHeight * 0.5
|
||||||
} else {
|
} else {
|
||||||
horizOffset = content.offsetWidth * -0.5
|
horizOffset = content.offsetWidth * -0.5
|
||||||
vertOffset = content.offsetWidth * -0.5
|
vertOffset = content.offsetHeight * -0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
const leftBorder = origin.x + horizOffset
|
const leftBorder = origin.x + horizOffset
|
||||||
const rightBorder = origin.x - horizOffset
|
const rightBorder = leftBorder + content.offsetWidth
|
||||||
|
const topBorder = origin.y + vertOffset
|
||||||
|
const bottomBorder = topBorder + content.offsetHeight
|
||||||
|
|
||||||
// If overflowing from left, move it so that it doesn't
|
// If overflowing from left, move it so that it doesn't
|
||||||
if (leftBorder < xBounds.min) {
|
if (leftBorder < xBounds.min) {
|
||||||
horizOffset += xBounds.min - leftBorder
|
horizOffset += xBounds.min - leftBorder
|
||||||
|
@ -141,6 +149,16 @@ const Popover = {
|
||||||
horizOffset -= rightBorder - xBounds.max
|
horizOffset -= rightBorder - xBounds.max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If overflowing from top, move it so that it doesn't
|
||||||
|
if (topBorder < yBounds.min) {
|
||||||
|
vertOffset += yBounds.min - topBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// If overflowing from bottom, move it so that it doesn't
|
||||||
|
if (bottomBorder > yBounds.max) {
|
||||||
|
vertOffset -= bottomBorder - yBounds.max
|
||||||
|
}
|
||||||
|
|
||||||
let translateX = 0
|
let translateX = 0
|
||||||
let translateY = 0
|
let translateY = 0
|
||||||
|
|
||||||
|
@ -182,9 +200,10 @@ const Popover = {
|
||||||
},
|
},
|
||||||
showPopover () {
|
showPopover () {
|
||||||
if (this.disabled) return
|
if (this.disabled) return
|
||||||
|
this.pinned = false
|
||||||
const wasHidden = this.hidden
|
const wasHidden = this.hidden
|
||||||
this.hidden = false
|
this.hidden = false
|
||||||
if (this.trigger === 'click') {
|
if (this.trigger === 'click' || this.stayOnClick) {
|
||||||
document.addEventListener('click', this.onClickOutside)
|
document.addEventListener('click', this.onClickOutside)
|
||||||
}
|
}
|
||||||
this.scrollable.addEventListener('scroll', this.onScroll)
|
this.scrollable.addEventListener('scroll', this.onScroll)
|
||||||
|
@ -213,7 +232,7 @@ const Popover = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMouseleave (e) {
|
onMouseleave (e) {
|
||||||
if (this.trigger === 'hover') {
|
if (this.trigger === 'hover' && !this.pinned) {
|
||||||
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
|
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -226,7 +245,7 @@ const Popover = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onMouseleaveContent (e) {
|
onMouseleaveContent (e) {
|
||||||
if (this.trigger === 'hover') {
|
if (this.trigger === 'hover' && !this.pinned) {
|
||||||
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
|
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -245,6 +264,11 @@ const Popover = {
|
||||||
if (this.$el.contains(e.target)) return
|
if (this.$el.contains(e.target)) return
|
||||||
this.hidePopover()
|
this.hidePopover()
|
||||||
},
|
},
|
||||||
|
onClickContent (e) {
|
||||||
|
if (this.trigger === 'hover' && this.stayOnClick) {
|
||||||
|
this.pinned = true
|
||||||
|
}
|
||||||
|
},
|
||||||
onScroll (e) {
|
onScroll (e) {
|
||||||
this.updateStyles()
|
this.updateStyles()
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,12 +21,22 @@
|
||||||
:class="popoverClass || 'popover-default'"
|
:class="popoverClass || 'popover-default'"
|
||||||
@mouseenter="onMouseenterContent"
|
@mouseenter="onMouseenterContent"
|
||||||
@mouseleave="onMouseleaveContent"
|
@mouseleave="onMouseleaveContent"
|
||||||
|
@click="onClickContent"
|
||||||
>
|
>
|
||||||
<slot
|
<slot
|
||||||
name="content"
|
name="content"
|
||||||
class="popover-inner"
|
class="popover-inner"
|
||||||
:close="hidePopover"
|
:close="hidePopover"
|
||||||
/>
|
/>
|
||||||
|
<div
|
||||||
|
v-if="stayOnClick && pinned"
|
||||||
|
class="pinned-tooltip-icon popover popover-default"
|
||||||
|
>
|
||||||
|
<FAIcon
|
||||||
|
icon="thumbtack"
|
||||||
|
class="faint"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</teleport>
|
</teleport>
|
||||||
|
@ -51,6 +61,17 @@
|
||||||
box-shadow: var(--popupShadow);
|
box-shadow: var(--popupShadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pinned-tooltip-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: -1em;
|
||||||
|
left: -1em;
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.popover-default {
|
.popover-default {
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
|
@ -41,11 +41,11 @@ export default {
|
||||||
.ModifiedIndicator {
|
.ModifiedIndicator {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.modified-tooltip {
|
.modified-tooltip {
|
||||||
margin: 0.5em 1em;
|
margin: 0.5em 1em;
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -41,11 +41,11 @@ export default {
|
||||||
.ServerSideIndicator {
|
.ServerSideIndicator {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
.serverside-tooltip {
|
.serverside-tooltip {
|
||||||
margin: 0.5em 1em;
|
margin: 0.5em 1em;
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<Popover
|
<Popover
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
|
:stay-on-click="true"
|
||||||
popover-class="popover-default status-popover"
|
popover-class="popover-default status-popover"
|
||||||
:bound-to="{ x: 'container' }"
|
:bound-to="{ x: 'container' }"
|
||||||
@show="enter"
|
@show="enter"
|
||||||
|
|
Loading…
Add table
Reference in a new issue