Refactor menu keyoboard navigation into mixin

This commit is contained in:
mikiher 2024-08-17 06:08:32 +03:00
parent f9f89e1e51
commit f1ddbeadaf
5 changed files with 110 additions and 107 deletions

View file

@ -37,7 +37,10 @@
</template>
<script>
import menuKeyboardNavigationMixin from '@/mixins/menuKeyboardNavigation'
export default {
mixins: [menuKeyboardNavigationMixin],
props: {
value: {
type: Array,
@ -63,8 +66,7 @@ export default {
typingTimeout: null,
isFocused: false,
menu: null,
filteredItems: null,
selectedMenuItemIndex: null
filteredItems: null
}
},
watch: {
@ -119,34 +121,8 @@ export default {
this.filteredItems = results || []
},
keydownInput(event) {
let items = this.itemsToShow
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
event.preventDefault()
if (!items.length) return
if (event.key === 'ArrowDown') {
if (this.selectedMenuItemIndex === null) {
this.selectedMenuItemIndex = 0
} else {
this.selectedMenuItemIndex = Math.min(this.selectedMenuItemIndex + 1, items.length - 1)
}
} else if (event.key === 'ArrowUp') {
if (this.selectedMenuItemIndex === null) {
this.selectedMenuItemIndex = items.length - 1
} else {
this.selectedMenuItemIndex = Math.max(this.selectedMenuItemIndex - 1, 0)
}
}
this.recalcScroll()
return
} else if (event.key === 'Enter') {
if (this.selectedMenuItemIndex !== null) {
this.clickedOption(event, items[this.selectedMenuItemIndex])
} else {
this.submitForm()
}
return
}
this.selectedMenuItemIndex = null
this.menuNavigationHandler(event)
clearTimeout(this.typingTimeout)
this.typingTimeout = setTimeout(() => {
this.search()
@ -161,24 +137,6 @@ export default {
this.recalcMenuPos()
}, 50)
},
recalcScroll() {
if (!this.menu) return
var menuItems = this.menu.querySelectorAll('li')
if (!menuItems.length) return
var selectedItem = menuItems[this.selectedMenuItemIndex]
if (!selectedItem) return
var menuHeight = this.menu.offsetHeight
var itemHeight = selectedItem.offsetHeight
var itemTop = selectedItem.offsetTop
var itemBottom = itemTop + itemHeight
if (itemBottom > this.menu.scrollTop + menuHeight) {
let menuPaddingBottom = parseFloat(window.getComputedStyle(this.menu).paddingBottom)
this.menu.scrollTop = itemBottom - menuHeight + menuPaddingBottom
} else if (itemTop < this.menu.scrollTop) {
let menuPaddingTop = parseFloat(window.getComputedStyle(this.menu).paddingTop)
this.menu.scrollTop = itemTop - menuPaddingTop
}
},
recalcMenuPos() {
if (!this.menu || !this.$refs.inputWrapper) return
var boundingBox = this.$refs.inputWrapper.getBoundingClientRect()
@ -317,9 +275,6 @@ export default {
this.textInput = null
this.currentSearch = null
this.selectedMenuItemIndex = null
this.$nextTick(() => {
this.blur()
})
},
submitForm() {
if (!this.textInput) return