FormToggle.vue 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <script setup>
  2. import { useIdGenerator, useValidationErrorIdGenerator } from '@/composables/helpers'
  3. import { UseColorMode } from '@vueuse/components'
  4. const props = defineProps({
  5. modelValue: [String, Number, Boolean],
  6. choices: {
  7. type: Array,
  8. required: true
  9. },
  10. fieldName: {
  11. type: String,
  12. required: true
  13. },
  14. fieldError: [String],
  15. hasOffset: Boolean,
  16. isDisabled: Boolean,
  17. label: {
  18. type: String,
  19. default: ''
  20. },
  21. help: {
  22. type: String,
  23. default: ''
  24. },
  25. })
  26. // defines what events our component emits
  27. const emit = defineEmits(['update:modelValue'])
  28. const { valErrorId } = useValidationErrorIdGenerator(props.fieldName)
  29. const legendId = useIdGenerator('legend', props.fieldName).inputId
  30. function setRadio(event) {
  31. emit('update:modelValue', event)
  32. }
  33. </script>
  34. <template>
  35. <div class="field" :class="{ 'pt-3': hasOffset }">
  36. <span v-if="label" class="label" v-html="$t(label)" />
  37. <div
  38. id="rdoGroup"
  39. role="radiogroup"
  40. :aria-describedby="help ? legendId : undefined"
  41. :aria-invalid="fieldError != undefined"
  42. :aria-errormessage="fieldError != undefined ? valErrorId : undefined"
  43. class="is-toggle buttons"
  44. >
  45. <UseColorMode v-slot="{ mode }">
  46. <button
  47. v-for="choice in choices"
  48. :key="choice.value"
  49. :id="useIdGenerator('button',fieldName+choice.value).inputId"
  50. role="radio"
  51. type="button"
  52. class="button"
  53. :aria-checked="modelValue===choice.value"
  54. :disabled="isDisabled"
  55. :class="{
  56. 'is-link': modelValue===choice.value,
  57. 'is-dark': mode==='dark',
  58. 'is-multiline': choice.legend,
  59. }"
  60. v-on:click.stop="setRadio(choice.value)">
  61. <input
  62. :id="useIdGenerator('radio',choice.value).inputId"
  63. type="radio"
  64. class="is-hidden"
  65. :checked="modelValue===choice.value"
  66. :value="choice.value"
  67. :disabled="isDisabled"
  68. />
  69. <span v-if="choice.legend" v-html="$t(choice.legend)" class="is-block is-size-7" />
  70. <FontAwesomeIcon :icon="['fas',choice.icon]" v-if="choice.icon" class="mr-2" />
  71. <label :for="useIdGenerator('button',fieldName+choice.value).inputId" class="is-clickable">
  72. {{ $t(choice.text) }}
  73. </label>
  74. </button>
  75. </UseColorMode>
  76. </div>
  77. <FieldError v-if="fieldError != undefined" :error="fieldError" :field="fieldName" />
  78. <p :id="legendId" class="help" v-html="$t(help)" v-if="help" />
  79. </div>
  80. </template>