AppDropdown.vue 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. <script setup>
  2. import { computed } from 'vue'
  3. const props = defineProps({
  4. label: {
  5. type: String,
  6. required: false,
  7. },
  8. labelClass: {
  9. type: String,
  10. },
  11. disabled: {
  12. type: Boolean,
  13. default: false,
  14. },
  15. placeholder: {
  16. type: String,
  17. required: true,
  18. },
  19. error: {
  20. type: String,
  21. default: null,
  22. },
  23. optionLabel: {
  24. type: String,
  25. default: 'label',
  26. },
  27. optionValue: {
  28. type: String,
  29. default: 'value',
  30. },
  31. optionDisabled: {
  32. type: String,
  33. default: 'disabled',
  34. },
  35. optionGroupChildren: {
  36. type: String,
  37. default: null,
  38. },
  39. optionGroupLabel: {
  40. type: String,
  41. default: null,
  42. },
  43. options: {
  44. type: Array,
  45. required: true,
  46. },
  47. modelValue: null,
  48. })
  49. const isError = computed(() => (props.error ? true : false))
  50. const forLabel = computed(() =>
  51. props.label ? props.label.toLowerCase().replace(/\s+/g, '-') : null
  52. )
  53. const ariaDescribedbyLabel = computed(
  54. () => props.label.toLowerCase().replace(/\s+/g, '-') + '-error'
  55. )
  56. const selectedDropdownLabel = (value) => {
  57. const result = props.options.find((option) => {
  58. if (option !== null) {
  59. return option[props.optionValue] == value
  60. }
  61. })
  62. if (result) {
  63. return result[props.optionLabel]
  64. }
  65. }
  66. </script>
  67. <template>
  68. <div class="field">
  69. <label v-if="label" :for="forLabel" :class="labelClass">{{ label }}</label>
  70. <Dropdown
  71. class="w-full"
  72. :class="{ 'p-invalid': isError }"
  73. :id="forLabel"
  74. :option-disabled="optionDisabled"
  75. :option-group-children="optionGroupChildren"
  76. :option-group-label="optionGroupLabel"
  77. :option-label="optionLabel"
  78. :option-value="optionValue"
  79. :placeholder="placeholder"
  80. :options="options"
  81. :model-value="modelValue"
  82. :disabled="disabled"
  83. @change="$emit('update:modelValue', $event.value)"
  84. >
  85. <template #value="slotProps">
  86. <div v-if="slotProps.value">
  87. {{ selectedDropdownLabel(slotProps.value) }}
  88. </div>
  89. </template>
  90. </Dropdown>
  91. <small
  92. v-if="error"
  93. :id="ariaDescribedbyLabel"
  94. :class="{ 'p-error': isError }"
  95. >
  96. {{ error }}
  97. </small>
  98. </div>
  99. </template>