QuickSearchInput.vue 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <!-- Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <script setup lang="ts">
  3. import { onBeforeUnmount, useTemplateRef, watch } from 'vue'
  4. import emitter from '#shared/utils/emitter.ts'
  5. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  6. import CommonInputSearch from '#desktop/components/CommonInputSearch/CommonInputSearch.vue'
  7. const searchValue = defineModel<string>()
  8. const isSearchActive = defineModel<boolean>('search-active', {
  9. default: false,
  10. })
  11. const inputSearchInstance = useTemplateRef('input-search')
  12. const resetInput = () => {
  13. searchValue.value = ''
  14. isSearchActive.value = false
  15. // Blur input to make sure it does not get refocuses automatically and focus event is not emitted
  16. inputSearchInstance.value?.blur()
  17. }
  18. const handleEscapeKey = (event: KeyboardEvent) => {
  19. if (event.code === 'Escape') resetInput()
  20. }
  21. watch(isSearchActive, (isActive) =>
  22. isActive
  23. ? window.addEventListener('keydown', handleEscapeKey)
  24. : window.removeEventListener('keydown', handleEscapeKey),
  25. )
  26. onBeforeUnmount(() => {
  27. window.removeEventListener('keydown', handleEscapeKey)
  28. })
  29. emitter.on('focus-quick-search-field', () => inputSearchInstance.value?.focus())
  30. emitter.on('reset-quick-search-field', () => resetInput())
  31. </script>
  32. <template>
  33. <div class="flex items-center gap-3">
  34. <CommonInputSearch
  35. ref="input-search"
  36. v-model="searchValue"
  37. wrapper-class="rounded-lg bg-blue-200 px-2.5 py-2 outline-offset-1 outline-blue-800 focus-within:outline dark:bg-gray-700"
  38. @focus-input="isSearchActive = true"
  39. />
  40. <CommonButton
  41. v-if="isSearchActive"
  42. :aria-label="$t('Reset Search')"
  43. icon="x-lg"
  44. variant="neutral"
  45. @click="resetInput"
  46. />
  47. </div>
  48. </template>