@cnamts/synapse 1.0.22 → 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 (426) hide show
  1. package/dist/AutocompleteFilter-BWLR3U7W.js +114 -0
  2. package/dist/AutocompleteFilter-D9jzRzAL.cjs +1 -0
  3. package/dist/{DateFilter-B5n-ZkLi.js → DateFilter-BpwFexzi.js} +1 -1
  4. package/dist/DateFilter-DTUl8hb1.cjs +1 -0
  5. package/dist/{NumberFilter-CtiZ9uj8.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-DzqiMb-b.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-BOFRNfcX.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/Accordion/Accordion.d.ts +13 -2
  16. package/dist/components/Accordion/composables/useAccordionState.d.ts +2 -1
  17. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7022 -9616
  18. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +2 -2
  19. package/dist/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.d.ts +1 -1
  20. package/dist/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.d.ts +1 -1
  21. package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +2 -2
  22. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +40 -40
  23. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +61 -61
  24. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7168 -9762
  25. package/dist/components/Amelipro/AmeliproStepper/AmeliproStepper.d.ts +2 -2
  26. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +7506 -10100
  27. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +22 -22
  28. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +42 -42
  29. package/dist/components/Amelipro/StructureMenu/StructureTabs/StructureTabs.d.ts +2 -2
  30. package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +20 -498
  31. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +130 -147
  32. package/dist/components/Customs/Selects/SyAutocomplete/locales.d.ts +5 -0
  33. package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +6 -6
  34. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +13 -17
  35. package/dist/components/Customs/Selects/SySelect/locales.d.ts +1 -0
  36. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +9 -9
  37. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +29 -507
  38. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +29 -507
  39. package/dist/components/Customs/SyTextField/SyTextField.d.ts +64 -81
  40. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +640 -780
  41. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +322 -407
  42. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +114 -156
  43. package/dist/components/DatePicker/composables/index.d.ts +1 -0
  44. package/dist/components/DatePicker/composables/useDatePickerFocusTrap.d.ts +11 -0
  45. package/dist/components/DatePicker/composables/useDateTextField.d.ts +4 -4
  46. package/dist/components/DatePicker/composables/useDateValidation.d.ts +3 -3
  47. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
  48. package/dist/components/DatePicker/composables/useManualDateValidation.d.ts +2 -2
  49. package/dist/components/ErrorPage/ErrorPage.d.ts +3 -1
  50. package/dist/components/FileList/UploadItem/UploadItem.d.ts +6 -0
  51. package/dist/components/FileList/UploadItem/locales.d.ts +1 -4
  52. package/dist/components/FileUpload/FileUploadContent.d.ts +2 -0
  53. package/dist/components/FileUpload/validateFiles.d.ts +2 -1
  54. package/dist/components/HeaderBar/HeaderBar.d.ts +2 -1
  55. package/dist/components/HeaderBar/HeaderLogo/HeaderLogo.d.ts +2 -1
  56. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +6 -5
  57. package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +20 -28
  58. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +3 -3
  59. package/dist/components/MonthPicker/MonthPicker.d.ts +1903 -0
  60. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1863 -0
  61. package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +21 -0
  62. package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.d.ts +21 -0
  63. package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.d.ts +12 -0
  64. package/dist/components/MonthPicker/MonthPickerVisual/MonthSelector.d.ts +11 -0
  65. package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.d.ts +6 -0
  66. package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.d.ts +14 -0
  67. package/dist/components/MonthPicker/MonthPickerVisual/YearSelector.d.ts +14 -0
  68. package/dist/components/MonthPicker/MonthPickerVisual/useMonthGrid.d.ts +9 -0
  69. package/dist/components/MonthPicker/MonthPickerVisual/useYearGrid.d.ts +8 -0
  70. package/dist/components/MonthPicker/MonthPickerVisual/utils.d.ts +8 -0
  71. package/dist/components/MonthPicker/locales.d.ts +12 -0
  72. package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +25 -0
  73. package/dist/components/NirField/NirField.d.ts +209 -271
  74. package/dist/components/NirField/locales.d.ts +10 -10
  75. package/dist/components/NirField/useNirValidation.d.ts +64 -0
  76. package/dist/components/NotificationBar/Notification/Notification.d.ts +3 -0
  77. package/dist/components/PasswordField/PasswordField.d.ts +9 -10
  78. package/dist/components/PeriodField/PeriodField.d.ts +1379 -1659
  79. package/dist/components/PhoneField/PhoneField.d.ts +90 -125
  80. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +12 -12
  81. package/dist/components/SyBtnMenu/SyBtnMenu.d.ts +1 -1
  82. package/dist/components/SyHeading/SyHeading.a11y.test.d.ts +1 -0
  83. package/dist/components/SyHeading/SyHeading.d.ts +4 -2
  84. package/dist/components/SyHeading/SyHeading.test.d.ts +1 -0
  85. package/dist/components/SyTextArea/SyTextArea.d.ts +35 -15
  86. package/dist/components/SyTextArea/useDefaultValidationRules.d.ts +11 -0
  87. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +11 -8
  88. package/dist/components/Tables/SyTable/SyTable.d.ts +11 -8
  89. package/dist/components/Tables/common/SyTableFilter.d.ts +2 -3
  90. package/dist/components/Tables/common/SyTablePagination.d.ts +21 -23
  91. package/dist/components/Tables/common/filters/AutocompleteFilter.d.ts +120 -0
  92. package/dist/components/Tables/common/filters/locales.d.ts +0 -1
  93. package/dist/components/Tables/common/types.d.ts +19 -3
  94. package/dist/components/Tables/common/useClickableTableRow.d.ts +17 -0
  95. package/dist/components/Tables/common/usePagination.d.ts +3 -1
  96. package/dist/components/Tables/common/usePinnedColumns.d.ts +31 -0
  97. package/dist/components/Tables/common/useTableHeaders.d.ts +2 -0
  98. package/dist/components/Tables/common/useTableRowCheckboxAccessibility.d.ts +5 -0
  99. package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +6 -6
  100. package/dist/components/index.d.ts +1 -0
  101. package/dist/composables/date/useDatePickerAccessibility.d.ts +1 -1
  102. package/dist/composables/rules/useFieldValidation.d.ts +4 -4
  103. package/dist/composables/unifyValidation/useCustomValidation.d.ts +8 -0
  104. package/dist/composables/unifyValidation/useValidation.d.ts +102 -0
  105. package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +18 -0
  106. package/dist/composables/useFormFieldErrorHandling.d.ts +2 -2
  107. package/dist/composables/validation/useFormValidation.d.ts +11 -2
  108. package/dist/composables/validation/useValidation.d.ts +15 -9
  109. package/dist/design-system-v3.d.ts +2 -0
  110. package/dist/design-system-v3.js +196 -194
  111. package/dist/design-system-v3.umd.cjs +1 -1066
  112. package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +5 -0
  113. package/dist/{main-CEl4J8_T.js → main-BtTqyn4z.js} +16983 -15576
  114. package/dist/main-C1e3eoxd.cjs +1067 -0
  115. package/dist/synapse.css +1 -0
  116. package/dist/tooth-11-D3sLWv2n.cjs +1 -0
  117. package/dist/tooth-12-CXrLuH03.cjs +1 -0
  118. package/dist/tooth-13-BSfo5fpT.cjs +1 -0
  119. package/dist/tooth-14-DMzulx0h.cjs +1 -0
  120. package/dist/tooth-15-BKRFVi-9.cjs +1 -0
  121. package/dist/tooth-16-CpuxAbuM.cjs +1 -0
  122. package/dist/tooth-17-BPoahUdg.cjs +1 -0
  123. package/dist/tooth-18-DhHJz8sy.cjs +1 -0
  124. package/dist/tooth-21-Dgd5hn_X.cjs +1 -0
  125. package/dist/tooth-22-C2Tn19sB.cjs +1 -0
  126. package/dist/tooth-23-C9uaaSGb.cjs +1 -0
  127. package/dist/tooth-24-BrK9UGpf.cjs +1 -0
  128. package/dist/tooth-25-CE_EfGNp.cjs +1 -0
  129. package/dist/tooth-26-Ctv4i9Fy.cjs +1 -0
  130. package/dist/tooth-27-C5J7JkWM.cjs +1 -0
  131. package/dist/tooth-28-Z9oWqjo0.cjs +1 -0
  132. package/dist/tooth-31-BrYqmkTi.cjs +1 -0
  133. package/dist/tooth-32-BNNR0oCZ.cjs +1 -0
  134. package/dist/tooth-33-DuxvqO2J.cjs +1 -0
  135. package/dist/tooth-34-BCSCXMB6.cjs +1 -0
  136. package/dist/tooth-35-BLUXkX88.cjs +1 -0
  137. package/dist/tooth-36-IrKHYqlA.cjs +1 -0
  138. package/dist/tooth-37-BYqpdMwo.cjs +1 -0
  139. package/dist/tooth-38-B_eNXXdu.cjs +1 -0
  140. package/dist/tooth-41-Ddva4Ot8.cjs +1 -0
  141. package/dist/tooth-42-szcDqlM0.cjs +1 -0
  142. package/dist/tooth-43-B3ka6rQm.cjs +1 -0
  143. package/dist/tooth-44-CazyQucj.cjs +1 -0
  144. package/dist/tooth-45-B4HQtc8n.cjs +1 -0
  145. package/dist/tooth-46-BPM40gbG.cjs +1 -0
  146. package/dist/tooth-47-Dvr20dlh.cjs +1 -0
  147. package/dist/tooth-48-Bd8ljGsF.cjs +1 -0
  148. package/dist/tooth-51-OBpwCOF3.cjs +1 -0
  149. package/dist/tooth-52-aKxyHcmq.cjs +1 -0
  150. package/dist/tooth-53-vCwJjTOc.cjs +1 -0
  151. package/dist/tooth-54-DsWu2iFy.cjs +1 -0
  152. package/dist/tooth-55-BxC1X2Dn.cjs +1 -0
  153. package/dist/tooth-61-BbLvxMQi.cjs +1 -0
  154. package/dist/tooth-62-CmTkWczP.cjs +1 -0
  155. package/dist/tooth-63-DI7l_2qI.cjs +1 -0
  156. package/dist/tooth-64-B21sOsJh.cjs +1 -0
  157. package/dist/tooth-65-D2ZC2VEr.cjs +1 -0
  158. package/dist/tooth-71-D473PPO5.cjs +1 -0
  159. package/dist/tooth-72-Drh1wnNu.cjs +1 -0
  160. package/dist/tooth-73-DzlwYI23.cjs +1 -0
  161. package/dist/tooth-74-8aGvcZPg.cjs +1 -0
  162. package/dist/tooth-75-BFK7At_r.cjs +1 -0
  163. package/dist/tooth-81-BZmR-I0M.cjs +1 -0
  164. package/dist/tooth-82-euVfUUZV.cjs +1 -0
  165. package/dist/tooth-83-KV010j64.cjs +1 -0
  166. package/dist/tooth-84-BBg1RjhZ.cjs +1 -0
  167. package/dist/tooth-85-Cr-kc1wM.cjs +1 -0
  168. package/dist/vuetifyConfig.js +561 -0
  169. package/dist/vuetifyConfig.umd.cjs +1 -0
  170. package/package.json +18 -6
  171. package/src/assets/apTokens.scss +2 -2
  172. package/src/assets/overrides/_btns.scss +2 -0
  173. package/src/assets/overrides/_forms.scss +9 -0
  174. package/src/assets/overrides/_icons.scss +41 -4
  175. package/src/assets/overrides/_tables.scss +19 -0
  176. package/src/assets/overrides/_typography.scss +0 -10
  177. package/src/components/Accordion/Accordion.mdx +23 -9
  178. package/src/components/Accordion/Accordion.stories.ts +153 -3
  179. package/src/components/Accordion/Accordion.vue +7 -6
  180. package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +40 -12
  181. package/src/components/Accordion/composables/useAccordionState.ts +3 -4
  182. package/src/components/Accordion/tests/accordion.spec.ts +131 -19
  183. package/src/components/Amelipro/AmeliproAutoCompleteField/__tests__/__snapshots__/AmeliproAutoCompleteField.spec.ts.snap +2 -2
  184. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
  185. package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.mdx +3 -1
  186. package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.stories.ts +8 -0
  187. package/src/components/Amelipro/AmeliproTextArea/__tests__/__snapshots__/AmeliproTextArea.spec.ts.snap +2 -2
  188. package/src/components/BackBtn/accessibilite/Accessibility.mdx +62 -10
  189. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +9 -3
  190. package/src/components/BackToTopBtn/accessibilite/Accessibility.mdx +86 -6
  191. package/src/components/Captcha/accessibilite/Accessibility.mdx +86 -8
  192. package/src/components/Captcha/tests/Captcha.spec.ts +0 -29
  193. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +14 -122
  194. package/src/components/ChipList/ChipList.stories.ts +0 -15
  195. package/src/components/ChipList/ChipList.vue +5 -1
  196. package/src/components/ChipList/accessibilite/Accessibility.mdx +83 -10
  197. package/src/components/ChipList/tests/ChipList.a11y.spec.ts +41 -0
  198. package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +124 -10
  199. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +379 -93
  200. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +162 -84
  201. package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibilite.stories.ts +40 -1
  202. package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibility.mdx +7 -1
  203. package/src/components/Customs/Selects/SyAutocomplete/locales.ts +5 -0
  204. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +96 -0
  205. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +377 -9
  206. package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +27 -13
  207. package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +9 -10
  208. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +4 -4
  209. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +8 -9
  210. package/src/components/Customs/Selects/SyInputSelect/tests/SyInputSelect.spec.ts +10 -10
  211. package/src/components/Customs/Selects/SySelect/SySelect.vue +60 -14
  212. package/src/components/Customs/Selects/SySelect/locales.ts +1 -0
  213. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +54 -0
  214. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +6 -9
  215. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +10 -16
  216. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +16 -11
  217. package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +35 -0
  218. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.a11y.spec.ts +134 -2
  219. package/src/components/Customs/SyForm/SyForm.stories.ts +31 -5
  220. package/src/components/Customs/SyIcon/SyIcon.vue +1 -1
  221. package/src/components/Customs/SyIcon/tests/SyIcon.a11y.spec.ts +20 -0
  222. package/src/components/Customs/SyIconButton/SyIconButton.mdx +46 -0
  223. package/src/components/Customs/SyIconButton/SyIconButton.stories.ts +184 -0
  224. package/src/components/Customs/SyIconButton/SyIconButton.vue +38 -0
  225. package/src/components/Customs/SyIconButton/accessibilite/Accessibility.mdx +64 -0
  226. package/src/components/Customs/SyIconButton/tests/SyIconButton.a11y.spec.ts +87 -0
  227. package/src/components/Customs/SyIconButton/tests/SyIconButton.spec.ts +152 -0
  228. package/src/components/Customs/SyIconButton/tests/__snapshots__/SyIconButton.spec.ts.snap +61 -0
  229. package/src/components/Customs/SyPagination/SyPagination.vue +5 -5
  230. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +4 -7
  231. package/src/components/Customs/SyTextField/SyTextField.mdx +1 -1
  232. package/src/components/Customs/SyTextField/SyTextField.stories.ts +29 -27
  233. package/src/components/Customs/SyTextField/SyTextField.vue +174 -159
  234. package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +67 -9
  235. package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +47 -0
  236. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +155 -10
  237. package/src/components/DataList/accessibilite/Accessibility.mdx +79 -11
  238. package/src/components/DataListGroup/accessibilite/Accessibility.mdx +80 -11
  239. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +62 -58
  240. package/src/components/DatePicker/CalendarMode/DatePicker.vue +330 -223
  241. package/src/components/DatePicker/CalendarMode/accessibilite/Accessibility.mdx +82 -0
  242. package/src/components/DatePicker/CalendarMode/tests/DatePicker.a11y.spec.ts +141 -0
  243. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +2 -56
  244. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +195 -159
  245. package/src/components/DatePicker/ComplexDatePicker/accessibilite/Accessibility.mdx +76 -0
  246. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +10 -10
  247. package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +8 -8
  248. package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +106 -8
  249. package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +12 -11
  250. package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +12 -12
  251. package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +0 -12
  252. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +63 -57
  253. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +3 -0
  254. package/src/components/DatePicker/DateTextInput/accessibilite/Accessibility.mdx +66 -0
  255. package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +52 -1
  256. package/src/components/DatePicker/composables/index.ts +1 -0
  257. package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +109 -65
  258. package/src/components/DatePicker/composables/tests/useDatePickerFocusTrap.spec.ts +138 -0
  259. package/src/components/DatePicker/composables/tests/useDateValidation.spec.ts +74 -18
  260. package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +39 -0
  261. package/src/components/DatePicker/composables/tests/useManualDateValidation.spec.ts +91 -0
  262. package/src/components/DatePicker/composables/useCalendarKeyboardNavigation.ts +442 -36
  263. package/src/components/DatePicker/composables/useDatePickerFocusTrap.ts +92 -0
  264. package/src/components/DatePicker/composables/useDateTextField.ts +7 -6
  265. package/src/components/DatePicker/composables/useDateValidation.ts +36 -35
  266. package/src/components/DatePicker/composables/useInputBlurHandler.ts +3 -3
  267. package/src/components/DatePicker/composables/useManualDateValidation.ts +6 -2
  268. package/src/components/DiacriticPicker/accessibilite/Accessibility.mdx +76 -8
  269. package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +25 -0
  270. package/src/components/ErrorPage/ErrorPage.stories.ts +113 -19
  271. package/src/components/ErrorPage/ErrorPage.vue +17 -2
  272. package/src/components/ErrorPage/tests/ErrorPage.a11y.spec.ts +17 -0
  273. package/src/components/ErrorPage/tests/ErrorPage.spec.ts +21 -1
  274. package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +0 -1
  275. package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +23 -0
  276. package/src/components/FileList/FileList.stories.ts +51 -1
  277. package/src/components/FileList/UploadItem/UploadItem.vue +13 -6
  278. package/src/components/FileList/UploadItem/locales.ts +3 -12
  279. package/src/components/FileList/accessibilite/Accessibility.mdx +3 -0
  280. package/src/components/FileUpload/FileUpload.vue +2 -1
  281. package/src/components/FileUpload/FileUploadContent.vue +2 -1
  282. package/src/components/FileUpload/tests/FileUpload.spec.ts +47 -0
  283. package/src/components/FileUpload/validateFiles.ts +5 -2
  284. package/src/components/FranceConnectBtn/accessibilite/Accessibility.mdx +62 -9
  285. package/src/components/HeaderBar/HeaderBar.stories.ts +14 -2
  286. package/src/components/HeaderBar/HeaderBar.vue +2 -1
  287. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -1
  288. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
  289. package/src/components/Logo/accessibilite/Accessibility.mdx +73 -11
  290. package/src/components/LogoBrandSection/accessibilite/Accessibility.mdx +85 -9
  291. package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +74 -8
  292. package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +163 -0
  293. package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +3 -1
  294. package/src/components/LunarCalendar/useLunarCalendarValidation.ts +4 -5
  295. package/src/components/MaintenancePage/MaintenancePage.vue +1 -1
  296. package/src/components/MaintenancePage/tests/MaintenancePage.spec.ts +4 -5
  297. package/src/components/MaintenancePage/tests/__snapshots__/MaintenancePage.spec.ts.snap +0 -1
  298. package/src/components/MonthPicker/MonthPicker.mdx +35 -0
  299. package/src/components/MonthPicker/MonthPicker.stories.ts +527 -0
  300. package/src/components/MonthPicker/MonthPicker.vue +79 -0
  301. package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +89 -0
  302. package/src/components/MonthPicker/MonthPickerText/useTextField.ts +27 -0
  303. package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.vue +154 -0
  304. package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.ts +13 -0
  305. package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +137 -0
  306. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +60 -0
  307. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +149 -0
  308. package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +143 -0
  309. package/src/components/MonthPicker/MonthPickerVisual/useMonthGrid.ts +45 -0
  310. package/src/components/MonthPicker/MonthPickerVisual/useYearGrid.ts +45 -0
  311. package/src/components/MonthPicker/MonthPickerVisual/utils.ts +17 -0
  312. package/src/components/MonthPicker/accessibilite/Accessibility.mdx +59 -0
  313. package/src/components/MonthPicker/locales.ts +12 -0
  314. package/src/components/MonthPicker/tests/MonthPicker.a11y.spec.ts +71 -0
  315. package/src/components/MonthPicker/tests/MonthPicker.spec.ts +1249 -0
  316. package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +2545 -0
  317. package/src/components/MonthPicker/useMonthPickerValidation.ts +30 -0
  318. package/src/components/NirField/NirField.mdx +1 -2
  319. package/src/components/NirField/NirField.stories.ts +70 -6
  320. package/src/components/NirField/NirField.vue +64 -260
  321. package/src/components/NirField/accessibilite/Accessibility.mdx +2 -2
  322. package/src/components/NirField/locales.ts +1 -1
  323. package/src/components/NirField/tests/NirField.spec.ts +6 -0
  324. package/src/components/NirField/useNirValidation.ts +271 -0
  325. package/src/components/NotFoundPage/tests/NotFoundPage.spec.ts +2 -3
  326. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +22 -14
  327. package/src/components/NotificationBar/Notification/Notification.vue +3 -1
  328. package/src/components/NotificationBar/NotificationBar.stories.ts +154 -0
  329. package/src/components/NotificationBar/tests/NotificationBar.a11y.spec.ts +26 -0
  330. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +60 -0
  331. package/src/components/PasswordField/PasswordField.stories.ts +4 -4
  332. package/src/components/PasswordField/PasswordField.vue +18 -24
  333. package/src/components/PasswordField/tests/PasswordField.spec.ts +6 -3
  334. package/src/components/PeriodField/PeriodField.stories.ts +4 -4
  335. package/src/components/PeriodField/PeriodField.vue +57 -57
  336. package/src/components/PeriodField/__tests__/PeriodField.async.spec.ts +32 -0
  337. package/src/components/PeriodField/accessibilite/Accessibility.mdx +68 -8
  338. package/src/components/PeriodField/tests/PeriodField.spec.ts +28 -2
  339. package/src/components/PhoneField/PhoneField.vue +5 -6
  340. package/src/components/PhoneField/tests/PhoneField.spec.ts +1 -0
  341. package/src/components/RangeField/RangeField.vue +6 -0
  342. package/src/components/RangeField/accessibilite/Accessibility.mdx +79 -11
  343. package/src/components/SkipLink/tests/SkipLink.a11y.spec.ts +23 -0
  344. package/src/components/StatusPage/StatusPage.stories.ts +118 -0
  345. package/src/components/StatusPage/StatusPage.vue +5 -3
  346. package/src/components/StatusPage/tests/StatusPage.a11y.spec.ts +22 -0
  347. package/src/components/StatusPage/tests/StatusPage.spec.ts +22 -0
  348. package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +22 -14
  349. package/src/components/SubHeader/tests/SubHeader.a11y.spec.ts +20 -0
  350. package/src/components/SyAlert/SyAlert.vue +1 -0
  351. package/src/components/SyAlert/accessibilite/Accessibility.mdx +79 -9
  352. package/src/components/SyAlert/tests/SyAlert.a11y.spec.ts +23 -0
  353. package/src/components/SyHeading/SyHeading.a11y.test.ts +149 -0
  354. package/src/components/SyHeading/SyHeading.test.ts +115 -0
  355. package/src/components/SyHeading/SyHeading.vue +5 -3
  356. package/src/components/SyTextArea/SyTextArea.stories.ts +138 -2
  357. package/src/components/SyTextArea/SyTextArea.vue +53 -23
  358. package/src/components/SyTextArea/accessibilite/Accessibility.mdx +80 -8
  359. package/src/components/SyTextArea/tests/SyTextArea.a11y.spec.ts +151 -0
  360. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +126 -3
  361. package/src/components/SyTextArea/useDefaultValidationRules.ts +74 -0
  362. package/src/components/Tables/SyServerTable/SyServerTable.mdx +25 -0
  363. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +673 -1
  364. package/src/components/Tables/SyServerTable/SyServerTable.vue +148 -91
  365. package/src/components/Tables/SyServerTable/tests/SyServerTable.a11y.spec.ts +58 -0
  366. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +122 -0
  367. package/src/components/Tables/SyTable/SyTable.mdx +25 -0
  368. package/src/components/Tables/SyTable/SyTable.stories.ts +452 -1
  369. package/src/components/Tables/SyTable/SyTable.vue +130 -56
  370. package/src/components/Tables/SyTable/tests/SyTable.a11y.spec.ts +57 -0
  371. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +108 -0
  372. package/src/components/Tables/common/SyTableFilter.vue +22 -2
  373. package/src/components/Tables/common/TableHeader.vue +5 -1
  374. package/src/components/Tables/common/filters/AutocompleteFilter.vue +160 -0
  375. package/src/components/Tables/common/filters/NumberFilter.vue +1 -1
  376. package/src/components/Tables/common/filters/SelectFilter.vue +10 -11
  377. package/src/components/Tables/common/filters/TextFilter.vue +1 -1
  378. package/src/components/Tables/common/filters/getFilterComponent.ts +8 -1
  379. package/src/components/Tables/common/filters/locales.ts +0 -1
  380. package/src/components/Tables/common/filters/tests/AutocompleteFilter.a11y.spec.ts +110 -0
  381. package/src/components/Tables/common/filters/tests/AutocompleteFilter.spec.ts +203 -0
  382. package/src/components/Tables/common/filters/tests/SelectFilter.a11y.spec.ts +104 -0
  383. package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +152 -16
  384. package/src/components/Tables/common/tableFilterUtils.ts +3 -0
  385. package/src/components/Tables/common/tableStyles.scss +48 -4
  386. package/src/components/Tables/common/tests/filterByRange.spec.ts +2 -1
  387. package/src/components/Tables/common/types.ts +13 -4
  388. package/src/components/Tables/common/useClickableTableRow.ts +103 -0
  389. package/src/components/Tables/common/usePagination.ts +13 -0
  390. package/src/components/Tables/common/usePinnedColumns.ts +237 -0
  391. package/src/components/Tables/common/useTableHeaders.ts +3 -3
  392. package/src/components/Tables/common/useTableRowCheckboxAccessibility.ts +41 -0
  393. package/src/components/ToolbarContainer/tests/ToolbarContainer.a11y.spec.ts +126 -0
  394. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +2 -2
  395. package/src/components/index.ts +1 -0
  396. package/src/composables/date/tests/useDatePickerAccessibility.spec.ts +2 -6
  397. package/src/composables/date/useDatePickerAccessibility.ts +42 -207
  398. package/src/composables/rules/tests/useFieldValidation.spec.ts +120 -120
  399. package/src/composables/rules/useFieldValidation.ts +34 -17
  400. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +601 -0
  401. package/src/composables/unifyValidation/tests/useValidation.spec.ts +2048 -0
  402. package/src/composables/unifyValidation/tests/useVuetifyValidation.spec.ts +184 -0
  403. package/src/composables/unifyValidation/useCustomValidation.ts +95 -0
  404. package/src/composables/unifyValidation/useValidation.ts +190 -0
  405. package/src/composables/unifyValidation/useVuetifyValidation.ts +54 -0
  406. package/src/composables/useFormFieldErrorHandling.ts +15 -9
  407. package/src/composables/validation/tests/useFormValidation.spec.ts +14 -0
  408. package/src/composables/validation/tests/useValidation.spec.ts +116 -21
  409. package/src/composables/validation/useFormValidation.ts +20 -13
  410. package/src/composables/validation/useValidatable.ts +8 -1
  411. package/src/composables/validation/useValidation.ts +135 -99
  412. package/src/composantsVuetify/Introduction.mdx +48 -0
  413. package/src/composantsVuetify/VBtn/VBtn.mdx +72 -0
  414. package/src/composantsVuetify/VBtn/v-btn.stories.ts +121 -0
  415. package/src/composantsVuetify/VTooltip/VTooltip.mdx +32 -0
  416. package/src/composantsVuetify/VTooltip/v-tooltip.stories.ts +95 -0
  417. package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -1
  418. package/src/designTokens/tokens/cnam/cnamSemantic.ts +2 -2
  419. package/src/stories/Components/Components.stories.ts +74 -9
  420. package/src/stories/Demarrer/Accueil.stories.ts +3 -3
  421. package/src/stories/GuideDuDev/Amelipro.mdx +15 -0
  422. package/src/stories/GuideDuDev/Amelipro.stories.ts +209 -0
  423. package/src/stories/GuideDuDev/vuetifyOptions.mdx +3 -3
  424. package/dist/SelectFilter-BOYlF7rX.js +0 -136
  425. package/dist/style.css +0 -1
  426. package/src/components/DatePicker/Accessibilite.mdx +0 -14
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
2
  import { mount, flushPromises } from '@vue/test-utils'
3
- import { VMenu, VChip } from 'vuetify/components'
3
+ import { VMenu } from 'vuetify/components'
4
4
 
5
5
  import SyAutocomplete from '../SyAutocomplete.vue'
6
6
  import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue'
@@ -128,13 +128,13 @@ describe('SyAutocomplete', () => {
128
128
 
129
129
  // Some environments can emit a follow-up input event with the previous DOM value.
130
130
  // Ensure it doesn't re-populate the query after selection.
131
- textField.vm.$emit('update:modelValue', 'Option 1, Opt')
131
+ textField.vm.$emit('update:modelValue', 'Opt')
132
132
  await flushPromises()
133
133
  await wrapper.vm.$nextTick()
134
134
 
135
- // Query should be cleared, leaving only selected label prefix in input
135
+ // Search and input should be cleared; selected items render as inline labels, not in input value
136
136
  expect(wrapper.vm.search).toBe('')
137
- expect(getInputEl()!.value).toBe('Option 1, ')
137
+ expect(getInputEl()!.value).toBe('')
138
138
  })
139
139
 
140
140
  it('displays chips in multiple mode', async () => {
@@ -150,12 +150,13 @@ describe('SyAutocomplete', () => {
150
150
  textKey: 'text',
151
151
  valueKey: 'value',
152
152
  },
153
+ attachTo: document.body,
153
154
  })
154
155
 
155
156
  await wrapper.vm.$nextTick()
156
- const chips = wrapper.findAllComponents(VChip)
157
+ const chips = wrapper.findAll('.v-chip')
157
158
  expect(chips.length).toBe(1)
158
- expect(chips[0]!.text()).toBe('Option 1')
159
+ expect(chips[0]!.text()).toContain('Option 1')
159
160
  })
160
161
 
161
162
  it('removes chip when close button is clicked', async () => {
@@ -171,14 +172,158 @@ describe('SyAutocomplete', () => {
171
172
  textKey: 'text',
172
173
  valueKey: 'value',
173
174
  },
175
+ attachTo: document.body,
176
+ })
177
+
178
+ await wrapper.vm.$nextTick()
179
+ const closeBtn = wrapper.find('.v-chip__close')
180
+ await closeBtn.trigger('click')
181
+ await wrapper.vm.$nextTick()
182
+
183
+ expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([null])
184
+ })
185
+
186
+ it('removes chip when Enter key is pressed on chip close button', async () => {
187
+ wrapper.unmount()
188
+ wrapper = mount(SyAutocomplete, {
189
+ props: {
190
+ modelValue: [items[0]!, items[1]!],
191
+ items,
192
+ multiple: true,
193
+ chips: true,
194
+ returnObject: true,
195
+ label: 'Test Chips Keyboard',
196
+ textKey: 'text',
197
+ valueKey: 'value',
198
+ },
199
+ attachTo: document.body,
200
+ })
201
+
202
+ await wrapper.vm.$nextTick()
203
+ const closeBtn = wrapper.find('.v-chip__close')
204
+ closeBtn.element.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true }))
205
+ await flushPromises()
206
+ await wrapper.vm.$nextTick()
207
+
208
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy()
209
+ // First item was removed — remaining is [items[1]]
210
+ const emitted = wrapper.emitted('update:modelValue')?.[0]?.[0] as unknown[]
211
+ expect(emitted).toHaveLength(1)
212
+ expect((emitted[0] as { value: string }).value).toBe('2')
213
+ })
214
+
215
+ it('removes chip when Space key is pressed on chip close button', async () => {
216
+ wrapper.unmount()
217
+ wrapper = mount(SyAutocomplete, {
218
+ props: {
219
+ modelValue: [items[0]!, items[1]!],
220
+ items,
221
+ multiple: true,
222
+ chips: true,
223
+ returnObject: true,
224
+ label: 'Test Chips Space',
225
+ textKey: 'text',
226
+ valueKey: 'value',
227
+ },
228
+ attachTo: document.body,
174
229
  })
175
230
 
176
231
  await wrapper.vm.$nextTick()
177
- const chip = wrapper.findComponent(VChip)
178
- await chip.vm.$emit('click:close')
232
+ const closeBtn = wrapper.find('.v-chip__close')
233
+ closeBtn.element.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true, cancelable: true }))
234
+ await flushPromises()
179
235
  await wrapper.vm.$nextTick()
180
236
 
181
- expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([[]])
237
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy()
238
+ const emitted = wrapper.emitted('update:modelValue')?.[0]?.[0] as unknown[]
239
+ expect(emitted).toHaveLength(1)
240
+ })
241
+
242
+ it('does not open menu when modelValue is set programmatically (suppressMenuOpen)', async () => {
243
+ // Menu must be closed initially
244
+ expect(isMenuOverlayActive()).toBe(false)
245
+
246
+ // Programmatic update (e.g., filter reset sets a value) should NOT open the menu
247
+ await wrapper.setProps({ modelValue: items[0] })
248
+ await flushPromises()
249
+ await wrapper.vm.$nextTick()
250
+
251
+ expect(isMenuOverlayActive()).toBe(false)
252
+ })
253
+
254
+ it('keeps menu open when blur target is a chip (checkErrorOnBlur)', async () => {
255
+ wrapper.unmount()
256
+ wrapper = mount(SyAutocomplete, {
257
+ props: {
258
+ modelValue: ['1'],
259
+ items,
260
+ multiple: true,
261
+ chips: true,
262
+ label: 'Test blur chip',
263
+ textKey: 'text',
264
+ valueKey: 'value',
265
+ menuId,
266
+ },
267
+ attachTo: document.body,
268
+ })
269
+
270
+ // Open menu
271
+ const input = wrapper.find('input')
272
+ await input.trigger('click')
273
+ await flushPromises()
274
+ await wrapper.vm.$nextTick()
275
+ expect(isMenuOverlayActive()).toBe(true)
276
+
277
+ // Create a chip DOM element as blur relatedTarget
278
+ const chipEl = document.createElement('span')
279
+ chipEl.className = 'sy-autocomplete__chip'
280
+ document.body.appendChild(chipEl)
281
+
282
+ const inputEl = getInputEl()!
283
+ inputEl.dispatchEvent(new FocusEvent('blur', { relatedTarget: chipEl, bubbles: true }))
284
+ await flushPromises()
285
+ await wrapper.vm.$nextTick()
286
+
287
+ // Menu should remain open
288
+ expect(isMenuOverlayActive()).toBe(true)
289
+
290
+ document.body.removeChild(chipEl)
291
+ })
292
+
293
+ it('keeps menu open when blur target is the clear button (checkErrorOnBlur)', async () => {
294
+ wrapper.unmount()
295
+ wrapper = mount(SyAutocomplete, {
296
+ props: {
297
+ modelValue: items[0],
298
+ items,
299
+ clearable: true,
300
+ label: 'Test blur clear',
301
+ textKey: 'text',
302
+ valueKey: 'value',
303
+ menuId,
304
+ },
305
+ attachTo: document.body,
306
+ })
307
+
308
+ const input = wrapper.find('input')
309
+ await input.trigger('click')
310
+ await flushPromises()
311
+ await wrapper.vm.$nextTick()
312
+ expect(isMenuOverlayActive()).toBe(true)
313
+
314
+ // Create a clear-button DOM element as blur relatedTarget
315
+ const clearBtn = document.createElement('button')
316
+ clearBtn.className = 'sy-autocomplete__clear-button'
317
+ document.body.appendChild(clearBtn)
318
+
319
+ const inputEl = getInputEl()!
320
+ inputEl.dispatchEvent(new FocusEvent('blur', { relatedTarget: clearBtn, bubbles: true }))
321
+ await flushPromises()
322
+ await wrapper.vm.$nextTick()
323
+
324
+ expect(isMenuOverlayActive()).toBe(true)
325
+
326
+ document.body.removeChild(clearBtn)
182
327
  })
183
328
 
184
329
  it('shows clear button when clearable and has selection', async () => {
@@ -298,6 +443,181 @@ describe('SyAutocomplete', () => {
298
443
  expect(isMenuOverlayActive()).toBe(false)
299
444
  })
300
445
 
446
+ describe('selectionText', () => {
447
+ const selectionText = (selected: unknown[]) => `${selected.length} élément${selected.length > 1 ? 's' : ''} sélectionné${selected.length > 1 ? 's' : ''}`
448
+
449
+ it('displays custom text in prepend-inner when items are selected', async () => {
450
+ wrapper.unmount()
451
+ wrapper = mount(SyAutocomplete, {
452
+ props: {
453
+ modelValue: ['1', '2'],
454
+ items,
455
+ multiple: true,
456
+ selectionText,
457
+ label: 'Test selectionText',
458
+ textKey: 'text',
459
+ valueKey: 'value',
460
+ menuId,
461
+ },
462
+ attachTo: document.body,
463
+ })
464
+ await wrapper.vm.$nextTick()
465
+
466
+ const selectionTextEl = wrapper.find('.sy-autocomplete__selection-text')
467
+ expect(selectionTextEl.exists()).toBe(true)
468
+ expect(selectionTextEl.text()).toBe('2 éléments sélectionnés')
469
+ expect(getInputEl()?.value).toBe('')
470
+ })
471
+
472
+ it('does not display selection text element when no items are selected', async () => {
473
+ wrapper.unmount()
474
+ wrapper = mount(SyAutocomplete, {
475
+ props: {
476
+ modelValue: [],
477
+ items,
478
+ multiple: true,
479
+ selectionText,
480
+ label: 'Test selectionText vide',
481
+ textKey: 'text',
482
+ valueKey: 'value',
483
+ menuId,
484
+ },
485
+ attachTo: document.body,
486
+ })
487
+ await wrapper.vm.$nextTick()
488
+
489
+ expect(wrapper.find('.sy-autocomplete__selection-text').exists()).toBe(false)
490
+ })
491
+
492
+ it('keeps custom text visible when menu is open', async () => {
493
+ wrapper.unmount()
494
+ wrapper = mount(SyAutocomplete, {
495
+ props: {
496
+ modelValue: ['1', '2'],
497
+ items,
498
+ multiple: true,
499
+ selectionText,
500
+ label: 'Test selectionText ouvert',
501
+ textKey: 'text',
502
+ valueKey: 'value',
503
+ menuId,
504
+ },
505
+ attachTo: document.body,
506
+ })
507
+ await wrapper.vm.$nextTick()
508
+
509
+ const input = wrapper.find('input')
510
+ await input.trigger('click')
511
+ await flushPromises()
512
+ await wrapper.vm.$nextTick()
513
+
514
+ // Custom text still visible in prepend-inner, input empty for searching
515
+ expect(wrapper.find('.sy-autocomplete__selection-text').text()).toBe('2 éléments sélectionnés')
516
+ expect(getInputEl()?.value).toBe('')
517
+ })
518
+
519
+ it('updates custom text when selection changes', async () => {
520
+ wrapper.unmount()
521
+ wrapper = mount(SyAutocomplete, {
522
+ props: {
523
+ modelValue: ['1'],
524
+ items,
525
+ multiple: true,
526
+ selectionText,
527
+ label: 'Test selectionText update',
528
+ textKey: 'text',
529
+ valueKey: 'value',
530
+ menuId,
531
+ },
532
+ attachTo: document.body,
533
+ })
534
+ await wrapper.vm.$nextTick()
535
+ expect(wrapper.find('.sy-autocomplete__selection-text').text()).toBe('1 élément sélectionné')
536
+
537
+ await wrapper.setProps({ modelValue: ['1', '2', '3'] })
538
+ await wrapper.vm.$nextTick()
539
+ expect(wrapper.find('.sy-autocomplete__selection-text').text()).toBe('3 éléments sélectionnés')
540
+ })
541
+ })
542
+
543
+ describe('loading', () => {
544
+ it('shows progress bar when loading is true', async () => {
545
+ wrapper.unmount()
546
+ wrapper = mount(SyAutocomplete, {
547
+ props: {
548
+ modelValue: null,
549
+ items,
550
+ label: 'Test Loading',
551
+ textKey: 'text',
552
+ valueKey: 'value',
553
+ loading: true,
554
+ menuId,
555
+ },
556
+ attachTo: document.body,
557
+ })
558
+
559
+ await wrapper.vm.$nextTick()
560
+ const progressBar = wrapper.find('.v-progress-linear')
561
+ expect(progressBar.exists()).toBe(true)
562
+ })
563
+
564
+ it('does not show progress bar when loading is false', async () => {
565
+ await wrapper.vm.$nextTick()
566
+ const progressBar = wrapper.find('.v-progress-linear')
567
+ expect(progressBar.exists()).toBe(false)
568
+ })
569
+
570
+ it('hides no-data message while loading', async () => {
571
+ wrapper.unmount()
572
+ wrapper = mount(SyAutocomplete, {
573
+ props: {
574
+ modelValue: null,
575
+ items: [],
576
+ label: 'Test Loading No Data',
577
+ textKey: 'text',
578
+ valueKey: 'value',
579
+ loading: true,
580
+ menuId,
581
+ },
582
+ attachTo: document.body,
583
+ })
584
+
585
+ const input = wrapper.find('input')
586
+ await input.trigger('click')
587
+ await flushPromises()
588
+ await wrapper.vm.$nextTick()
589
+
590
+ // No-data item should not appear while loading
591
+ const noDataItem = document.body.querySelector(`#${menuId} .v-list-item`)
592
+ expect(noDataItem).toBeNull()
593
+ })
594
+
595
+ it('shows no-data message once loading is done and items is empty', async () => {
596
+ wrapper.unmount()
597
+ wrapper = mount(SyAutocomplete, {
598
+ props: {
599
+ modelValue: null,
600
+ items: [],
601
+ label: 'Test Loading Done',
602
+ textKey: 'text',
603
+ valueKey: 'value',
604
+ loading: false,
605
+ menuId,
606
+ },
607
+ attachTo: document.body,
608
+ })
609
+
610
+ const input = wrapper.find('input')
611
+ await input.trigger('click')
612
+ await flushPromises()
613
+ await wrapper.vm.$nextTick()
614
+
615
+ const listItems = document.body.querySelectorAll(`#${menuId} .v-list-item`)
616
+ const texts = Array.from(listItems).map(el => el.textContent?.trim())
617
+ expect(texts).toContain('Aucune option')
618
+ })
619
+ })
620
+
301
621
  it('selects and deselects items in multiple mode (mouse + keyboard)', async () => {
302
622
  wrapper.unmount()
303
623
  wrapper = mount(SyAutocomplete, {
@@ -342,4 +662,52 @@ describe('SyAutocomplete', () => {
342
662
  option0 = getOption(0)
343
663
  expect(option0?.getAttribute('aria-selected')).toBe('false')
344
664
  })
665
+
666
+ describe('hideDetails', () => {
667
+ it('hides the details zone when hideDetails is true', async () => {
668
+ wrapper.unmount()
669
+ wrapper = mount(SyAutocomplete, {
670
+ props: {
671
+ modelValue: null,
672
+ items,
673
+ label: 'Test hideDetails',
674
+ textKey: 'text',
675
+ valueKey: 'value',
676
+ hideDetails: true,
677
+ menuId,
678
+ },
679
+ attachTo: document.body,
680
+ })
681
+
682
+ await wrapper.vm.$nextTick()
683
+ expect(wrapper.find('.v-input__details').exists()).toBe(false)
684
+ })
685
+
686
+ it('shows the details zone when hideDetails is false', async () => {
687
+ await wrapper.vm.$nextTick()
688
+ expect(wrapper.find('.v-input__details').exists()).toBe(true)
689
+ })
690
+
691
+ it('does not show error messages when hideDetails is true even with validation errors', async () => {
692
+ wrapper.unmount()
693
+ wrapper = mount(SyAutocomplete, {
694
+ props: {
695
+ modelValue: null,
696
+ items,
697
+ label: 'Test hideDetails + erreur',
698
+ textKey: 'text',
699
+ valueKey: 'value',
700
+ hideDetails: true,
701
+ hasError: true,
702
+ errorMessages: ['Erreur de validation'],
703
+ menuId,
704
+ },
705
+ attachTo: document.body,
706
+ })
707
+
708
+ await wrapper.vm.$nextTick()
709
+ expect(wrapper.find('.v-input__details').exists()).toBe(false)
710
+ expect(wrapper.find('.v-messages').exists()).toBe(false)
711
+ })
712
+ })
345
713
  })
@@ -145,26 +145,40 @@ export const ariaManager = {
145
145
  popupRendered,
146
146
  },
147
147
  )
148
- const labelToApply = inputLabel || inputEl.getAttribute('aria-label') || inputEl.getAttribute('placeholder') || ''
149
- if (labelToApply) {
150
- inputEl.setAttribute('aria-label', labelToApply)
148
+ const labelledById = inputEl.getAttribute('aria-labelledby')
149
+ const labelElement = labelledById ? document.getElementById(labelledById) : null
150
+ const labelElementHasText = Boolean(labelElement?.textContent?.trim())
151
+ if (labelElementHasText) {
152
+ // aria-labelledby references a visible label — aria-label is redundant and causes validator errors
153
+ inputEl.removeAttribute('aria-label')
154
+ }
155
+ else {
156
+ // No visible label element (e.g. chips mode with label="") — use aria-label as fallback
157
+ const labelToApply = inputLabel || inputEl.getAttribute('aria-label') || inputEl.getAttribute('placeholder') || ''
158
+ if (labelToApply) {
159
+ inputEl.setAttribute('aria-label', labelToApply)
160
+ }
151
161
  }
152
162
  inputEl.setAttribute('aria-haspopup', 'listbox')
153
- if (!popupRendered) {
163
+ if (!isOpen.value) {
154
164
  inputEl.removeAttribute('aria-controls')
155
- if (isOpen.value) {
156
- nextTick(() => {
157
- const popupNowRendered = Boolean(document.getElementById(menuId))
158
- if (popupNowRendered) {
159
- inputEl.setAttribute('aria-controls', menuId)
160
- }
161
- })
162
- }
165
+ }
166
+ else if (!popupRendered) {
167
+ inputEl.removeAttribute('aria-controls')
168
+ nextTick(() => {
169
+ const popupNowRendered = Boolean(document.getElementById(menuId))
170
+ if (isOpen.value && popupNowRendered) {
171
+ inputEl.setAttribute('aria-controls', menuId)
172
+ }
173
+ else {
174
+ inputEl.removeAttribute('aria-controls')
175
+ }
176
+ })
163
177
  }
164
178
  ariaManager.updateValidationAttributes(inputEl, false, false)
165
179
  nextTick(() => {
166
180
  const popupStillThere = Boolean(document.getElementById(menuId))
167
- if (popupStillThere) {
181
+ if (isOpen.value && popupStillThere) {
168
182
  inputEl.setAttribute('aria-controls', menuId)
169
183
  }
170
184
  else {
@@ -19,15 +19,9 @@ export function useSelectionLogic(
19
19
  emit: EmitFunction,
20
20
  ) {
21
21
  const resetValue = () => {
22
- if (props.multiple) {
23
- selected.value = []
24
- emit('update:modelValue', [])
25
- }
26
- else {
27
- selected.value = null
28
- search.value = ''
29
- emit('update:modelValue', null)
30
- }
22
+ selected.value = null
23
+ search.value = ''
24
+ emit('update:modelValue', null)
31
25
  }
32
26
 
33
27
  const updateMultipleSelection = (valueKeyValue: string | number, valueToStore: ItemType | string | number) => {
@@ -44,7 +38,12 @@ export function useSelectionLogic(
44
38
  arr.push(valueToStore)
45
39
  }
46
40
  selected.value = arr as SelectArray
47
- emit('update:modelValue', arr as SelectArray)
41
+ if (arr.length === 0) {
42
+ emit('update:modelValue', null)
43
+ }
44
+ else {
45
+ emit('update:modelValue', arr as SelectArray)
46
+ }
48
47
  }
49
48
 
50
49
  const updateSingleSelection = (valueToStore: SelectValue, item: ItemType) => {
@@ -508,12 +508,12 @@ const options = [
508
508
  { text: 'Option 3', value: '3' },
509
509
  ]
510
510
 
511
- const validateForm = () => {
511
+ const validateForm = async (): Promise<void> => {
512
512
  // Réinitialiser
513
513
  formSubmitted.value = false
514
514
 
515
515
  // Valider le champ avec la méthode validateOnSubmit
516
- const isValid = selectField.value.validateOnSubmit()
516
+ const isValid = await selectField.value.validateOnSubmit()
517
517
 
518
518
  if (!isValid) {
519
519
  return
@@ -551,7 +551,7 @@ const validateForm = () => {
551
551
  const errorMessages = ref([])
552
552
  const formSubmitted = ref(false)
553
553
 
554
- const validateForm = () => {
554
+ const validateForm = async (): Promise<void> => {
555
555
  // Réinitialiser
556
556
  formSubmitted.value = false
557
557
 
@@ -562,7 +562,7 @@ const validateForm = () => {
562
562
  }
563
563
 
564
564
  // Valider le champ avec la méthode validateOnSubmit
565
- const isValid = selectField.value.validateOnSubmit()
565
+ const isValid = await selectField.value.validateOnSubmit()
566
566
 
567
567
  if (!isValid) {
568
568
  return
@@ -50,7 +50,6 @@
50
50
 
51
51
  // Initialisation du composable de validation
52
52
  const validation = useValidation({
53
- customRules: props.customRules,
54
53
  fieldIdentifier: props.label,
55
54
  disableErrorHandling: props.disableErrorHandling,
56
55
  })
@@ -90,11 +89,11 @@
90
89
  const inputId = ref(`sy-input-select-${Math.random().toString(36).substring(7)}`)
91
90
 
92
91
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
93
- const selectItem = (item: any) => {
92
+ const selectItem = async (item: any) => {
94
93
  selectedItem.value = item
95
94
  emit('update:modelValue', item)
96
95
  isOpen.value = false
97
- validateField(item)
96
+ await validateField(item)
98
97
  emit('update:errorMessages', localErrorMessages.value)
99
98
  }
100
99
 
@@ -182,7 +181,7 @@
182
181
  : [],
183
182
  )
184
183
 
185
- const validateField = (value: unknown) => {
184
+ const validateField = async (value: unknown) => {
186
185
  if (props.readonly) {
187
186
  validation.clearValidation()
188
187
  localErrorMessages.value = []
@@ -195,7 +194,7 @@
195
194
  return true
196
195
  }
197
196
 
198
- const result = validation.validateField(
197
+ const result = await validation.validateField(
199
198
  value,
200
199
  [...defaultRules.value, ...(props.customRules || [])],
201
200
  )
@@ -204,14 +203,14 @@
204
203
  return !result.hasError
205
204
  }
206
205
 
207
- const validateOnSubmit = () => {
208
- const isValid = validateField(selectedItem.value)
206
+ const validateOnSubmit = async () => {
207
+ const isValid = await validateField(selectedItem.value)
209
208
  hasError.value = !isValid
210
209
  return isValid
211
210
  }
212
211
 
213
- const checkForErrors = () => {
214
- return validateField(selectedItem.value)
212
+ const checkForErrors = async () => {
213
+ return await validateField(selectedItem.value)
215
214
  }
216
215
 
217
216
  defineExpose({
@@ -96,7 +96,7 @@ describe('SyInputSelect', () => {
96
96
  })
97
97
  })
98
98
 
99
- describe('Validation', () => {
99
+ describe('Validation', async () => {
100
100
  it('validateField valide correctement un champ requis avec une valeur', async () => {
101
101
  const wrapper = mount(SyInputSelect, {
102
102
  props: {
@@ -105,7 +105,7 @@ describe('SyInputSelect', () => {
105
105
  },
106
106
  })
107
107
 
108
- const result = wrapper.vm.validateField({ text: 'Option 1', value: '1' })
108
+ const result = await wrapper.vm.validateField({ text: 'Option 1', value: '1' })
109
109
  expect(result).toBe(true)
110
110
  expect(wrapper.find('.v-messages__message').exists()).toBe(false)
111
111
  })
@@ -119,7 +119,7 @@ describe('SyInputSelect', () => {
119
119
  },
120
120
  })
121
121
 
122
- const result = wrapper.vm.validateField(null)
122
+ const result = await wrapper.vm.validateField(null)
123
123
  expect(result).toBe(false)
124
124
 
125
125
  await wrapper.setProps({ errorMessages: ['Test Label est requis'] })
@@ -134,15 +134,15 @@ describe('SyInputSelect', () => {
134
134
  props: { required: true },
135
135
  })
136
136
 
137
- const result = wrapper.vm.validateOnSubmit()
137
+ const result = await wrapper.vm.validateOnSubmit()
138
138
  expect(result).toBe(false)
139
139
 
140
140
  await wrapper.setProps({ modelValue: { text: 'Option 1', value: '1' } })
141
- const resultWithValue = wrapper.vm.validateOnSubmit()
141
+ const resultWithValue = await wrapper.vm.validateOnSubmit()
142
142
  expect(resultWithValue).toBe(true)
143
143
  })
144
144
 
145
- it('vérifie que checkForErrors retourne le résultat de la validation', () => {
145
+ it('vérifie que checkForErrors retourne le résultat de la validation', async () => {
146
146
  const wrapper1 = mount(SyInputSelect, {
147
147
  props: {
148
148
  required: true,
@@ -150,7 +150,7 @@ describe('SyInputSelect', () => {
150
150
  },
151
151
  })
152
152
 
153
- const result1 = wrapper1.vm.checkForErrors()
153
+ const result1 = await wrapper1.vm.checkForErrors()
154
154
  expect(result1).toBe(false)
155
155
 
156
156
  const wrapper2 = mount(SyInputSelect, {
@@ -160,13 +160,13 @@ describe('SyInputSelect', () => {
160
160
  },
161
161
  })
162
162
 
163
- const result2 = wrapper2.vm.checkForErrors()
163
+ const result2 = await wrapper2.vm.checkForErrors()
164
164
  expect(result2).toBe(true)
165
165
  })
166
166
  })
167
167
 
168
168
  describe('Mode readonly', () => {
169
- it('désactive la validation en mode readonly', () => {
169
+ it('désactive la validation en mode readonly', async () => {
170
170
  const wrapper = mount(SyInputSelect, {
171
171
  props: {
172
172
  readonly: true,
@@ -174,7 +174,7 @@ describe('SyInputSelect', () => {
174
174
  },
175
175
  })
176
176
 
177
- const result = wrapper.vm.validateField(null)
177
+ const result = await wrapper.vm.validateField(null)
178
178
  expect(result).toBe(true)
179
179
  expect(wrapper.find('.v-messages__message').exists()).toBe(false)
180
180
  })