[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:
Fabio Manganiello 2024-08-25 00:13:25 +02:00
parent 8f2e68f0db
commit db34a607e4
Signed by untrusted user: blacklight
GPG key ID: D90FBA7F76362774
2 changed files with 47 additions and 27 deletions

View file

@ -6,7 +6,11 @@
</button> </button>
<div class="body-container hidden" ref="dropdownContainer"> <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 /> <slot />
</DropdownBody> </DropdownBody>
</div> </div>
@ -41,6 +45,11 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
style: {
type: Object,
default: () => ({}),
},
}, },
data() { data() {
@ -127,7 +136,10 @@ export default {
this.visible = true this.visible = true
this.$refs.dropdownContainer.classList.remove('hidden') this.$refs.dropdownContainer.classList.remove('hidden')
this.$nextTick(() => { this.$nextTick(this.adjustDropdownPos)
},
adjustDropdownPos() {
const buttonRect = this.$refs.button.getBoundingClientRect() const buttonRect = this.$refs.button.getBoundingClientRect()
const buttonPos = { const buttonPos = {
left: buttonRect.left + window.scrollX, left: buttonRect.left + window.scrollX,
@ -147,7 +159,11 @@ export default {
} }
if ((pos.top + dropdownHeight) > (window.innerHeight + window.scrollY) / 2) { if ((pos.top + dropdownHeight) > (window.innerHeight + window.scrollY) / 2) {
pos.top -= (dropdownHeight + this.buttonHeight - 10) let newPosTop = pos.top - (dropdownHeight + this.buttonHeight - 10)
if (newPosTop < 0)
newPosTop = 0
pos.top = newPosTop
} }
const element = this.$refs.dropdown.$el const element = this.$refs.dropdown.$el
@ -156,7 +172,6 @@ export default {
element.style.left = `${pos.left}px` element.style.left = `${pos.left}px`
bus.emit('dropdown-open', this.$refs.dropdown) bus.emit('dropdown-open', this.$refs.dropdown)
this.$refs.dropdownContainer.classList.add('hidden') this.$refs.dropdownContainer.classList.add('hidden')
})
}, },
toggle(event) { toggle(event) {

View file

@ -1,5 +1,5 @@
<template> <template>
<div class="dropdown" :id="id" @click="$emit('click', $event)"> <div class="dropdown" :id="id" :style="style" @click="$emit('click', $event)">
<slot /> <slot />
</div> </div>
</template> </template>
@ -16,6 +16,11 @@ export default {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
style: {
type: Object,
default: () => ({}),
},
}, },
} }
</script> </script>