import CraterTheme from '../theme/index' const { multiselectOption } = CraterTheme.BaseSelect 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), }, multiselectOption, ] }, groupHighlight(index, selectedGroup) { if (!this.groupSelect) { return [ 'multiselect__option--group', 'multiselect__option--disabled', multiselectOption, ] } 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 ), }, multiselectOption, ] : ['multiselect__option--disabled', multiselectOption] }, 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 }, }, }