feat: change direction of dropdown if they cannot be fully seen

This commit is contained in:
Valentin Kaelin 2019-11-09 23:04:40 +01:00
parent 1e3e8f13da
commit a87510e998

View file

@ -2,9 +2,9 @@
<div> <div>
<!-- trigger --> <!-- trigger -->
<div <div
@mouseenter="isOpen = true" @mouseenter="showDropdown"
@mousemove="mousemove" @mousemove="mousemove"
@mouseleave="isOpen = false" @mouseleave="hideDropdown"
:aria-expanded="isOpen" :aria-expanded="isOpen"
aria-haspopup="true" aria-haspopup="true"
> >
@ -14,6 +14,7 @@
<!-- dropdown content --> <!-- dropdown content -->
<div <div
v-show="isOpen" v-show="isOpen"
ref="content"
class="fixed z-40 bg-blue-1000 py-2 rounded-md shadow" class="fixed z-40 bg-blue-1000 py-2 rounded-md shadow"
:style="{ width, ...position }" :style="{ width, ...position }"
> >
@ -25,10 +26,6 @@
<script> <script>
export default { export default {
props: { props: {
openMethod: {
type: String,
default: 'click'
},
width: { width: {
type: String, type: String,
default: 'auto' default: 'auto'
@ -40,23 +37,58 @@ export default {
isOpen: false, isOpen: false,
left: 0, left: 0,
offset: 12, offset: 12,
top: 0 top: 0,
directionBottom: true,
directionChecked: false,
} }
}, },
computed: { computed: {
position() { position() {
const valuetoRemove = this.directionBottom ? 0 : this.height()
return { return {
left: `${this.left + this.offset}px`, left: `${this.left + this.offset}px`,
top: `${this.top + this.offset}px`, top: `${this.top + this.offset - valuetoRemove}px`,
} }
} }
}, },
created() {
window.addEventListener('scroll', this.handleScroll)
},
destroyed() {
window.removeEventListener('scroll', this.handleScroll)
},
methods: { methods: {
mousemove(event) { checkDropdownVisibility() {
this.directionChecked = true
const rect = this.$refs.content.getBoundingClientRect()
const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight)
this.directionBottom = (rect.bottom + this.offset) < viewHeight
},
handleScroll() {
this.isOpen = false
},
height() {
return this.$refs.content ? this.$refs.content.clientHeight : 0
},
hideDropdown() {
this.isOpen = false
this.directionBottom = true
this.directionChecked = false
},
async mousemove(event) {
this.left = event.clientX this.left = event.clientX
this.top = event.clientY this.top = event.clientY
if (!this.directionChecked) {
await this.$nextTick()
this.checkDropdownVisibility()
}
},
showDropdown() {
this.isOpen = true
} }
} }
} }