mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-11-04 06:23:17 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
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
 | 
						|
    },
 | 
						|
  },
 | 
						|
}
 |