mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-11-04 06:23:17 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			141 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { toRefs } from 'vue'
 | 
						|
 | 
						|
export default function useKeyboard(props, context, dep) {
 | 
						|
  const {
 | 
						|
    mode, addTagOn, createTag, openDirection, searchable,
 | 
						|
    showOptions, valueProp, groups: groupped,
 | 
						|
  } = toRefs(props)
 | 
						|
 | 
						|
  // ============ DEPENDENCIES ============
 | 
						|
 | 
						|
  const iv = dep.iv
 | 
						|
  const update = dep.update
 | 
						|
  const search = dep.search
 | 
						|
  const setPointer = dep.setPointer
 | 
						|
  const selectPointer = dep.selectPointer
 | 
						|
  const backwardPointer = dep.backwardPointer
 | 
						|
  const forwardPointer = dep.forwardPointer
 | 
						|
  const blur = dep.blur
 | 
						|
  const fo = dep.fo
 | 
						|
 | 
						|
  // =============== METHODS ==============
 | 
						|
 | 
						|
  // no export
 | 
						|
  const preparePointer = () => {
 | 
						|
    // When options are hidden and creating tags is allowed
 | 
						|
    // no pointer will be set (because options are hidden).
 | 
						|
    // In such case we need to set the pointer manually to the
 | 
						|
    // first option, which equals to the option created from
 | 
						|
    // the search value.
 | 
						|
    if (mode.value === 'tags' && !showOptions.value && createTag.value && searchable.value && !groupped.value) {
 | 
						|
      setPointer(fo.value[fo.value.map(o => o[valueProp.value]).indexOf(search.value)])
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const handleKeydown = (e) => {
 | 
						|
    switch (e.keyCode) {
 | 
						|
      // backspace
 | 
						|
      case 8:
 | 
						|
        if (mode.value === 'single') {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        if (searchable.value && [null, ''].indexOf(search.value) === -1) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        if (iv.value.length === 0) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        update([...iv.value].slice(0, -1))
 | 
						|
        break
 | 
						|
 | 
						|
      // enter
 | 
						|
      case 13:
 | 
						|
        e.preventDefault()
 | 
						|
 | 
						|
        if (mode.value === 'tags' && addTagOn.value.indexOf('enter') === -1 && createTag.value) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        preparePointer()
 | 
						|
        selectPointer()
 | 
						|
        break
 | 
						|
 | 
						|
      // space
 | 
						|
      case 32:
 | 
						|
        if (searchable.value && mode.value !== 'tags' && !createTag.value) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        if (mode.value === 'tags' && ((addTagOn.value.indexOf('space') === -1 && createTag.value) || !createTag.value)) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        e.preventDefault()
 | 
						|
 | 
						|
        preparePointer()
 | 
						|
        selectPointer()
 | 
						|
        break
 | 
						|
 | 
						|
      // tab
 | 
						|
      // semicolon
 | 
						|
      // comma
 | 
						|
      case 9:
 | 
						|
      case 186:
 | 
						|
      case 188:
 | 
						|
        if (mode.value !== 'tags') {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        const charMap = {
 | 
						|
          9: 'tab',
 | 
						|
          186: ';',
 | 
						|
          188: ','
 | 
						|
        }
 | 
						|
 | 
						|
        if (addTagOn.value.indexOf(charMap[e.keyCode]) === -1 || !createTag.value) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        preparePointer()
 | 
						|
        selectPointer()
 | 
						|
        e.preventDefault()
 | 
						|
        break
 | 
						|
 | 
						|
      // escape
 | 
						|
      case 27:
 | 
						|
        blur()
 | 
						|
        break
 | 
						|
 | 
						|
      // up
 | 
						|
      case 38:
 | 
						|
        e.preventDefault()
 | 
						|
 | 
						|
        if (!showOptions.value) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        openDirection.value === 'top' ? forwardPointer() : backwardPointer()
 | 
						|
        break
 | 
						|
 | 
						|
      // down
 | 
						|
      case 40:
 | 
						|
        e.preventDefault()
 | 
						|
 | 
						|
        if (!showOptions.value) {
 | 
						|
          return
 | 
						|
        }
 | 
						|
 | 
						|
        openDirection.value === 'top' ? backwardPointer() : forwardPointer()
 | 
						|
        break
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return {
 | 
						|
    handleKeydown,
 | 
						|
    preparePointer,
 | 
						|
  }
 | 
						|
}
 |