FormField.vue 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <script setup>
  2. import { useIdGenerator } from '@/composables/helpers'
  3. defineOptions({
  4. inheritAttrs: false
  5. })
  6. const props = defineProps({
  7. modelValue: [String, Number, Boolean],
  8. label: {
  9. type: String,
  10. default: ''
  11. },
  12. fieldName: {
  13. type: String,
  14. default: '',
  15. required: true
  16. },
  17. fieldError: [String],
  18. inputType: {
  19. type: String,
  20. default: 'text'
  21. },
  22. placeholder: {
  23. type: String,
  24. default: ''
  25. },
  26. help: {
  27. type: String,
  28. default: ''
  29. },
  30. hasOffset: {
  31. type: Boolean,
  32. default: false
  33. },
  34. isDisabled: {
  35. type: Boolean,
  36. default: false
  37. },
  38. maxLength: {
  39. type: Number,
  40. default: null
  41. },
  42. isIndented: Boolean,
  43. leftIcon: '',
  44. rightIcon: '',
  45. })
  46. const { inputId } = useIdGenerator(props.inputType, props.fieldName)
  47. </script>
  48. <template>
  49. <div class="mb-3" :class="{ 'pt-3' : hasOffset, 'is-flex' : isIndented }">
  50. <div v-if="isIndented" class="mx-2 pr-1" :style="{ 'opacity': isDisabled ? '0.5' : '1' }">
  51. <FontAwesomeIcon class="has-text-grey" :icon="['fas', 'chevron-right']" transform="rotate-135"/>
  52. </div>
  53. <div class="field" :class="{ 'is-flex-grow-5' : isIndented }">
  54. <label :for="inputId" class="label" :style="{ 'opacity': isDisabled ? '0.5' : '1' }" v-html="$t(label)"></label>
  55. <div class="control" :class="{ 'has-icons-left' : leftIcon, 'has-icons-right': rightIcon }">
  56. <input
  57. :disabled="isDisabled"
  58. :id="inputId"
  59. :type="inputType"
  60. class="input"
  61. :value="modelValue"
  62. :placeholder="placeholder"
  63. v-bind="$attrs"
  64. v-on:input="$emit('update:modelValue', $event.target.value)"
  65. v-on:change="$emit('change:modelValue', $event.target.value)"
  66. :maxlength="maxLength"
  67. />
  68. <span v-if="leftIcon" class="icon is-small is-left">
  69. <FontAwesomeIcon :icon="['fas', leftIcon]" transform="rotate-75" size="xs" />
  70. </span>
  71. <span v-if="rightIcon" class="icon is-small is-right">
  72. <FontAwesomeIcon :icon="['fas', rightIcon]" transform="rotate-75" size="xs" />
  73. </span>
  74. </div>
  75. <FieldError v-if="fieldError != undefined" :error="fieldError" :field="fieldName" />
  76. <p class="help" v-html="$t(help)" v-if="help"></p>
  77. </div>
  78. </div>
  79. </template>