DatePicker.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <!--
  2. Sélecteur de dates, à placer dans un composant `UiForm`
  3. -->
  4. <template>
  5. <main>
  6. <div class="d-flex flex-column">
  7. <span>{{ $t(fieldLabel) }}</span>
  8. <UiDatePicker
  9. v-model="date"
  10. :readonly="readonly"
  11. :format="format"
  12. :position="position"
  13. @update:model-value="onUpdate($event)"
  14. />
  15. <span v-if="error || !!fieldViolations" class="theme-danger">
  16. {{ errorMessage || fieldViolations ? $t(fieldViolations) : '' }}
  17. </span>
  18. </div>
  19. </main>
  20. </template>
  21. <script setup lang="ts">
  22. import {useFieldViolation} from "~/composables/form/useFieldViolation";
  23. import {formatISO} from "date-fns";
  24. import {PropType} from "@vue/runtime-core";
  25. const props = defineProps({
  26. /**
  27. * v-model
  28. */
  29. modelValue: {
  30. type: String,
  31. required: false,
  32. default: null
  33. },
  34. /**
  35. * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
  36. * - Utilisé par la validation
  37. * - Laisser null si le champ ne s'applique pas à une entité
  38. */
  39. field: {
  40. type: String,
  41. required: false,
  42. default: null
  43. },
  44. /**
  45. * Label du champ
  46. * Si non défini, c'est le nom de propriété qui est utilisé
  47. */
  48. label: {
  49. type: String,
  50. required: false,
  51. default: null
  52. },
  53. /**
  54. * Définit si le champ est en lecture seule
  55. */
  56. readonly: {
  57. type: Boolean,
  58. required: false
  59. },
  60. /**
  61. * Format d'affichage des dates
  62. * @see https://vue3datepicker.com/props/formatting/
  63. */
  64. format: {
  65. type: String,
  66. required: false,
  67. default: null
  68. },
  69. /**
  70. * Règles de validation
  71. * @see https://vuetify.cn/en/components/forms/#validation-with-submit-clear
  72. */
  73. rules: {
  74. type: Array,
  75. required: false,
  76. default: () => []
  77. },
  78. /**
  79. * Le champ est-il actuellement en état d'erreur
  80. */
  81. error: {
  82. type: Boolean,
  83. required: false
  84. },
  85. /**
  86. * Si le champ est en état d'erreur, quel est le message d'erreur?
  87. */
  88. errorMessage: {
  89. type: String,
  90. required: false,
  91. default: null
  92. },
  93. /**
  94. * @see https://vue3datepicker.com/props/positioning/#position
  95. */
  96. position: {
  97. type: String as PropType<'left' | 'center' | 'right'>,
  98. required: false,
  99. default: 'center'
  100. }
  101. })
  102. const input = ref(null)
  103. const {fieldViolations, updateViolationState} = useFieldViolation(props.field)
  104. const fieldLabel = props.label ?? props.field
  105. const emit = defineEmits(['update:model-value', 'change'])
  106. const date: Ref<Date> = ref(new Date(props.modelValue))
  107. const onUpdate = (event: string) => {
  108. updateViolationState(event)
  109. emit('update:model-value', formatISO(date.value))
  110. }
  111. </script>
  112. <style scoped>
  113. </style>