@cnamts/synapse 0.0.11-alpha → 0.0.13-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/dist/design-system-v3.js +5394 -3813
  2. package/dist/design-system-v3.umd.cjs +1 -1
  3. package/dist/src/components/Amelipro/types/types.d.ts +38 -0
  4. package/dist/src/components/CookieBanner/CookieBanner.d.ts +1 -1
  5. package/dist/src/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
  6. package/dist/src/components/Customs/SyTextField/SyTextField.d.ts +31 -23
  7. package/dist/src/components/Customs/SyTextField/types.d.ts +1 -0
  8. package/dist/src/components/DatePicker/DatePicker.d.ts +105 -102
  9. package/dist/src/components/DatePicker/DateTextInput.d.ts +82 -74
  10. package/dist/src/components/ErrorPage/ErrorPage.d.ts +1 -1
  11. package/dist/src/components/FileList/FileList.d.ts +1 -0
  12. package/dist/src/components/FileList/UploadItem/UploadItem.d.ts +1 -1
  13. package/dist/src/components/FilterInline/AccessibiliteItems.d.ts +30 -0
  14. package/dist/src/components/FilterInline/constants/ExpertiseLevelEnum.d.ts +4 -0
  15. package/dist/src/components/FilterSideBar/AccessibiliteItems.d.ts +29 -0
  16. package/dist/src/components/FilterSideBar/FilterSideBar.d.ts +31 -0
  17. package/dist/src/components/FilterSideBar/constants/ExpertiseLevelEnum.d.ts +4 -0
  18. package/dist/src/components/FilterSideBar/locales.d.ts +7 -0
  19. package/dist/src/components/LangBtn/LangBtn.d.ts +2 -2
  20. package/dist/src/components/NirField/NirField.d.ts +952 -0
  21. package/dist/src/components/NotificationBar/NotificationBar.d.ts +6 -6
  22. package/dist/src/components/PasswordField/PasswordField.d.ts +42 -8
  23. package/dist/src/components/PeriodField/PeriodField.d.ts +259 -235
  24. package/dist/src/components/PhoneField/PhoneField.d.ts +33 -3
  25. package/dist/src/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +1 -1
  26. package/dist/src/components/RatingPicker/NumberPicker/NumberPicker.d.ts +1 -1
  27. package/dist/src/components/RatingPicker/StarsPicker/StarsPicker.d.ts +1 -1
  28. package/dist/src/components/UploadWorkflow/AccessibiliteItems.d.ts +29 -0
  29. package/dist/src/components/UploadWorkflow/config.d.ts +29 -0
  30. package/dist/src/components/UploadWorkflow/constants/ExpertiseLevelEnum.d.ts +4 -0
  31. package/dist/src/components/UploadWorkflow/locales.d.ts +7 -0
  32. package/dist/src/components/UploadWorkflow/types.d.ts +19 -0
  33. package/dist/src/components/UploadWorkflow/useFileList.d.ts +10 -0
  34. package/dist/src/components/UploadWorkflow/useFileUploadJourney.d.ts +9 -0
  35. package/dist/src/components/Usages/Usages.d.ts +10 -0
  36. package/dist/src/components/index.d.ts +5 -0
  37. package/dist/src/composables/date/tests/useDateFormat.spec.d.ts +1 -0
  38. package/dist/src/composables/date/tests/useDateInitialization.spec.d.ts +1 -0
  39. package/dist/src/composables/date/tests/useDatePickerAccessibility.spec.d.ts +1 -0
  40. package/dist/src/composables/date/useDateFormat.d.ts +26 -0
  41. package/dist/src/composables/date/useDateInitialization.d.ts +18 -0
  42. package/dist/src/composables/date/useDatePickerAccessibility.d.ts +8 -0
  43. package/dist/src/composables/rules/useFieldValidation.d.ts +1 -0
  44. package/dist/src/composables/useFilterable/useFilterable.d.ts +1 -1
  45. package/dist/src/composables/validation/tests/useValidation.spec.d.ts +1 -0
  46. package/dist/src/composables/validation/useValidation.d.ts +40 -0
  47. package/dist/src/designTokens/index.d.ts +3 -1
  48. package/dist/src/main.d.ts +1 -0
  49. package/dist/src/utils/formatDate/index.d.ts +3 -0
  50. package/dist/src/utils/formatDate/tests/formatDate.spec.d.ts +1 -0
  51. package/dist/src/utils/functions/validation/isDateAfter/index.d.ts +2 -0
  52. package/dist/src/utils/functions/validation/isDateAfter/tests/isDateAfter.spec.d.ts +1 -0
  53. package/dist/src/utils/functions/validation/isDateBefore/index.d.ts +2 -0
  54. package/dist/src/utils/functions/validation/isDateBefore/tests/isDateBefore.spec.d.ts +1 -0
  55. package/dist/src/utils/functions/validation/isDateInRange/index.d.ts +3 -0
  56. package/dist/src/utils/functions/validation/isDateInRange/tests/isDateInRange.spec.d.ts +1 -0
  57. package/dist/src/utils/functions/validation/isDateValid/index.d.ts +9 -0
  58. package/dist/src/utils/functions/validation/isDateValid/tests/isDateValid.spec.d.ts +1 -0
  59. package/dist/src/utils/functions/validation/isEmailValid/tests/isEmailValid.spec.d.ts +1 -0
  60. package/dist/src/utils/functions/validation/isWeekend/index.d.ts +3 -0
  61. package/dist/src/utils/functions/validation/isWeekend/tests/isWeekend.spec.d.ts +1 -0
  62. package/dist/src/utils/parseDate/index.d.ts +3 -0
  63. package/dist/src/utils/parseDate/tests/parseDate.spec.d.ts +1 -0
  64. package/dist/src/utils/rules/doMatchPattern/index.d.ts +3 -0
  65. package/dist/src/utils/rules/doMatchPattern/tests/matchPattern.spec.d.ts +1 -0
  66. package/dist/src/utils/rules/index.d.ts +11 -0
  67. package/dist/src/utils/rules/isDateValid/index.d.ts +4 -0
  68. package/dist/src/utils/rules/isDateValid/tests/isDateValid.spec.d.ts +1 -0
  69. package/dist/src/utils/rules/isExactLength/index.d.ts +3 -0
  70. package/dist/src/utils/rules/isExactLength/locales.d.ts +2 -0
  71. package/dist/src/utils/rules/isExactLength/tests/exactLength.spec.d.ts +1 -0
  72. package/dist/src/utils/rules/isMaxLength/index.d.ts +3 -0
  73. package/dist/src/utils/rules/isMaxLength/locales.d.ts +2 -0
  74. package/dist/src/utils/rules/isMaxLength/tests/isMaxLength.spec.d.ts +1 -0
  75. package/dist/src/utils/rules/isMinLength/index.d.ts +3 -0
  76. package/dist/src/utils/rules/isMinLength/locales.d.ts +2 -0
  77. package/dist/src/utils/rules/isMinLength/tests/isMinLength.spec.d.ts +1 -0
  78. package/dist/src/utils/rules/isNotAfterDate/index.d.ts +3 -0
  79. package/dist/src/utils/rules/isNotAfterDate/tests/isNotAfterDate.spec.d.ts +1 -0
  80. package/dist/src/utils/rules/isNotAfterToday/index.d.ts +4 -0
  81. package/dist/src/utils/rules/isNotAfterToday/locales.d.ts +2 -0
  82. package/dist/src/utils/rules/isNotAfterToday/tests/isNotAfterToday.spec.d.ts +1 -0
  83. package/dist/src/utils/rules/isNotBeforeDate/index.d.ts +3 -0
  84. package/dist/src/utils/rules/isNotBeforeDate/locales.d.ts +2 -0
  85. package/dist/src/utils/rules/isNotBeforeDate/tests/IsNotBeforeDate.spec.d.ts +1 -0
  86. package/dist/src/utils/rules/isNotBeforeToday/index.d.ts +4 -0
  87. package/dist/src/utils/rules/isNotBeforeToday/locales.d.ts +2 -0
  88. package/dist/src/utils/rules/isNotBeforeToday/tests/notBeforeToday.spec.d.ts +1 -0
  89. package/dist/src/utils/rules/isRequired/index.d.ts +4 -0
  90. package/dist/src/utils/rules/isRequired/locales.d.ts +2 -0
  91. package/dist/src/utils/rules/isRequired/tests/isRequred.spec.d.ts +1 -0
  92. package/dist/src/utils/rules/isValidEmail/index.d.ts +4 -0
  93. package/dist/src/utils/rules/isValidEmail/locales.d.ts +2 -0
  94. package/dist/src/utils/rules/isValidEmail/tests/isValidEmail.spec.d.ts +1 -0
  95. package/dist/src/vuetifyConfig.d.ts +81 -0
  96. package/dist/style.css +1 -1
  97. package/package.json +3 -1
  98. package/src/assets/_elevations.scss +89 -0
  99. package/src/assets/_fonts.scss +6 -0
  100. package/src/assets/_radius.scss +92 -0
  101. package/src/assets/_spacers.scss +149 -0
  102. package/src/assets/settings.scss +15 -3
  103. package/src/assets/tokens.scss +32 -29
  104. package/src/components/Amelipro/types/types.ts +40 -0
  105. package/src/components/ChipList/ChipList.stories.ts +26 -27
  106. package/src/components/ChipList/ChipList.vue +5 -1
  107. package/src/components/ChipList/config.ts +1 -0
  108. package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +2 -2
  109. package/src/components/Customs/SyBtnSelect/SyBtnSelect.mdx +1 -1
  110. package/src/components/Customs/SyInputSelect/SyInputSelect.mdx +1 -1
  111. package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +65 -0
  112. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +13 -3
  113. package/src/components/Customs/SySelect/SySelect.mdx +1 -1
  114. package/src/components/Customs/SySelect/SySelect.stories.ts +88 -5
  115. package/src/components/Customs/SySelect/SySelect.vue +55 -14
  116. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +135 -2
  117. package/src/components/Customs/SyTextField/SyTextField.mdx +2 -2
  118. package/src/components/Customs/SyTextField/SyTextField.stories.ts +809 -79
  119. package/src/components/Customs/SyTextField/SyTextField.vue +135 -104
  120. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +190 -38
  121. package/src/components/Customs/SyTextField/types.d.ts +1 -0
  122. package/src/components/DatePicker/DatePicker.stories.ts +177 -5
  123. package/src/components/DatePicker/DatePicker.vue +302 -233
  124. package/src/components/DatePicker/DateTextInput.vue +101 -246
  125. package/src/components/DatePicker/tests/DatePicker.spec.ts +123 -60
  126. package/src/components/DatePicker/tests/DateTextInput.spec.ts +202 -6
  127. package/src/components/FileList/Accessibilite.stories.ts +1 -1
  128. package/src/components/FileList/AccessibiliteItems.ts +22 -0
  129. package/src/components/FileList/FileList.vue +2 -1
  130. package/src/components/FileList/UploadItem/UploadItem.vue +10 -0
  131. package/src/components/FileUpload/FileUpload.stories.ts +93 -7
  132. package/src/components/FileUpload/FileUpload.vue +1 -0
  133. package/src/components/FileUpload/tests/FileUpload.spec.ts +4 -4
  134. package/src/components/FilterInline/Accessibilite.mdx +14 -0
  135. package/src/components/FilterInline/Accessibilite.stories.ts +216 -0
  136. package/src/components/FilterInline/AccessibiliteItems.ts +132 -0
  137. package/src/components/FilterInline/FilterInline.mdx +180 -34
  138. package/src/components/FilterInline/FilterInline.stories.ts +363 -6
  139. package/src/components/FilterInline/constants/ExpertiseLevelEnum.ts +4 -0
  140. package/src/components/FilterSideBar/Accessibilite.mdx +14 -0
  141. package/src/components/FilterSideBar/Accessibilite.stories.ts +216 -0
  142. package/src/components/FilterSideBar/AccessibiliteItems.ts +153 -0
  143. package/src/components/FilterSideBar/FilterSideBar.mdx +237 -0
  144. package/src/components/FilterSideBar/FilterSideBar.stories.ts +798 -0
  145. package/src/components/FilterSideBar/FilterSideBar.vue +193 -0
  146. package/src/components/FilterSideBar/constants/ExpertiseLevelEnum.ts +4 -0
  147. package/src/components/FilterSideBar/locales.ts +8 -0
  148. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +305 -0
  149. package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +39 -0
  150. package/src/components/HeaderBar/Usages.mdx +1 -1
  151. package/src/components/NirField/NirField.stories.ts +738 -29
  152. package/src/components/NirField/NirField.vue +401 -359
  153. package/src/components/NirField/examples//342/200/257dataset/342/200/257.md +12 -0
  154. package/src/components/NirField/tests/NirField.spec.ts +88 -52
  155. package/src/components/NirField/tests/config.spec.ts +65 -0
  156. package/src/components/NotificationBar/Accessibilite.stories.ts +4 -0
  157. package/src/components/NotificationBar/NotificationBar.mdx +2 -2
  158. package/src/components/NotificationBar/NotificationBar.stories.ts +66 -13
  159. package/src/components/NotificationBar/NotificationBar.vue +42 -114
  160. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +28 -33
  161. package/src/components/NotificationBar/tests/__snapshots__/NotificationBar.spec.ts.snap +1 -1
  162. package/src/components/PaginatedTable/PaginatedTable.vue +6 -10
  163. package/src/components/PaginatedTable/tests/__snapshots__/PaginatedTable.spec.ts.snap +4 -4
  164. package/src/components/PasswordField/PasswordField.mdx +129 -47
  165. package/src/components/PasswordField/PasswordField.stories.ts +1111 -120
  166. package/src/components/PasswordField/PasswordField.vue +212 -99
  167. package/src/components/PasswordField/tests/PasswordField.spec.ts +138 -9
  168. package/src/components/PeriodField/PeriodField.stories.ts +214 -118
  169. package/src/components/PeriodField/PeriodField.vue +238 -190
  170. package/src/components/PeriodField/tests/PeriodField.spec.ts +146 -0
  171. package/src/components/PhoneField/PhoneField.stories.ts +170 -0
  172. package/src/components/PhoneField/PhoneField.vue +76 -17
  173. package/src/components/PhoneField/indicatifs.ts +1 -1
  174. package/src/components/PhoneField/tests/PhoneField.spec.ts +40 -0
  175. package/src/components/RatingPicker/RatingPicker.stories.ts +7 -7
  176. package/src/components/SearchListField/SearchListField.stories.ts +1 -1
  177. package/src/components/UploadWorkflow/Accessibilite.mdx +14 -0
  178. package/src/components/UploadWorkflow/Accessibilite.stories.ts +216 -0
  179. package/src/components/UploadWorkflow/AccessibiliteItems.ts +192 -0
  180. package/src/components/UploadWorkflow/UploadWorkflow.mdx +75 -0
  181. package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +943 -0
  182. package/src/components/UploadWorkflow/UploadWorkflow.vue +230 -0
  183. package/src/components/UploadWorkflow/config.ts +29 -0
  184. package/src/components/UploadWorkflow/constants/ExpertiseLevelEnum.ts +4 -0
  185. package/src/components/UploadWorkflow/locales.ts +8 -0
  186. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +257 -0
  187. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +54 -0
  188. package/src/components/UploadWorkflow/types.ts +21 -0
  189. package/src/components/UploadWorkflow/useFileList.ts +84 -0
  190. package/src/components/UploadWorkflow/useFileUploadJourney.ts +18 -0
  191. package/src/components/Usages/tests/Usages.spec.ts +183 -0
  192. package/src/components/index.ts +5 -0
  193. package/src/composables/date/tests/useDateFormat.spec.ts +67 -0
  194. package/src/composables/date/tests/useDateInitialization.spec.ts +89 -0
  195. package/src/composables/date/tests/useDatePickerAccessibility.spec.ts +102 -0
  196. package/src/composables/date/useDateFormat.ts +94 -0
  197. package/src/composables/date/useDateInitialization.ts +92 -0
  198. package/src/composables/date/useDatePickerAccessibility.ts +78 -0
  199. package/src/composables/rules/tests/useFieldValidation.spec.ts +385 -4
  200. package/src/composables/rules/useFieldValidation.ts +5 -2
  201. package/src/composables/useFilterable/useFilterable.ts +5 -4
  202. package/src/composables/validation/tests/useValidation.spec.ts +154 -0
  203. package/src/composables/validation/useValidation.ts +180 -0
  204. package/src/designTokens/index.ts +4 -0
  205. package/src/main.ts +1 -0
  206. package/src/stories/Accessibilite/Aculturation/AuditDesignSystem.mdx +28 -0
  207. package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +2 -2
  208. package/src/stories/Accessibilite/Audit/RGAA.mdx +6 -6
  209. package/src/stories/Accessibilite/Introduction.mdx +2 -1
  210. package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +1 -1
  211. package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +1 -1
  212. package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +8 -11
  213. package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +77 -0
  214. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru.mdx +9 -3
  215. package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +2 -2
  216. package/src/stories/Demarrer/Accueil.mdx +1 -1
  217. package/src/stories/Demarrer/Introduction.stories.ts +3 -3
  218. package/src/stories/Demarrer/Releases.mdx +8 -0
  219. package/src/stories/Demarrer/Releases.stories.ts +66 -0
  220. package/src/stories/DesignTokens/Conteneurs.stories.ts +3 -3
  221. package/src/stories/DesignTokens/ThemePA.mdx +4 -30
  222. package/src/stories/GuideDuDev/LesBreackingChanges.mdx +36 -0
  223. package/src/stories/GuideDuDev/UtiliserLesRules.mdx +321 -78
  224. package/src/stories/GuideDuDev/moduleDeNotification.mdx +1 -1
  225. package/src/utils/formatDate/index.ts +6 -0
  226. package/src/utils/formatDate/tests/formatDate.spec.ts +18 -0
  227. package/src/utils/functions/validation/isDateAfter/index.ts +9 -0
  228. package/src/utils/functions/validation/isDateAfter/tests/isDateAfter.spec.ts +18 -0
  229. package/src/utils/functions/validation/isDateBefore/index.ts +9 -0
  230. package/src/utils/functions/validation/isDateBefore/tests/isDateBefore.spec.ts +23 -0
  231. package/src/utils/functions/validation/isDateInRange/index.ts +22 -0
  232. package/src/utils/functions/validation/isDateInRange/tests/isDateInRange.spec.ts +28 -0
  233. package/src/utils/functions/validation/isDateValid/index.ts +67 -0
  234. package/src/utils/functions/validation/isDateValid/tests/isDateValid.spec.ts +46 -0
  235. package/src/utils/functions/validation/isEmailValid/index.ts +9 -0
  236. package/src/utils/functions/validation/isWeekend/index.ts +10 -0
  237. package/src/utils/functions/validation/isWeekend/tests/isWeekend.spec.ts +16 -0
  238. package/src/utils/parseDate/index.ts +29 -0
  239. package/src/utils/parseDate/tests/parseDate.spec.ts +52 -0
  240. package/src/utils/rules/Rules.mdx +16 -0
  241. package/src/utils/rules/doMatchPattern/DoMachPattern.mdx +66 -0
  242. package/src/utils/rules/doMatchPattern/DoMatchPattern.stories.ts +106 -0
  243. package/src/utils/rules/doMatchPattern/index.ts +28 -0
  244. package/src/utils/rules/doMatchPattern/locales.ts +5 -0
  245. package/src/utils/rules/doMatchPattern/tests/matchPattern.spec.ts +38 -0
  246. package/src/utils/rules/index.ts +11 -0
  247. package/src/utils/rules/isDateValid/IsDateValid.mdx +87 -0
  248. package/src/utils/rules/isDateValid/IsDateValid.stories.ts +113 -0
  249. package/src/utils/rules/isDateValid/index.ts +32 -0
  250. package/src/utils/rules/isDateValid/locales.ts +10 -0
  251. package/src/utils/rules/isDateValid/tests/isDateValid.spec.ts +27 -0
  252. package/src/utils/rules/isExactLength/IsExactLenght.mdx +68 -0
  253. package/src/utils/rules/isExactLength/IsExactLength.stories.ts +151 -0
  254. package/src/utils/rules/{exactLength → isExactLength}/index.ts +2 -4
  255. package/src/utils/rules/isExactLength/tests/exactLength.spec.ts +48 -0
  256. package/src/utils/rules/isMaxLength/IsMaxLength.mdx +68 -0
  257. package/src/utils/rules/isMaxLength/IsMaxLength.stories.ts +152 -0
  258. package/src/utils/rules/isMaxLength/index.ts +30 -0
  259. package/src/utils/rules/isMaxLength/locales.ts +6 -0
  260. package/src/utils/rules/isMaxLength/tests/isMaxLength.spec.ts +42 -0
  261. package/src/utils/rules/isMinLength/IsMinLength.mdx +68 -0
  262. package/src/utils/rules/isMinLength/IsMinLength.stories.ts +152 -0
  263. package/src/utils/rules/isMinLength/index.ts +30 -0
  264. package/src/utils/rules/isMinLength/locales.ts +6 -0
  265. package/src/utils/rules/isMinLength/tests/isMinLength.spec.ts +42 -0
  266. package/src/utils/rules/isNotAfterDate/IsNotAfterDate.mdx +68 -0
  267. package/src/utils/rules/isNotAfterDate/IsNotAfterDate.stories.ts +109 -0
  268. package/src/utils/rules/isNotAfterDate/index.ts +25 -0
  269. package/src/utils/rules/isNotAfterDate/locales.ts +6 -0
  270. package/src/utils/rules/isNotAfterDate/tests/isNotAfterDate.spec.ts +25 -0
  271. package/src/utils/rules/isNotAfterToday/IsNotAfterToday.mdx +83 -0
  272. package/src/utils/rules/isNotAfterToday/IsNotAfterToday.stories.ts +110 -0
  273. package/src/utils/rules/isNotAfterToday/index.ts +28 -0
  274. package/src/utils/rules/isNotAfterToday/locales.ts +5 -0
  275. package/src/utils/rules/isNotAfterToday/tests/isNotAfterToday.spec.ts +30 -0
  276. package/src/utils/rules/isNotBeforeDate/IsNotBeforeDate.mdx +68 -0
  277. package/src/utils/rules/isNotBeforeDate/IsNotBeforeDate.stories.ts +114 -0
  278. package/src/utils/rules/isNotBeforeDate/index.ts +25 -0
  279. package/src/utils/rules/isNotBeforeDate/locales.ts +6 -0
  280. package/src/utils/rules/isNotBeforeDate/tests/IsNotBeforeDate.spec.ts +25 -0
  281. package/src/utils/rules/isNotBeforeToday/IsNotBeforeToday.mdx +83 -0
  282. package/src/utils/rules/isNotBeforeToday/IsNotBeforeToday.stories.ts +110 -0
  283. package/src/utils/rules/isNotBeforeToday/index.ts +28 -0
  284. package/src/utils/rules/isNotBeforeToday/locales.ts +5 -0
  285. package/src/utils/rules/isNotBeforeToday/tests/notBeforeToday.spec.ts +36 -0
  286. package/src/utils/rules/isRequired/IsRequired.mdx +81 -0
  287. package/src/utils/rules/isRequired/IsRequired.stories.ts +101 -0
  288. package/src/utils/rules/{required → isRequired}/index.ts +3 -3
  289. package/src/utils/rules/{required/tests/index.spec.ts → isRequired/tests/isRequred.spec.ts} +9 -9
  290. package/src/utils/rules/isValidEmail/IsValidEmail.mdx +81 -0
  291. package/src/utils/rules/isValidEmail/IsValidEmail.stories.ts +101 -0
  292. package/src/utils/rules/{email → isValidEmail}/index.ts +3 -5
  293. package/src/utils/rules/{email/tests/email.spec.ts → isValidEmail/tests/isValidEmail.spec.ts} +5 -5
  294. package/src/vuetifyConfig.ts +61 -0
  295. package/dist/src/utils/rules/email/index.d.ts +0 -4
  296. package/dist/src/utils/rules/exactLength/index.d.ts +0 -4
  297. package/dist/src/utils/rules/required/index.d.ts +0 -4
  298. package/dist/src/utils/rules/required/ruleMessageHelper.d.ts +0 -3
  299. package/src/components/Customs/SyTextField/tests/__snapshots__/SyTextField.spec.ts.snap +0 -58
  300. package/src/composables/useFilterable/__snapshots__/useFilterable.spec.ts.snap +0 -3
  301. package/src/utils/functions/isEmailValid/index.ts +0 -8
  302. package/src/utils/rules/required/ruleMessageHelper.ts +0 -14
  303. package/src/utils/rules/required/tests/rulesMessageHelper.spec.ts +0 -22
  304. /package/dist/src/{utils/functions/isEmailValid/tests/isEmailValid.spec.d.ts → components/FilterSideBar/tests/FilterSideBar.spec.d.ts} +0 -0
  305. /package/dist/src/{utils/rules/email/tests/email.spec.d.ts → components/NirField/tests/config.spec.d.ts} +0 -0
  306. /package/dist/src/{utils/rules/required/tests/index.spec.d.ts → components/UploadWorkflow/tests/UploadWorkflow.spec.d.ts} +0 -0
  307. /package/dist/src/{utils/rules/required/tests/rulesMessageHelper.spec.d.ts → components/Usages/tests/Usages.spec.d.ts} +0 -0
  308. /package/dist/src/utils/functions/{isEmailValid → validation/isEmailValid}/index.d.ts +0 -0
  309. /package/dist/src/utils/rules/{exactLength → doMatchPattern}/locales.d.ts +0 -0
  310. /package/dist/src/utils/rules/{email → isDateValid}/locales.d.ts +0 -0
  311. /package/dist/src/utils/rules/{required → isNotAfterDate}/locales.d.ts +0 -0
  312. /package/src/utils/functions/{isEmailValid → validation/isEmailValid}/tests/isEmailValid.spec.ts +0 -0
  313. /package/src/utils/rules/{exactLength → isExactLength}/locales.ts +0 -0
  314. /package/src/utils/rules/{required → isRequired}/locales.ts +0 -0
  315. /package/src/utils/rules/{email → isValidEmail}/locales.ts +0 -0
@@ -1,457 +1,499 @@
1
1
  <script lang="ts" setup>
2
- import { ref, watch, computed, nextTick } from 'vue'
3
- import { useFieldValidation } from '@/composables/rules/useFieldValidation'
2
+ import { ref, watch, computed, nextTick, toRef } from 'vue'
4
3
  import { vMaska } from 'maska/vue'
5
4
  import { checkNIR, isNIRKeyValid } from './nirValidation'
6
- import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
5
+ // import useCustomizableOptions, { type CustomizableOptions } from '@/composables/useCustomizableOptions'
6
+ import { type CustomizableOptions } from '@/composables/useCustomizableOptions'
7
7
  import SyTextField from '../Customs/SyTextField/SyTextField.vue'
8
- import { mdiInformationOutline } from '@mdi/js'
9
8
  import { locales } from './locales'
10
- import defaultOptions from './config'
11
-
12
- type Rule = (value: string) => { error?: string, success?: string }
13
-
9
+ // import defaultOptions from './config'
10
+ import { useValidation, type ValidationRule } from '@/composables/validation/useValidation'
14
11
  const props = withDefaults(defineProps<CustomizableOptions & {
15
12
  modelValue?: string | undefined
16
- outlined?: boolean
17
- required?: boolean
18
- nirTooltip?: string
19
- keyTooltip?: string
13
+ label?: string
20
14
  numberLabel?: string
21
15
  keyLabel?: string
22
16
  displayKey?: boolean
17
+ outlined?: boolean
18
+ nirTooltip?: string
19
+ keyTooltip?: string
20
+ nirTooltipPosition?: 'prepend' | 'append'
21
+ keyTooltipPosition?: 'prepend' | 'append'
22
+ required?: boolean
23
+ displayAsterisk?: boolean
24
+ customNumberRules?: ValidationRule[]
25
+ customKeyRules?: ValidationRule[]
26
+ customNumberWarningRules?: ValidationRule[]
27
+ customKeyWarningRules?: ValidationRule[]
23
28
  showSuccessMessages?: boolean
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
25
- customNumberRules?: any
26
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
27
- customKeyRules?: any
28
29
  width?: string
30
+ bgColor?: string
31
+ isDisabled?: boolean
32
+ density?: 'default' | 'comfortable' | 'compact'
33
+ hideDetails?: boolean | 'auto'
34
+ hideSpinButtons?: boolean
35
+ placeholder?: string
36
+ readonly?: boolean
37
+ variant?: 'filled' | 'outlined' | 'plain' | 'underlined' | 'solo'
38
+ clearable?: boolean
39
+ counter?: boolean | number | string
40
+ hint?: string
41
+ persistentHint?: boolean
42
+ persistentPlaceholder?: boolean
43
+ disableErrorHandling?: boolean
29
44
  }>(), {
30
45
  modelValue: undefined,
31
- outlined: true,
32
- required: false,
33
- nirTooltip: undefined,
34
- keyTooltip: undefined,
46
+ label: undefined,
35
47
  numberLabel: 'Numéro de sécurité sociale',
36
48
  keyLabel: 'Clé',
37
49
  displayKey: true,
38
- showSuccessMessages: false,
39
- customNumberRules: [],
40
- customKeyRules: [],
50
+ outlined: true,
51
+ nirTooltip: undefined,
52
+ keyTooltip: undefined,
53
+ nirTooltipPosition: 'append',
54
+ keyTooltipPosition: 'append',
55
+ required: false,
56
+ displayAsterisk: false,
57
+ customNumberRules: () => [],
58
+ customKeyRules: () => [],
59
+ customNumberWarningRules: () => [],
60
+ customKeyWarningRules: () => [],
61
+ showSuccessMessages: true,
41
62
  width: '100%',
63
+ bgColor: undefined,
64
+ isDisabled: false,
65
+ density: 'default',
66
+ hideDetails: false,
67
+ hideSpinButtons: false,
68
+ placeholder: undefined,
69
+ readonly: false,
70
+ variant: 'outlined',
71
+ clearable: false,
72
+ counter: false,
73
+ hint: undefined,
74
+ persistentHint: false,
75
+ persistentPlaceholder: false,
76
+ disableErrorHandling: false,
42
77
  })
43
78
 
44
79
  const emit = defineEmits(['update:modelValue'])
45
- const options = useCustomizableOptions(defaultOptions, props)
46
- const infoIcon = mdiInformationOutline
80
+ const modelValueRef = toRef(props, 'modelValue')
81
+ // const options = useCustomizableOptions(defaultOptions, props)
47
82
 
48
83
  // Champs
49
84
  const numberValue = ref('')
50
85
  const keyValue = ref('')
51
- const keyDeleted = ref(false)
52
86
 
53
87
  // Refs pour les champs
54
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
55
- const keyField = ref<any | null>(null)
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
57
- const numberField = ref<any | null>(null)
88
+ const keyField = ref<InstanceType<typeof SyTextField> | null>(null)
89
+ const numberField = ref<InstanceType<typeof SyTextField> | null>(null)
58
90
 
91
+ // Valeurs non masquées
59
92
  const unmaskedNumberValue = computed(() => numberValue.value.replace(/\s/g, ''))
60
-
61
- watch(() => props.modelValue, async (value) => {
62
- numberValue.value = value?.slice(0, 13) ?? ''
63
- keyValue.value = value?.slice(13, 15) ?? ''
64
- }, { immediate: true })
65
-
66
- // Etats d’erreur/succès
67
- const errors = ref<string[]>([])
68
- const successes = ref<string[]>([])
69
-
70
- // Flags de validation
71
- const isValidating = ref(false)
93
+ const unmaskedKeyValue = computed(() => keyValue.value.replace(/\s/g, ''))
72
94
 
73
95
  // Masques
74
96
  const numberMask = {
75
97
  mask: '# ## ## #C ### ###',
76
98
  preProcess: (value: string) => value.toUpperCase(),
77
99
  tokens: {
78
- C: {
100
+ '#': {
101
+ pattern: /[0-9]/,
102
+ },
103
+ 'C': {
79
104
  pattern: /[0-9AB]/,
80
105
  transform: (char: string) => char.toUpperCase(),
81
106
  },
82
107
  },
83
108
  }
84
- const keyMask = { mask: '##' }
85
-
86
- // Règles de validation par défaut
87
- const { generateRules } = useFieldValidation()
88
-
89
- const defaultNumberRules = [
90
- {
91
- type: 'exactLength',
92
- options: { length: 13, message: locales.errorLengthNumber(13), ignoreSpace: true, fieldIdentifier: 'numéro' },
93
- },
94
- {
95
- type: 'custom',
96
- options: {
97
- validate: checkNIR,
98
- message: 'Le numéro de sécurité sociale est invalide.',
99
- successMessage: 'Le numéro de sécurité sociale est valide.',
100
- fieldIdentifier: 'numéro',
101
- },
102
- },
103
- ...(props.required
104
- ? [{
105
- type: 'required',
106
- options: { message: 'Le numéro de sécurité sociale est requis.', fieldIdentifier: 'numéro' },
107
- }]
108
- : []),
109
- ]
110
-
111
- const defaultKeyRules = [
112
- {
113
- type: 'exactLength',
114
- options: { length: 2, message: locales.errorLengthKey(2), ignoreSpace: true, fieldIdentifier: 'clé' },
115
- },
116
- {
117
- type: 'custom',
118
- options: {
119
- validate: () => isNIRKeyValid(`${numberValue.value}${keyValue.value}`),
120
- message: 'La clé du numéro de sécurité sociale est invalide.',
121
- successMessage: 'Le champ clé est valide.',
122
- fieldIdentifier: 'clé',
109
+ const keyMask = {
110
+ mask: '##',
111
+ tokens: {
112
+ '#': {
113
+ pattern: /[0-9]/,
123
114
  },
124
115
  },
125
- ...(props.required
126
- ? [{
127
- type: 'required',
128
- options: { message: 'La clé est requise.', fieldIdentifier: 'clé' },
129
- }]
130
- : []),
131
- ]
116
+ }
132
117
 
133
- // Computed pour statut des champs
134
- const fieldIdentifierNumber = defaultNumberRules[0]?.options?.fieldIdentifier
135
- const fieldIdentifierKey = defaultKeyRules[0]?.options?.fieldIdentifier
136
-
137
- const hasNumberErrors = computed(() => errors.value.some(error => error.includes(fieldIdentifierNumber)))
138
- const hasKeyErrors = computed(() => errors.value.some(error => error.includes(fieldIdentifierKey)))
139
- const hasNumberSuccess = computed(() => successes.value.some(success => success.includes(fieldIdentifierNumber)))
140
- const hasKeySuccess = computed(() => successes.value.some(success => success.includes(fieldIdentifierKey)))
141
-
142
- // Génération des règles finales
143
- const numberRules = props.customNumberRules?.length
144
- ? generateRules(props.customNumberRules)
145
- : generateRules(defaultNumberRules)
146
-
147
- const keyRules = props.displayKey
148
- ? (props.customKeyRules?.length
149
- ? generateRules(props.customKeyRules)
150
- : generateRules(defaultKeyRules))
151
- : []
152
-
153
- /**
154
- * Valide une liste de règles sur une valeur et met à jour les tableaux d'erreurs et de succès.
155
- * @param value Valeur du champ à valider
156
- * @param rules Ensemble de règles
157
- */
158
- function validateFieldSet(value: string, rules: Rule[]) {
159
- rules.forEach((rule) => {
160
- const { error, success } = rule(value)
161
- if (error) errors.value.push(error)
162
- if (success && success !== 'Le champ est valide.') successes.value.push(success)
118
+ // Fonction pour gérer le focus des champs
119
+ const focusField = (field: typeof numberField | typeof keyField) => {
120
+ nextTick(() => {
121
+ const input = field.value?.$el.querySelector('input')
122
+ if (input) {
123
+ // Focus and select all text
124
+ input.focus()
125
+ // Adding a slight delay to ensure focus is applied
126
+ setTimeout(() => {
127
+ input.click()
128
+ }, 50)
129
+ }
163
130
  })
164
131
  }
165
132
 
166
- /**
167
- * Valide les champs numéro et clé (si activée).
168
- * @param onBlur Si true, la validation est lancée suite à un blur, sinon validation continue
169
- */
170
- function validateFields(onBlur = false) {
171
- errors.value = []
172
- successes.value = []
173
-
174
- const shouldValidateNumber = onBlur || isValidating.value || numberValue.value.length === 18
175
- const shouldValidateKey = props.displayKey && (onBlur || isValidating.value || keyValue.value.length === 2)
176
-
177
- if (shouldValidateNumber) {
178
- validateFieldSet(numberValue.value, numberRules)
133
+ // Watch sur la valeur non masquée du numéro pour gérer le focus automatique
134
+ watch(unmaskedNumberValue, (newValue) => {
135
+ if (newValue.length === 13 && props.displayKey) {
136
+ focusField(keyField)
179
137
  }
180
-
181
- if (shouldValidateKey) {
182
- validateFieldSet(keyValue.value, keyRules)
183
- }
184
-
185
- // Unicité des succès
186
- successes.value = Array.from(new Set(successes.value))
187
- }
188
-
189
- // Compteurs
190
- const numberCounter = computed(() => {
191
- const length = numberValue.value.replace(/\s/g, '').length
192
- return `${Math.min(length, 13)}/13`
193
138
  })
194
139
 
195
- const keyCounter = computed(() => {
196
- const length = keyValue.value.replace(/\s/g, '').length
197
- return `${Math.min(length, 2)}/2`
140
+ watch(unmaskedKeyValue, (newValue) => {
141
+ if (newValue.length === 0) {
142
+ focusField(numberField)
143
+ }
198
144
  })
199
145
 
200
- watch([unmaskedNumberValue, keyValue], () => {
201
- validateFields()
202
- if (unmaskedNumberValue.value + keyValue.value !== props.modelValue) {
203
- emit('update:modelValue', `${unmaskedNumberValue.value}${keyValue.value}`)
146
+ // Watch pour détecter la suppression des chiffres de la clé
147
+ watch(keyValue, (newValue, oldValue) => {
148
+ // Si l'ancienne valeur avait des chiffres et la nouvelle est vide ou ne contient que des espaces
149
+ if (oldValue.trim() && !newValue.trim()) {
150
+ focusField(numberField)
204
151
  }
205
152
  })
206
153
 
207
- watch(keyValue, (newValue, oldValue) => {
208
- keyDeleted.value = !!(!newValue && oldValue)
154
+ // Initialisation des validations
155
+ const numberValidation = useValidation({
156
+ showSuccessMessages: props.showSuccessMessages,
157
+ fieldIdentifier: props.numberLabel,
158
+ disableErrorHandling: props.disableErrorHandling,
209
159
  })
210
160
 
211
- watch(numberValue, () => {
212
- if (unmaskedNumberValue.value.length < 13) {
213
- keyDeleted.value = false
214
- }
161
+ const keyValidation = useValidation({
162
+ showSuccessMessages: props.showSuccessMessages,
163
+ fieldIdentifier: props.keyLabel,
164
+ disableErrorHandling: props.disableErrorHandling,
215
165
  })
216
166
 
217
- // Déplacement du focus sur la clé quand le numéro est rempli
218
- const focusElement = computed(() => {
219
- if (props.displayKey && numberValue.value.length === 18) {
220
- if (!keyDeleted.value) {
221
- return keyField.value?.$el?.querySelector('input')
222
- }
223
- else {
224
- return numberField.value?.$el?.querySelector('input')
225
- }
167
+ // Règles de validation
168
+ const defaultNumberRules = computed(() => {
169
+ const rules: ValidationRule[] = []
170
+
171
+ if (props.required) {
172
+ rules.push({
173
+ type: 'required',
174
+ options: {
175
+ message: `Le champ ${props.numberLabel} est requis.`,
176
+ fieldIdentifier: props.numberLabel,
177
+ },
178
+ })
226
179
  }
227
- return null
228
- })
229
180
 
230
- watch(focusElement, (newEl) => {
231
- nextTick(() => {
232
- newEl?.focus()
181
+ rules.push({
182
+ type: 'custom',
183
+ options: {
184
+ validate: (value: string) => {
185
+ if (!value) return true
186
+ // Ne valider que si tous les caractères sont saisis
187
+ if (value.length < 13) {
188
+ return 'Le numéro de sécurité sociale est invalide.'
189
+ }
190
+ const result = checkNIR(value)
191
+ return result === true ? true : 'Le numéro de sécurité sociale est invalide.'
192
+ },
193
+ message: 'Le numéro de sécurité sociale est invalide.',
194
+ successMessage: 'Le numéro de sécurité sociale est valide.',
195
+ fieldIdentifier: props.numberLabel,
196
+ },
233
197
  })
234
- })
235
198
 
236
- function validateOnSubmit() {
237
- isValidating.value = true
238
- validateFields(true)
239
- return errors.value.length === 0
240
- }
199
+ // Ajout des règles personnalisées
200
+ if (props.customNumberRules) {
201
+ rules.push(...props.customNumberRules.map(rule => ({
202
+ ...rule,
203
+ options: rule.options || {},
204
+ })))
205
+ }
241
206
 
242
- defineExpose({
243
- validateOnSubmit,
207
+ return rules
244
208
  })
245
- </script>
246
209
 
247
- <template>
248
- <div class="d-flex align-start nir-container">
249
- <v-input
250
- ref="vInput"
251
- :class="{
252
- 'v-messages__message--success': successes.length > 0 && props.showSuccessMessages,
253
- 'v-messages__message--error': errors.length > 0
254
- }"
255
- :error-messages="errors"
256
- :label="numberLabel"
257
- :max-errors="3"
258
- :messages="props.showSuccessMessages ? successes : []"
259
- :model-value="[numberValue, keyValue]"
260
- class="vd-nir-field__fields-wrapper multi-line"
261
- validate-on="blur lazy"
262
- >
263
- <VTooltip v-if="nirTooltip">
264
- <template #activator="{ props: iconProps }">
265
- <VIcon
266
- class="vd-tooltip-icon mt-4 mr-4"
267
- v-bind="{ ...iconProps, ...options.tooltip }"
268
- >
269
- {{ infoIcon }}
270
- </VIcon>
271
- </template>
272
- <slot name="nirTooltip">
273
- {{ nirTooltip }}
274
- </slot>
275
- </VTooltip>
276
- <SyTextField
277
- ref="numberField"
278
- v-model="numberValue"
279
- v-maska="numberMask"
280
- :append-inner-icon="hasNumberErrors ? 'error' : (hasNumberSuccess ? 'success' : undefined)"
281
- :aria-errormessage="hasNumberErrors ? 'number-field-errors' : undefined"
282
- :aria-invalid="hasNumberErrors"
283
- :aria-required="required"
284
- :color="hasNumberErrors ? 'error' : 'primary'"
285
- :error="hasNumberErrors"
286
- :hint="locales.numberHint"
287
- :label="numberLabel"
288
- :variant="outlined ? 'outlined' : 'underlined'"
289
- class="vd-number-field"
290
- title="nirField"
291
- @blur="validateFields(true)"
292
- >
293
- <template #details>
294
- <span class="custom-counter">
295
- {{ numberCounter }}
296
- </span>
297
- </template>
298
- </SyTextField>
299
-
300
- <template v-if="displayKey">
301
- <SyTextField
302
- ref="keyField"
303
- v-model="keyValue"
304
- v-maska="keyMask"
305
- :append-inner-icon="hasKeyErrors ? 'error' : (hasKeySuccess ? 'success' : undefined)"
306
- :aria-errormessage="hasKeyErrors ? 'key-field-errors' : undefined"
307
- :aria-invalid="hasKeyErrors"
308
- :aria-required="required"
309
- :color="hasKeyErrors ? 'error' : 'primary'"
310
- :error="hasKeyErrors"
311
- :hint="locales.keyHint"
312
- :label="keyLabel"
313
- :variant="outlined ? 'outlined' : 'underlined'"
314
- class="vd-key-field"
315
- title="nirKeyField"
316
- @blur="validateFields(true)"
317
- >
318
- <template #details>
319
- <span class="custom-counter">
320
- {{ keyCounter }}
321
- </span>
322
- </template>
323
- </SyTextField>
324
-
325
- <VTooltip v-if="keyTooltip">
326
- <template #activator="{ props: iconProps }">
327
- <VIcon
328
- class="vd-tooltip-icon mt-4 ml-4"
329
- v-bind="{ ...iconProps, ...options.icon }"
330
- >
331
- {{ infoIcon }}
332
- </VIcon>
333
- </template>
334
- <slot name="keyTooltip">
335
- {{ keyTooltip }}
336
- </slot>
337
- </VTooltip>
338
- </template>
339
- </v-input>
340
- </div>
341
- </template>
210
+ const defaultKeyRules = computed(() => {
211
+ const rules: ValidationRule[] = []
342
212
 
343
- <style lang="scss" scoped>
344
- @use '@/assets/tokens';
213
+ if (props.required) {
214
+ rules.push({
215
+ type: 'required',
216
+ options: {
217
+ message: `Le champ ${props.keyLabel} est requis.`,
218
+ fieldIdentifier: props.keyLabel,
219
+ },
220
+ })
221
+ }
345
222
 
346
- .nir-container {
347
- width: v-bind('props.width');
348
- }
223
+ const validateKey = (value: string) => {
224
+ if (!value) return true
225
+ if (!unmaskedNumberValue.value) return true
226
+ const fullNir = unmaskedNumberValue.value + value
227
+ return isNIRKeyValid(fullNir)
228
+ }
349
229
 
350
- .v-messages__message--success {
351
- color: tokens.$colors-border-success !important;
230
+ // Ajout des règles personnalisées
231
+ if (props.customKeyRules) {
232
+ rules.push(...props.customKeyRules)
233
+ }
352
234
 
353
- .v-field--active & {
354
- color: tokens.$colors-border-success !important;
355
- }
356
- }
235
+ // Ajout de la règle de validation par défaut si pas de règle personnalisée avec validation de clé
236
+ if (!props.customKeyRules?.some(rule => rule.options.validate)) {
237
+ rules.push({
238
+ type: 'custom',
239
+ options: {
240
+ validate: validateKey,
241
+ message: 'La clé du numéro de sécurité sociale est invalide.',
242
+ successMessage: `Le champ ${props.keyLabel} est valide.`,
243
+ fieldIdentifier: props.keyLabel,
244
+ },
245
+ })
246
+ }
357
247
 
358
- .v-messages__message--error {
359
- color: tokens.$colors-border-error;
248
+ return rules
249
+ })
360
250
 
361
- .v-field--active & {
362
- color: tokens.$colors-border-error;
363
- }
364
- }
251
+ // Synchronisation avec modelValue
252
+ watch(modelValueRef, (newValue) => {
253
+ if (newValue === undefined) {
254
+ numberValue.value = ''
255
+ keyValue.value = ''
256
+ return
257
+ }
258
+ if (newValue.length === 15) {
259
+ const number = newValue.slice(0, -2)
260
+ const key = newValue.slice(-2)
261
+ numberValue.value = number
262
+ keyValue.value = key
263
+ }
264
+ if (newValue.length === 14) {
265
+ const number = newValue.slice(0, -1)
266
+ const key = newValue.slice(-1)
267
+ numberValue.value = number
268
+ keyValue.value = key
269
+ }
270
+ if (newValue.length === 13) {
271
+ const number = newValue
272
+ numberValue.value = number
273
+ keyValue.value = ''
274
+ }
275
+ }, { immediate: true })
365
276
 
366
- :deep(.v-field.v-field--active .v-label.v-field-label--floating) {
367
- opacity: 1;
368
- }
277
+ // Émission de la valeur
278
+ const emitValue = () => {
279
+ const number = unmaskedNumberValue.value
280
+ const key = unmaskedKeyValue.value
369
281
 
370
- .multi-line {
371
- white-space: pre-line !important;
372
- }
282
+ if (!number && !key) {
283
+ emit('update:modelValue', undefined)
284
+ return
285
+ }
373
286
 
374
- .vd-number-field {
375
- min-width: 296px;
376
- }
287
+ emit('update:modelValue', `${number}${key}`)
288
+ }
377
289
 
378
- .vd-key-field {
379
- min-width: 104px;
380
- flex: none;
381
- margin-left: 1rem;
382
- }
290
+ // Validation des champs
291
+ const validateFields = async (onBlur = false) => {
292
+ // Valider le numéro
293
+ const numberResult = numberValidation.validateField(
294
+ unmaskedNumberValue.value,
295
+ defaultNumberRules.value,
296
+ // N'appliquer les warnings que si le numéro est complet
297
+ unmaskedNumberValue.value?.length === 13 ? props.customNumberWarningRules : [],
298
+ )
299
+
300
+ // Valider la clé si elle est affichée
301
+ let keyResult = { hasError: false }
302
+ if (props.displayKey) {
303
+ keyResult = keyValidation.validateField(
304
+ keyValue.value,
305
+ defaultKeyRules.value,
306
+ // N'appliquer les warnings que si la clé est complète
307
+ keyValue.value?.length === 2 ? props.customKeyWarningRules : [],
308
+ )
309
+ }
383
310
 
384
- .custom-counter {
385
- color: rgb(0 0 0 / 54%);
386
- }
311
+ // Si on est en mode blur et qu'il y a des erreurs, focus sur le premier champ en erreur
312
+ if (onBlur) {
313
+ await nextTick()
314
+ if (numberResult.hasError) {
315
+ numberField.value?.$el.querySelector('input')?.focus()
316
+ }
317
+ else if (keyResult.hasError) {
318
+ keyField.value?.$el.querySelector('input')?.focus()
319
+ }
320
+ }
387
321
 
388
- .vd-nir-field :deep(.v-input__append-inner),
389
- .vd-tooltip-icon {
390
- flex: none;
391
- color: rgb(0 0 0 / 54%);
392
- }
322
+ return !numberResult.hasError && !keyResult.hasError
323
+ }
393
324
 
394
- :deep(.v-overlay__content) {
395
- background: rgb(84 88 89 / 95%) !important;
396
- }
325
+ const validateOnSubmit = () => {
326
+ return validateFields(true)
327
+ }
397
328
 
398
- .vd-nir-field--outlined :deep(.v-messages.error--text) {
399
- padding: 6px;
400
- }
329
+ // Computed pour statut des champs
330
+ const hasNumberErrors = computed(() => numberValidation.hasError.value)
331
+ const hasNumberWarning = computed(() => !hasNumberErrors.value && numberValidation.hasWarning.value)
332
+ const hasNumberSuccess = computed(() => !hasNumberErrors.value && !hasNumberWarning.value && numberValidation.hasSuccess.value)
401
333
 
402
- .vd-nir-field {
403
- container-name: nirfieldwrapper;
404
- }
334
+ const hasKeyErrors = computed(() => keyValidation.hasError.value)
335
+ const hasKeyWarning = computed(() => !hasKeyErrors.value && keyValidation.hasWarning.value)
336
+ const hasKeySuccess = computed(() => !hasKeyErrors.value && !hasKeyWarning.value && keyValidation.hasSuccess.value)
405
337
 
406
- :deep(.v-input__append) {
407
- margin-inline-start: 0 !important;
408
- }
338
+ // Labels avec astérisque si nécessaire
339
+ const numberLabelWithAsterisk = computed(() => {
340
+ return props.required && props.displayAsterisk ? `${props.numberLabel} *` : props.numberLabel
341
+ })
409
342
 
410
- :deep(.vd-number-field > .v-input__prepend) {
411
- margin-right: 0 !important;
412
- }
343
+ const keyLabelWithAsterisk = computed(() => {
344
+ return props.required && props.displayAsterisk ? `${props.keyLabel} *` : props.keyLabel
345
+ })
413
346
 
414
- :deep(.vd-key-field > .v-input__prepend) {
415
- @media screen and (width <= 360px) {
416
- margin-inline-end: 0 !important;
347
+ // Gestion des événements
348
+ const handleNumberInput = () => {
349
+ emitValue()
350
+ validateFields()
417
351
  }
418
- }
419
352
 
420
- :deep(.v-text-field .v-input__details) {
421
- padding-inline: 0 !important;
422
- flex: none !important;
423
- }
353
+ const handleKeyInput = () => {
354
+ emitValue()
355
+ validateFields()
424
356
 
425
- :deep(.v-text-field .v-input__details .v-messages) {
426
- color: rgb(0 0 0 / 100%) !important;
427
- }
357
+ // Si on supprime le contenu de la clé, on revient au champ NIR
358
+ if (unmaskedKeyValue.value.length === 0) {
359
+ nextTick(() => {
360
+ numberField.value?.$el.querySelector('input')?.focus()
361
+ })
362
+ }
363
+ }
428
364
 
429
- @mixin responsive-nir-wrapper {
430
- .vd-nir-field__fields-wrapper :deep(> .v-input__control) {
431
- justify-content: start;
432
- flex-wrap: wrap;
433
- gap: 4px;
434
- margin-bottom: 4px;
365
+ const handleNumberBlur = () => {
366
+ validateFields(true)
367
+ }
435
368
 
436
- .vd-number-field {
437
- flex: 100% 0 0;
438
- }
369
+ const handleKeyBlur = () => {
370
+ validateFields(true)
439
371
  }
440
- }
441
372
 
442
- @container nirFieldwrapper (max-width: 300px) {
443
- @include responsive-nir-wrapper;
373
+ defineExpose({
374
+ validateOnSubmit,
375
+ numberMask,
376
+ keyMask,
377
+ numberValidation,
378
+ keyValidation,
379
+ } satisfies {
380
+ validateOnSubmit: () => Promise<boolean>
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
382
+ numberMask: { mask: string, preProcess: (value: string) => string, tokens: Record<string, any> }
383
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
384
+ keyMask: { mask: string, tokens: Record<string, any> }
385
+ numberValidation: ReturnType<typeof useValidation>
386
+ keyValidation: ReturnType<typeof useValidation>
387
+ })
388
+ </script>
389
+
390
+ <template>
391
+ <div
392
+ class="nir-field"
393
+ >
394
+ <div class="number-field-container">
395
+ <SyTextField
396
+ ref="numberField"
397
+ v-model="numberValue"
398
+ v-maska="numberMask"
399
+ :label="numberLabelWithAsterisk"
400
+ :variant-style="outlined ? 'outlined' : 'underlined'"
401
+ :prepend-icon="nirTooltip && nirTooltipPosition === 'prepend' ? 'info' : undefined"
402
+ :append-icon="nirTooltip && nirTooltipPosition === 'append' ? 'info' : undefined"
403
+ :prepend-tooltip="nirTooltip && nirTooltipPosition === 'prepend' ? nirTooltip : undefined"
404
+ :append-tooltip="nirTooltip && nirTooltipPosition === 'append' ? nirTooltip : undefined"
405
+ :max-errors="2"
406
+ :error-messages="[...numberValidation.errors.value, ...keyValidation.errors.value]"
407
+ :warning-messages="numberValidation.warnings.value"
408
+ :success-messages="numberValidation.successes.value"
409
+ :show-success-messages="showSuccessMessages"
410
+ :has-warning="hasNumberWarning"
411
+ :has-success="hasNumberSuccess"
412
+ :error="hasNumberErrors"
413
+ :messages="hasNumberErrors ? numberValidation.errors.value : (hasNumberWarning ? numberValidation.warnings.value : (hasNumberSuccess && props.showSuccessMessages ? numberValidation.successes.value : []))"
414
+ :has-error="hasNumberErrors"
415
+ :required="required"
416
+ :is-disabled="isDisabled"
417
+ :bg-color="bgColor"
418
+ :density="props.density"
419
+ :hide-details="props.hideDetails"
420
+ :hide-spin-buttons="props.hideSpinButtons"
421
+ :placeholder="props.placeholder"
422
+ :readonly="props.readonly"
423
+ :variant="props.variant"
424
+ :clearable="props.clearable"
425
+ :counter="props.counter"
426
+ :persistent-hint="props.persistentHint"
427
+ :persistent-placeholder="props.persistentPlaceholder"
428
+ :hint="props.hint || locales.numberHint"
429
+ class="number-field"
430
+ :display-asterisk="false"
431
+ @input="handleNumberInput"
432
+ @blur="handleNumberBlur"
433
+ />
434
+ </div>
435
+ <div
436
+ v-if="displayKey"
437
+ class="key-field-container"
438
+ >
439
+ <SyTextField
440
+ ref="keyField"
441
+ v-model="keyValue"
442
+ v-maska="keyMask"
443
+ :label="keyLabelWithAsterisk"
444
+ :variant-style="outlined ? 'outlined' : 'underlined'"
445
+ :prepend-icon="keyTooltip && keyTooltipPosition === 'prepend' ? 'info' : undefined"
446
+ :append-icon="keyTooltip && keyTooltipPosition === 'append' ? 'info' : undefined"
447
+ :prepend-tooltip="keyTooltip && keyTooltipPosition === 'prepend' ? keyTooltip : undefined"
448
+ :append-tooltip="keyTooltip && keyTooltipPosition === 'append' ? keyTooltip : undefined"
449
+ :error-messages="keyValidation.errors.value.length > 0 ? [''] : []"
450
+ :warning-messages="keyValidation.warnings.value"
451
+ :success-messages="keyValidation.successes.value"
452
+ :show-success-messages="showSuccessMessages"
453
+ :has-warning="hasKeyWarning"
454
+ :has-success="hasKeySuccess"
455
+ :hint="props.hint || locales.keyHint"
456
+ :messages="hasKeyErrors ? keyValidation.errors.value : (hasKeyWarning ? keyValidation.warnings.value : (hasKeySuccess && props.showSuccessMessages ? keyValidation.successes.value : []))"
457
+ :has-error="hasKeyErrors"
458
+ :is-disabled="isDisabled"
459
+ :bg-color="bgColor"
460
+ :density="props.density"
461
+ :hide-details="props.hideDetails"
462
+ :hide-spin-buttons="props.hideSpinButtons"
463
+ :placeholder="props.placeholder"
464
+ :readonly="props.readonly"
465
+ :variant="props.variant"
466
+ :clearable="props.clearable"
467
+ :counter="props.counter"
468
+ :persistent-hint="props.persistentHint"
469
+ :persistent-placeholder="props.persistentPlaceholder"
470
+ class="key-field"
471
+ :display-asterisk="false"
472
+ @input="handleKeyInput"
473
+ @blur="handleKeyBlur"
474
+ />
475
+ </div>
476
+ </div>
477
+ </template>
478
+
479
+ <style lang="scss" scoped>
480
+ .nir-field {
481
+ display: flex;
482
+ gap: 16px;
483
+ width: v-bind('props.width');
484
+ align-items: flex-start;
444
485
  }
445
486
 
446
- @media screen and (width <= 360px) {
447
- @include responsive-nir-wrapper;
487
+ .number-field-container {
488
+ flex: 0 0 80%;
448
489
  }
449
490
 
450
- .v-text-field .v-input__append-inner {
451
- padding-left: 0 !important;
491
+ .key-field-container {
492
+ flex: 0 0 20%;
452
493
  }
453
494
 
454
- :deep(.v-text-field > .v-input__control > .v-input__slot > .v-text-field__slot) {
455
- width: min-content !important;
495
+ .number-field,
496
+ .key-field {
497
+ width: 100%;
456
498
  }
457
499
  </style>