mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
ee0ac00f80
When using accessibility tools like screen magnifiers, dynamic screen content can be quite problematic. In particular content, which only appears if you interact with elements somewhere else on the screen. That is the case, for example, with the current implementation of tooltips used by audiobookshelf. This patch provides a slight adjustment, keeping the tooltips open if you hover over them. This allows users to have better access to the content.
126 lines
3.3 KiB
Vue
126 lines
3.3 KiB
Vue
<template>
|
|
<div ref="box" @mouseover="mouseover" @mouseleave="mouseleave">
|
|
<slot />
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
text: {
|
|
type: [String, Number],
|
|
required: true
|
|
},
|
|
direction: {
|
|
type: String,
|
|
default: 'right'
|
|
},
|
|
disabled: Boolean
|
|
},
|
|
data() {
|
|
return {
|
|
tooltip: null,
|
|
tooltipId: null,
|
|
isShowing: false,
|
|
hideTimeout: null
|
|
}
|
|
},
|
|
watch: {
|
|
text() {
|
|
this.updateText()
|
|
},
|
|
disabled(newVal) {
|
|
if (newVal && this.isShowing) {
|
|
this.hideTooltip()
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
updateText() {
|
|
if (this.tooltip) {
|
|
this.tooltip.innerHTML = this.text
|
|
this.setTooltipPosition(this.tooltip)
|
|
}
|
|
},
|
|
createTooltip() {
|
|
if (!this.$refs.box) return
|
|
var tooltip = document.createElement('div')
|
|
this.tooltipId = String(Math.floor(Math.random() * 10000))
|
|
tooltip.id = this.tooltipId
|
|
tooltip.className = 'tooltip-wrapper absolute px-2 py-1 text-white text-xs rounded shadow-lg max-w-xs text-center hidden sm:block'
|
|
tooltip.style.zIndex = 100
|
|
tooltip.style.backgroundColor = 'rgba(0,0,0,0.85)'
|
|
tooltip.innerHTML = this.text
|
|
tooltip.addEventListener('mouseover', this.cancelHide);
|
|
tooltip.addEventListener('mouseleave', this.hideTooltip);
|
|
|
|
this.setTooltipPosition(tooltip)
|
|
|
|
this.tooltip = tooltip
|
|
},
|
|
setTooltipPosition(tooltip) {
|
|
var boxChow = this.$refs.box.getBoundingClientRect()
|
|
|
|
var shouldMount = !tooltip.isConnected
|
|
// Calculate size of tooltip
|
|
if (shouldMount) document.body.appendChild(tooltip)
|
|
var { width, height } = tooltip.getBoundingClientRect()
|
|
if (shouldMount) tooltip.remove()
|
|
|
|
var top = 0
|
|
var left = 0
|
|
if (this.direction === 'right') {
|
|
top = boxChow.top - height / 2 + boxChow.height / 2
|
|
left = boxChow.left + boxChow.width + 4
|
|
} else if (this.direction === 'bottom') {
|
|
top = boxChow.top + boxChow.height + 4
|
|
left = boxChow.left - width / 2 + boxChow.width / 2
|
|
} else if (this.direction === 'top') {
|
|
top = boxChow.top - height - 4
|
|
left = boxChow.left - width / 2 + boxChow.width / 2
|
|
} else if (this.direction === 'left') {
|
|
top = boxChow.top - height / 2 + boxChow.height / 2
|
|
left = boxChow.left - width - 4
|
|
}
|
|
tooltip.style.top = top + 'px'
|
|
tooltip.style.left = left + 'px'
|
|
},
|
|
showTooltip() {
|
|
if (this.disabled) return
|
|
if (!this.tooltip) {
|
|
this.createTooltip()
|
|
if (!this.tooltip) return
|
|
}
|
|
if (!this.$refs.box) return // Ensure element is not destroyed
|
|
try {
|
|
document.body.appendChild(this.tooltip)
|
|
this.setTooltipPosition(this.tooltip)
|
|
} catch (error) {
|
|
console.error(error)
|
|
}
|
|
|
|
this.isShowing = true
|
|
},
|
|
hideTooltip() {
|
|
if (!this.tooltip) return
|
|
this.tooltip.remove()
|
|
this.isShowing = false
|
|
},
|
|
cancelHide() {
|
|
if (this.hideTimeout) clearTimeout(this.hideTimeout);
|
|
},
|
|
mouseover() {
|
|
if (!this.isShowing) this.showTooltip()
|
|
},
|
|
mouseleave() {
|
|
if (this.isShowing) {
|
|
this.hideTimeout = setTimeout(this.hideTooltip, 100)
|
|
}
|
|
}
|
|
},
|
|
beforeDestroy() {
|
|
this.hideTooltip()
|
|
}
|
|
}
|
|
</script>
|