FormTextarea.vue 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <script setup>
  2. import { useIdGenerator, useValidationErrorIdGenerator } 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. placeholder: {
  19. type: String,
  20. default: ''
  21. },
  22. help: {
  23. type: String,
  24. default: ''
  25. },
  26. size: {
  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. isLocked: Boolean,
  44. leftIcon: '',
  45. rightIcon: '',
  46. idSuffix: {
  47. type: String,
  48. default: ''
  49. }
  50. })
  51. const { inputId } = useIdGenerator(props.inputType, props.fieldName + props.idSuffix)
  52. const { valErrorId } = useValidationErrorIdGenerator(props.fieldName)
  53. const legendId = useIdGenerator('legend', props.fieldName).inputId
  54. </script>
  55. <template>
  56. <div class="mb-3" :class="{ 'pt-3' : hasOffset, 'is-flex' : isIndented }">
  57. <div v-if="isIndented" class="mx-2 pr-1" :class="{ 'is-opacity-5' : isDisabled || isLocked }">
  58. <FontAwesomeIcon class="has-text-grey" :icon="['fas', 'chevron-right']" transform="rotate-135"/>
  59. </div>
  60. <div class="field" :class="{ 'is-flex-grow-5' : isIndented }">
  61. <label v-if="label" :for="inputId" class="label">
  62. {{ $t(label) }}<FontAwesomeIcon v-if="isLocked" :icon="['fas', 'lock']" class="ml-2" size="xs" />
  63. </label>
  64. <div class="control" :class="{ 'has-icons-left' : leftIcon, 'has-icons-right': rightIcon }">
  65. <textarea
  66. :disabled="isDisabled || isLocked"
  67. :id="inputId"
  68. class="textarea"
  69. :class="size"
  70. :value="modelValue"
  71. :placeholder="placeholder"
  72. v-bind="$attrs"
  73. v-on:input="$emit('update:modelValue', $event.target.value)"
  74. v-on:change="$emit('change:modelValue', $event.target.value)"
  75. :maxlength="maxLength"
  76. :aria-describedby="help ? legendId : undefined"
  77. :aria-invalid="fieldError != undefined"
  78. :aria-errormessage="fieldError != undefined ? valErrorId : undefined"
  79. />
  80. </div>
  81. <FieldError v-if="fieldError != undefined" :error="fieldError" :field="fieldName" />
  82. <p :id="legendId" class="help" v-html="$t(help)" v-if="help"></p>
  83. </div>
  84. </div>
  85. </template>