@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,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, onMounted, ref, watch, type PropType } from 'vue'
2
+ import { computed, nextTick, onMounted, ref, watch, type PropType } from 'vue'
3
3
  import { VMenu, VList, VListItem, VListItemTitle, VChip } from 'vuetify/components'
4
4
  import { mdiChevronDown, mdiCloseCircle } from '@mdi/js'
5
5
  import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue'
@@ -12,6 +12,7 @@
12
12
  import { useItemUtils } from './utils/useItemUtils'
13
13
  import { useSelectionLogic } from './utils/useSelectionLogic'
14
14
  import { useSyAutocompleteKeyboard } from './utils/useKeyboardHandler'
15
+ import { locales } from './locales'
15
16
 
16
17
  const props = defineProps({
17
18
  bgColor: {
@@ -74,6 +75,10 @@
74
75
  type: Boolean,
75
76
  default: false,
76
77
  },
78
+ hideDetails: {
79
+ type: Boolean,
80
+ default: false,
81
+ },
77
82
  hideNoData: {
78
83
  type: Boolean,
79
84
  default: false,
@@ -108,7 +113,7 @@
108
113
  },
109
114
  noDataText: {
110
115
  type: String,
111
- default: 'Aucune option',
116
+ default: locales.noData,
112
117
  },
113
118
  placeholder: {
114
119
  type: String,
@@ -138,6 +143,10 @@
138
143
  type: Array as PropType<string[] | null>,
139
144
  default: null,
140
145
  },
146
+ selectionText: {
147
+ type: Function as PropType<(selected: SelectArray) => string>,
148
+ default: undefined,
149
+ },
141
150
  textKey: {
142
151
  type: String,
143
152
  default: 'text',
@@ -152,14 +161,14 @@
152
161
  },
153
162
  })
154
163
 
155
- const emit = defineEmits(['update:modelValue'])
164
+ const emit = defineEmits(['update:modelValue', 'search'])
156
165
 
157
166
  const isOpen = ref(false)
158
167
  const search = ref('')
159
168
  const selected = ref<SelectValue | SelectArray>(props.modelValue as SelectValue | SelectArray)
160
169
  const hasInteracted = ref(false)
161
170
  const suppressNextInput = ref(false)
162
- let suppressOpenOnSearch = false
171
+ const suppressMenuOpen = ref(false)
163
172
  type SyTextFieldInstance = InstanceType<typeof SyTextField> & { $refs?: { input?: HTMLInputElement } }
164
173
  const textFieldRef = ref<SyTextFieldInstance | null>(null)
165
174
  const randomId = Math.random().toString(36).slice(2)
@@ -191,6 +200,7 @@
191
200
 
192
201
  const syncSearchFromValue = () => {
193
202
  if (props.multiple) return
203
+ suppressMenuOpen.value = true
194
204
  if (!selected.value) {
195
205
  search.value = ''
196
206
  return
@@ -202,7 +212,7 @@
202
212
  const normalizedSearch = computed(() => (search.value || '').toLowerCase())
203
213
 
204
214
  const filteredItems = computed(() => {
205
- if (!props.filter) return formattedItems.value
215
+ if (!props.filter || props.loading) return formattedItems.value
206
216
  return formattedItems.value.filter((item) => {
207
217
  const text = String(item[props.plainTextKey || props.textKey] ?? item[props.textKey] ?? '').toLowerCase()
208
218
  return text.includes(normalizedSearch.value)
@@ -215,7 +225,6 @@
215
225
 
216
226
  const selectItem = (item: ItemType | string | number | null | undefined) => {
217
227
  markInteracted()
218
- suppressOpenOnSearch = true
219
228
  updateValue(item ?? null)
220
229
  if (props.multiple) {
221
230
  suppressNextInput.value = true
@@ -225,16 +234,17 @@
225
234
  }
226
235
 
227
236
  watch(() => props.modelValue, (val) => {
228
- selected.value = val as SelectValue | SelectArray
229
- suppressOpenOnSearch = true
237
+ selected.value = props.multiple && (val === null || val === undefined)
238
+ ? []
239
+ : val as SelectValue | SelectArray
230
240
  syncSearchFromValue()
231
241
  }, { immediate: true })
232
242
 
233
243
  let debounceHandle: ReturnType<typeof setTimeout> | null = null
234
244
 
235
245
  watch(search, () => {
236
- if (suppressOpenOnSearch) {
237
- suppressOpenOnSearch = false
246
+ if (suppressMenuOpen.value) {
247
+ suppressMenuOpen.value = false
238
248
  return
239
249
  }
240
250
 
@@ -261,13 +271,15 @@
261
271
  })
262
272
 
263
273
  const hasChips = computed(() => props.multiple && props.chips && Array.isArray(selected.value) && selected.value.length > 0)
274
+ const hasSelectionTextDisplay = computed(() => !!props.selectionText && Array.isArray(selected.value) && (selected.value as SelectArray).length > 0)
275
+ const hasMultipleSelections = computed(() => props.multiple && !props.chips && !props.selectionText && Array.isArray(selected.value) && (selected.value as SelectArray).length > 0)
276
+ const hasInlineSelections = computed(() => hasChips.value || hasMultipleSelections.value)
264
277
 
265
278
  const displayValue = computed(() => {
266
279
  if (props.multiple && !props.chips) {
267
- const selectedItems = Array.isArray(selected.value) ? selected.value : []
268
- const selectedTexts: string[] = selectedItems.map(item => getChipLabel(item as ItemType | string | number))
269
- const prefix = selectedTexts.length > 0 ? selectedTexts.join(', ') + ', ' : ''
270
- return prefix + search.value
280
+ if (props.selectionText || hasMultipleSelections.value) {
281
+ return search.value
282
+ }
271
283
  }
272
284
  return search.value
273
285
  })
@@ -328,20 +340,50 @@
328
340
  return (textFieldRef.value?.$el as HTMLElement | undefined)?.querySelector('.v-field') ?? undefined
329
341
  })
330
342
 
343
+ const shouldDisableErrorHandling = computed(() => props.disableErrorHandling)
344
+
331
345
  const externalErrors = computed(() => props.errorMessages || [])
332
- const displayErrors = computed(() => externalErrors.value.length > 0 ? externalErrors.value : (hasInteracted.value ? errorHandling.errors.value : []))
333
- const displayWarnings = computed(() => hasInteracted.value ? errorHandling.warnings.value : [])
334
- const displaySuccesses = computed(() => hasInteracted.value ? errorHandling.successes.value : [])
335
- const displayHasError = computed(() => externalErrors.value.length > 0 || (hasInteracted.value && errorHandling.hasError.value))
336
- const displayHasWarning = computed(() => hasInteracted.value && errorHandling.hasWarning.value)
337
- const displayHasSuccess = computed(() => hasInteracted.value && errorHandling.hasSuccess.value)
346
+ const displayErrors = computed(() => {
347
+ if (shouldDisableErrorHandling.value) return []
348
+ return externalErrors.value.length > 0
349
+ ? externalErrors.value
350
+ : (hasInteracted.value ? errorHandling.errors.value : [])
351
+ })
352
+ const displayWarnings = computed(() => {
353
+ if (shouldDisableErrorHandling.value) return []
354
+ return hasInteracted.value ? errorHandling.warnings.value : []
355
+ })
356
+ const displaySuccesses = computed(() => {
357
+ if (shouldDisableErrorHandling.value) return []
358
+ return hasInteracted.value ? errorHandling.successes.value : []
359
+ })
360
+ const displayHasError = computed(() => {
361
+ if (shouldDisableErrorHandling.value) return false
362
+ return externalErrors.value.length > 0 || (hasInteracted.value && errorHandling.hasError.value)
363
+ })
364
+ const displayHasWarning = computed(() => {
365
+ if (shouldDisableErrorHandling.value) return false
366
+ return hasInteracted.value && errorHandling.hasWarning.value
367
+ })
368
+ const displayHasSuccess = computed(() => {
369
+ if (shouldDisableErrorHandling.value) return false
370
+ return hasInteracted.value && errorHandling.hasSuccess.value
371
+ })
338
372
 
339
373
  const validateOnSubmit = () => {
340
374
  markInteracted()
341
375
  return errorHandling.validateOnSubmit()
342
376
  }
343
377
 
344
- const checkErrorOnBlur = () => {
378
+ const checkErrorOnBlur = (event?: FocusEvent) => {
379
+ const relatedTarget = event?.relatedTarget as HTMLElement | null | undefined
380
+ if (relatedTarget?.closest('.sy-autocomplete__chip') || relatedTarget?.closest('.sy-autocomplete__clear-button')) {
381
+ isOpen.value = true
382
+ nextTick(() => {
383
+ focusInput(textFieldRef)
384
+ })
385
+ return
386
+ }
345
387
  markInteracted()
346
388
  return errorHandling.checkErrorOnBlur()
347
389
  }
@@ -363,36 +405,17 @@
363
405
  const inputValue = getInputValue(value)
364
406
  if (inputValue === null) return
365
407
 
366
- if (props.multiple && !props.chips) {
367
- const selectedItems = Array.isArray(selected.value) ? selected.value : []
368
- const labels = selectedItems.map(item =>
369
- getChipLabel(item as ItemType | string | number),
370
- )
371
-
372
- const parts = inputValue.split(',').map(p => p.trim())
373
- let matched = 0
374
- for (let i = 0; i < Math.min(parts.length, labels.length); i++) {
375
- if (parts[i] === labels[i]) {
376
- matched++
377
- }
378
- else {
379
- break
380
- }
381
- }
408
+ // Ignore outside emissions (e.g. SyTextField.checkErrorOnBlur re-emitting
409
+ // the current value after a programmatic update): no actual user input occurred.
410
+ if (inputValue === search.value) return
382
411
 
383
- if (matched < selectedItems.length) {
384
- const kept = selectedItems.slice(0, matched)
385
- selected.value = kept
386
- emit('update:modelValue', kept)
387
- }
412
+ search.value = inputValue
388
413
 
389
- const remainingParts = parts.slice(matched).filter(p => p !== '')
390
- search.value = remainingParts.join(', ')
391
- }
392
- else {
393
- search.value = inputValue
414
+ if (!inputValue && !props.multiple && selected.value != null) {
415
+ updateValue(null)
394
416
  }
395
417
 
418
+ emit('search', inputValue)
396
419
  openAndFocus()
397
420
  }
398
421
 
@@ -405,6 +428,7 @@
405
428
  const getOptionId = (index: number) => `${optionIdPrefixed.value}-${index}`
406
429
 
407
430
  const resultsLiveText = computed(() => {
431
+ if (!hasInteracted.value) return
408
432
  if (props.loading) return 'Chargement des résultats'
409
433
  const count = filteredItems.value.length
410
434
  if (!props.filter) return ''
@@ -424,7 +448,6 @@
424
448
 
425
449
  watch(isOpen, (open) => {
426
450
  if (!open && props.multiple) {
427
- suppressOpenOnSearch = true
428
451
  search.value = ''
429
452
  }
430
453
  })
@@ -440,7 +463,10 @@
440
463
  </script>
441
464
 
442
465
  <template>
443
- <div class="sy-autocomplete">
466
+ <div
467
+ class="sy-autocomplete"
468
+ :class="{ 'sy-autocomplete--has-selection-text': hasSelectionTextDisplay }"
469
+ >
444
470
  <VMenu
445
471
  v-model="isOpen"
446
472
  transition="slide-y-transition"
@@ -459,12 +485,13 @@
459
485
  ref="textFieldRef"
460
486
  :model-value="displayValue"
461
487
  :label="hasChips ? '' : label"
462
- :placeholder="hasChips ? '' : placeholder"
488
+ :placeholder="hasInlineSelections || hasSelectionTextDisplay ? '' : placeholder"
489
+ :is-active="hasInlineSelections || hasSelectionTextDisplay"
463
490
  :readonly="readonly"
464
491
  :bg-color="bgColor"
465
492
  :density="density"
466
493
  :autocomplete="'off'"
467
- :class="{ 'sy-autocomplete--clearable': clearable }"
494
+ :class="{ 'sy-autocomplete--clearable': clearable, 'sy-autocomplete__field--has-chips': hasInlineSelections }"
468
495
  :error-messages="displayErrors"
469
496
  :warning-messages="displayWarnings"
470
497
  :success-messages="displaySuccesses"
@@ -473,7 +500,10 @@
473
500
  :has-success="displayHasSuccess"
474
501
  :required="required"
475
502
  :display-asterisk="required && displayAsterisk"
476
- :aria-label="hasChips ? label : undefined"
503
+ :disable-error-handling="disableErrorHandling"
504
+ :loading="loading"
505
+ :are-details-hidden="hideDetails"
506
+ :aria-label="hasInlineSelections ? label : undefined"
477
507
  @click="openAndFocus"
478
508
  @update:model-value="handleInput"
479
509
  @blur="checkErrorOnBlur"
@@ -481,10 +511,10 @@
481
511
  >
482
512
  <template #append-inner>
483
513
  <button
484
- v-if="clearable && hasSelectionToClear && !hasChips"
514
+ v-if="clearable && hasSelectionToClear"
485
515
  type="button"
486
516
  class="sy-autocomplete__clear-button"
487
- :aria-label="'Réinitialiser la sélection'"
517
+ :aria-label="locales.clearSelection"
488
518
  @click.stop.prevent="selectItem(null)"
489
519
  >
490
520
  <SyIcon
@@ -499,23 +529,37 @@
499
529
  decorative
500
530
  />
501
531
  </template>
532
+ <template v-if="hasChips">
533
+ <VChip
534
+ v-for="(item, index) in selected as SelectArray"
535
+ :key="getChipKey(item, index)"
536
+ size="small"
537
+ class="sy-autocomplete__chip"
538
+ closable
539
+ :close-label="locales.removeChip(getChipLabel(item as ItemType))"
540
+ @click:close.stop.prevent="() => selectItem(item as ItemType)"
541
+ @keydown.enter.capture.stop.prevent="(event) => (event.target as HTMLElement | null)?.closest('.v-chip__close') && selectItem(item as ItemType)"
542
+ @keydown.space.capture.stop.prevent="(event) => (event.target as HTMLElement | null)?.closest('.v-chip__close') && selectItem(item as ItemType)"
543
+ >
544
+ {{ getChipLabel(item as ItemType) }}
545
+ </VChip>
546
+ </template>
547
+ <template v-else-if="hasMultipleSelections">
548
+ <span
549
+ v-for="(item, index) in selected as SelectArray"
550
+ :key="getChipKey(item, index)"
551
+ class="sy-autocomplete__label"
552
+ >
553
+ {{ getChipLabel(item as ItemType) }}
554
+ </span>
555
+ </template>
502
556
  <template
503
- v-if="hasChips"
557
+ v-if="hasSelectionTextDisplay"
504
558
  #prepend-inner
505
559
  >
506
- <div class="sy-autocomplete__chips">
507
- <VChip
508
- v-for="(item, index) in selected as SelectArray"
509
- :key="getChipKey(item, index)"
510
- size="small"
511
- class="ma-1"
512
- closable
513
- :close-label="`Supprimer ${getChipLabel(item as ItemType)}`"
514
- @click:close="() => selectItem(item as ItemType)"
515
- >
516
- {{ getChipLabel(item as ItemType) }}
517
- </VChip>
518
- </div>
560
+ <span class="sy-autocomplete__selection-text">
561
+ {{ selectionText!(selected as SelectArray) }}
562
+ </span>
519
563
  </template>
520
564
  </SyTextField>
521
565
  </template>
@@ -524,21 +568,14 @@
524
568
  :id="uniqueMenuId"
525
569
  ref="listRef"
526
570
  role="listbox"
527
- :aria-label="label"
528
- :aria-labelledby="`${uniqueMenuId}-input`"
571
+ :aria-labelledby="`${uniqueMenuId}-input-label`"
529
572
  :aria-multiselectable="multiple ? 'true' : undefined"
530
573
  :style="{ minWidth: `${textFieldRef?.$el?.offsetWidth || 0}px` }"
531
574
  tag="ul"
532
575
  tabindex="-1"
533
576
  @click.stop
534
577
  >
535
- <template v-if="loading">
536
- <VListItem
537
- title="Chargement..."
538
- tag="li"
539
- />
540
- </template>
541
- <template v-else-if="filteredItems.length === 0 && !hideNoData">
578
+ <template v-if="filteredItems.length === 0 && !hideNoData && !loading">
542
579
  <VListItem
543
580
  :title="noDataText"
544
581
  disabled
@@ -619,14 +656,55 @@
619
656
  }
620
657
 
621
658
  .sy-autocomplete__clear-icon {
622
- color: rgb(0 0 0 / 54%);
659
+ color: rgb(var(--v-theme-iconBase));
623
660
  }
624
661
 
625
- .sy-autocomplete__chips {
626
- display: flex;
627
- flex-direction: row !important;
628
- gap: 4px;
629
- align-items: center;
662
+ .sy-autocomplete__chip {
663
+ margin: 2px;
664
+ align-self: center;
665
+ flex-shrink: 0;
666
+ }
667
+
668
+ /* Style spécifique pour les chips */
669
+ :deep(.sy-autocomplete__chip .v-chip__close .v-icon__svg) {
670
+ fill: inherit !important;
671
+ }
672
+
673
+ .sy-autocomplete__label {
674
+ align-self: center;
675
+ white-space: nowrap;
676
+ flex-shrink: 0;
677
+ font-size: inherit;
678
+
679
+ &:not(:last-of-type)::after {
680
+ content: ',';
681
+ margin-right: 4px;
682
+ }
683
+ }
684
+
685
+ :deep(.sy-autocomplete__field--has-chips .v-field) {
686
+ height: auto;
687
+ min-height: var(--v-input-control-height, 56px);
688
+ }
689
+
690
+ :deep(.sy-autocomplete__field--has-chips .v-field__input) {
691
+ flex-wrap: wrap;
692
+ }
693
+
694
+ :deep(.sy-autocomplete__field--has-chips .v-field__input input) {
695
+ flex: 1 1 auto;
696
+ min-width: 64px;
697
+ align-self: center;
698
+ }
699
+
700
+ .sy-autocomplete__selection-text {
701
+ padding: 0 4px;
702
+ white-space: nowrap;
703
+ font-size: inherit;
704
+ }
705
+
706
+ .sy-autocomplete--has-selection-text :deep(input) {
707
+ caret-color: transparent !important;
630
708
  }
631
709
 
632
710
  .v-list-item.active,
@@ -646,7 +724,7 @@ li:hover {
646
724
  .v-list-item.keyboard-focused,
647
725
  li:focus-visible,
648
726
  li.keyboard-focused {
649
- outline: 2px solid tokens.$primary-base;
727
+ outline: 2px solid rgb(var(--v-theme-accentPrimary));
650
728
  outline-offset: -2px;
651
729
  background-color: rgb(0 0 0 / 8%);
652
730
  }
@@ -1,7 +1,8 @@
1
1
  import type { StoryObj } from '@storybook/vue3'
2
- import { mdiKeyboard } from '@mdi/js'
2
+ import { mdiKeyboard, mdiLoading } from '@mdi/js'
3
3
 
4
4
  const keyboardIcon = mdiKeyboard
5
+ const loadingIcon = mdiLoading
5
6
 
6
7
  export default {
7
8
  title: 'Composants/Formulaires/Selects/SyAutocomplete/Accessibility',
@@ -68,3 +69,41 @@ export const ComboboxKeyboardNavigation: StoryObj = {
68
69
  }
69
70
  },
70
71
  }
72
+
73
+ export const LoadingAccessibility: StoryObj = {
74
+ tags: ['!dev'],
75
+ render: () => {
76
+ return {
77
+ setup() {
78
+ return { loadingIcon }
79
+ },
80
+ template: `
81
+ <div>
82
+ <p>Lorsque la prop <code>loading</code> est à <code>true</code>, le composant affiche une barre de progression au bas du champ.</p>
83
+ <v-table density="compact" style="margin-top: 16px;">
84
+ <thead>
85
+ <tr>
86
+ <th>Comportement</th>
87
+ <th>Détail</th>
88
+ </tr>
89
+ </thead>
90
+ <tbody>
91
+ <tr>
92
+ <td>Barre de progression accessible</td>
93
+ <td>La barre porte un <code>aria-label</code> nommant le champ (<em>« Chargement de [label] »</em>) afin que les lecteurs d’écran annoncent son état.</td>
94
+ </tr>
95
+ <tr>
96
+ <td>Message « Aucune option » masqué</td>
97
+ <td>Le message d’absence de résultats n’est pas affiché pendant le chargement, pour éviter de signaler à tort que la liste est vide.</td>
98
+ </tr>
99
+ <tr>
100
+ <td>Critère RGAA 4.1 / WCAG 4.1.2</td>
101
+ <td>Le rôle <code>progressbar</code> et son nom accessible satisfont le critère « Nom, rôle, valeur » pour les composants d’interface.</td>
102
+ </tr>
103
+ </tbody>
104
+ </v-table>
105
+ </div>
106
+ `,
107
+ }
108
+ },
109
+ }
@@ -73,6 +73,11 @@ import '@/stories/styles/shared.css';
73
73
  <Story of={AccessStories.ComboboxKeyboardNavigation} />
74
74
  </div>
75
75
 
76
+ <div className="loading-section">
77
+ <h2>État de chargement</h2>
78
+ <Story of={AccessStories.LoadingAccessibility} />
79
+ </div>
80
+
76
81
  <div className="implementation-section">
77
82
  <h2>Spécificités d'implémentation</h2>
78
83
  <p>
@@ -172,7 +177,8 @@ import '@/stories/styles/shared.css';
172
177
  line-height: 1.5;
173
178
  }
174
179
 
175
- .keyboard-section {
180
+ .keyboard-section,
181
+ .loading-section {
176
182
  background-color: #f0f7ff;
177
183
  padding: 20px;
178
184
  border-radius: 8px;
@@ -0,0 +1,5 @@
1
+ export const locales = {
2
+ noData: 'Aucune option',
3
+ clearSelection: 'Réinitialiser la sélection',
4
+ removeChip: (label: string) => `Supprimer ${label}`,
5
+ }
@@ -69,4 +69,100 @@ describe('SyAutocomplete – accessibility (axe)', () => {
69
69
  ignoreRules: ['region'],
70
70
  })
71
71
  })
72
+
73
+ it('has no obvious axe violations for selectionText with no selection', async () => {
74
+ const wrapper = mount(SyAutocomplete, {
75
+ props: {
76
+ modelValue: [],
77
+ items,
78
+ label: 'Colonnes affichées',
79
+ textKey: 'text',
80
+ valueKey: 'value',
81
+ multiple: true,
82
+ selectionText: (selected: unknown[]) => `${selected.length} colonnes sélectionnées`,
83
+ },
84
+ })
85
+
86
+ const results = await axe(wrapper.element as HTMLElement)
87
+ assertNoA11yViolations(results, 'SyAutocomplete – selectionText empty', {
88
+ ignoreRules: ['region'],
89
+ })
90
+ })
91
+
92
+ it('has no obvious axe violations when loading is true', async () => {
93
+ const wrapper = mount(SyAutocomplete, {
94
+ props: {
95
+ modelValue: null,
96
+ items,
97
+ label: 'Choisir une option',
98
+ textKey: 'text',
99
+ valueKey: 'value',
100
+ loading: true,
101
+ },
102
+ })
103
+
104
+ const results = await axe(wrapper.element as HTMLElement)
105
+ assertNoA11yViolations(results, 'SyAutocomplete – loading state', {
106
+ ignoreRules: ['region'],
107
+ })
108
+ })
109
+
110
+ it('has no obvious axe violations when loading is true with no label (chips mode)', async () => {
111
+ const wrapper = mount(SyAutocomplete, {
112
+ props: {
113
+ modelValue: ['1'],
114
+ items,
115
+ label: 'Options',
116
+ textKey: 'text',
117
+ valueKey: 'value',
118
+ multiple: true,
119
+ chips: true,
120
+ loading: true,
121
+ },
122
+ })
123
+
124
+ const results = await axe(wrapper.element as HTMLElement)
125
+ assertNoA11yViolations(results, 'SyAutocomplete – loading + chips', {
126
+ ignoreRules: ['region'],
127
+ })
128
+ })
129
+
130
+ it('has no obvious axe violations for selectionText with selection', async () => {
131
+ const wrapper = mount(SyAutocomplete, {
132
+ props: {
133
+ modelValue: [items[0]!.value, items[1]!.value],
134
+ items,
135
+ label: 'Colonnes affichées',
136
+ textKey: 'text',
137
+ valueKey: 'value',
138
+ multiple: true,
139
+ selectionText: (selected: unknown[]) => `${selected.length} colonnes sélectionnées`,
140
+ },
141
+ })
142
+
143
+ const results = await axe(wrapper.element as HTMLElement)
144
+ assertNoA11yViolations(results, 'SyAutocomplete – selectionText with selection', {
145
+ ignoreRules: ['region'],
146
+ })
147
+ })
148
+
149
+ it('has no obvious axe violations when hideDetails is true', async () => {
150
+ const wrapper = mount(SyAutocomplete, {
151
+ props: {
152
+ modelValue: '1',
153
+ items,
154
+ label: 'Filtrer par option',
155
+ textKey: 'text',
156
+ valueKey: 'value',
157
+ hideDetails: true,
158
+ hasSuccess: true,
159
+ successMessages: ['Sélection valide'],
160
+ },
161
+ })
162
+
163
+ const results = await axe(wrapper.element as HTMLElement)
164
+ assertNoA11yViolations(results, 'SyAutocomplete – hideDetails', {
165
+ ignoreRules: ['region'],
166
+ })
167
+ })
72
168
  })