@cnamts/synapse 1.0.24 → 1.0.26

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 (493) hide show
  1. package/README.md +27 -5
  2. package/dist/{AutocompleteFilter-BWLR3U7W.js → AutocompleteFilter-BPR-a55G.js} +1 -1
  3. package/dist/{DateFilter-BpwFexzi.js → DateFilter-CknrJWs2.js} +2 -2
  4. package/dist/{NumberFilter-Bz_NTdX9.js → NumberFilter-DJ-yNlzv.js} +1 -1
  5. package/dist/{PeriodFilter-DX_wy9g-.js → PeriodFilter-CiB5Oa9Z.js} +1 -1
  6. package/dist/{SelectFilter-xqiPtPgX.js → SelectFilter-EiafX97M.js} +2 -2
  7. package/dist/{TextFilter-BBl3JFqK.js → TextFilter-BzOmpdxj.js} +1 -1
  8. package/dist/{apLightTheme-D1P4jcD0.js → apLightTheme-DS0Uy44H.js} +446 -723
  9. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +14 -8
  10. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +60 -289
  11. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +1 -0
  12. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +4 -0
  13. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1 -0
  14. package/dist/components/Customs/SyTabs/SyTabs.d.ts +13 -11
  15. package/dist/components/Customs/SyTextField/SyTextField.d.ts +0 -2
  16. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +54 -73
  17. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +31 -40
  18. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +9 -14
  19. package/dist/components/DatePicker/composables/useDatePickerState.d.ts +4 -3
  20. package/dist/components/DatePicker/composables/useDateTextField.d.ts +2 -2
  21. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
  22. package/dist/components/DatePicker/types.d.ts +1 -2
  23. package/dist/components/FileList/FileList.d.ts +6 -0
  24. package/dist/components/FilterSideBar/FilterSideBar.d.ts +2 -0
  25. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +13 -13
  26. package/dist/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.d.ts +3 -3
  27. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +1 -0
  28. package/dist/components/MonthPicker/MonthPicker.d.ts +2 -7
  29. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +2 -7
  30. package/dist/components/NirField/NirField.d.ts +12 -20
  31. package/dist/components/NirField/useNirValidation.d.ts +6 -2
  32. package/dist/components/PeriodField/PeriodField.d.ts +110 -150
  33. package/dist/components/PhoneField/PhoneField.d.ts +12 -7
  34. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +0 -3
  35. package/dist/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +3 -1
  36. package/dist/components/RatingPicker/NumberPicker/NumberPicker.d.ts +4 -3
  37. package/dist/components/RatingPicker/RatingPicker.d.ts +18 -5
  38. package/dist/components/RatingPicker/StarsPicker/StarsPicker.d.ts +3 -1
  39. package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +1 -0
  40. package/dist/components/RatingPicker/useRatingFocus.d.ts +18 -0
  41. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -4
  42. package/dist/components/Tables/SyTable/SyTable.d.ts +5 -4
  43. package/dist/components/Tables/common/SyTablePagination.d.ts +154 -364
  44. package/dist/components/Tables/common/TableHeader.d.ts +6 -1
  45. package/dist/components/Tables/common/filters/DateFilter.d.ts +4 -4
  46. package/dist/components/Tables/common/locales.d.ts +3 -0
  47. package/dist/components/Tables/common/types.d.ts +2 -0
  48. package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +1 -0
  49. package/dist/composables/date/useDateInitializationDayjs.d.ts +3 -1
  50. package/dist/composables/unifyValidation/documentationValidationProps.d.ts +230 -0
  51. package/dist/composables/unifyValidation/useCustomValidation.d.ts +3 -1
  52. package/dist/composables/unifyValidation/useValidation.d.ts +12 -6
  53. package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +1 -1
  54. package/dist/composables/validation/useValidation.d.ts +6 -1
  55. package/dist/design-system-v3.js +2 -2
  56. package/dist/designTokens/tokens/amelipro/apColors.d.ts +10 -10
  57. package/dist/designTokens/tokens/amelipro/apColors2026.d.ts +1 -2
  58. package/dist/designTokens/tokens/amelipro/apContextual.d.ts +44 -0
  59. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +2 -0
  60. package/dist/designTokens/tokens/amelipro/apSemantic.d.ts +1 -1
  61. package/dist/designTokens/tokens/baseColors.d.ts +127 -0
  62. package/dist/designTokens/tokens/baseContextualTokens.d.ts +50 -0
  63. package/dist/designTokens/tokens/cnam/cnamColors.d.ts +10 -10
  64. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +2 -0
  65. package/dist/designTokens/tokens/cnam/cnamSemantic.d.ts +1 -1
  66. package/dist/designTokens/tokens/pa/paColors.d.ts +1 -166
  67. package/dist/designTokens/tokens/pa/paSemantic.d.ts +1 -1
  68. package/dist/designTokens/utils/buildColorClassMap.d.ts +12 -0
  69. package/dist/designTokens/utils/createFlattenTheme.d.ts +1 -3
  70. package/dist/designTokens/utils/index.d.ts +2 -2
  71. package/dist/{main-BtTqyn4z.js → main-BsJ9ec3i.js} +16021 -15715
  72. package/dist/synapse.css +1 -1
  73. package/dist/utils/functions/classToHex.d.ts +1 -1
  74. package/dist/utils/functions/createHexResolver.d.ts +16 -0
  75. package/dist/vuetifyConfig.js +113 -152
  76. package/package.json +35 -23
  77. package/src/assets/amelipro/apTokens2026.scss +5 -5
  78. package/src/assets/overrides/_breakpoints.scss +25 -0
  79. package/src/assets/overrides/_btns.scss +0 -2
  80. package/src/assets/overrides/_forms.scss +1 -3
  81. package/src/assets/overrides/_icons.scss +5 -22
  82. package/src/assets/overrides/_otp.scss +40 -0
  83. package/src/assets/overrides/_tables.scss +11 -20
  84. package/src/assets/overrides/_tooltips.scss +17 -7
  85. package/src/assets/overrides/_typography.scss +35 -37
  86. package/src/assets/overrides/_utilities.scss +43 -47
  87. package/src/assets/themes.scss +1 -0
  88. package/src/components/Accordion/Accordion.vue +2 -0
  89. package/src/components/Amelipro/AmeliproAccordion/AmeliproAccordionTemplate/AmeliproAccordionTemplate.vue +20 -20
  90. package/src/components/Amelipro/AmeliproAccordionFrieze/AmeliproAccordionFrieze.vue +12 -14
  91. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +4 -6
  92. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.vue +5 -5
  93. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +4 -6
  94. package/src/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.vue +4 -6
  95. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.vue +4 -6
  96. package/src/components/Amelipro/AmeliproBreadcrumb/AmeliproBreadcrumb.vue +1 -3
  97. package/src/components/Amelipro/AmeliproBtn/AmeliproBtn.vue +4 -6
  98. package/src/components/Amelipro/AmeliproCallback/AmeliproCallback.vue +2 -2
  99. package/src/components/Amelipro/AmeliproCard/AmeliproCard.vue +31 -31
  100. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.vue +5 -7
  101. package/src/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.vue +13 -15
  102. package/src/components/Amelipro/AmeliproCheckboxGroup/AmeliproCheckboxGroup.vue +23 -23
  103. package/src/components/Amelipro/AmeliproChips/AmeliproChips.vue +1 -3
  104. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +17 -12
  105. package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +2 -2
  106. package/src/components/Amelipro/AmeliproCopyBtn/AmeliproCopyBtn.vue +4 -6
  107. package/src/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.vue +13 -13
  108. package/src/components/Amelipro/AmeliproDentalChart/AmeliproDentalChart.vue +4 -2
  109. package/src/components/Amelipro/AmeliproDentalChart/AmeliproTooth/AmeliproTooth.vue +4 -4
  110. package/src/components/Amelipro/AmeliproDialog/AmeliproDialog.vue +5 -7
  111. package/src/components/Amelipro/AmeliproDisclosure/AmeliproDisclosure.vue +1 -3
  112. package/src/components/Amelipro/AmeliproErrorTemplate/AmeliproErrorTemplate.vue +2 -4
  113. package/src/components/Amelipro/AmeliproFilePreview/AmeliproFilePreview.vue +4 -6
  114. package/src/components/Amelipro/AmeliproFilters/AmeliproFilters.vue +13 -13
  115. package/src/components/Amelipro/AmeliproFirstLogin/AmeliproFirstLogin.vue +3 -5
  116. package/src/components/Amelipro/AmeliproFooter/AmeliproFooter.vue +1 -3
  117. package/src/components/Amelipro/AmeliproHeader/AmeliproHeader.vue +2 -4
  118. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBar.vue +1 -3
  119. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/AmeliproHeaderBrandSection.vue +20 -16
  120. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
  121. package/src/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.vue +2 -4
  122. package/src/components/Amelipro/AmeliproIllustratedDataTile/AmeliproIllustratedDataTile.vue +5 -7
  123. package/src/components/Amelipro/AmeliproIllustratedRadioGroup/AmeliproIllustratedRadioGroup.vue +6 -8
  124. package/src/components/Amelipro/AmeliproMailTile/AmeliproMailTile.vue +14 -14
  125. package/src/components/Amelipro/AmeliproMenu/AmeliproMenu.vue +11 -13
  126. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenu.vue +2 -4
  127. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingLayout.vue +8 -8
  128. package/src/components/Amelipro/AmeliproMultipleFoldingCard/AmeliproMultipleFoldingCard.vue +40 -40
  129. package/src/components/Amelipro/AmeliproNumberedCard/AmeliproNumberedCard.vue +27 -27
  130. package/src/components/Amelipro/AmeliproOnboarding/AmeliproOnboarding.vue +3 -5
  131. package/src/components/Amelipro/AmeliproPageLayout/AmeliproPageLayout.vue +2 -4
  132. package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.vue +2 -4
  133. package/src/components/Amelipro/AmeliproPagination/AmeliproPaginationBtn/AmeliproPaginationBtn.vue +3 -5
  134. package/src/components/Amelipro/AmeliproPatientBanner/AmeliproPatientBanner.vue +1 -3
  135. package/src/components/Amelipro/AmeliproPatientLogged/AmeliproPatientLogged.vue +2 -4
  136. package/src/components/Amelipro/AmeliproPatientLogin/AmeliproPatientLogin.vue +4 -4
  137. package/src/components/Amelipro/AmeliproPatientLogin/AmeliproPatientLoginForm/AmeliproPatientLoginForm.vue +1 -3
  138. package/src/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.vue +3 -5
  139. package/src/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.vue +3 -5
  140. package/src/components/Amelipro/AmeliproRadioGroup/AmeliproRadioGroup.vue +23 -23
  141. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.vue +4 -6
  142. package/src/components/Amelipro/AmeliproSelect/AmeliproSelect.vue +12 -22
  143. package/src/components/Amelipro/AmeliproStateTile/AmeliproStateTile.vue +10 -12
  144. package/src/components/Amelipro/AmeliproStepper/AmeliproStepper.vue +17 -17
  145. package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +8 -10
  146. package/src/components/Amelipro/AmeliproTabs/AmeliproTabBtn/AmeliproTabBtn.vue +6 -8
  147. package/src/components/Amelipro/AmeliproTabs/AmeliproTabs.vue +4 -4
  148. package/src/components/Amelipro/AmeliproTextArea/AmeliproTextArea.vue +4 -6
  149. package/src/components/Amelipro/AmeliproTextField/AmeliproTextField.vue +7 -9
  150. package/src/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.vue +3 -5
  151. package/src/components/Amelipro/AmeliproTooltips/AmeliproTooltips.vue +0 -2
  152. package/src/components/Amelipro/AmeliproUpload/AmeliproUpload.vue +6 -6
  153. package/src/components/Amelipro/ServiceMenu/ServiceMenu.vue +2 -2
  154. package/src/components/Amelipro/StructureMenu/StructureBtn/StructureBtn.vue +4 -4
  155. package/src/components/Amelipro/StructureMenu/StructureItem/StructureItem.vue +4 -6
  156. package/src/components/Amelipro/StructureMenu/StructureMenu.vue +2 -2
  157. package/src/components/Amelipro/StructureMenu/StructureTabs/StructureTabs.vue +2 -2
  158. package/src/components/Amelipro/UserMenu/UserMenu.vue +1 -3
  159. package/src/components/BackBtn/tests/BackBtn.visual.cy.ts +43 -0
  160. package/src/components/BackBtn/tests/__snapshots__/back-btn-custom-bg.snap.png +0 -0
  161. package/src/components/BackBtn/tests/__snapshots__/back-btn-dark-mode.snap.png +0 -0
  162. package/src/components/BackBtn/tests/__snapshots__/back-btn-default.snap.png +0 -0
  163. package/src/components/BackBtn/tests/__snapshots__/back-btn-no-icon.snap.png +0 -0
  164. package/src/components/Captcha/Captcha.vue +1 -3
  165. package/src/components/ChipList/ChipList.vue +14 -16
  166. package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +2 -3
  167. package/src/components/CookiesSelection/CookiesSelection.vue +2 -1
  168. package/src/components/CopyBtn/CopyBtn.vue +10 -3
  169. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +17 -17
  170. package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +31 -0
  171. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +66 -0
  172. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +8 -4
  173. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +18 -0
  174. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +66 -0
  175. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +4 -6
  176. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +414 -135
  177. package/src/components/Customs/Selects/SySelect/SySelect.vue +502 -257
  178. package/src/components/Customs/Selects/SySelect/accessibilite/Accessibility.mdx +199 -269
  179. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +278 -4
  180. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +3 -3
  181. package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +5 -0
  182. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +52 -2
  183. package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +18 -3
  184. package/src/components/Customs/SyPagination/SyPagination.vue +0 -2
  185. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +23 -5
  186. package/src/components/Customs/SyTabs/SyTabs.mdx +0 -58
  187. package/src/components/Customs/SyTabs/SyTabs.stories.ts +34 -35
  188. package/src/components/Customs/SyTabs/SyTabs.vue +87 -67
  189. package/src/components/Customs/SyTabs/accessibilite/Accessibility.mdx +83 -23
  190. package/src/components/Customs/SyTabs/config.ts +3 -3
  191. package/src/components/Customs/SyTabs/tests/SyTabs.a11y.spec.ts +88 -0
  192. package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +46 -1
  193. package/src/components/Customs/SyTextField/SyTextField.stories.ts +21 -41
  194. package/src/components/Customs/SyTextField/SyTextField.vue +34 -9
  195. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +1 -1
  196. package/src/components/DatePicker/CalendarMode/DatePicker.vue +29 -28
  197. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +1 -1
  198. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +28 -23
  199. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +24 -1
  200. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
  201. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +65 -33
  202. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +1 -1
  203. package/src/components/DatePicker/composables/tests/useDatePickerState.spec.ts +53 -0
  204. package/src/components/DatePicker/composables/useDatePickerState.ts +56 -13
  205. package/src/components/DatePicker/composables/useDateRangeInput.ts +2 -1
  206. package/src/components/DatePicker/composables/useDateSelection.ts +2 -1
  207. package/src/components/DatePicker/composables/useDateTextField.ts +2 -3
  208. package/src/components/DatePicker/composables/useInputBlurHandler.ts +2 -2
  209. package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +9 -8
  210. package/src/components/DatePicker/playground/DatePickerHolidayRule.vue +1 -1
  211. package/src/components/DatePicker/types.ts +1 -2
  212. package/src/components/DialogBox/DialogBox.stories.ts +8 -8
  213. package/src/components/DialogBox/DialogBox.vue +3 -5
  214. package/src/components/DialogBox/accessibilite/Accessibility.mdx +86 -22
  215. package/src/components/DialogBox/tests/DialogBox.visual.cy.ts +76 -0
  216. package/src/components/DialogBox/tests/__snapshots__/dialog-box-custom-texts.snap.png +0 -0
  217. package/src/components/DialogBox/tests/__snapshots__/dialog-box-default.snap.png +0 -0
  218. package/src/components/DialogBox/tests/__snapshots__/dialog-box-no-actions.snap.png +0 -0
  219. package/src/components/FileList/FileList.vue +9 -2
  220. package/src/components/FileList/UploadItem/UploadItem.vue +11 -13
  221. package/src/components/FileList/tests/FileList.spec.ts +47 -0
  222. package/src/components/FileUpload/FileUpload.vue +3 -5
  223. package/src/components/FileUpload/FileUploadContent.vue +3 -5
  224. package/src/components/FilterInline/FilterInline.vue +1 -3
  225. package/src/components/FilterSideBar/FilterSideBar.mdx +44 -1
  226. package/src/components/FilterSideBar/FilterSideBar.stories.ts +105 -1
  227. package/src/components/FilterSideBar/FilterSideBar.vue +9 -1
  228. package/src/components/FilterSideBar/tests/FilterSideBar.a11y.spec.ts +54 -1
  229. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +42 -0
  230. package/src/components/FooterBar/FooterBar.vue +9 -13
  231. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +1 -1
  232. package/src/components/HeaderBar/HeaderBar.vue +2 -3
  233. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderBurgerMenu.vue +2 -3
  234. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +2 -3
  235. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuSection/HeaderMenuSection.vue +0 -1
  236. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +8 -9
  237. package/src/components/HeaderBar/HeaderBurgerMenu/menu.scss +0 -8
  238. package/src/components/HeaderBar/HeaderBurgerMenu/tests/HeaderBurgerMenu.visual.cy.ts +196 -0
  239. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated-submenu-open.snap.png +0 -0
  240. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated.snap.png +0 -0
  241. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +0 -1
  242. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +6 -7
  243. package/src/components/HeaderBar/tests/HeaderBar.visual.cy.ts +81 -0
  244. package/src/components/HeaderBar/tests/__snapshots__/header-bar-custom-width.snap.png +0 -0
  245. package/src/components/HeaderBar/tests/__snapshots__/header-bar-default.snap.png +0 -0
  246. package/src/components/HeaderBar/tests/__snapshots__/header-bar-no-sticky.snap.png +0 -0
  247. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-prepend.snap.png +0 -0
  248. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-side.snap.png +0 -0
  249. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-subtitle.snap.png +0 -0
  250. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +12 -3
  251. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +15 -8
  252. package/src/components/HeaderToolbar/HeaderToolbar.vue +6 -7
  253. package/src/components/LangBtn/LangBtn.vue +4 -5
  254. package/src/components/Logo/tests/Logo.visual.cy.ts +57 -0
  255. package/src/components/Logo/tests/__snapshots__/logo-avatar.snap.png +0 -0
  256. package/src/components/Logo/tests/__snapshots__/logo-dark.snap.png +0 -0
  257. package/src/components/Logo/tests/__snapshots__/logo-default.snap.png +0 -0
  258. package/src/components/Logo/tests/__snapshots__/logo-no-organism.snap.png +0 -0
  259. package/src/components/Logo/tests/__snapshots__/logo-no-signature.snap.png +0 -0
  260. package/src/components/Logo/tests/__snapshots__/logo-risque-pro.snap.png +0 -0
  261. package/src/components/LogoBrandSection/LogoBrandSection.vue +2 -2
  262. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +1 -1
  263. package/src/components/NirField/NirField.stories.ts +2 -2
  264. package/src/components/NirField/NirField.vue +3 -5
  265. package/src/components/NirField/accessibilite/Accessibility.mdx +100 -5
  266. package/src/components/NirField/tests/NirField.spec.ts +118 -0
  267. package/src/components/NirField/tests/useNirValidation.spec.ts +449 -0
  268. package/src/components/NirField/useNirValidation.ts +38 -32
  269. package/src/components/NotificationBar/Notification/Notification.vue +7 -9
  270. package/src/components/NotificationBar/NotificationBar.vue +1 -3
  271. package/src/components/PaginatedTable/PaginatedTable.vue +3 -4
  272. package/src/components/PaginatedTable/Pagination.vue +4 -6
  273. package/src/components/PasswordField/PasswordField.vue +15 -13
  274. package/src/components/PhoneField/PhoneField.vue +7 -5
  275. package/src/components/RangeField/RangeSlider/RangeSlider.vue +11 -20
  276. package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +1 -1
  277. package/src/components/RangeField/tests/RangeField.visual.cy.ts +65 -0
  278. package/src/components/RangeField/tests/__snapshots__/range-field-custom-bg.snap.png +0 -0
  279. package/src/components/RangeField/tests/__snapshots__/range-field-custom-range.snap.png +0 -0
  280. package/src/components/RangeField/tests/__snapshots__/range-field-default.snap.png +0 -0
  281. package/src/components/RangeField/tests/__snapshots__/range-field-step.snap.png +0 -0
  282. package/src/components/RangeField/tests/__snapshots__/range-field-with-label.snap.png +0 -0
  283. package/src/components/RatingPicker/EmotionPicker/EmotionPicker.vue +38 -56
  284. package/src/components/RatingPicker/EmotionPicker/tests/__snapshots__/EmotionPicker.spec.ts.snap +5 -0
  285. package/src/components/RatingPicker/NumberPicker/NumberPicker.vue +48 -53
  286. package/src/components/RatingPicker/NumberPicker/tests/NumberPicker.spec.ts +2 -1
  287. package/src/components/RatingPicker/NumberPicker/tests/__snapshots__/NumberPicker.spec.ts.snap +40 -13
  288. package/src/components/RatingPicker/RatingPicker.stories.ts +65 -88
  289. package/src/components/RatingPicker/RatingPicker.vue +71 -15
  290. package/src/components/RatingPicker/StarsPicker/StarsPicker.vue +31 -42
  291. package/src/components/RatingPicker/StarsPicker/tests/StarsPicker.spec.ts +1 -1
  292. package/src/components/RatingPicker/StarsPicker/tests/__snapshots__/StarsPicker.spec.ts.snap +5 -0
  293. package/src/components/RatingPicker/accessibilite/Accessibility.mdx +137 -9
  294. package/src/components/RatingPicker/tests/RatingPicker.a11y.spect.ts +123 -0
  295. package/src/components/RatingPicker/tests/RatingPicker.spec.ts +3 -2
  296. package/src/components/RatingPicker/tests/__snapshots__/RatingPicker.spec.ts.snap +40 -11
  297. package/src/components/RatingPicker/useRatingFocus.ts +97 -0
  298. package/src/components/SearchListField/SearchListField.vue +0 -2
  299. package/src/components/SkipLink/SkipLink.vue +2 -4
  300. package/src/components/SocialMediaLinks/SocialMediaLinks.vue +6 -6
  301. package/src/components/SubHeader/SubHeader.vue +1 -1
  302. package/src/components/SyAlert/SyAlert.vue +7 -9
  303. package/src/components/SyAlert/tests/SyAlert.visual.cy.ts +46 -0
  304. package/src/components/SyAlert/tests/__snapshots__/sy-alert-closable.snap.png +0 -0
  305. package/src/components/SyAlert/tests/__snapshots__/sy-alert-error.snap.png +0 -0
  306. package/src/components/SyAlert/tests/__snapshots__/sy-alert-info.snap.png +0 -0
  307. package/src/components/SyAlert/tests/__snapshots__/sy-alert-success.snap.png +0 -0
  308. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-outlined.snap.png +0 -0
  309. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-tonal.snap.png +0 -0
  310. package/src/components/SyAlert/tests/__snapshots__/sy-alert-warning.snap.png +0 -0
  311. package/src/components/SyBtnMenu/SyBtnMenu.vue +2 -4
  312. package/src/components/SyTextArea/SyTextArea.vue +32 -1
  313. package/src/components/TableToolbar/TableToolbar.vue +6 -8
  314. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +166 -0
  315. package/src/components/Tables/SyServerTable/SyServerTable.vue +10 -8
  316. package/src/components/Tables/SyServerTable/tests/SyServerTable.a11y.spec.ts +23 -0
  317. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +268 -0
  318. package/src/components/Tables/SyTable/SyTable.stories.ts +104 -0
  319. package/src/components/Tables/SyTable/SyTable.vue +10 -8
  320. package/src/components/Tables/SyTable/tests/SyTable.a11y.spec.ts +22 -0
  321. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +274 -0
  322. package/src/components/Tables/common/SyTableFilter.vue +31 -6
  323. package/src/components/Tables/common/SyTablePagination.vue +143 -19
  324. package/src/components/Tables/common/TableHeader.vue +41 -4
  325. package/src/components/Tables/common/filters/DateFilter.vue +2 -2
  326. package/src/components/Tables/common/filters/SelectFilter.vue +1 -1
  327. package/src/components/Tables/common/locales.ts +3 -0
  328. package/src/components/Tables/common/tableStyles.scss +16 -19
  329. package/src/components/Tables/common/tests/SyTablePagination.spec.ts +18 -0
  330. package/src/components/Tables/common/tests/TableHeader.spec.ts +39 -0
  331. package/src/components/Tables/common/types.ts +2 -0
  332. package/src/components/Tables/common/useTableHeaders.ts +49 -27
  333. package/src/components/UploadWorkflow/UploadWorkflow.vue +1 -0
  334. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +23 -0
  335. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +66 -0
  336. package/src/components/UploadWorkflow/useFileList.ts +3 -0
  337. package/src/components/UserMenuBtn/UserMenuBtn.vue +1 -3
  338. package/src/composables/date/tests/useDateFormatDayjs.spec.ts +81 -0
  339. package/src/composables/date/tests/{useDateInitialization.spec.ts → useDateInitializationDayjs.spec.ts} +39 -3
  340. package/src/composables/date/useDateInitializationDayjs.ts +4 -1
  341. package/src/composables/unifyValidation/documentationValidationProps.ts +235 -0
  342. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +2 -1
  343. package/src/composables/unifyValidation/tests/useValidation.spec.ts +22 -0
  344. package/src/composables/unifyValidation/useCustomValidation.ts +16 -4
  345. package/src/composables/unifyValidation/useValidation.ts +46 -15
  346. package/src/composables/unifyValidation/useVuetifyValidation.ts +2 -2
  347. package/src/composables/useFormFieldErrorHandling.ts +4 -1
  348. package/src/composables/validation/tests/useValidation.spec.ts +2 -2
  349. package/src/composables/validation/useValidation.ts +32 -4
  350. package/src/composantsVuetify/VBreadcrumbs/VBreadcrumbs.mdx +28 -0
  351. package/src/composantsVuetify/VBreadcrumbs/v-breadcrumbs.stories.ts +108 -0
  352. package/src/composantsVuetify/VCard/VCard.mdx +59 -0
  353. package/src/composantsVuetify/VCard/v-card.stories.ts +279 -0
  354. package/src/composantsVuetify/VOtpInput/VOtpInput.mdx +39 -0
  355. package/src/composantsVuetify/VOtpInput/v-otp-input.stories.ts +56 -0
  356. package/src/composantsVuetify/VSkeletonLoader/VSkeletonLoader.mdx +42 -0
  357. package/src/composantsVuetify/VSkeletonLoader/v-skeleton-loader.stories.ts +77 -0
  358. package/src/composantsVuetify/VSwitch/VSwitch.mdx +47 -0
  359. package/src/composantsVuetify/VSwitch/v-switch.stories.ts +166 -0
  360. package/src/designTokens/tests/buildColorClassMap.spec.ts +31 -0
  361. package/src/designTokens/tests/generateScssTokens.spec.ts +12 -0
  362. package/src/designTokens/tests/themeUtils.spec.ts +53 -0
  363. package/src/designTokens/tokens/amelipro/apColors.ts +8 -130
  364. package/src/designTokens/tokens/amelipro/apColors2026.ts +3 -15
  365. package/src/designTokens/tokens/amelipro/apContextual.ts +55 -47
  366. package/src/designTokens/tokens/amelipro/apLightTheme.ts +4 -1
  367. package/src/designTokens/tokens/amelipro/apSemantic.ts +1 -1
  368. package/src/designTokens/tokens/baseColors.ts +129 -0
  369. package/src/designTokens/tokens/baseContextualTokens.ts +52 -0
  370. package/src/designTokens/tokens/cnam/cnamColors.ts +3 -125
  371. package/src/designTokens/tokens/cnam/cnamContextual.ts +4 -48
  372. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +4 -1
  373. package/src/designTokens/tokens/cnam/cnamSemantic.ts +1 -1
  374. package/src/designTokens/tokens/pa/paColors.ts +2 -166
  375. package/src/designTokens/tokens/pa/paContextual.ts +3 -48
  376. package/src/designTokens/tokens/pa/paLightTheme.ts +1 -1
  377. package/src/designTokens/tokens/pa/paSemantic.ts +2 -2
  378. package/src/designTokens/utils/buildColorClassMap.ts +34 -0
  379. package/src/designTokens/utils/convertSemanticsToken.ts +8 -11
  380. package/src/designTokens/utils/createFlattenTheme.ts +15 -7
  381. package/src/designTokens/utils/index.ts +2 -2
  382. package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +61 -91
  383. package/src/stories/Accessibilite/AuditDesignSystem.mdx +5 -19
  384. package/src/stories/Accessibilite/AuditEtContreAudit/Exemptions-derogations.mdx +1 -1
  385. package/src/stories/Accessibilite/AuditEtContreAudit/Introduction.mdx +11 -8
  386. package/src/stories/Accessibilite/AuditEtContreAudit/RGAA.mdx +6 -7
  387. package/src/stories/Accessibilite/DesignSystem/Avancement.mdx +433 -0
  388. package/src/stories/Accessibilite/DesignSystem/a11y-status.json +692 -0
  389. package/src/stories/Accessibilite/Introduction.mdx +30 -30
  390. package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +176 -79
  391. package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +67 -19
  392. package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +78 -50
  393. package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +23 -49
  394. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru/FauxPositifs.stories.ts +6 -0
  395. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru/Utilisation.mdx +7 -19
  396. package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +55 -67
  397. package/src/stories/Components/Components.stories.ts +92 -4
  398. package/src/stories/Demarrer/EnrichirLeDesignSystem.mdx +4 -9
  399. package/src/stories/Demarrer/EnrichirLeDesignSystem.stories.ts +28 -0
  400. package/src/stories/Demarrer/Releases.stories.ts +48 -5
  401. package/src/stories/DesignTokens/ColorDisplay.vue +6 -5
  402. package/src/stories/DesignTokens/ColorIntegrationExample.vue +2 -4
  403. package/src/stories/DesignTokens/colors.stories.ts +5 -6
  404. package/src/stories/GuideDuDev/CreateVuetifyInstance.mdx +95 -0
  405. package/src/stories/GuideDuDev/Theme.mdx +36 -26
  406. package/src/stories/GuideDuDev/moduleDeNotification.mdx +3 -2
  407. package/src/stories/styles/accessibility-guide.css +3 -3
  408. package/src/utils/functions/classToHex.ts +6 -34
  409. package/src/utils/functions/createHexResolver.ts +45 -0
  410. package/src/utils/functions/tests/classToHex.spec.ts +36 -0
  411. package/src/utils/functions/tests/convertToHex.spec.ts +31 -0
  412. package/src/utils/functions/tests/createHexResolver.spec.ts +66 -0
  413. package/src/utils/functions/tests/isCssColor.spec.ts +48 -0
  414. package/dist/AutocompleteFilter-D9jzRzAL.cjs +0 -1
  415. package/dist/DateFilter-DTUl8hb1.cjs +0 -1
  416. package/dist/NumberFilter-MAEojdk0.cjs +0 -1
  417. package/dist/PeriodFilter-CC4WgIhl.cjs +0 -1
  418. package/dist/SelectFilter-BR3fvl-a.cjs +0 -1
  419. package/dist/TextFilter-CCfYFl5F.cjs +0 -1
  420. package/dist/apLightTheme-CFSRrjv2.cjs +0 -1
  421. package/dist/composables/date/useDateFormat.d.ts +0 -26
  422. package/dist/composables/date/useDateInitialization.d.ts +0 -18
  423. package/dist/design-system-v3.umd.cjs +0 -1
  424. package/dist/designTokens/utils/convertGaps.d.ts +0 -5
  425. package/dist/main-C1e3eoxd.cjs +0 -1067
  426. package/dist/tooth-11-D3sLWv2n.cjs +0 -1
  427. package/dist/tooth-12-CXrLuH03.cjs +0 -1
  428. package/dist/tooth-13-BSfo5fpT.cjs +0 -1
  429. package/dist/tooth-14-DMzulx0h.cjs +0 -1
  430. package/dist/tooth-15-BKRFVi-9.cjs +0 -1
  431. package/dist/tooth-16-CpuxAbuM.cjs +0 -1
  432. package/dist/tooth-17-BPoahUdg.cjs +0 -1
  433. package/dist/tooth-18-DhHJz8sy.cjs +0 -1
  434. package/dist/tooth-21-Dgd5hn_X.cjs +0 -1
  435. package/dist/tooth-22-C2Tn19sB.cjs +0 -1
  436. package/dist/tooth-23-C9uaaSGb.cjs +0 -1
  437. package/dist/tooth-24-BrK9UGpf.cjs +0 -1
  438. package/dist/tooth-25-CE_EfGNp.cjs +0 -1
  439. package/dist/tooth-26-Ctv4i9Fy.cjs +0 -1
  440. package/dist/tooth-27-C5J7JkWM.cjs +0 -1
  441. package/dist/tooth-28-Z9oWqjo0.cjs +0 -1
  442. package/dist/tooth-31-BrYqmkTi.cjs +0 -1
  443. package/dist/tooth-32-BNNR0oCZ.cjs +0 -1
  444. package/dist/tooth-33-DuxvqO2J.cjs +0 -1
  445. package/dist/tooth-34-BCSCXMB6.cjs +0 -1
  446. package/dist/tooth-35-BLUXkX88.cjs +0 -1
  447. package/dist/tooth-36-IrKHYqlA.cjs +0 -1
  448. package/dist/tooth-37-BYqpdMwo.cjs +0 -1
  449. package/dist/tooth-38-B_eNXXdu.cjs +0 -1
  450. package/dist/tooth-41-Ddva4Ot8.cjs +0 -1
  451. package/dist/tooth-42-szcDqlM0.cjs +0 -1
  452. package/dist/tooth-43-B3ka6rQm.cjs +0 -1
  453. package/dist/tooth-44-CazyQucj.cjs +0 -1
  454. package/dist/tooth-45-B4HQtc8n.cjs +0 -1
  455. package/dist/tooth-46-BPM40gbG.cjs +0 -1
  456. package/dist/tooth-47-Dvr20dlh.cjs +0 -1
  457. package/dist/tooth-48-Bd8ljGsF.cjs +0 -1
  458. package/dist/tooth-51-OBpwCOF3.cjs +0 -1
  459. package/dist/tooth-52-aKxyHcmq.cjs +0 -1
  460. package/dist/tooth-53-vCwJjTOc.cjs +0 -1
  461. package/dist/tooth-54-DsWu2iFy.cjs +0 -1
  462. package/dist/tooth-55-BxC1X2Dn.cjs +0 -1
  463. package/dist/tooth-61-BbLvxMQi.cjs +0 -1
  464. package/dist/tooth-62-CmTkWczP.cjs +0 -1
  465. package/dist/tooth-63-DI7l_2qI.cjs +0 -1
  466. package/dist/tooth-64-B21sOsJh.cjs +0 -1
  467. package/dist/tooth-65-D2ZC2VEr.cjs +0 -1
  468. package/dist/tooth-71-D473PPO5.cjs +0 -1
  469. package/dist/tooth-72-Drh1wnNu.cjs +0 -1
  470. package/dist/tooth-73-DzlwYI23.cjs +0 -1
  471. package/dist/tooth-74-8aGvcZPg.cjs +0 -1
  472. package/dist/tooth-75-BFK7At_r.cjs +0 -1
  473. package/dist/tooth-81-BZmR-I0M.cjs +0 -1
  474. package/dist/tooth-82-euVfUUZV.cjs +0 -1
  475. package/dist/tooth-83-KV010j64.cjs +0 -1
  476. package/dist/tooth-84-BBg1RjhZ.cjs +0 -1
  477. package/dist/tooth-85-Cr-kc1wM.cjs +0 -1
  478. package/dist/vuetifyConfig.umd.cjs +0 -1
  479. package/src/assets/apTokens.scss +0 -343
  480. package/src/assets/overrides/_container.scss +0 -36
  481. package/src/assets/tokens.scss +0 -388
  482. package/src/composables/date/tests/useDateFormat.spec.ts +0 -67
  483. package/src/composables/date/useDateFormat.ts +0 -110
  484. package/src/composables/date/useDateInitialization.ts +0 -92
  485. package/src/designTokens/apColors.md +0 -66
  486. package/src/designTokens/cnamColors.md +0 -193
  487. package/src/designTokens/paColors.md +0 -66
  488. package/src/designTokens/tokens/json/contextual-tokens.json +0 -156
  489. package/src/designTokens/tokens/json/primitives.json +0 -209
  490. package/src/designTokens/tokens/json/semantic.json +0 -120
  491. package/src/designTokens/utils/convertGaps.ts +0 -11
  492. package/src/stories/Accessibilite/Avancement/Avancement.mdx +0 -533
  493. package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +0 -306
@@ -4,9 +4,8 @@
4
4
  inheritAttrs: false,
5
5
  })
6
6
  import { mdiAlertCircle, mdiAlertOutline, mdiCheck, mdiChevronDown, mdiClose, mdiCloseCircle, mdiInformationOutline } from '@mdi/js'
7
- import { ref, watch, watchEffect, onMounted, onBeforeUnmount, computed, nextTick, type PropType } from 'vue'
7
+ import { ref, watch, watchEffect, onMounted, onBeforeUnmount, computed, nextTick, useAttrs, toRef, type Ref } from 'vue'
8
8
  import { useSySelectKeyboard } from './composables/useSySelectKeyboard'
9
- import { useValidatable } from '@/composables/validation/useValidatable'
10
9
  import type { ColorType, IconType, VariantStyle } from '@/types/vuetifyTypes'
11
10
  import type { VList, VTextField } from 'vuetify/components'
12
11
  import { VChip } from 'vuetify/components'
@@ -14,6 +13,8 @@
14
13
  import IconSlot from '@/components/Common/IconSlot/IconSlot.vue'
15
14
  import SyIcon from '@/components/Customs/SyIcon/SyIcon.vue'
16
15
  import { locales } from './locales'
16
+ import type { ValidationRule } from '@/composables/validation/useValidation'
17
+ import { useValidation, validationPropsDefaults, type FieldValidationProps } from '@/composables/unifyValidation/useValidation'
17
18
 
18
19
  export type ItemType = {
19
20
  [key: string]: unknown
@@ -22,147 +23,74 @@
22
23
  export type SelectItemValueType = Record<string, unknown> | string | number | null | undefined
23
24
  export type SelectItemArrayType = Array<Record<string, unknown> | string | number>
24
25
 
25
- // Définition des props avec typage correct pour modelValue
26
- const props = defineProps({
27
- modelValue: {
28
- // En Vue, on ne peut pas mettre null directement comme type
29
- // On utilise PropType pour définir le type complet incluant null
30
- type: [Object, String, Number, Array] as PropType<Record<string, unknown> | string | number | null | SelectItemArrayType>,
31
- default: null,
26
+ const props = withDefaults(
27
+ defineProps<{
28
+ modelValue?: Record<string, unknown> | string | number | null | SelectItemArrayType
29
+ items?: ItemType[]
30
+ label?: string
31
+ menuId?: string
32
+ outlined?: boolean
33
+ variantStyle?: VariantStyle
34
+ color?: ColorType
35
+ textKey?: string
36
+ plainTextKey?: string
37
+ valueKey?: string
38
+ displayAsterisk?: boolean
39
+ returnObject?: boolean
40
+ density?: 'default' | 'comfortable' | 'compact'
41
+ bgColor?: string
42
+ clearable?: boolean
43
+ hideDetails?: boolean
44
+ width?: string
45
+ multiple?: boolean
46
+ chips?: boolean
47
+ helpText?: string
48
+ allowHtml?: boolean
49
+ autocomplete?: 'on' | 'off' | string
50
+ prependIcon?: IconType
51
+ appendIcon?: IconType
52
+ prependTooltip?: string
53
+ appendTooltip?: string
54
+ tooltipLocation?: 'top' | 'bottom' | 'start' | 'end'
55
+ noIcon?: boolean
56
+ disableClickButton?: boolean
57
+ } & FieldValidationProps>(),
58
+ {
59
+ modelValue: null,
60
+ items: () => [],
61
+ label: 'Sélectionnez une option',
62
+ menuId: 'sy-select-menu',
63
+ outlined: true,
64
+ variantStyle: undefined,
65
+ color: 'primary',
66
+ textKey: 'text',
67
+ plainTextKey: '',
68
+ valueKey: 'value',
69
+ displayAsterisk: false,
70
+ returnObject: false,
71
+ density: 'default',
72
+ bgColor: 'white',
73
+ clearable: false,
74
+ hideDetails: false,
75
+ width: 'undefined',
76
+ multiple: false,
77
+ chips: false,
78
+ helpText: '',
79
+ allowHtml: false,
80
+ autocomplete: 'on',
81
+ prependIcon: undefined,
82
+ appendIcon: undefined,
83
+ prependTooltip: undefined,
84
+ appendTooltip: undefined,
85
+ tooltipLocation: 'top',
86
+ noIcon: false,
87
+ disableClickButton: true,
88
+ ...validationPropsDefaults,
32
89
  },
33
- items: {
34
- type: Array as PropType<ItemType[]>,
35
- default: () => [],
36
- },
37
- label: {
38
- type: String,
39
- default: 'Sélectionnez une option',
40
- },
41
- errorMessages: {
42
- type: [String, Array] as PropType<string | readonly string[]>,
43
- default: () => [],
44
- },
45
- required: {
46
- type: Boolean,
47
- default: false,
48
- },
49
- disabled: {
50
- type: Boolean,
51
- default: false,
52
- },
53
- menuId: {
54
- type: String,
55
- default: 'sy-select-menu',
56
- },
57
- outlined: {
58
- type: Boolean,
59
- default: true,
60
- },
61
- variantStyle: {
62
- type: String as PropType<VariantStyle | undefined>,
63
- default: undefined,
64
- },
65
- color: {
66
- type: String as PropType<ColorType>,
67
- default: 'primary',
68
- },
69
- textKey: {
70
- type: String,
71
- default: 'text',
72
- },
73
- plainTextKey: {
74
- type: String,
75
- default: '',
76
- },
77
- valueKey: {
78
- type: String,
79
- default: 'value',
80
- },
81
- displayAsterisk: {
82
- type: Boolean,
83
- default: false,
84
- },
85
- returnObject: {
86
- type: Boolean,
87
- default: false,
88
- },
89
- disableErrorHandling: {
90
- type: Boolean,
91
- default: false,
92
- },
93
- density: {
94
- type: String as PropType<'default' | 'comfortable' | 'compact' | undefined>,
95
- default: 'default',
96
- },
97
- bgColor: {
98
- type: String,
99
- default: 'white',
100
- },
101
- readonly: {
102
- type: Boolean,
103
- default: false,
104
- },
105
- clearable: {
106
- type: Boolean,
107
- default: false,
108
- },
109
- hideMessages: {
110
- type: Boolean,
111
- default: false,
112
- },
113
- width: {
114
- type: String,
115
- default: 'undefined',
116
- },
117
- multiple: {
118
- type: Boolean,
119
- default: false,
120
- },
121
- chips: {
122
- type: Boolean,
123
- default: false,
124
- },
125
- helpText: {
126
- type: String,
127
- default: '',
128
- },
129
- allowHtml: {
130
- type: Boolean,
131
- default: false,
132
- },
133
- autocomplete: {
134
- type: String as PropType<'on' | 'off' | undefined | string>,
135
- default: 'on',
136
- },
137
- prependIcon: {
138
- type: String as PropType<IconType>,
139
- default: undefined,
140
- },
141
- appendIcon: {
142
- type: String as PropType<IconType>,
143
- default: undefined,
144
- },
145
- prependTooltip: {
146
- type: String,
147
- default: undefined,
148
- },
149
- appendTooltip: {
150
- type: String,
151
- default: undefined,
152
- },
153
- tooltipLocation: {
154
- type: String as PropType<'top' | 'bottom' | 'start' | 'end'>,
155
- default: 'top',
156
- },
157
- noIcon: {
158
- type: Boolean,
159
- default: false,
160
- },
161
- disableClickButton: {
162
- type: Boolean,
163
- default: true,
164
- },
165
- })
90
+ )
91
+
92
+ // pr récupérer proprement aria-label
93
+ const attrs = useAttrs()
166
94
 
167
95
  const ICONS: Record<NonNullable<IconType>, string> = {
168
96
  info: mdiInformationOutline,
@@ -192,8 +120,10 @@
192
120
  const disableClickButton = computed(() => props.disableClickButton)
193
121
 
194
122
  const iconColor = computed(() => {
195
- if (hasError.value || Boolean(isRequired.value) || props.errorMessages.length > 0) return 'error'
196
- return 'rgb(var(--v-theme-iconBase));'
123
+ if (hasError.value) return 'error'
124
+ if (hasWarning.value) return 'warning'
125
+ if (hasSuccess.value) return 'success'
126
+ return 'rgb(var(--v-theme-iconBase))'
197
127
  })
198
128
 
199
129
  const variant = computed(() => {
@@ -204,9 +134,44 @@
204
134
  const isOpen = ref(false)
205
135
  // Initialize selectedItem with props.modelValue or empty array for multiple mode
206
136
  const selectedItem = ref<SelectItemValueType | SelectItemArrayType>(props.modelValue)
207
- const hasError = ref(false)
137
+ const focused = ref(false)
208
138
  const menuMinWidth = ref<number | null>(null)
209
139
 
140
+ const defaultRules = computed<ValidationRule[]>(() => props.required
141
+ ? [{
142
+ type: 'required',
143
+ options: {
144
+ message: `Le champ ${props.label || 'ce champ'} est requis.`,
145
+ fieldIdentifier: props.label,
146
+ },
147
+ }]
148
+ : [],
149
+ )
150
+
151
+ const { validate, clearValidation, errors, warnings, successes, hasError, hasWarning, hasSuccess } = useValidation({
152
+ modelValue: toRef(props, 'modelValue') as Ref<unknown>,
153
+ readonly: toRef(props, 'readonly'),
154
+ disabled: toRef(props, 'disabled'),
155
+ required: toRef(props, 'required'),
156
+ isValidateOnBlur: toRef(props, 'isValidateOnBlur'),
157
+ showSuccessMessages: toRef(props, 'showSuccessMessages'),
158
+ disableErrorHandling: toRef(props, 'disableErrorHandling'),
159
+ useVuetifyValidation: toRef(props, 'useVuetifyValidation'),
160
+ label: toRef(props, 'label'),
161
+ rules: toRef(props, 'rules'),
162
+ customRules: computed(() => [...defaultRules.value, ...(props.customRules ?? [])]),
163
+ customWarningRules: toRef(props, 'customWarningRules'),
164
+ customSuccessRules: toRef(props, 'customSuccessRules'),
165
+ errorMessages: toRef(props, 'errorMessages'),
166
+ warningMessages: toRef(props, 'warningMessages'),
167
+ successMessages: toRef(props, 'successMessages'),
168
+ hasErrorProp: toRef(props, 'hasError'),
169
+ hasWarningProp: toRef(props, 'hasWarning'),
170
+ hasSuccessProp: toRef(props, 'hasSuccess'),
171
+ maxErrors: toRef(props, 'maxErrors'),
172
+ focused: focused,
173
+ })
174
+
210
175
  const labelWidth = ref(0)
211
176
  const labelRef = ref<HTMLElement | null>(null)
212
177
  const list = ref<VList | null>(null)
@@ -256,9 +221,37 @@
256
221
  menuMinWidth.value = (controlEl ?? el).offsetWidth
257
222
  }
258
223
  const inputId = ref(`sy-select-${Math.random().toString(36).substring(7)}`)
224
+ // text d'aide
225
+ const helpTextId = computed(() => `${inputId.value}-help`)
226
+ // messages d'erreur, success avertissement
227
+ const messagesId = computed(() => `${inputId.value}-sr-messages`)
228
+ // live region pour le lecteur ecran
229
+ const liveRegionId = computed(() => `${inputId.value}-live`)
230
+ // un libellé caché pour la popup/grid
231
+ const overlayLabelId = computed(() => `${inputId.value}-overlay-label`)
232
+
259
233
  // Generate unique menu ID for each component instance to avoid conflicts and validation issues
260
234
  const uniqueMenuId = ref(props.menuId === 'sy-select-menu' ? `sy-select-menu-${Math.random().toString(36).substring(7)}` : props.menuId)
261
235
 
236
+ const rawAriaLabel = computed(() => {
237
+ const ariaLabel = attrs['aria-label']
238
+ return typeof ariaLabel === 'string' && ariaLabel.trim().length > 0 ? ariaLabel.trim() : ''
239
+ })
240
+
241
+ // met en place un fallback robuste du nom accessible :
242
+ const accessibleLabel = computed(() => {
243
+ // si aria-label existant
244
+ if (rawAriaLabel.value) return rawAriaLabel.value
245
+
246
+ // return label
247
+ if (props.label?.trim()) return labelWithAsterisk.value
248
+
249
+ // message d'aide si aucun label fourni
250
+ if (typeof props.helpText === 'string' && props.helpText.trim()) return props.helpText.trim()
251
+
252
+ return 'Selectionnez une option'
253
+ })
254
+
262
255
  const selectItem = (item: ItemType | null | undefined, event?: Event) => {
263
256
  // Prevent default action if event is provided
264
257
  event?.preventDefault()
@@ -284,6 +277,7 @@
284
277
  if (item === null || item === undefined) {
285
278
  selectedItem.value = props.multiple ? [] : null
286
279
  emit('update:modelValue', props.multiple ? [] : null)
280
+ clearValidation()
287
281
 
288
282
  // Garder la liste ouverte après une suppression et réinitialiser la navigation au clavier
289
283
  const target = event?.target as HTMLElement | undefined
@@ -469,12 +463,25 @@
469
463
  return !props.chips && props.multiple && Array.isArray(selectedItem.value) && (selectedItem.value as unknown[]).length > 0
470
464
  })
471
465
 
466
+ const hasSingleSelection = computed(() => {
467
+ return !props.multiple && selectedItem.value !== null && selectedItem.value !== undefined && selectedItemText.value !== ''
468
+ })
469
+
472
470
  const hasSelectionToClear = computed(() => {
473
471
  return props.multiple
474
472
  ? (((selectedItem.value as unknown[] | null | undefined)?.length) ?? 0) > 0
475
473
  : selectedItem.value != null
476
474
  })
477
475
 
476
+ const isFieldActive = computed(() => {
477
+ return hasChips.value
478
+ || hasMultipleSelections.value
479
+ || hasSingleSelection.value
480
+ || isOpen.value
481
+ || focused.value
482
+ || hasMessages.value
483
+ })
484
+
478
485
  const labelWithAsterisk = computed(() => {
479
486
  return isShouldDisplayAsterisk.value ? `${props.label} *` : props.label
480
487
  })
@@ -489,15 +496,14 @@
489
496
  })
490
497
 
491
498
  const isRequired = computed(() => {
492
- if (props.disableErrorHandling) return false
493
- if (props.readonly) return
494
- return (props.required || props.errorMessages.length > 0) && !selectedItem.value
499
+ if (props.readonly) return false
500
+ return props.required === true
495
501
  })
496
502
 
497
503
  // Détecte s'il y a des messages d'erreur, de succès ou d'avertissement
498
504
  const hasMessages = computed(() => {
499
505
  if (props.disableErrorHandling) return false
500
- return props.errorMessages.length > 0 || hasError.value
506
+ return hasError.value || hasWarning.value || hasSuccess.value
501
507
  })
502
508
 
503
509
  // Détermine si le helpText doit être affiché à la position du message ou en dessous
@@ -507,8 +513,28 @@
507
513
  })
508
514
 
509
515
  const showHelpTextBelow = computed(() => {
510
- // Afficher en dessous si il y a des messages d'erreur ET hideMessages n'est pas activé
511
- return props.helpText && hasMessages.value && !props.hideMessages
516
+ // Afficher en dessous si il y a des messages d'erreur ET hideDetails n'est pas activé
517
+ return props.helpText && hasMessages.value && !props.hideDetails
518
+ })
519
+
520
+ // Ici on calcule dynamiquement la liste des ids à rattacher à l'input :
521
+ const describedByIds = computed(() => {
522
+ const ids: string[] = []
523
+
524
+ // help text / hint
525
+ if ((showHelpTextAsMessage.value || showHelpTextBelow.value) && props.helpText) {
526
+ ids.push(helpTextId.value)
527
+ }
528
+ // messages affichés
529
+ if (!props.hideDetails && hasMessages.value) {
530
+ ids.push(messagesId.value)
531
+ }
532
+ // live region si erreur
533
+ if (hasError.value || errors.value.length > 0) {
534
+ ids.push(liveRegionId.value)
535
+ }
536
+
537
+ return ids.join(' ')
512
538
  })
513
539
 
514
540
  const calculatedWidth = computed(() => {
@@ -533,6 +559,22 @@
533
559
  return (rootEl.querySelector('.v-field') as HTMLElement | null) ?? rootEl
534
560
  })
535
561
 
562
+ const formattedErrorMessages = computed(() => errors.value.join(' '))
563
+
564
+ const liveRegionMessage = computed(() => {
565
+ if (!hasError.value) return ''
566
+
567
+ return formattedErrorMessages.value || 'Le champ contient une erreur.'
568
+ })
569
+
570
+ const validationIcon = computed(() => {
571
+ if (props.useVuetifyValidation) return null
572
+ if (hasError.value) return mdiAlertCircle
573
+ if (hasWarning.value) return mdiAlertOutline
574
+ if (hasSuccess.value) return mdiCheck
575
+ return null
576
+ })
577
+
536
578
  watch(() => props.modelValue, (newValue) => {
537
579
  selectedItem.value = newValue
538
580
  })
@@ -653,42 +695,38 @@
653
695
  }
654
696
  }
655
697
 
656
- watch([isOpen, hasError], ([newIsOpen, newHasError]) => {
657
- if (!newIsOpen) {
658
- if (props.disableErrorHandling || props.readonly) {
659
- hasError.value = false
660
- }
661
- else {
662
- hasError.value = (!selectedItem.value && isRequired.value) || props.errorMessages.length > 0
663
- }
664
- }
665
- else {
666
- hasError.value = newHasError
667
- }
668
- })
669
-
670
- watch(() => props.errorMessages, (newValue) => {
671
- if (!props.disableErrorHandling) {
672
- hasError.value = newValue.length > 0
673
- }
674
- })
675
-
676
698
  const ariaManager = {
677
699
  cleanInputAttributes(inputElement: HTMLElement): void {
678
700
  if (!inputElement) return
679
-
680
- inputElement.removeAttribute('aria-describedby')
681
701
  inputElement.removeAttribute('size')
682
702
  inputElement.removeAttribute('tabindex')
683
703
  inputElement.removeAttribute('aria-hidden')
704
+ inputElement.removeAttribute('aria-owns')
684
705
  },
685
706
 
686
- updateInputState(inputElement: HTMLElement, isOpenValue: boolean, menuId: string, activeDescendant?: string): void {
707
+ updateInputState(
708
+ inputElement: HTMLElement,
709
+ isOpenValue: boolean,
710
+ menuId: string,
711
+ activeDescendant?: string,
712
+ describedBy?: string,
713
+ ): void {
687
714
  if (!inputElement) return
715
+ inputElement.removeAttribute('aria-owns')
688
716
 
689
717
  inputElement.setAttribute('role', 'combobox')
690
718
  inputElement.setAttribute('aria-expanded', isOpenValue ? 'true' : 'false')
691
719
  inputElement.setAttribute('aria-haspopup', 'listbox')
720
+ // On ajoute aria-autocomplete="list" pour le role combobox
721
+ inputElement.setAttribute('aria-autocomplete', 'list')
722
+
723
+ // On rattache aria-describedby à l'input
724
+ if (describedBy && describedBy.trim().length > 0) {
725
+ inputElement.setAttribute('aria-describedby', describedBy)
726
+ }
727
+ else {
728
+ inputElement.removeAttribute('aria-describedby')
729
+ }
692
730
 
693
731
  if (isOpenValue) {
694
732
  inputElement.setAttribute('aria-controls', menuId)
@@ -697,6 +735,7 @@
697
735
  inputElement.removeAttribute('aria-controls')
698
736
  }
699
737
 
738
+ // aria-activedescendant sur l'input
700
739
  if (isOpenValue && activeDescendant) {
701
740
  inputElement.setAttribute('aria-activedescendant', activeDescendant)
702
741
  }
@@ -715,12 +754,7 @@
715
754
  inputElement.removeAttribute('aria-required')
716
755
  }
717
756
 
718
- if (hasErrorValue) {
719
- inputElement.setAttribute('aria-invalid', 'true')
720
- }
721
- else {
722
- inputElement.removeAttribute('aria-invalid')
723
- }
757
+ inputElement.setAttribute('aria-invalid', hasErrorValue ? 'true' : 'false')
724
758
  },
725
759
 
726
760
  cleanParentAttributes(parentElement: HTMLElement): void {
@@ -755,7 +789,14 @@
755
789
 
756
790
  if (inputElement) {
757
791
  ariaManager.cleanInputAttributes(inputElement)
758
- ariaManager.updateInputState(inputElement, isOpen.value, uniqueMenuId.value, activeDescendantId.value)
792
+ ariaManager.updateInputState(
793
+ inputElement,
794
+ isOpen.value,
795
+ uniqueMenuId.value,
796
+ activeDescendantId.value,
797
+ // On injecte ici les ids calculés pour aria-describedby,
798
+ describedByIds.value,
799
+ )
759
800
  ariaManager.updateValidationAttributes(inputElement, Boolean(isRequired.value), Boolean(hasError.value))
760
801
  }
761
802
 
@@ -788,11 +829,21 @@
788
829
  })
789
830
  })
790
831
 
791
- watch(isOpen, () => {
792
- nextTick(() => {
793
- if (!textInput.value || !textInput.value.$el) return
794
- setupAriaAttributes()
795
- })
832
+ watch(isOpen, async (newValue) => {
833
+ await nextTick()
834
+
835
+ focused.value = newValue
836
+
837
+ if (!textInput.value || !textInput.value.$el) return
838
+
839
+ setupAriaAttributes()
840
+
841
+ if (newValue) {
842
+ updateMenuAccessibility()
843
+ }
844
+ else {
845
+ focusInput()
846
+ }
796
847
  })
797
848
 
798
849
  watch(activeDescendantId, (newValue) => {
@@ -834,25 +885,6 @@
834
885
  })
835
886
  }, { deep: true })
836
887
 
837
- // Méthode de validation pour l'enregistrement avec le système de validation du formulaire
838
- const validateOnSubmit = (): boolean => {
839
- // Si en mode readonly ou si la gestion d'erreur est désactivée, toujours valide
840
- if (props.readonly || props.disableErrorHandling) {
841
- return true
842
- }
843
-
844
- // Vérifier si une valeur est sélectionnée quand le champ est requis
845
- const isValid = !isRequired.value
846
-
847
- // Mettre à jour l'état d'erreur
848
- hasError.value = !isValid || props.errorMessages.length > 0
849
-
850
- return isValid
851
- }
852
-
853
- // Intégration avec le système de validation du formulaire
854
- useValidatable(validateOnSubmit)
855
-
856
888
  watch(isOpen, () => {
857
889
  nextTick(() => {
858
890
  updateMenuMinWidth()
@@ -867,9 +899,34 @@
867
899
  defineExpose({
868
900
  isOpen,
869
901
  closeList,
870
- validateOnSubmit,
902
+ validateOnSubmit: validate,
871
903
  })
872
904
 
905
+ // on reprend la mm methode que pour le datepicker : useDatePickerAccesssibity (updateAccessibility)
906
+ const updateMenuAccessibility = async (): Promise<void> => {
907
+ await nextTick()
908
+
909
+ const listElement = list.value?.$el as HTMLElement | null
910
+ if (!listElement) return
911
+
912
+ listElement.setAttribute('role', 'listbox')
913
+ if (props.multiple) {
914
+ listElement.setAttribute('aria-multiselectable', 'true')
915
+ }
916
+ else {
917
+ listElement.removeAttribute('aria-multiselectable')
918
+ }
919
+ listElement.setAttribute('aria-labelledby', overlayLabelId.value)
920
+ }
921
+
922
+ const focusInput = () => {
923
+ // eviter un focus inutile si le composant est disebled ou readonly
924
+ if (props.disabled || props.readonly) return
925
+
926
+ const inputElement = textInput.value?.$el?.querySelector('input') as HTMLInputElement | null
927
+ inputElement?.focus()
928
+ }
929
+
873
930
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
874
931
  function initializeActivatorProps(activatorProps: Record<string, any>) {
875
932
  const onFocus = (event: FocusEvent) => {
@@ -925,24 +982,31 @@
925
982
  :id="inputId"
926
983
  v-model="selectedItemText"
927
984
  v-click-outside="closeList"
928
- :title="$attrs['aria-label'] || labelWithAsterisk"
985
+ :title="accessibleLabel"
929
986
  :color="props.color"
930
987
  :disabled="disabled"
931
988
  :label="labelWithAsterisk"
932
- :aria-label="$attrs['aria-label'] || labelWithAsterisk"
933
- :error-messages="props.disableErrorHandling ? [] : errorMessages"
989
+ :aria-label="accessibleLabel"
990
+ :error="hasError"
991
+ :error-messages="errors"
992
+ :messages="hasError ? errors : (hasWarning ? warnings : (hasSuccess && props.showSuccessMessages ? successes : undefined))"
934
993
  :variant="variant"
935
- :rules="isRequired && !props.disableErrorHandling ? ['Le champ est requis.'] : []"
936
994
  :bg-color="props.bgColor"
937
995
  :density="props.density"
938
- :active="hasChips || hasMultipleSelections || isOpen"
996
+ :active="isFieldActive"
939
997
  readonly
940
- :hide-details="props.hideMessages && !showHelpTextAsMessage"
998
+ :hide-details="props.hideDetails && !showHelpTextAsMessage"
941
999
  :hint="showHelpTextAsMessage ? props.helpText : ''"
942
1000
  :persistent-hint="!!showHelpTextAsMessage"
943
1001
  :autocomplete="props.autocomplete"
944
1002
  :width="calculatedWidth"
945
- :style="hasError ? { minWidth: `${labelWidth + 18}px`} : {minWidth: `${labelWidth}px`}"
1003
+ :style="hasError ? { minWidth: `${labelWidth + 18}px`} : { minWidth: `${labelWidth}px` }"
1004
+ :class="{
1005
+ 'error-field': hasError,
1006
+ 'warning-field': hasWarning,
1007
+ 'success-field': hasSuccess,
1008
+ 'basic-field': !hasError && !hasWarning && !hasSuccess,
1009
+ }"
946
1010
  v-bind="{
947
1011
  ...Object.fromEntries(Object.entries($attrs).filter(([key]) => key !== 'display-asterisk')),
948
1012
  ...initializeActivatorProps(activatorProps),
@@ -978,6 +1042,7 @@
978
1042
  {{ getChipText(item) }}
979
1043
  </VChip>
980
1044
  </div>
1045
+
981
1046
  <template v-else-if="hasMultipleSelections">
982
1047
  <span
983
1048
  v-for="item in (selectedItem as unknown[])"
@@ -987,6 +1052,7 @@
987
1052
  {{ getChipText(item) }}
988
1053
  </span>
989
1054
  </template>
1055
+
990
1056
  <!-- Prepend -->
991
1057
  <template
992
1058
  v-if="$slots.prepend || props.prependIcon || props.prependTooltip"
@@ -1032,21 +1098,21 @@
1032
1098
  />
1033
1099
  </IconSlot>
1034
1100
  </template>
1101
+
1035
1102
  <template #append-inner>
1036
1103
  <SyIcon
1037
- v-if="hasError"
1104
+ v-if="validationIcon"
1038
1105
  class="mr-6"
1039
- color="error"
1040
- :icon="mdiAlertCircle"
1041
- :decorative="false"
1042
- label="Information"
1043
- role="img"
1106
+ :color="hasError ? 'error' : (hasWarning ? 'warning' : 'success')"
1107
+ :icon="validationIcon"
1108
+ :decorative="true"
1109
+ role="presentation"
1044
1110
  />
1045
1111
  <button
1046
1112
  v-if="props.clearable && hasSelectionToClear"
1047
1113
  type="button"
1048
1114
  class="sy-select__clear-button"
1049
- :style="{ right: hasError ? '62px' : '42px' }"
1115
+ :style="{ right: (hasError || hasWarning || hasSuccess) ? '62px' : '42px' }"
1050
1116
  :aria-label="locales.clear"
1051
1117
  @keydown.enter.prevent="$event => selectItem(null, $event)"
1052
1118
  @keydown.space.prevent="$event => selectItem(null, $event)"
@@ -1071,18 +1137,30 @@
1071
1137
  class="hidden-label"
1072
1138
  >{{ label }}</span>
1073
1139
  </template>
1140
+
1141
+ <!--
1142
+ Libellé caché utilisé pour nommer la popup/grid.
1143
+ -->
1144
+ <span
1145
+ :id="overlayLabelId"
1146
+ class="d-sr-only"
1147
+ >
1148
+ {{ accessibleLabel }}
1149
+ </span>
1150
+
1074
1151
  <VList
1075
1152
  :id="uniqueMenuId"
1076
1153
  ref="list"
1077
- class="v-list"
1154
+ class="v-list sy-select-grid"
1078
1155
  role="listbox"
1079
- :aria-label="$attrs['aria-label'] || labelWithAsterisk"
1080
- :title="$attrs['aria-label'] || labelWithAsterisk"
1156
+ :aria-multiselectable="props.multiple ? 'true' : undefined"
1157
+ :aria-labelledby="overlayLabelId"
1158
+ :title="accessibleLabel"
1081
1159
  :style="{
1082
1160
  minWidth: `${textInput?.$el.offsetWidth}px`
1083
1161
  }"
1084
1162
  bg-color="white"
1085
- tabindex="0"
1163
+ tabindex="-1"
1086
1164
  @keydown.esc.prevent="closeList"
1087
1165
  @keydown.tab="handleTabKey"
1088
1166
  @keydown.enter.prevent="handleEnterKey"
@@ -1094,50 +1172,82 @@
1094
1172
  @keydown.page-down.prevent="handlePageDownKey"
1095
1173
  @click.stop
1096
1174
  >
1097
- <VListItem
1175
+ <div
1098
1176
  v-for="(item, index) in formattedItems"
1099
1177
  :id="`option-${index}`"
1100
1178
  :key="index"
1101
1179
  :ref="'options-' + index"
1102
1180
  role="option"
1103
- class="v-list-item"
1104
- :aria-selected="isItemSelected(item) ? 'true' : 'false'"
1181
+ :aria-selected="isItemSelected(item)"
1182
+ class="v-list-item sy-select-grid__row"
1105
1183
  tabindex="-1"
1106
- :class="{ active: isItemSelected(item) || `option-${index}` === activeDescendantId }"
1184
+ :class="{
1185
+ active: isItemSelected(item) || `option-${index}` === activeDescendantId,
1186
+ 'v-list-item--selected': isItemSelected(item),
1187
+ }"
1107
1188
  @click.stop="(event) => selectItem(item, event)"
1189
+ @keydown.enter.prevent="(event) => selectItem(item, event)"
1190
+ @keydown.space.prevent="(event) => selectItem(item, event)"
1108
1191
  >
1109
- <template
1192
+ <div
1110
1193
  v-if="props.multiple && !isDefaultOption(item)"
1111
- #prepend
1194
+ class="sy-select-grid__cell sy-select-grid__cell--checkbox"
1195
+ aria-hidden="true"
1112
1196
  >
1113
1197
  <SyCheckbox
1114
1198
  :model-value="isItemSelected(item)"
1115
- density="compact"
1116
- hide-details
1199
+ decorative
1117
1200
  color="primary"
1118
- class="mt-0 pt-0 mr-1"
1119
- :title="getItemText(item)"
1120
- :aria-label="getItemText(item)"
1121
- @click.stop="(event) => selectItem(item, event)"
1122
- />
1123
- </template>
1124
- <VListItemTitle>
1125
- <span
1126
- v-if="allowHtml"
1127
- ref="htmlItemRefs"
1128
- class="item-text"
1201
+ class="mt-0 pt-0 mr-1 pointer-events-none"
1129
1202
  />
1130
- <span
1131
- v-else
1132
- class="item-text"
1133
- >
1134
- {{ getItemText(item) }}
1135
- </span>
1136
- </VListItemTitle>
1137
- </VListItem>
1203
+ </div>
1204
+
1205
+ <div
1206
+ class="sy-select-grid__cell sy-select-grid__cell--label"
1207
+ >
1208
+ <VListItemTitle>
1209
+ <span
1210
+ v-if="allowHtml"
1211
+ ref="htmlItemRefs"
1212
+ class="item-text"
1213
+ />
1214
+ <span
1215
+ v-else
1216
+ class="item-text"
1217
+ >
1218
+ {{ getItemText(item) }}
1219
+ </span>
1220
+ </VListItemTitle>
1221
+ </div>
1222
+ </div>
1138
1223
  </VList>
1139
1224
  </VMenu>
1140
1225
 
1226
+ <div
1227
+ v-if="(showHelpTextAsMessage || showHelpTextBelow) && props.helpText"
1228
+ :id="helpTextId"
1229
+ class="d-sr-only"
1230
+ >
1231
+ {{ props.helpText }}
1232
+ </div>
1233
+
1234
+ <div
1235
+ v-if="!props.hideDetails && hasMessages"
1236
+ :id="messagesId"
1237
+ class="d-sr-only"
1238
+ >
1239
+ {{ hasError ? errors.join(' ') : (hasWarning ? warnings.join(' ') : successes.join(' ')) }}
1240
+ </div>
1241
+
1242
+ <div
1243
+ :id="liveRegionId"
1244
+ class="d-sr-only"
1245
+ aria-live="polite"
1246
+ aria-atomic="true"
1247
+ >
1248
+ {{ liveRegionMessage }}
1249
+ </div>
1250
+
1141
1251
  <div
1142
1252
  v-if="showHelpTextBelow"
1143
1253
  class="help-text-below px-4 mt-1"
@@ -1165,12 +1275,123 @@
1165
1275
 
1166
1276
  :deep(.v-input__prepend .v-icon:focus-visible),
1167
1277
  :deep(.v-input__append .v-icon:focus-visible) {
1168
- outline: 2px solid rgb(var(--v-theme-accentPrimary));
1278
+ outline: 2px solid rgb(var(--v-theme-borderAccentPrimary));
1169
1279
  outline-offset: 2px;
1170
1280
  opacity: 1;
1171
1281
  }
1172
1282
  }
1173
1283
 
1284
+ .warning-field {
1285
+ :deep(.v-icon__svg) {
1286
+ fill: rgb(var(--v-theme-textWarning)) !important;
1287
+ }
1288
+
1289
+ :deep(.v-icon.arrow) {
1290
+ color: rgb(var(--v-theme-iconBase)) !important;
1291
+ }
1292
+
1293
+ :deep(.v-icon.arrow .v-icon__svg) {
1294
+ fill: rgb(var(--v-theme-iconBase)) !important;
1295
+ }
1296
+
1297
+ :deep(.sy-select__clear-icon .v-icon__svg) {
1298
+ fill: rgb(var(--v-theme-iconBase)) !important;
1299
+ }
1300
+
1301
+ :deep(.v-field) {
1302
+ color: rgb(var(--v-theme-borderWarning)) !important;
1303
+
1304
+ --v-medium-emphasis-opacity: 1;
1305
+
1306
+ .v-field__outline {
1307
+ --v-field-border-opacity: 1;
1308
+
1309
+ color: rgb(var(--v-theme-borderWarning)) !important;
1310
+ }
1311
+ }
1312
+
1313
+ :deep(.v-messages) {
1314
+ opacity: 1 !important;
1315
+
1316
+ .v-messages__message {
1317
+ color: rgb(var(--v-theme-borderWarning)) !important;
1318
+ }
1319
+ }
1320
+ }
1321
+
1322
+ .error-field {
1323
+ :deep(.v-field) {
1324
+ color: rgb(var(--v-theme-borderError)) !important;
1325
+
1326
+ .v-field__outline {
1327
+ --v-field-border-opacity: 1;
1328
+
1329
+ color: rgb(var(--v-theme-borderError)) !important;
1330
+ }
1331
+ }
1332
+
1333
+ :deep(.v-messages) {
1334
+ opacity: 1 !important;
1335
+
1336
+ .v-messages__message {
1337
+ color: rgb(var(--v-theme-borderError)) !important;
1338
+ }
1339
+ }
1340
+
1341
+ :deep(.v-icon.arrow) {
1342
+ color: rgb(var(--v-theme-iconSubdued)) !important;
1343
+ }
1344
+
1345
+ :deep(.v-icon.arrow .v-icon__svg) {
1346
+ fill: rgb(var(--v-theme-iconSubdued)) !important;
1347
+ }
1348
+ }
1349
+
1350
+ .success-field {
1351
+ :deep(.v-icon__svg) {
1352
+ fill: rgb(var(--v-theme-textSuccess)) !important;
1353
+ }
1354
+
1355
+ :deep(.v-icon.arrow) {
1356
+ color: rgb(var(--v-theme-iconBase)) !important;
1357
+ }
1358
+
1359
+ :deep(.v-icon.arrow .v-icon__svg) {
1360
+ fill: rgb(var(--v-theme-iconBase)) !important;
1361
+ }
1362
+
1363
+ :deep(.sy-select__clear-icon .v-icon__svg) {
1364
+ fill: rgb(var(--v-theme-iconBase)) !important;
1365
+ }
1366
+
1367
+ :deep(.v-field) {
1368
+ color: rgb(var(--v-theme-borderSuccess)) !important;
1369
+
1370
+ --v-medium-emphasis-opacity: 1;
1371
+
1372
+ .v-field__outline {
1373
+ --v-field-border-opacity: 1;
1374
+
1375
+ color: rgb(var(--v-theme-borderSuccess)) !important;
1376
+ }
1377
+ }
1378
+
1379
+ :deep(.v-messages) {
1380
+ opacity: 1 !important;
1381
+
1382
+ .v-messages__message {
1383
+ color: rgb(var(--v-theme-borderSuccess)) !important;
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ .basic-field {
1389
+ :deep(.v-field--focused .v-field__outline) {
1390
+ color: rgb(var(--v-theme-borderAccentPrimary)) !important;
1391
+ opacity: 1 !important;
1392
+ }
1393
+ }
1394
+
1174
1395
  .v-field {
1175
1396
  position: relative;
1176
1397
  }
@@ -1185,7 +1406,7 @@
1185
1406
  background-color: rgb(0 0 0 / 4%);
1186
1407
  }
1187
1408
 
1188
- .v-list-item[aria-selected='true'] {
1409
+ .v-list-item--selected {
1189
1410
  background-color: rgb(0 0 0 / 8%);
1190
1411
  }
1191
1412
 
@@ -1195,7 +1416,7 @@
1195
1416
 
1196
1417
  .help-text {
1197
1418
  color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
1198
- font-size: 14px;
1419
+ font-size: var(--v-fontSize-liensEtLibelles);
1199
1420
  line-height: 1.2;
1200
1421
  }
1201
1422
 
@@ -1205,7 +1426,7 @@
1205
1426
 
1206
1427
  .help-text-below {
1207
1428
  color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
1208
- font-size: 14px;
1429
+ font-size: var(--v-fontSize-liensEtLibelles);
1209
1430
  line-height: 1.2;
1210
1431
  }
1211
1432
 
@@ -1216,7 +1437,7 @@
1216
1437
  /* Ensure focus styles match selection styles for keyboard navigation */
1217
1438
  .v-list-item:focus-visible,
1218
1439
  .v-list-item.keyboard-focused {
1219
- outline: 2px solid rgb(var(--v-theme-accentPrimary));
1440
+ outline: 2px solid rgb(var(--v-theme-borderAccentPrimary));
1220
1441
  outline-offset: -2px;
1221
1442
  background-color: rgb(0 0 0 / 8%);
1222
1443
  }
@@ -1243,7 +1464,6 @@
1243
1464
  .v-icon.arrow {
1244
1465
  position: absolute;
1245
1466
  right: 10px;
1246
- color: rgb(var(--v-theme-iconBase));
1247
1467
  }
1248
1468
 
1249
1469
  .sy-select__clear-icon {
@@ -1320,4 +1540,29 @@
1320
1540
  position: absolute;
1321
1541
  z-index: -1;
1322
1542
  }
1543
+
1544
+ .sy-select-grid__row {
1545
+ display: grid;
1546
+ grid-template-columns: auto 1fr;
1547
+ align-items: center;
1548
+ }
1549
+
1550
+ .sy-select-grid__cell {
1551
+ display: flex;
1552
+ align-items: center;
1553
+ min-width: 0;
1554
+ }
1555
+
1556
+ .sy-select-grid__cell--checkbox {
1557
+ padding-right: 4px;
1558
+ }
1559
+
1560
+ .sy-select-grid__cell--label {
1561
+ padding-right: 16px;
1562
+ min-width: 0;
1563
+ }
1564
+
1565
+ .pointer-events-none {
1566
+ pointer-events: none;
1567
+ }
1323
1568
  </style>