AppAutocompleteBasic.vue 1.9KB

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