forked from platypush/platypush
[UI] Improvements to the Dropdown
element.
- Added `style` property to pass static style rules to the dropdown body. - Better positioning of the dropdown when the resulting body is too long and may overflow the top of the screen - in that case, the dropdown position needs to be maximized at zero.
This commit is contained in:
parent
8f2e68f0db
commit
db34a607e4
2 changed files with 47 additions and 27 deletions
|
@ -6,7 +6,11 @@
|
|||
</button>
|
||||
|
||||
<div class="body-container hidden" ref="dropdownContainer">
|
||||
<DropdownBody :id="id" :keepOpenOnItemClick="keepOpenOnItemClick" ref="dropdown" @click="onClick">
|
||||
<DropdownBody :id="id"
|
||||
:keepOpenOnItemClick="keepOpenOnItemClick"
|
||||
:style="style"
|
||||
ref="dropdown"
|
||||
@click="onClick">
|
||||
<slot />
|
||||
</DropdownBody>
|
||||
</div>
|
||||
|
@ -41,6 +45,11 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
style: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -127,36 +136,42 @@ export default {
|
|||
|
||||
this.visible = true
|
||||
this.$refs.dropdownContainer.classList.remove('hidden')
|
||||
this.$nextTick(() => {
|
||||
const buttonRect = this.$refs.button.getBoundingClientRect()
|
||||
const buttonPos = {
|
||||
left: buttonRect.left + window.scrollX,
|
||||
top: buttonRect.top + window.scrollY,
|
||||
}
|
||||
this.$nextTick(this.adjustDropdownPos)
|
||||
},
|
||||
|
||||
const pos = {
|
||||
left: buttonPos.left,
|
||||
top: buttonPos.top + this.buttonHeight,
|
||||
}
|
||||
adjustDropdownPos() {
|
||||
const buttonRect = this.$refs.button.getBoundingClientRect()
|
||||
const buttonPos = {
|
||||
left: buttonRect.left + window.scrollX,
|
||||
top: buttonRect.top + window.scrollY,
|
||||
}
|
||||
|
||||
const dropdownWidth = this.getDropdownWidth()
|
||||
const dropdownHeight = this.getDropdownHeight()
|
||||
const pos = {
|
||||
left: buttonPos.left,
|
||||
top: buttonPos.top + this.buttonHeight,
|
||||
}
|
||||
|
||||
if ((pos.left + dropdownWidth) > (window.innerWidth + window.scrollX) / 2) {
|
||||
pos.left -= (dropdownWidth - this.buttonWidth)
|
||||
}
|
||||
const dropdownWidth = this.getDropdownWidth()
|
||||
const dropdownHeight = this.getDropdownHeight()
|
||||
|
||||
if ((pos.top + dropdownHeight) > (window.innerHeight + window.scrollY) / 2) {
|
||||
pos.top -= (dropdownHeight + this.buttonHeight - 10)
|
||||
}
|
||||
if ((pos.left + dropdownWidth) > (window.innerWidth + window.scrollX) / 2) {
|
||||
pos.left -= (dropdownWidth - this.buttonWidth)
|
||||
}
|
||||
|
||||
const element = this.$refs.dropdown.$el
|
||||
element.classList.add('fade-in')
|
||||
element.style.top = `${pos.top}px`
|
||||
element.style.left = `${pos.left}px`
|
||||
bus.emit('dropdown-open', this.$refs.dropdown)
|
||||
this.$refs.dropdownContainer.classList.add('hidden')
|
||||
})
|
||||
if ((pos.top + dropdownHeight) > (window.innerHeight + window.scrollY) / 2) {
|
||||
let newPosTop = pos.top - (dropdownHeight + this.buttonHeight - 10)
|
||||
if (newPosTop < 0)
|
||||
newPosTop = 0
|
||||
|
||||
pos.top = newPosTop
|
||||
}
|
||||
|
||||
const element = this.$refs.dropdown.$el
|
||||
element.classList.add('fade-in')
|
||||
element.style.top = `${pos.top}px`
|
||||
element.style.left = `${pos.left}px`
|
||||
bus.emit('dropdown-open', this.$refs.dropdown)
|
||||
this.$refs.dropdownContainer.classList.add('hidden')
|
||||
},
|
||||
|
||||
toggle(event) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="dropdown" :id="id" @click="$emit('click', $event)">
|
||||
<div class="dropdown" :id="id" :style="style" @click="$emit('click', $event)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
@ -16,6 +16,11 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
|
||||
style: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in a new issue