Phone.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <!--
  2. Champs de saisie d'un numéro de téléphone
  3. @see https://github.com/yogakurniawan/vue-tel-input-vuetify
  4. // TODO: tester compatibilité avec Vue 3
  5. -->
  6. <template>
  7. <client-only>
  8. <vue-tel-input-vuetify
  9. v-model="myPhone"
  10. :error="error || !!violation"
  11. :error-messages="errorMessage || violation ? $t(violation) : ''"
  12. :field="field"
  13. :label="label"
  14. :readonly="readonly"
  15. clearable
  16. valid-characters-only
  17. validate-on-blur
  18. :rules="rules"
  19. @input="onInput"
  20. @change="onChangeValue"
  21. />
  22. </client-only>
  23. </template>
  24. <script setup lang="ts">
  25. import { useNuxtApp } from '#app'
  26. import type { Ref } from 'vue'
  27. import { useFieldViolation } from '~/composables/form/useFieldViolation'
  28. const props = defineProps({
  29. label: {
  30. type: String,
  31. required: false,
  32. default: '',
  33. },
  34. field: {
  35. type: String,
  36. required: false,
  37. default: null,
  38. },
  39. data: {
  40. type: [String, Number],
  41. required: false,
  42. default: null,
  43. },
  44. readonly: {
  45. type: Boolean,
  46. required: false,
  47. },
  48. error: {
  49. type: Boolean,
  50. required: false,
  51. },
  52. errorMessage: {
  53. type: String,
  54. required: false,
  55. default: null,
  56. },
  57. })
  58. const { emit } = useNuxtApp()
  59. const i18n = useI18n()
  60. const { violation, onChange } = useFieldViolation(props.field, emit)
  61. const nationalNumber: Ref<string | number> = ref('')
  62. const internationalNumber: Ref<string | number> = ref('')
  63. const isValid: Ref<boolean> = ref(false)
  64. const onInit: Ref<boolean> = ref(true)
  65. const onInput = (
  66. _: unknown,
  67. {
  68. number,
  69. valid,
  70. countryChoice,
  71. }: {
  72. number: {
  73. national: string | number;
  74. international: string | number
  75. };
  76. valid: boolean;
  77. countryChoice: Record<string, unknown>
  78. },
  79. ) => {
  80. isValid.value = valid
  81. nationalNumber.value = number.national
  82. internationalNumber.value = number.international
  83. onInit.value = false
  84. }
  85. const onChangeValue = () => {
  86. if (isValid.value) {
  87. onChange(internationalNumber.value)
  88. }
  89. }
  90. const myPhone = computed({
  91. get: () => {
  92. return onInit.value ? props.data : nationalNumber.value
  93. },
  94. set: (value) => {
  95. return props.data
  96. },
  97. })
  98. const rules = [
  99. (phone: string) => !phone || isValid.value || i18n.t('phone_error'),
  100. ]
  101. </script>
  102. <style lang="scss">
  103. input:read-only {
  104. color: rgb(var(--v-theme-on-neutral));
  105. }
  106. </style>