AppAutocompleteBasic.vue 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. <script setup>
  2. import { computed } from 'vue'
  3. const props = defineProps({
  4. field: {
  5. type: String,
  6. required: true,
  7. },
  8. suggestions: {
  9. type: Array,
  10. required: true,
  11. },
  12. empty: {
  13. type: Boolean,
  14. default: false,
  15. },
  16. label: {
  17. type: String,
  18. required: true,
  19. },
  20. dropdown: {
  21. type: Boolean,
  22. default: false,
  23. },
  24. placeholder: {
  25. type: String,
  26. required: true,
  27. },
  28. error: {
  29. type: String,
  30. default: null,
  31. },
  32. modelValue: null,
  33. })
  34. defineEmits(['complete', 'itemSelect', 'update:modelValue'])
  35. const isError = computed(() => (props.error ? true : false))
  36. const forLabel = computed(() => props.label.toLowerCase().replace(/\s+/g, '-'))
  37. const ariaDescribedbyLabel = computed(() => props.label.toLowerCase().replace(/\s+/g, '-') + '-help')
  38. </script>
  39. <template>
  40. <div class="field">
  41. <label :for="forLabel">{{ label }}</label>
  42. <AutoComplete
  43. class="w-full"
  44. inputClass="w-full"
  45. :model-value="modelValue"
  46. :aria-describedby="ariaDescribedbyLabel"
  47. :id="forLabel"
  48. :class="{ 'p-invalid': isError }"
  49. :field="field"
  50. :placeholder="placeholder"
  51. :suggestions="suggestions"
  52. :auto-highlight="true"
  53. :dropdown="dropdown"
  54. @input="$emit('update:modelValue', $event.target.value)"
  55. @item-select="$emit('itemSelect', $event)"
  56. @complete="$emit('complete', $event)"
  57. >
  58. <template #item="slotProps">
  59. <slot name="item" :item="slotProps.item" />
  60. </template>
  61. </AutoComplete>
  62. <div class="flex flex-column">
  63. <small
  64. v-if="error"
  65. class="mt-1"
  66. :class="{ 'mb-2': suggestions.length === 0 || (modelValue.length === 0 && empty), 'p-error': isError }"
  67. :id="ariaDescribedbyLabel"
  68. >
  69. {{ error }}
  70. </small>
  71. <small v-if="suggestions.length === 0 || (modelValue.length === 0 && empty)" class="mt-1">
  72. <slot v-if="empty" name="empty" />
  73. </small>
  74. </div>
  75. </div>
  76. </template>