mirror of
https://github.com/crater-invoice/crater.git
synced 2025-10-28 12:11:08 -04:00
141 lines
3.9 KiB
JavaScript
Executable File
141 lines
3.9 KiB
JavaScript
Executable File
export default {
|
|
data () {
|
|
return {
|
|
pointer: 0,
|
|
pointerDirty: false
|
|
}
|
|
},
|
|
props: {
|
|
/**
|
|
* Enable/disable highlighting of the pointed value.
|
|
* @type {Boolean}
|
|
* @default true
|
|
*/
|
|
showPointer: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
optionHeight: {
|
|
type: Number,
|
|
default: 40
|
|
}
|
|
},
|
|
computed: {
|
|
pointerPosition () {
|
|
return this.pointer * this.optionHeight
|
|
},
|
|
visibleElements () {
|
|
return this.optimizedHeight / this.optionHeight
|
|
}
|
|
},
|
|
watch: {
|
|
filteredOptions () {
|
|
this.pointerAdjust()
|
|
},
|
|
isOpen () {
|
|
this.pointerDirty = false
|
|
},
|
|
pointer () {
|
|
this.$refs.search.setAttribute('aria-activedescendant', this.id + '-' + this.pointer.toString())
|
|
}
|
|
},
|
|
methods: {
|
|
optionHighlight (index, option) {
|
|
return {
|
|
'multiselect__option--highlight': index === this.pointer && this.showPointer,
|
|
'multiselect__option--selected': this.isSelected(option)
|
|
}
|
|
},
|
|
groupHighlight (index, selectedGroup) {
|
|
if (!this.groupSelect) {
|
|
return ['multiselect__option--group', 'multiselect__option--disabled']
|
|
}
|
|
|
|
const group = this.options.find(option => {
|
|
return option[this.groupLabel] === selectedGroup.$groupLabel
|
|
})
|
|
|
|
return group && !this.wholeGroupDisabled(group) ? [
|
|
'multiselect__option--group',
|
|
{ 'multiselect__option--highlight': index === this.pointer && this.showPointer },
|
|
{ 'multiselect__option--group-selected': this.wholeGroupSelected(group) }
|
|
] : 'multiselect__option--disabled'
|
|
},
|
|
addPointerElement ({ key } = 'Enter') {
|
|
/* istanbul ignore else */
|
|
if (this.filteredOptions.length > 0) {
|
|
this.select(this.filteredOptions[this.pointer], key)
|
|
}
|
|
this.pointerReset()
|
|
},
|
|
pointerForward () {
|
|
/* istanbul ignore else */
|
|
if (this.pointer < this.filteredOptions.length - 1) {
|
|
this.pointer++
|
|
/* istanbul ignore next */
|
|
if (this.$refs.list.scrollTop <= this.pointerPosition - (this.visibleElements - 1) * this.optionHeight) {
|
|
this.$refs.list.scrollTop = this.pointerPosition - (this.visibleElements - 1) * this.optionHeight
|
|
}
|
|
/* istanbul ignore else */
|
|
if (
|
|
this.filteredOptions[this.pointer] &&
|
|
this.filteredOptions[this.pointer].$isLabel &&
|
|
!this.groupSelect
|
|
) this.pointerForward()
|
|
}
|
|
this.pointerDirty = true
|
|
},
|
|
pointerBackward () {
|
|
if (this.pointer > 0) {
|
|
this.pointer--
|
|
/* istanbul ignore else */
|
|
if (this.$refs.list.scrollTop >= this.pointerPosition) {
|
|
this.$refs.list.scrollTop = this.pointerPosition
|
|
}
|
|
/* istanbul ignore else */
|
|
if (
|
|
this.filteredOptions[this.pointer] &&
|
|
this.filteredOptions[this.pointer].$isLabel &&
|
|
!this.groupSelect
|
|
) this.pointerBackward()
|
|
} else {
|
|
/* istanbul ignore else */
|
|
if (
|
|
this.filteredOptions[this.pointer] &&
|
|
this.filteredOptions[0].$isLabel &&
|
|
!this.groupSelect
|
|
) this.pointerForward()
|
|
}
|
|
this.pointerDirty = true
|
|
},
|
|
pointerReset () {
|
|
/* istanbul ignore else */
|
|
if (!this.closeOnSelect) return
|
|
this.pointer = 0
|
|
/* istanbul ignore else */
|
|
if (this.$refs.list) {
|
|
this.$refs.list.scrollTop = 0
|
|
}
|
|
},
|
|
pointerAdjust () {
|
|
/* istanbul ignore else */
|
|
if (this.pointer >= this.filteredOptions.length - 1) {
|
|
this.pointer = this.filteredOptions.length
|
|
? this.filteredOptions.length - 1
|
|
: 0
|
|
}
|
|
|
|
if (this.filteredOptions.length > 0 &&
|
|
this.filteredOptions[this.pointer].$isLabel &&
|
|
!this.groupSelect
|
|
) {
|
|
this.pointerForward()
|
|
}
|
|
},
|
|
pointerSet (index) {
|
|
this.pointer = index
|
|
this.pointerDirty = true
|
|
}
|
|
}
|
|
}
|