@cnamts/synapse 1.0.23 → 1.0.24

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 (292) hide show
  1. package/dist/AutocompleteFilter-BWLR3U7W.js +114 -0
  2. package/dist/AutocompleteFilter-D9jzRzAL.cjs +1 -0
  3. package/dist/{DateFilter-Dc-gSGwk.js → DateFilter-BpwFexzi.js} +1 -1
  4. package/dist/DateFilter-DTUl8hb1.cjs +1 -0
  5. package/dist/{NumberFilter-vP38Wp6j.js → NumberFilter-Bz_NTdX9.js} +3 -3
  6. package/dist/NumberFilter-MAEojdk0.cjs +1 -0
  7. package/dist/PeriodFilter-CC4WgIhl.cjs +1 -0
  8. package/dist/{PeriodFilter-Ba1uYUnT.js → PeriodFilter-DX_wy9g-.js} +1 -1
  9. package/dist/SelectFilter-BR3fvl-a.cjs +1 -0
  10. package/dist/SelectFilter-xqiPtPgX.js +135 -0
  11. package/dist/{TextFilter-B84dpnoq.js → TextFilter-BBl3JFqK.js} +7 -7
  12. package/dist/TextFilter-CCfYFl5F.cjs +1 -0
  13. package/dist/apLightTheme-CFSRrjv2.cjs +1 -0
  14. package/dist/apLightTheme-D1P4jcD0.js +1231 -0
  15. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7022 -9616
  16. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +2 -2
  17. package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +2 -2
  18. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +40 -40
  19. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +60 -60
  20. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7168 -9762
  21. package/dist/components/Amelipro/AmeliproStepper/AmeliproStepper.d.ts +2 -2
  22. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +7501 -10095
  23. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +21 -21
  24. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +41 -41
  25. package/dist/components/Amelipro/StructureMenu/StructureTabs/StructureTabs.d.ts +2 -2
  26. package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +20 -498
  27. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +108 -146
  28. package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +5 -5
  29. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +12 -16
  30. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +8 -8
  31. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +28 -506
  32. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +28 -506
  33. package/dist/components/Customs/SyTextField/SyTextField.d.ts +65 -85
  34. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +627 -771
  35. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +315 -402
  36. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +112 -155
  37. package/dist/components/DatePicker/composables/index.d.ts +1 -0
  38. package/dist/components/DatePicker/composables/useDatePickerFocusTrap.d.ts +11 -0
  39. package/dist/components/DatePicker/composables/useDateTextField.d.ts +4 -4
  40. package/dist/components/DatePicker/composables/useDateValidation.d.ts +3 -3
  41. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
  42. package/dist/components/DatePicker/composables/useManualDateValidation.d.ts +2 -2
  43. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +4 -4
  44. package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +20 -28
  45. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +3 -3
  46. package/dist/components/MonthPicker/MonthPicker.d.ts +86 -122
  47. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +85 -121
  48. package/dist/components/NirField/NirField.d.ts +206 -270
  49. package/dist/components/NirField/locales.d.ts +10 -10
  50. package/dist/components/NirField/useNirValidation.d.ts +64 -0
  51. package/dist/components/PasswordField/PasswordField.d.ts +8 -9
  52. package/dist/components/PeriodField/PeriodField.d.ts +1352 -1640
  53. package/dist/components/PhoneField/PhoneField.d.ts +88 -124
  54. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +12 -12
  55. package/dist/components/SyTextArea/SyTextArea.d.ts +34 -14
  56. package/dist/components/SyTextArea/useDefaultValidationRules.d.ts +11 -0
  57. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +9 -6
  58. package/dist/components/Tables/SyTable/SyTable.d.ts +9 -6
  59. package/dist/components/Tables/common/SyTableFilter.d.ts +2 -3
  60. package/dist/components/Tables/common/SyTablePagination.d.ts +17 -19
  61. package/dist/components/Tables/common/filters/AutocompleteFilter.d.ts +120 -0
  62. package/dist/components/Tables/common/filters/locales.d.ts +0 -1
  63. package/dist/components/Tables/common/types.d.ts +19 -3
  64. package/dist/components/Tables/common/useClickableTableRow.d.ts +17 -0
  65. package/dist/components/Tables/common/usePagination.d.ts +3 -1
  66. package/dist/components/Tables/common/usePinnedColumns.d.ts +31 -0
  67. package/dist/components/Tables/common/useTableHeaders.d.ts +2 -0
  68. package/dist/components/Tables/common/useTableRowCheckboxAccessibility.d.ts +5 -0
  69. package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +6 -6
  70. package/dist/composables/date/useDatePickerAccessibility.d.ts +1 -1
  71. package/dist/composables/rules/useFieldValidation.d.ts +4 -4
  72. package/dist/composables/unifyValidation/useCustomValidation.d.ts +8 -0
  73. package/dist/composables/unifyValidation/useValidation.d.ts +102 -0
  74. package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +18 -0
  75. package/dist/composables/useFormFieldErrorHandling.d.ts +2 -2
  76. package/dist/composables/validation/useFormValidation.d.ts +11 -2
  77. package/dist/composables/validation/useValidation.d.ts +15 -9
  78. package/dist/design-system-v3.d.ts +2 -0
  79. package/dist/design-system-v3.js +186 -187
  80. package/dist/design-system-v3.umd.cjs +1 -1066
  81. package/dist/{main-aLKwdMi1.js → main-BtTqyn4z.js} +16434 -15672
  82. package/dist/main-C1e3eoxd.cjs +1067 -0
  83. package/dist/main.d.ts +0 -1
  84. package/dist/synapse.css +1 -0
  85. package/dist/tooth-11-D3sLWv2n.cjs +1 -0
  86. package/dist/tooth-12-CXrLuH03.cjs +1 -0
  87. package/dist/tooth-13-BSfo5fpT.cjs +1 -0
  88. package/dist/tooth-14-DMzulx0h.cjs +1 -0
  89. package/dist/tooth-15-BKRFVi-9.cjs +1 -0
  90. package/dist/tooth-16-CpuxAbuM.cjs +1 -0
  91. package/dist/tooth-17-BPoahUdg.cjs +1 -0
  92. package/dist/tooth-18-DhHJz8sy.cjs +1 -0
  93. package/dist/tooth-21-Dgd5hn_X.cjs +1 -0
  94. package/dist/tooth-22-C2Tn19sB.cjs +1 -0
  95. package/dist/tooth-23-C9uaaSGb.cjs +1 -0
  96. package/dist/tooth-24-BrK9UGpf.cjs +1 -0
  97. package/dist/tooth-25-CE_EfGNp.cjs +1 -0
  98. package/dist/tooth-26-Ctv4i9Fy.cjs +1 -0
  99. package/dist/tooth-27-C5J7JkWM.cjs +1 -0
  100. package/dist/tooth-28-Z9oWqjo0.cjs +1 -0
  101. package/dist/tooth-31-BrYqmkTi.cjs +1 -0
  102. package/dist/tooth-32-BNNR0oCZ.cjs +1 -0
  103. package/dist/tooth-33-DuxvqO2J.cjs +1 -0
  104. package/dist/tooth-34-BCSCXMB6.cjs +1 -0
  105. package/dist/tooth-35-BLUXkX88.cjs +1 -0
  106. package/dist/tooth-36-IrKHYqlA.cjs +1 -0
  107. package/dist/tooth-37-BYqpdMwo.cjs +1 -0
  108. package/dist/tooth-38-B_eNXXdu.cjs +1 -0
  109. package/dist/tooth-41-Ddva4Ot8.cjs +1 -0
  110. package/dist/tooth-42-szcDqlM0.cjs +1 -0
  111. package/dist/tooth-43-B3ka6rQm.cjs +1 -0
  112. package/dist/tooth-44-CazyQucj.cjs +1 -0
  113. package/dist/tooth-45-B4HQtc8n.cjs +1 -0
  114. package/dist/tooth-46-BPM40gbG.cjs +1 -0
  115. package/dist/tooth-47-Dvr20dlh.cjs +1 -0
  116. package/dist/tooth-48-Bd8ljGsF.cjs +1 -0
  117. package/dist/tooth-51-OBpwCOF3.cjs +1 -0
  118. package/dist/tooth-52-aKxyHcmq.cjs +1 -0
  119. package/dist/tooth-53-vCwJjTOc.cjs +1 -0
  120. package/dist/tooth-54-DsWu2iFy.cjs +1 -0
  121. package/dist/tooth-55-BxC1X2Dn.cjs +1 -0
  122. package/dist/tooth-61-BbLvxMQi.cjs +1 -0
  123. package/dist/tooth-62-CmTkWczP.cjs +1 -0
  124. package/dist/tooth-63-DI7l_2qI.cjs +1 -0
  125. package/dist/tooth-64-B21sOsJh.cjs +1 -0
  126. package/dist/tooth-65-D2ZC2VEr.cjs +1 -0
  127. package/dist/tooth-71-D473PPO5.cjs +1 -0
  128. package/dist/tooth-72-Drh1wnNu.cjs +1 -0
  129. package/dist/tooth-73-DzlwYI23.cjs +1 -0
  130. package/dist/tooth-74-8aGvcZPg.cjs +1 -0
  131. package/dist/tooth-75-BFK7At_r.cjs +1 -0
  132. package/dist/tooth-81-BZmR-I0M.cjs +1 -0
  133. package/dist/tooth-82-euVfUUZV.cjs +1 -0
  134. package/dist/tooth-83-KV010j64.cjs +1 -0
  135. package/dist/tooth-84-BBg1RjhZ.cjs +1 -0
  136. package/dist/tooth-85-Cr-kc1wM.cjs +1 -0
  137. package/dist/vuetifyConfig.js +561 -0
  138. package/dist/vuetifyConfig.umd.cjs +1 -0
  139. package/package.json +10 -4
  140. package/src/assets/overrides/_btns.scss +0 -6
  141. package/src/assets/overrides/_icons.scss +9 -1
  142. package/src/assets/overrides/_typography.scss +0 -10
  143. package/src/components/Amelipro/AmeliproAutoCompleteField/__tests__/__snapshots__/AmeliproAutoCompleteField.spec.ts.snap +2 -2
  144. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
  145. package/src/components/Amelipro/AmeliproTextArea/__tests__/__snapshots__/AmeliproTextArea.spec.ts.snap +2 -2
  146. package/src/components/Captcha/accessibilite/Accessibility.mdx +86 -8
  147. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +12 -12
  148. package/src/components/ChipList/ChipList.stories.ts +0 -15
  149. package/src/components/ChipList/ChipList.vue +5 -1
  150. package/src/components/ChipList/accessibilite/Accessibility.mdx +83 -10
  151. package/src/components/ChipList/tests/ChipList.a11y.spec.ts +41 -0
  152. package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +0 -9
  153. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +22 -5
  154. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +143 -0
  155. package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +14 -10
  156. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +4 -4
  157. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +8 -9
  158. package/src/components/Customs/Selects/SyInputSelect/tests/SyInputSelect.spec.ts +10 -10
  159. package/src/components/Customs/Selects/SySelect/SySelect.vue +14 -11
  160. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +54 -0
  161. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +6 -9
  162. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +10 -16
  163. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +16 -11
  164. package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +35 -0
  165. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.a11y.spec.ts +134 -2
  166. package/src/components/Customs/SyForm/SyForm.stories.ts +31 -5
  167. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +4 -7
  168. package/src/components/Customs/SyTextField/SyTextField.mdx +1 -1
  169. package/src/components/Customs/SyTextField/SyTextField.stories.ts +29 -27
  170. package/src/components/Customs/SyTextField/SyTextField.vue +154 -157
  171. package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +32 -0
  172. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +120 -11
  173. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +62 -58
  174. package/src/components/DatePicker/CalendarMode/DatePicker.vue +330 -223
  175. package/src/components/DatePicker/CalendarMode/accessibilite/Accessibility.mdx +82 -0
  176. package/src/components/DatePicker/CalendarMode/tests/DatePicker.a11y.spec.ts +141 -0
  177. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +2 -56
  178. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +195 -159
  179. package/src/components/DatePicker/ComplexDatePicker/accessibilite/Accessibility.mdx +76 -0
  180. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +10 -10
  181. package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +8 -8
  182. package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +106 -8
  183. package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +12 -11
  184. package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +12 -12
  185. package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +0 -12
  186. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +63 -57
  187. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +3 -0
  188. package/src/components/DatePicker/DateTextInput/accessibilite/Accessibility.mdx +66 -0
  189. package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +52 -1
  190. package/src/components/DatePicker/composables/index.ts +1 -0
  191. package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +109 -65
  192. package/src/components/DatePicker/composables/tests/useDatePickerFocusTrap.spec.ts +138 -0
  193. package/src/components/DatePicker/composables/tests/useDateValidation.spec.ts +74 -18
  194. package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +39 -0
  195. package/src/components/DatePicker/composables/tests/useManualDateValidation.spec.ts +91 -0
  196. package/src/components/DatePicker/composables/useCalendarKeyboardNavigation.ts +442 -36
  197. package/src/components/DatePicker/composables/useDatePickerFocusTrap.ts +92 -0
  198. package/src/components/DatePicker/composables/useDateTextField.ts +7 -6
  199. package/src/components/DatePicker/composables/useDateValidation.ts +36 -35
  200. package/src/components/DatePicker/composables/useInputBlurHandler.ts +3 -3
  201. package/src/components/DatePicker/composables/useManualDateValidation.ts +6 -2
  202. package/src/components/DiacriticPicker/accessibilite/Accessibility.mdx +76 -8
  203. package/src/components/HeaderBar/HeaderBar.stories.ts +14 -2
  204. package/src/components/Logo/accessibilite/Accessibility.mdx +73 -11
  205. package/src/components/LogoBrandSection/accessibilite/Accessibility.mdx +85 -9
  206. package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +3 -1
  207. package/src/components/LunarCalendar/useLunarCalendarValidation.ts +4 -5
  208. package/src/components/MonthPicker/tests/MonthPicker.spec.ts +2 -1
  209. package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +7 -7
  210. package/src/components/NirField/NirField.stories.ts +4 -0
  211. package/src/components/NirField/NirField.vue +64 -260
  212. package/src/components/NirField/accessibilite/Accessibility.mdx +2 -2
  213. package/src/components/NirField/locales.ts +1 -1
  214. package/src/components/NirField/tests/NirField.spec.ts +6 -0
  215. package/src/components/NirField/useNirValidation.ts +271 -0
  216. package/src/components/PasswordField/PasswordField.stories.ts +4 -4
  217. package/src/components/PasswordField/PasswordField.vue +18 -24
  218. package/src/components/PasswordField/tests/PasswordField.spec.ts +6 -3
  219. package/src/components/PeriodField/PeriodField.stories.ts +4 -4
  220. package/src/components/PeriodField/PeriodField.vue +57 -57
  221. package/src/components/PeriodField/__tests__/PeriodField.async.spec.ts +32 -0
  222. package/src/components/PeriodField/accessibilite/Accessibility.mdx +68 -8
  223. package/src/components/PeriodField/tests/PeriodField.spec.ts +28 -2
  224. package/src/components/PhoneField/PhoneField.vue +5 -6
  225. package/src/components/PhoneField/tests/PhoneField.spec.ts +1 -0
  226. package/src/components/RangeField/RangeField.vue +6 -0
  227. package/src/components/SyTextArea/SyTextArea.stories.ts +138 -2
  228. package/src/components/SyTextArea/SyTextArea.vue +53 -23
  229. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +126 -3
  230. package/src/components/SyTextArea/useDefaultValidationRules.ts +74 -0
  231. package/src/components/Tables/SyServerTable/SyServerTable.mdx +25 -0
  232. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +673 -1
  233. package/src/components/Tables/SyServerTable/SyServerTable.vue +148 -91
  234. package/src/components/Tables/SyServerTable/tests/SyServerTable.a11y.spec.ts +58 -0
  235. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +122 -0
  236. package/src/components/Tables/SyTable/SyTable.mdx +25 -0
  237. package/src/components/Tables/SyTable/SyTable.stories.ts +452 -1
  238. package/src/components/Tables/SyTable/SyTable.vue +130 -56
  239. package/src/components/Tables/SyTable/tests/SyTable.a11y.spec.ts +57 -0
  240. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +108 -0
  241. package/src/components/Tables/common/SyTableFilter.vue +22 -2
  242. package/src/components/Tables/common/TableHeader.vue +5 -1
  243. package/src/components/Tables/common/filters/AutocompleteFilter.vue +160 -0
  244. package/src/components/Tables/common/filters/NumberFilter.vue +1 -1
  245. package/src/components/Tables/common/filters/SelectFilter.vue +10 -11
  246. package/src/components/Tables/common/filters/TextFilter.vue +1 -1
  247. package/src/components/Tables/common/filters/getFilterComponent.ts +8 -1
  248. package/src/components/Tables/common/filters/locales.ts +0 -1
  249. package/src/components/Tables/common/filters/tests/AutocompleteFilter.a11y.spec.ts +110 -0
  250. package/src/components/Tables/common/filters/tests/AutocompleteFilter.spec.ts +203 -0
  251. package/src/components/Tables/common/filters/tests/SelectFilter.a11y.spec.ts +104 -0
  252. package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +152 -16
  253. package/src/components/Tables/common/tableFilterUtils.ts +3 -0
  254. package/src/components/Tables/common/tableStyles.scss +48 -4
  255. package/src/components/Tables/common/tests/filterByRange.spec.ts +2 -1
  256. package/src/components/Tables/common/types.ts +13 -4
  257. package/src/components/Tables/common/useClickableTableRow.ts +103 -0
  258. package/src/components/Tables/common/usePagination.ts +13 -0
  259. package/src/components/Tables/common/usePinnedColumns.ts +237 -0
  260. package/src/components/Tables/common/useTableHeaders.ts +3 -3
  261. package/src/components/Tables/common/useTableRowCheckboxAccessibility.ts +41 -0
  262. package/src/composables/date/tests/useDatePickerAccessibility.spec.ts +2 -6
  263. package/src/composables/date/useDatePickerAccessibility.ts +42 -207
  264. package/src/composables/rules/tests/useFieldValidation.spec.ts +120 -120
  265. package/src/composables/rules/useFieldValidation.ts +34 -17
  266. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +601 -0
  267. package/src/composables/unifyValidation/tests/useValidation.spec.ts +2048 -0
  268. package/src/composables/unifyValidation/tests/useVuetifyValidation.spec.ts +184 -0
  269. package/src/composables/unifyValidation/useCustomValidation.ts +95 -0
  270. package/src/composables/unifyValidation/useValidation.ts +190 -0
  271. package/src/composables/unifyValidation/useVuetifyValidation.ts +54 -0
  272. package/src/composables/useFormFieldErrorHandling.ts +4 -7
  273. package/src/composables/validation/tests/useFormValidation.spec.ts +14 -0
  274. package/src/composables/validation/tests/useValidation.spec.ts +116 -21
  275. package/src/composables/validation/useFormValidation.ts +20 -13
  276. package/src/composables/validation/useValidatable.ts +8 -1
  277. package/src/composables/validation/useValidation.ts +135 -99
  278. package/src/composantsVuetify/Introduction.mdx +48 -0
  279. package/src/composantsVuetify/VBtn/VBtn.mdx +72 -0
  280. package/src/composantsVuetify/VBtn/v-btn.stories.ts +121 -0
  281. package/src/composantsVuetify/VTooltip/VTooltip.mdx +32 -0
  282. package/src/composantsVuetify/VTooltip/v-tooltip.stories.ts +95 -0
  283. package/src/designTokens/tokens/cnam/cnamSemantic.ts +2 -2
  284. package/src/main.ts +0 -2
  285. package/src/stories/Components/Components.stories.ts +74 -9
  286. package/src/stories/Demarrer/Accueil.stories.ts +3 -3
  287. package/src/stories/GuideDuDev/Amelipro.mdx +15 -0
  288. package/src/stories/GuideDuDev/Amelipro.stories.ts +209 -0
  289. package/src/stories/GuideDuDev/vuetifyOptions.mdx +3 -3
  290. package/dist/SelectFilter-BioGT6Nn.js +0 -136
  291. package/dist/style.css +0 -1
  292. package/src/components/DatePicker/Accessibilite.mdx +0 -14
@@ -0,0 +1,271 @@
1
+ import { type ValidationRule as SyValidationRule } from '@/composables/validation/useValidation'
2
+ import { computed, nextTick, onBeforeUnmount, onMounted, ref, type Ref } from 'vue'
3
+ import { checkNIR, isNIRKeyValid } from './nirValidation'
4
+ import type { locales } from './locales'
5
+ import { useValidation } from '@/composables/unifyValidation/useValidation'
6
+ import type { SyTextField } from '@/main'
7
+ import type { ValidationRule as VuetifyValidationRule } from 'vuetify'
8
+
9
+ export type NirValidationProps = {
10
+ customKeyRules?: SyValidationRule[]
11
+ customKeyWarningRules?: SyValidationRule[]
12
+ customNumberRules?: SyValidationRule[]
13
+ customNumberWarningRules?: SyValidationRule[]
14
+ customRulesPrecedence?: boolean
15
+ disabled?: boolean
16
+ isValidateOnBlur?: boolean
17
+ keyLabel?: string
18
+ keyRules?: VuetifyValidationRule[]
19
+ nirType?: 'simple' | 'complexe'
20
+ numberLabel?: string
21
+ numberRules?: VuetifyValidationRule[]
22
+ readonly?: boolean
23
+ required?: boolean
24
+ showSuccessMessages?: boolean
25
+ useVuetifyValidation?: boolean
26
+ }
27
+
28
+ /**
29
+ * Handle validation for NIR fields, including both the number and the key
30
+ */
31
+ export function useNirValidation(
32
+ numberValue: Ref<string>,
33
+ keyValue: Ref<string>,
34
+ unmaskedNumberValue: Ref<string>,
35
+ unmaskedKeyValue: Ref<string>,
36
+ readonly: Ref<boolean>,
37
+ disabled: Ref<boolean>,
38
+ required: Ref<boolean>,
39
+ numberField: Ref<InstanceType<typeof SyTextField> | null>,
40
+ keyField: Ref<InstanceType<typeof SyTextField> | null>,
41
+ customLocale: Ref<typeof locales>,
42
+ numberLabel: Ref<string>,
43
+ keyLabel: Ref<string>,
44
+ customNumberRules: Ref<SyValidationRule[]>,
45
+ customKeyRules: Ref<SyValidationRule[]>,
46
+ customNumberWarningRules: Ref<SyValidationRule[]>,
47
+ customKeyWarningRules: Ref<SyValidationRule[]>,
48
+ displayKey: Ref<boolean>,
49
+ customRulesPrecedence: Ref<boolean>,
50
+ nirType: Ref<'simple' | 'complexe'>,
51
+ label: Ref<string>,
52
+ showSuccessMessages: Ref<boolean>,
53
+ disableErrorHandling: Ref<boolean>,
54
+ isValidateOnBlur: Ref<boolean>,
55
+ useVuetifyValidation: Ref<boolean>,
56
+ vuetifyNumberRules: Ref<VuetifyValidationRule[]>,
57
+ vuetifyKeyRules: Ref<VuetifyValidationRule[]>,
58
+ ) {
59
+ // Règles de validation
60
+ const numberRules = computed(() => {
61
+ if (useVuetifyValidation.value) {
62
+ return []
63
+ }
64
+ const rules: SyValidationRule[] = []
65
+ if (required.value) {
66
+ rules.push({
67
+ type: 'required',
68
+ options: {
69
+ message: customLocale.value.errorRequiredNumber,
70
+ fieldIdentifier: numberLabel.value,
71
+ },
72
+ })
73
+ }
74
+
75
+ // Ajout des règles personnalisées avec prévalence si demandé
76
+ if (customRulesPrecedence.value && customNumberRules.value && customNumberRules.value.length > 0) {
77
+ rules.push(...customNumberRules.value.map(rule => ({
78
+ ...rule,
79
+ options: rule.options || {},
80
+ })))
81
+ }
82
+
83
+ // Règle de validation standard du NIR
84
+ rules.push({
85
+ type: 'custom',
86
+ options: {
87
+ validate: (value: string) => {
88
+ if (!value) return true
89
+ // Ne valider que si tous les caractères sont saisis
90
+ if (value.length < 13) {
91
+ return customLocale.value.errorInvalidNumber || customLocale.value.errorInvalidNumber
92
+ }
93
+ const result = checkNIR(value, nirType.value)
94
+ return result ? true : customLocale.value.errorInvalidNumber || customLocale.value.errorInvalidNumber
95
+ },
96
+ message: customLocale.value.errorInvalidNumber,
97
+ successMessage: customLocale.value.successNumberValid,
98
+ fieldIdentifier: numberLabel.value,
99
+ },
100
+ })
101
+
102
+ // Ajout des règles personnalisées sans prévalence (comportement par défaut)
103
+ if (!customRulesPrecedence.value && customNumberRules.value && customNumberRules.value.length > 0) {
104
+ rules.push(...customNumberRules.value.map(rule => ({
105
+ ...rule,
106
+ options: rule.options || {},
107
+ })))
108
+ }
109
+
110
+ return rules
111
+ })
112
+
113
+ const keyRules = computed(() => {
114
+ if (useVuetifyValidation.value) {
115
+ return []
116
+ }
117
+ const rules: SyValidationRule[] = []
118
+ if (required.value) {
119
+ rules.push({
120
+ type: 'required',
121
+ options: {
122
+ message: customLocale.value.errorRequiredKey,
123
+ fieldIdentifier: keyLabel.value,
124
+ },
125
+ })
126
+ }
127
+
128
+ const validateKey = (value: string) => {
129
+ if (!value) return true
130
+ if (!unmaskedNumberValue.value) return true
131
+ const fullNir = unmaskedNumberValue.value + value
132
+ return isNIRKeyValid(fullNir)
133
+ }
134
+
135
+ // Ajout des règles personnalisées
136
+ if (customKeyRules.value) {
137
+ rules.push(...customKeyRules.value)
138
+ }
139
+
140
+ // Ajout de la règle de validation par défaut si pas de règle personnalisée avec validation de clé
141
+ if (!customKeyRules.value?.some(rule => rule.options.validate)) {
142
+ rules.push({
143
+ type: 'custom',
144
+ options: {
145
+ validate: validateKey,
146
+ message: customLocale.value.errorInvalidKey,
147
+ successMessage: customLocale.value.successKeyValid,
148
+ fieldIdentifier: keyLabel.value,
149
+ },
150
+ })
151
+ }
152
+
153
+ return rules
154
+ })
155
+
156
+ // État pour suivre si une validation est en cours
157
+ const isValidating = ref(false)
158
+ const shouldValidateOnBlur = ref(false)
159
+ const numberFieldFocused = ref(false)
160
+ const keyFieldFocused = ref(false)
161
+
162
+ // update focus state on blur and focus
163
+ const onNumberFocus = () => {
164
+ numberFieldFocused.value = true
165
+ }
166
+ const onNumberBlur = () => {
167
+ numberFieldFocused.value = false
168
+ }
169
+ const onKeyFocus = () => {
170
+ keyFieldFocused.value = true
171
+ }
172
+ const onKeyBlur = () => {
173
+ keyFieldFocused.value = false
174
+ }
175
+
176
+ let numberInput: HTMLInputElement | null = null
177
+ let keyInput: HTMLInputElement | null = null
178
+
179
+ onMounted(() => {
180
+ numberInput = numberField.value?.$el?.querySelector('input') ?? null
181
+ if (numberInput) {
182
+ numberInput.addEventListener('focus', onNumberFocus)
183
+ numberInput.addEventListener('blur', onNumberBlur)
184
+ }
185
+
186
+ keyInput = keyField.value?.$el?.querySelector('input') ?? null
187
+ if (keyInput) {
188
+ keyInput.addEventListener('focus', onKeyFocus)
189
+ keyInput.addEventListener('blur', onKeyBlur)
190
+ }
191
+ })
192
+
193
+ onBeforeUnmount(() => {
194
+ numberInput?.removeEventListener('focus', onNumberFocus)
195
+ numberInput?.removeEventListener('blur', onNumberBlur)
196
+ keyInput?.removeEventListener('focus', onKeyFocus)
197
+ keyInput?.removeEventListener('blur', onKeyBlur)
198
+ })
199
+
200
+ const numberValidation = useValidation({
201
+ modelValue: numberValue,
202
+ readonly,
203
+ disabled,
204
+ required,
205
+ isValidateOnBlur,
206
+ showSuccessMessages,
207
+ disableErrorHandling,
208
+ useVuetifyValidation,
209
+ label,
210
+ customRules: numberRules,
211
+ customWarningRules: computed(() => unmaskedNumberValue.value.length === 13 ? customNumberWarningRules.value : []),
212
+ rules: vuetifyNumberRules,
213
+ focused: numberFieldFocused,
214
+ })
215
+
216
+ const keyValidation = useValidation({
217
+ modelValue: keyValue,
218
+ readonly,
219
+ disabled,
220
+ required,
221
+ isValidateOnBlur,
222
+ showSuccessMessages,
223
+ disableErrorHandling,
224
+ useVuetifyValidation,
225
+ label,
226
+ customRules: keyRules,
227
+ customWarningRules: computed(() => (displayKey.value && unmaskedKeyValue.value.length === 2) ? customKeyWarningRules.value : []),
228
+ rules: vuetifyKeyRules,
229
+ focused: keyFieldFocused,
230
+ })
231
+
232
+ // Validation des champs
233
+ const validateFields = async (onBlur = false) => {
234
+ // Éviter les validations redondantes
235
+ if (isValidating.value) {
236
+ shouldValidateOnBlur.value = shouldValidateOnBlur.value || onBlur
237
+ return true
238
+ }
239
+
240
+ isValidating.value = true
241
+
242
+ await numberValidation.validate()
243
+
244
+ if (displayKey.value) {
245
+ await keyValidation.validate()
246
+ }
247
+
248
+ if (onBlur || shouldValidateOnBlur.value) {
249
+ await nextTick()
250
+ if (numberValidation.hasError.value) {
251
+ numberField.value?.$el?.querySelector?.('input')?.focus()
252
+ }
253
+ else if (keyValidation.hasError.value) {
254
+ keyField.value?.$el?.querySelector?.('input')?.focus()
255
+ }
256
+ shouldValidateOnBlur.value = false
257
+ }
258
+
259
+ isValidating.value = false
260
+ return !numberValidation.hasError.value && !keyValidation.hasError.value
261
+ }
262
+
263
+ const hasFieldErrors = computed(() => numberValidation.hasError.value || keyValidation.hasError.value)
264
+
265
+ return {
266
+ numberValidation,
267
+ keyValidation,
268
+ validateFields,
269
+ hasFieldErrors,
270
+ }
271
+ }
@@ -962,9 +962,9 @@ export const WithFormValidation: Story = {
962
962
  ]
963
963
 
964
964
  // Fonction de soumission du formulaire
965
- const handleSubmit = () => {
965
+ const handleSubmit = async (): Promise<void> => {
966
966
  if (passwordFieldRef.value) {
967
- const isValid = passwordFieldRef.value.validateOnSubmit()
967
+ const isValid = await passwordFieldRef.value.validateOnSubmit()
968
968
  if (isValid) {
969
969
  formStatus.value = 'Formulaire soumis avec succès !'
970
970
  } else {
@@ -1013,9 +1013,9 @@ export const WithFormValidation: Story = {
1013
1013
  ]
1014
1014
 
1015
1015
  // Fonction de soumission du formulaire
1016
- const handleSubmit = () => {
1016
+ const handleSubmit = async () => {
1017
1017
  if (passwordFieldRef.value) {
1018
- const isValid = passwordFieldRef.value.validateOnSubmit()
1018
+ const isValid = await passwordFieldRef.value.validateOnSubmit()
1019
1019
  if (isValid) {
1020
1020
  formStatus.value = 'Formulaire soumis avec succès !'
1021
1021
  }
@@ -20,7 +20,7 @@
20
20
  modelValue?: string | null
21
21
  variantStyle?: 'outlined' | 'underlined'
22
22
  color?: ColorType
23
- label?: string
23
+ label: string
24
24
  required?: boolean
25
25
  errorMessages?: string[] | null
26
26
  warningMessages?: string[] | null
@@ -41,7 +41,6 @@
41
41
  modelValue: null,
42
42
  variantStyle: 'outlined',
43
43
  color: 'primary',
44
- label: undefined,
45
44
  required: false,
46
45
  errorMessages: null,
47
46
  warningMessages: null,
@@ -96,25 +95,12 @@
96
95
  })
97
96
  }
98
97
 
99
- // Règle pour le message de succès
100
- // rules.push({
101
- // type: 'custom',
102
- // options: {
103
- // validate: (value: string) => value ? true : 'Ce champ est requis',
104
- // successMessage: 'Mot de passe fort',
105
- // fieldIdentifier: props.label || 'password',
106
- // },
107
- // })
108
-
109
98
  return rules
110
99
  })
111
100
 
112
101
  // Initialisation du composable de validation
113
102
  const { errors, warnings, successes, validateField } = !props.readonly
114
103
  ? useValidation({
115
- customRules: defaultRules.value,
116
- warningRules: props.customWarningRules || [],
117
- successRules: props.customSuccessRules || [],
118
104
  showSuccessMessages: props.showSuccessMessages,
119
105
  fieldIdentifier: props.label || 'password',
120
106
  disableErrorHandling: props.disableErrorHandling,
@@ -123,7 +109,7 @@
123
109
  errors: ref<string[]>([]),
124
110
  warnings: ref<string[]>([]),
125
111
  successes: ref<string[]>([]),
126
- validateField: () => {},
112
+ validateField: () => ({ hasError: false, hasWarning: false, hasSuccess: false, state: { errors: [], warnings: [], successes: [] } }),
127
113
  }
128
114
 
129
115
  const hasError = computed(() => errors.value.length > 0)
@@ -199,15 +185,15 @@
199
185
  })
200
186
  }
201
187
 
202
- function handleKeydown(event: KeyboardEvent): void {
188
+ async function handleKeydown(event: KeyboardEvent): Promise<void> {
203
189
  if (event.key === 'Enter') {
204
- validateOnSubmit()
190
+ await validateOnSubmit()
205
191
  }
206
192
  }
207
193
 
208
- const validateOnSubmit = (): boolean => {
194
+ const validateOnSubmit = async (): Promise<boolean> => {
209
195
  if (props.readonly) return true // Retourner true au lieu de undefined
210
- validateField(password.value, [...defaultRules.value, ...(props.customRules || [])], props.customWarningRules || [], props.customSuccessRules || [])
196
+ await validateField(password.value, [...defaultRules.value, ...(props.customRules || [])], props.customWarningRules || [], props.customSuccessRules || [])
211
197
  const isValid = errors.value.length === 0
212
198
  if (isValid) {
213
199
  emit('submit')
@@ -280,7 +266,16 @@
280
266
  :autocomplete="props.autocompleteType"
281
267
  class="vd-password"
282
268
  :validate-on="props.isValidateOnBlur ? 'blur lazy' : 'lazy'"
283
- @blur="props.isValidateOnBlur && !props.readonly ? validateField(password, [...defaultRules, ...(props.customRules || [])], props.customWarningRules || [], props.customSuccessRules || []) : () => {}"
269
+ @blur="async () => {
270
+ if (props.isValidateOnBlur && !props.readonly) {
271
+ await validateField(
272
+ password,
273
+ [...defaultRules, ...(props.customRules || [])],
274
+ props.customWarningRules || [],
275
+ props.customSuccessRules || []
276
+ )
277
+ }
278
+ }"
284
279
  @keydown="handleKeydown"
285
280
  >
286
281
  <template #append-inner>
@@ -293,8 +288,7 @@
293
288
  decorative
294
289
  class="mr-2"
295
290
  />
296
- <!-- Utiliser un vrai élément button plutôt qu'une icône avec role="button" -->
297
- <v-button
291
+ <VBtn
298
292
  type="button"
299
293
  class="password-toggle-button"
300
294
  :aria-label="btnLabel"
@@ -311,7 +305,7 @@
311
305
  :aria-hidden="true"
312
306
  decorative
313
307
  />
314
- </v-button>
308
+ </VBtn>
315
309
  </div>
316
310
  <div
317
311
  :id="`${passwordFieldId}-status`"
@@ -6,7 +6,7 @@ import { describe, it, expect } from 'vitest'
6
6
  interface PasswordFieldVM {
7
7
  showEyeIcon: boolean
8
8
  errors: string[]
9
- validateOnSubmit: () => boolean
9
+ validateOnSubmit: () => Promise<boolean>
10
10
  hasError: boolean
11
11
  hasWarning: boolean
12
12
  hasSuccess: boolean
@@ -65,12 +65,12 @@ describe('PasswordField.vue', () => {
65
65
  })
66
66
  const vm = wrapper.vm as unknown as PasswordFieldVM
67
67
 
68
- const result = vm.validateOnSubmit()
68
+ const result = await vm.validateOnSubmit()
69
69
  expect(result).toBe(false)
70
70
  expect(vm.errors).toContain('Le mot de passe est requis')
71
71
 
72
72
  await wrapper.setProps({ modelValue: 'valid-password' })
73
- const validResult = vm.validateOnSubmit()
73
+ const validResult = await vm.validateOnSubmit()
74
74
  expect(validResult).toBe(true)
75
75
  expect(wrapper.emitted().submit).toBeTruthy()
76
76
  })
@@ -78,6 +78,7 @@ describe('PasswordField.vue', () => {
78
78
  it('displays warning and success messages', async () => {
79
79
  const wrapper = mount(PasswordField, {
80
80
  props: {
81
+ label: 'Password',
81
82
  modelValue: 'test',
82
83
  warningMessages: ['Attention: mot de passe court'],
83
84
  successMessages: ['Mot de passe valide'],
@@ -97,6 +98,7 @@ describe('PasswordField.vue', () => {
97
98
  it('handles custom validation rules', async () => {
98
99
  const wrapper = mount(PasswordField, {
99
100
  props: {
101
+ label: 'Password',
100
102
  modelValue: 'test',
101
103
  customRules: [{
102
104
  type: 'custom',
@@ -141,6 +143,7 @@ describe('PasswordField.vue', () => {
141
143
  it('displays validation states based on validation rules', async () => {
142
144
  const wrapper = mount(PasswordField, {
143
145
  props: {
146
+ label: 'Password',
144
147
  modelValue: 'test',
145
148
  customRules: [{
146
149
  type: 'custom',
@@ -995,9 +995,9 @@ export const FormValidation: Story = {
995
995
  ]
996
996
 
997
997
  // Soumission du formulaire
998
- const submitForm = () => {
998
+ const submitForm = async (): Promise<void> => {
999
999
  if (periodFieldRef.value) {
1000
- const isValid = periodFieldRef.value.validateOnSubmit()
1000
+ const isValid = await periodFieldRef.value.validateOnSubmit()
1001
1001
  if (isValid) {
1002
1002
  formStatus.value = 'Formulaire soumis avec succès !'
1003
1003
  isFormSubmitted.value = true
@@ -1035,9 +1035,9 @@ export const FormValidation: Story = {
1035
1035
  ]
1036
1036
 
1037
1037
  // Soumission du formulaire
1038
- const submitForm = () => {
1038
+ const submitForm = async (): Promise<void> => {
1039
1039
  if (periodFieldRef.value) {
1040
- const isValid = periodFieldRef.value.validateOnSubmit()
1040
+ const isValid = await periodFieldRef.value.validateOnSubmit()
1041
1041
  if (isValid) {
1042
1042
  formStatus.value = 'Formulaire soumis avec succès !'
1043
1043
  isFormSubmitted.value = true
@@ -11,51 +11,51 @@
11
11
  type PeriodValue = { from: DateInput, to: DateInput }
12
12
 
13
13
  const props = withDefaults(defineProps<{
14
+ bgColor?: string
15
+ customRules?: ValidationRule[]
16
+ customWarningRules?: ValidationRule[]
17
+ dateFormatReturn?: string
18
+ density?: 'default' | 'comfortable' | 'compact'
19
+ disableErrorHandling?: boolean
20
+ disabled?: boolean
21
+ displayAppendIcon?: boolean
22
+ displayIcon?: boolean
23
+ format?: string
24
+ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6
25
+ hideDetails?: boolean | 'auto'
26
+ isOutlined?: boolean
14
27
  modelValue?: PeriodValue
28
+ noCalendar?: boolean
29
+ noIcon?: boolean
15
30
  placeholderFrom?: string
16
31
  placeholderTo?: string
17
- format?: string
18
- dateFormatReturn?: string
19
- showWeekNumber?: boolean
32
+ readonly?: boolean
20
33
  required?: boolean
21
- displayIcon?: boolean
22
- displayAppendIcon?: boolean
23
- disabled?: boolean
24
- noIcon?: boolean
25
- noCalendar?: boolean
26
- isOutlined?: boolean
27
34
  showSuccessMessages?: boolean
28
- customRules?: ValidationRule[]
29
- customWarningRules?: ValidationRule[]
30
- disableErrorHandling?: boolean
31
- readonly?: boolean
32
- bgColor?: string
33
- density?: 'default' | 'comfortable' | 'compact'
34
- hideDetails?: boolean | 'auto'
35
- headingLevel?: 1 | 2 | 3 | 4 | 5 | 6
35
+ showWeekNumber?: boolean
36
36
  }>(), {
37
+ bgColor: 'white',
38
+ customRules: () => [],
39
+ customWarningRules: () => [],
40
+ dateFormatReturn: '',
41
+ density: 'default',
42
+ disableErrorHandling: false,
43
+ disabled: false,
44
+ displayAppendIcon: false,
45
+ displayIcon: true,
46
+ format: 'DD/MM/YYYY',
47
+ headingLevel: 2,
48
+ hideDetails: false,
49
+ isOutlined: true,
37
50
  modelValue: () => ({ from: null, to: null }),
51
+ noCalendar: false,
52
+ noIcon: false,
38
53
  placeholderFrom: 'Début',
39
54
  placeholderTo: 'Fin',
40
- format: 'DD/MM/YYYY',
41
- dateFormatReturn: '',
42
- showWeekNumber: false,
55
+ readonly: false,
43
56
  required: false,
44
- displayIcon: true,
45
- displayAppendIcon: false,
46
- disabled: false,
47
- noIcon: false,
48
- noCalendar: false,
49
- isOutlined: true,
50
57
  showSuccessMessages: true,
51
- customRules: () => [],
52
- customWarningRules: () => [],
53
- disableErrorHandling: false,
54
- readonly: false,
55
- bgColor: 'white',
56
- density: 'default',
57
- hideDetails: false,
58
- headingLevel: 2,
58
+ showWeekNumber: false,
59
59
  })
60
60
 
61
61
  const emit = defineEmits(['update:modelValue'])
@@ -230,42 +230,42 @@
230
230
  })
231
231
 
232
232
  // Synchronisation lorsque l'une des dates change
233
- function validateBothDates() {
233
+ async function validateBothDates() {
234
234
  if (fromDateRef.value) {
235
235
  fromDateRef.value.validateOnSubmit()
236
236
  }
237
237
  if (toDateRef.value) {
238
- toDateRef.value.validateOnSubmit()
238
+ await toDateRef.value.validateOnSubmit()
239
239
  }
240
240
  }
241
241
 
242
242
  // Validation complète du PeriodField
243
- function validateFields() {
244
- fromDateValidation.validateField(parsedFromDate.value, fromDateRules.value, props.customWarningRules)
245
- toDateValidation.validateField(parsedToDate.value, toDateRules.value, props.customWarningRules)
243
+ async function validateFields() {
244
+ await fromDateValidation.validateField(parsedFromDate.value, fromDateRules.value, props.customWarningRules)
245
+ await toDateValidation.validateField(parsedToDate.value, toDateRules.value, props.customWarningRules)
246
246
  }
247
247
 
248
248
  // Gestionnaires d'événements closed
249
- function handleFromDateClosed() {
250
- validateBothDates()
249
+ async function handleFromDateClosed() {
250
+ await validateBothDates()
251
251
  }
252
252
 
253
- function handleToDateClosed() {
254
- validateBothDates()
253
+ async function handleToDateClosed() {
254
+ await validateBothDates()
255
255
  }
256
256
 
257
257
  // Watch pour les changements des dates - validation croisée
258
- watch(formattedFromDate, () => {
259
- validateFields()
258
+ watch(formattedFromDate, async () => {
259
+ await validateFields()
260
260
  if (formattedToDate.value && toDateRef.value) {
261
- toDateRef.value.validateOnSubmit()
261
+ await toDateRef.value.validateOnSubmit()
262
262
  }
263
263
  })
264
264
 
265
- watch(formattedToDate, () => {
266
- validateFields()
265
+ watch(formattedToDate, async () => {
266
+ await validateFields()
267
267
  if (formattedFromDate.value && fromDateRef.value) {
268
- fromDateRef.value.validateOnSubmit()
268
+ await fromDateRef.value.validateOnSubmit()
269
269
  }
270
270
  })
271
271
 
@@ -278,7 +278,7 @@
278
278
  })
279
279
 
280
280
  // Watch pour les changements externes - Synchronisation
281
- watch(() => props.modelValue, (newValue) => {
281
+ watch(() => props.modelValue, async (newValue) => {
282
282
  if (!newValue) return
283
283
 
284
284
  const newFromDate = formatDateValue(newValue.from)
@@ -291,28 +291,28 @@
291
291
  internalToDate.value = newToDate
292
292
  }
293
293
  // Valider les champs après la mise à jour des valeurs
294
- validateFields()
294
+ await validateFields()
295
295
  }, { deep: true, immediate: true })
296
296
 
297
297
  // Fonction publique de validation
298
- const validateOnSubmit = (): boolean => {
298
+ const validateOnSubmit = async (): Promise<boolean> => {
299
299
  // Valider les deux CalendarMode
300
- const fromDateValid = fromDateRef.value?.validateOnSubmit() ?? true
301
- const toDateValid = toDateRef.value?.validateOnSubmit() ?? true
300
+ const fromDateValid = await fromDateRef.value?.validateOnSubmit() ?? true
301
+ const toDateValid = await toDateRef.value?.validateOnSubmit() ?? true
302
302
 
303
303
  // Valider avec les règles personnalisées
304
- validateFields()
304
+ await validateFields()
305
305
 
306
306
  // Retourner true seulement si tout est valide
307
307
  return fromDateValid && toDateValid && isValid.value
308
308
  }
309
309
 
310
310
  // Initialisation
311
- onMounted(() => {
311
+ onMounted(async () => {
312
312
  internalFromDate.value = formatDateValue(props.modelValue?.from)
313
313
  internalToDate.value = formatDateValue(props.modelValue?.to)
314
314
  // Validation initiale
315
- validateFields()
315
+ await validateFields()
316
316
  })
317
317
 
318
318
  defineExpose({
@@ -0,0 +1,32 @@
1
+ import { mount, flushPromises } from '@vue/test-utils'
2
+ import PeriodField from '../PeriodField.vue'
3
+ import { describe, it, expect } from 'vitest'
4
+ import { nextTick } from 'vue'
5
+
6
+ describe('PeriodField async validation', () => {
7
+ it('shows error when from date is after to date', async () => {
8
+ const wrapper = mount(PeriodField, {
9
+ props: {
10
+ modelValue: { from: '2024-01-01', to: '2024-01-31' },
11
+ },
12
+ })
13
+
14
+ // Find both DatePicker components
15
+ const datePickers = wrapper.findAllComponents({ name: 'DatePicker' })
16
+ expect(datePickers.length).toBe(2)
17
+
18
+ const fromInput = datePickers[0]!.find('input')
19
+ await fromInput.setValue('15/01/2024')
20
+ await fromInput.trigger('blur')
21
+ await flushPromises()
22
+
23
+ const toInput = datePickers[1]!.find('input')
24
+ await toInput.setValue('10/01/2024')
25
+ await toInput.trigger('blur')
26
+ await flushPromises()
27
+ await nextTick()
28
+
29
+ expect(datePickers[0]?.text()).toContain('date de début ne peut pas être supérieure à la date de fin')
30
+ expect(datePickers[1]?.text()).toContain('La date de fin ne peut pas être inférieure à la date de début')
31
+ })
32
+ })