@cnamts/synapse 1.0.26 → 1.0.27

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 (253) hide show
  1. package/dist/{AutocompleteFilter-BPR-a55G.js → AutocompleteFilter-C9eLKyW8.js} +3 -3
  2. package/dist/{DateFilter-CknrJWs2.js → DateFilter-y-GLkAkn.js} +8 -8
  3. package/dist/{NumberFilter-DJ-yNlzv.js → NumberFilter-DN6hIBS7.js} +1 -1
  4. package/dist/{PeriodFilter-CiB5Oa9Z.js → PeriodFilter-MoUUp9qS.js} +1 -1
  5. package/dist/{SelectFilter-EiafX97M.js → SelectFilter-bCbrdLmu.js} +1 -1
  6. package/dist/{TextFilter-BzOmpdxj.js → TextFilter-CvjgEaoM.js} +4 -4
  7. package/dist/apLightTheme2026-ug4Y23ns.js +611 -0
  8. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +2369 -353
  9. package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +18 -0
  10. package/dist/components/Customs/Selects/SyAutocomplete/utils/ariaManager.d.ts +1 -1
  11. package/dist/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.d.ts +3 -1
  12. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +9 -10
  13. package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +1 -0
  14. package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +15 -0
  15. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +3 -3
  16. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +3 -3
  17. package/dist/components/Customs/SyIconButton/SyIconButton.d.ts +18 -0
  18. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +20 -38
  19. package/dist/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.d.ts +50 -0
  20. package/dist/components/Customs/SyTextField/SyTextField.d.ts +6 -6
  21. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +147 -136
  22. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +62 -54
  23. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +27 -24
  24. package/dist/components/DatePicker/composables/index.d.ts +1 -0
  25. package/dist/components/DatePicker/composables/useDatePickerValidationBridge.d.ts +51 -0
  26. package/dist/components/MonthPicker/MonthPicker.d.ts +23 -23
  27. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +23 -23
  28. package/dist/components/NirField/NirField.d.ts +56 -56
  29. package/dist/components/PasswordField/PasswordField.d.ts +3 -3
  30. package/dist/components/PeriodField/PeriodField.d.ts +236 -212
  31. package/dist/components/PhoneField/PhoneField.d.ts +23 -23
  32. package/dist/components/SyTextArea/SyTextArea.d.ts +25 -15
  33. package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +20 -0
  34. package/dist/components/SyTextArea/locales.d.ts +1 -0
  35. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +1 -0
  36. package/dist/components/Tables/SyTable/SyTable.d.ts +1 -0
  37. package/dist/components/Tables/common/SyTablePagination.d.ts +25 -25
  38. package/dist/components/Tables/common/types.d.ts +2 -0
  39. package/dist/components/index.d.ts +1 -0
  40. package/dist/composables/unifyValidation/documentationValidationProps.d.ts +160 -160
  41. package/dist/composables/unifyValidation/useValidation.d.ts +16 -14
  42. package/dist/design-system-v3.js +81 -80
  43. package/dist/designTokens/tokens/amelipro/apContextual.d.ts +6 -6
  44. package/dist/designTokens/tokens/amelipro/apDarkTheme.d.ts +3 -1
  45. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +53 -100
  46. package/dist/designTokens/tokens/baseContextualTokens.d.ts +0 -6
  47. package/dist/designTokens/tokens/baseTokens.d.ts +232 -0
  48. package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +6 -6
  49. package/dist/designTokens/tokens/cnam/cnamDarkTheme.d.ts +1 -1
  50. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +57 -101
  51. package/dist/designTokens/tokens/pa/paContextual.d.ts +0 -6
  52. package/dist/designTokens/tokens/pa/paDarkTheme.d.ts +1 -1
  53. package/dist/designTokens/tokens/pa/paLightTheme.d.ts +53 -97
  54. package/dist/designTokens/tokens/pa/paSemantic.d.ts +1 -0
  55. package/dist/designTokens/tokens/semanticTokens.d.ts +112 -0
  56. package/dist/main-CI6Q9nmO.js +39234 -0
  57. package/dist/synapse.css +1 -1
  58. package/dist/vuetifyConfig.js +208 -72
  59. package/package.json +4 -2
  60. package/src/assets/overrides/_icons.scss +5 -4
  61. package/src/assets/overrides/_otp.scss +4 -4
  62. package/src/assets/overrides/_typography.scss +2 -1
  63. package/src/assets/overrides/_utilities.scss +1 -42
  64. package/src/components/ChipList/ChipList.vue +30 -18
  65. package/src/components/ChipList/tests/chipList.spec.ts +4 -4
  66. package/src/components/CopyBtn/CopyBtn.vue +2 -2
  67. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +4 -0
  68. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +7 -6
  69. package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +223 -0
  70. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +283 -351
  71. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +182 -218
  72. package/src/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.ts +101 -0
  73. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +761 -1
  74. package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +3 -1
  75. package/src/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.ts +79 -5
  76. package/src/components/Customs/Selects/SyAutocomplete/validation/Validation.stories.ts +1029 -0
  77. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +9 -491
  78. package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -79
  79. package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +3 -0
  80. package/src/components/Customs/Selects/SySelect/composables/useSySelectValidation.ts +64 -0
  81. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +196 -0
  82. package/src/components/Customs/Selects/SySelect/validation/Validation.stories.ts +1026 -0
  83. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +18 -7
  84. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +2 -2
  85. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +8 -8
  86. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +8 -8
  87. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +1 -1
  88. package/src/components/Customs/SyIcon/accessibilite/Accessibility.mdx +0 -6
  89. package/src/components/Customs/SyIcon/utils/tests/iconUtils.spec.ts +107 -0
  90. package/src/components/Customs/SyRadioGroup/SyRadioGroup.mdx +2 -2
  91. package/src/components/Customs/SyRadioGroup/SyRadioGroup.stories.ts +395 -200
  92. package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +82 -127
  93. package/src/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.ts +127 -0
  94. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.a11y.spec.ts +93 -1
  95. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.spec.ts +146 -9
  96. package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.visual.cy.ts +165 -0
  97. package/src/components/Customs/SyRadioGroup/validation/Validation.stories.ts +773 -0
  98. package/src/components/Customs/SyTabs/config.ts +3 -3
  99. package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +265 -0
  100. package/src/components/Customs/SyTabs/tests/useTabTransition.spec.ts +188 -0
  101. package/src/components/Customs/SyTextField/SyTextField.stories.ts +10 -29
  102. package/src/components/Customs/SyTextField/SyTextField.vue +23 -15
  103. package/src/components/DataList/DataList.stories.ts +1 -1
  104. package/src/components/DataListItem/tests/DataListItem.spec.ts +3 -1
  105. package/src/components/DatePicker/CalendarMode/DatePicker.vue +37 -142
  106. package/src/components/DatePicker/CalendarMode/tests/DatePicker.coverage.spec.ts +156 -0
  107. package/src/components/DatePicker/CalendarMode/tests/DatePicker.spec.ts +495 -4
  108. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +47 -66
  109. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +206 -0
  110. package/src/components/DatePicker/ComplexDatePicker/tests/bridge-integration.regression.spec.ts +210 -0
  111. package/src/components/DatePicker/ComplexDatePicker/tests/calendar-navigation.regression.spec.ts +214 -0
  112. package/src/components/DatePicker/ComplexDatePicker/tests/validation-cross.regression.spec.ts +194 -0
  113. package/src/components/DatePicker/ComplexDatePicker/tests/validation-success-messages.regression.spec.ts +83 -0
  114. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +129 -54
  115. package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +320 -0
  116. package/src/components/DatePicker/composables/index.ts +1 -0
  117. package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +360 -0
  118. package/src/components/DatePicker/composables/tests/useDatePickerValidationBridge.spec.ts +129 -0
  119. package/src/components/DatePicker/composables/useDatePickerValidationBridge.ts +205 -0
  120. package/src/components/DatePicker/docExamples/BidirectionalComplexValidation.vue +1 -1
  121. package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +1 -1
  122. package/src/components/DatePicker/tests/exposed-methods.coverage.spec.ts +75 -0
  123. package/src/components/DialogBox/DialogBox.vue +1 -1
  124. package/src/components/FileList/UploadItem/UploadItem.vue +4 -4
  125. package/src/components/FileUpload/FileUpload.vue +2 -2
  126. package/src/components/FileUpload/FileUploadContent.vue +1 -1
  127. package/src/components/FilterInline/FilterInline.mdx +2 -2
  128. package/src/components/FilterSideBar/FilterSideBar.stories.ts +1 -1
  129. package/src/components/FilterSideBar/FilterSideBar.vue +2 -2
  130. package/src/components/FooterBar/FooterBar.vue +7 -7
  131. package/src/components/FranceConnectBtn/FranceConnectBtn.vue +1 -1
  132. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +2 -2
  133. package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +7 -7
  134. package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +2 -2
  135. package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +87 -8
  136. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +3 -3
  137. package/src/components/HeaderNavigationBar/HorizontalNavbar/tests/HorizontalNavbar.spec.ts +589 -0
  138. package/src/components/HeaderToolbar/tests/HeaderToolBar.spec.ts +153 -1
  139. package/src/components/HeaderToolbar/tests/useMobileRightMenu.spec.ts +258 -0
  140. package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +2 -2
  141. package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +1 -1
  142. package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +184 -0
  143. package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +3 -3
  144. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +1 -1
  145. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +2 -2
  146. package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +1 -1
  147. package/src/components/NirField/NirField.vue +3 -3
  148. package/src/components/NotificationBar/Notification/Notification.vue +12 -12
  149. package/src/components/NotificationBar/NotificationBar.stories.ts +8 -8
  150. package/src/components/PaginatedTable/Pagination.vue +2 -2
  151. package/src/components/PasswordField/PasswordField.vue +8 -8
  152. package/src/components/PasswordField/tests/PasswordField.spec.ts +3 -3
  153. package/src/components/RangeField/RangeSlider/RangeSlider.vue +2 -2
  154. package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +1 -1
  155. package/src/components/StatusPage/tests/StatusPage.spec.ts +149 -0
  156. package/src/components/SubHeader/SubHeader.vue +1 -1
  157. package/src/components/SyAlert/SyAlert.vue +23 -23
  158. package/src/components/SyTextArea/SyTextArea.stories.ts +177 -131
  159. package/src/components/SyTextArea/SyTextArea.vue +235 -83
  160. package/src/components/SyTextArea/composables/useSyTextAreaValidation.ts +81 -0
  161. package/src/components/SyTextArea/locales.ts +1 -0
  162. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +449 -1
  163. package/src/components/SyTextArea/useDefaultValidationRules.ts +2 -7
  164. package/src/components/SyTextArea/validation/Validation.stories.ts +856 -0
  165. package/src/components/TableToolbar/TableToolbar.vue +6 -6
  166. package/src/components/TableToolbar/accessibilite/Accessibility.mdx +81 -7
  167. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +163 -0
  168. package/src/components/Tables/SyServerTable/SyServerTable.vue +2 -1
  169. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
  170. package/src/components/Tables/SyTable/SyTable.stories.ts +94 -0
  171. package/src/components/Tables/SyTable/SyTable.vue +2 -1
  172. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +64 -0
  173. package/src/components/Tables/common/TableHeader.vue +2 -2
  174. package/src/components/Tables/common/filters/logics/tests/NumberFilterLogic.spec.ts +176 -0
  175. package/src/components/Tables/common/filters/logics/tests/SelectFilterLogic.spec.ts +111 -0
  176. package/src/components/Tables/common/tableStyles.scss +6 -6
  177. package/src/components/Tables/common/types.ts +2 -0
  178. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +2 -0
  179. package/src/components/index.ts +1 -0
  180. package/src/composables/date/tests/useDateFormatDayjs.spec.ts +31 -0
  181. package/src/composables/date/tests/useHolidayDay.spec.ts +109 -0
  182. package/src/composables/rules/tests/useFieldValidation.spec.ts +374 -0
  183. package/src/composables/tests/useError.spec.ts +30 -0
  184. package/src/composables/tests/useFormFieldErrorHandling.spec.ts +234 -0
  185. package/src/composables/unifyValidation/documentationValidationProps.ts +5 -5
  186. package/src/composables/unifyValidation/tests/documentationValidationProps.spec.ts +177 -0
  187. package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +30 -0
  188. package/src/composables/unifyValidation/tests/useValidation.spec.ts +6 -2
  189. package/src/composables/unifyValidation/useCustomValidation.ts +19 -9
  190. package/src/composables/unifyValidation/useValidation.ts +18 -21
  191. package/src/composables/useFilterable/useFilterable.spec.ts +42 -0
  192. package/src/composables/useFilterable/useFilterable.ts +11 -7
  193. package/src/composables/useFormFieldErrorHandling.ts +2 -2
  194. package/src/composantsVuetify/VBtn/VBtn.mdx +9 -39
  195. package/src/composantsVuetify/VBtn/v-btn.stories.ts +26 -86
  196. package/src/designTokens/tokens/amelipro/apContextual.ts +6 -0
  197. package/src/designTokens/tokens/amelipro/apDarkTheme.ts +2 -2
  198. package/src/designTokens/tokens/amelipro/apLightTheme.ts +72 -103
  199. package/src/designTokens/tokens/amelipro/apSemantic.ts +1 -1
  200. package/src/designTokens/tokens/baseContextualTokens.ts +1 -6
  201. package/src/designTokens/tokens/baseTokens.ts +232 -0
  202. package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -0
  203. package/src/designTokens/tokens/cnam/cnamDarkTheme.ts +2 -2
  204. package/src/designTokens/tokens/cnam/cnamLightTheme.ts +76 -104
  205. package/src/designTokens/tokens/pa/paDarkTheme.ts +2 -2
  206. package/src/designTokens/tokens/pa/paLightTheme.ts +73 -99
  207. package/src/designTokens/tokens/pa/paSemantic.ts +2 -0
  208. package/src/designTokens/tokens/semanticTokens.ts +114 -0
  209. package/src/stories/Components/Components.stories.ts +7 -3
  210. package/src/stories/DesignTokens/ColorIntegrationExample.vue +2 -3
  211. package/src/stories/DesignTokens/Colors.mdx +6 -8
  212. package/src/stories/DesignTokens/colors.stories.ts +244 -1081
  213. package/src/utils/amelipro/toKebabCase/tests/toKebabCase.spec.ts +52 -0
  214. package/src/utils/formatNir/tests/formatNir.spec.ts +34 -0
  215. package/src/utils/tests/insertAt.spec.ts +44 -0
  216. package/dist/apLightTheme-DS0Uy44H.js +0 -954
  217. package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +0 -1
  218. package/dist/main-BsJ9ec3i.js +0 -38954
  219. package/src/components/BackBtn/tests/__snapshots__/back-btn-custom-bg.snap.png +0 -0
  220. package/src/components/BackBtn/tests/__snapshots__/back-btn-dark-mode.snap.png +0 -0
  221. package/src/components/BackBtn/tests/__snapshots__/back-btn-default.snap.png +0 -0
  222. package/src/components/BackBtn/tests/__snapshots__/back-btn-no-icon.snap.png +0 -0
  223. package/src/components/DatePicker/CalendarMode/tests/DatePicker.events.spec.ts +0 -178
  224. package/src/components/DialogBox/tests/__snapshots__/dialog-box-custom-texts.snap.png +0 -0
  225. package/src/components/DialogBox/tests/__snapshots__/dialog-box-default.snap.png +0 -0
  226. package/src/components/DialogBox/tests/__snapshots__/dialog-box-no-actions.snap.png +0 -0
  227. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated-submenu-open.snap.png +0 -0
  228. package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated.snap.png +0 -0
  229. package/src/components/HeaderBar/tests/__snapshots__/header-bar-custom-width.snap.png +0 -0
  230. package/src/components/HeaderBar/tests/__snapshots__/header-bar-default.snap.png +0 -0
  231. package/src/components/HeaderBar/tests/__snapshots__/header-bar-no-sticky.snap.png +0 -0
  232. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-prepend.snap.png +0 -0
  233. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-side.snap.png +0 -0
  234. package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-subtitle.snap.png +0 -0
  235. package/src/components/Logo/tests/__snapshots__/logo-avatar.snap.png +0 -0
  236. package/src/components/Logo/tests/__snapshots__/logo-dark.snap.png +0 -0
  237. package/src/components/Logo/tests/__snapshots__/logo-default.snap.png +0 -0
  238. package/src/components/Logo/tests/__snapshots__/logo-no-organism.snap.png +0 -0
  239. package/src/components/Logo/tests/__snapshots__/logo-no-signature.snap.png +0 -0
  240. package/src/components/Logo/tests/__snapshots__/logo-risque-pro.snap.png +0 -0
  241. package/src/components/RangeField/tests/__snapshots__/range-field-custom-bg.snap.png +0 -0
  242. package/src/components/RangeField/tests/__snapshots__/range-field-custom-range.snap.png +0 -0
  243. package/src/components/RangeField/tests/__snapshots__/range-field-default.snap.png +0 -0
  244. package/src/components/RangeField/tests/__snapshots__/range-field-step.snap.png +0 -0
  245. package/src/components/RangeField/tests/__snapshots__/range-field-with-label.snap.png +0 -0
  246. package/src/components/SyAlert/tests/__snapshots__/sy-alert-closable.snap.png +0 -0
  247. package/src/components/SyAlert/tests/__snapshots__/sy-alert-error.snap.png +0 -0
  248. package/src/components/SyAlert/tests/__snapshots__/sy-alert-info.snap.png +0 -0
  249. package/src/components/SyAlert/tests/__snapshots__/sy-alert-success.snap.png +0 -0
  250. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-outlined.snap.png +0 -0
  251. package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-tonal.snap.png +0 -0
  252. package/src/components/SyAlert/tests/__snapshots__/sy-alert-warning.snap.png +0 -0
  253. /package/src/components/RatingPicker/tests/{RatingPicker.a11y.spect.ts → RatingPicker.a11y.spec.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { mount, flushPromises, type VueWrapper } from '@vue/test-utils'
2
- import { describe, it, expect, afterEach } from 'vitest'
2
+ import { describe, it, expect, afterEach, beforeEach } from 'vitest'
3
3
  import { nextTick } from 'vue'
4
4
  import DatePicker from '../DatePicker.vue'
5
5
 
@@ -21,6 +21,13 @@ describe('DatePicker', () => {
21
21
  return wrapper
22
22
  }
23
23
 
24
+ const typeDigits = async (input: ReturnType<ReturnType<typeof mountComponent>['find']>, digits: string) => {
25
+ for (const digit of digits) {
26
+ await input.trigger('keydown', { key: digit })
27
+ await flushPromises()
28
+ }
29
+ }
30
+
24
31
  it('renders the calendar mode activator input by default', () => {
25
32
  const wrapper = mountComponent({
26
33
  required: true,
@@ -31,19 +38,141 @@ describe('DatePicker', () => {
31
38
  expect(input.exists()).toBe(true)
32
39
  })
33
40
 
34
- it('emits update:modelValue when a valid date is typed in single mode', async () => {
41
+ /**
42
+ * AutoClamp est testé dans useDateAutoClamp.spec.ts (composable natif)
43
+ * Tests de composant conservés pour intégration
44
+ */
45
+ it('preserves autoClamp in no-calendar mode', async () => {
35
46
  const wrapper = mountComponent({
36
47
  format: 'DD/MM/YYYY',
48
+ noCalendar: true,
49
+ autoClamp: true,
37
50
  })
38
51
 
39
52
  const input = wrapper.find('input')
40
- await input.setValue('01/01/2023')
53
+ await input.setValue('31/04/2025')
41
54
  await input.trigger('blur')
42
55
  await flushPromises()
43
56
 
57
+ expect(input.element.value).toBe('30/04/2025')
44
58
  const emitted = wrapper.emitted('update:modelValue')
45
59
  expect(emitted).toBeTruthy()
46
- expect(emitted && emitted[0]?.[0]).toBe('01/01/2023')
60
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toBe('30/04/2025')
61
+ })
62
+
63
+ it('preserves autoClamp with masked keyboard input in no-calendar mode', async () => {
64
+ const wrapper = mountComponent({
65
+ format: 'DD/MM/YYYY',
66
+ noCalendar: true,
67
+ autoClamp: true,
68
+ })
69
+
70
+ const input = wrapper.find('input')
71
+ await typeDigits(input, '31042025')
72
+ await input.trigger('blur')
73
+ await flushPromises()
74
+
75
+ expect(input.element.value).toBe('30/04/2025')
76
+ const emitted = wrapper.emitted('update:modelValue')
77
+ expect(emitted).toBeTruthy()
78
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toBe('30/04/2025')
79
+ })
80
+
81
+ it('preserves autoClamp in combined mode', async () => {
82
+ const wrapper = mountComponent({
83
+ format: 'DD/MM/YYYY',
84
+ useCombinedMode: true,
85
+ autoClamp: true,
86
+ })
87
+
88
+ const input = wrapper.find('input')
89
+ await input.setValue('31/04/2025')
90
+ await input.trigger('blur')
91
+ await flushPromises()
92
+
93
+ expect(input.element.value).toBe('30/04/2025')
94
+ const emitted = wrapper.emitted('update:modelValue')
95
+ expect(emitted).toBeTruthy()
96
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toBe('30/04/2025')
97
+ })
98
+
99
+ it('preserves autoClamp with masked keyboard input in combined mode', async () => {
100
+ const wrapper = mountComponent({
101
+ format: 'DD/MM/YYYY',
102
+ useCombinedMode: true,
103
+ autoClamp: true,
104
+ })
105
+
106
+ const input = wrapper.find('input')
107
+ await typeDigits(input, '31042025')
108
+ await input.trigger('blur')
109
+ await flushPromises()
110
+
111
+ expect(input.element.value).toBe('30/04/2025')
112
+ const emitted = wrapper.emitted('update:modelValue')
113
+ expect(emitted).toBeTruthy()
114
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toBe('30/04/2025')
115
+ })
116
+
117
+ it('preserves autoClamp in combined mode with dateFormatReturn', async () => {
118
+ const wrapper = mountComponent({
119
+ format: 'DD/MM/YYYY',
120
+ dateFormatReturn: 'YYYY-MM-DD',
121
+ useCombinedMode: true,
122
+ autoClamp: true,
123
+ })
124
+
125
+ const input = wrapper.find('input')
126
+ await input.setValue('31/04/2025')
127
+ await input.trigger('blur')
128
+ await flushPromises()
129
+
130
+ expect(input.element.value).toBe('30/04/2025')
131
+ const emitted = wrapper.emitted('update:modelValue')
132
+ expect(emitted).toBeTruthy()
133
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toBe('2025-04-30')
134
+ })
135
+
136
+ it('preserves autoClamp in combined range mode', async () => {
137
+ const wrapper = mountComponent({
138
+ format: 'DD/MM/YYYY',
139
+ useCombinedMode: true,
140
+ displayRange: true,
141
+ autoClamp: true,
142
+ })
143
+
144
+ const input = wrapper.find('input')
145
+ await input.setValue('29/02/2025 - 31/04/2025')
146
+ await input.trigger('blur')
147
+ await flushPromises()
148
+
149
+ expect(input.element.value).toBe('28/02/2025 - 30/04/2025')
150
+ const emitted = wrapper.emitted('update:modelValue')
151
+ expect(emitted).toBeTruthy()
152
+ expect(emitted && emitted[emitted.length - 1]?.[0]).toEqual(['28/02/2025', '30/04/2025'])
153
+ })
154
+
155
+ it('keeps combined autoClamp value visible after parent v-model sync', async () => {
156
+ const wrapper = mountComponent({
157
+ format: 'DD/MM/YYYY',
158
+ useCombinedMode: true,
159
+ autoClamp: true,
160
+ modelValue: undefined,
161
+ })
162
+
163
+ const input = wrapper.find('input')
164
+ await input.setValue('31/04/2025')
165
+ await input.trigger('blur')
166
+ await flushPromises()
167
+
168
+ const emitted = wrapper.emitted('update:modelValue')
169
+ const clampedValue = emitted && emitted[emitted.length - 1]?.[0]
170
+ expect(clampedValue).toBe('30/04/2025')
171
+
172
+ await wrapper.setProps({ modelValue: clampedValue })
173
+ await flushPromises()
174
+
175
+ expect(wrapper.find('input').element.value).toBe('30/04/2025')
47
176
  })
48
177
 
49
178
  it('handles invalid typed date input gracefully', async () => {
@@ -208,6 +337,21 @@ describe('DatePicker', () => {
208
337
  expect(vm.errorMessages.length).toBe(0)
209
338
  })
210
339
 
340
+ it('keeps current disableErrorHandling contract: required empty submit does not expose errors', async () => {
341
+ const wrapper = mountComponent({
342
+ required: true,
343
+ format: 'DD/MM/YYYY',
344
+ disableErrorHandling: true,
345
+ })
346
+ const vm = wrapper.vm as DatePickerInstance
347
+
348
+ vm.selectedDates = null
349
+ const result = await vm.validateOnSubmit()
350
+
351
+ expect(result).toBe(true)
352
+ expect(vm.errorMessages).toEqual([])
353
+ })
354
+
211
355
  it('toggles date picker visibility with openDatePicker', async () => {
212
356
  const wrapper = mountComponent()
213
357
  const vm = wrapper.vm as DatePickerInstance
@@ -278,6 +422,15 @@ describe('DatePicker', () => {
278
422
  expect(vm.isDatePickerVisible).toBe(true)
279
423
  }, 20000)
280
424
 
425
+ it('keeps deprecated birthDate prop as an alias for birth date mode', () => {
426
+ const wrapper = mountComponent({
427
+ birthDate: true,
428
+ })
429
+
430
+ expect(wrapper.props('birthDate')).toBe(true)
431
+ expect(wrapper.vm.currentViewMode).toBe('year')
432
+ })
433
+
281
434
  it('emits closed when handleClickOutside is called while open', () => {
282
435
  const wrapper = mountComponent({
283
436
  format: 'DD/MM/YYYY',
@@ -303,3 +456,341 @@ describe('DatePicker', () => {
303
456
  expect(wrapper.exists()).toBe(true)
304
457
  })
305
458
  })
459
+
460
+ describe('DatePicker - Events & Interactions', () => {
461
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
462
+ let evWrapper: any
463
+
464
+ beforeEach(() => {
465
+ evWrapper = mount(DatePicker, {
466
+ props: {
467
+ label: 'Date Field',
468
+ modelValue: '',
469
+ format: 'DD/MM/YYYY',
470
+ },
471
+ })
472
+ })
473
+
474
+ afterEach(() => {
475
+ evWrapper?.unmount()
476
+ evWrapper = null
477
+ })
478
+
479
+ it('gère la visibilité du calendrier', async () => {
480
+ await evWrapper.find('.v-text-field').trigger('click')
481
+ await nextTick()
482
+ expect(evWrapper.vm.isDatePickerVisible).toBe(true)
483
+
484
+ evWrapper.vm.isDatePickerVisible = false
485
+ await nextTick()
486
+ expect(evWrapper.vm.isDatePickerVisible).toBe(false)
487
+ })
488
+
489
+ it('accepte la saisie de dates', async () => {
490
+ const input = evWrapper.find('input')
491
+ await input.setValue('0101')
492
+ await nextTick()
493
+ expect(input.element.value).toContain('01')
494
+ })
495
+
496
+ it('permet la saisie manuelle même avec disablePickerInteraction', async () => {
497
+ const w = mount(DatePicker, {
498
+ props: { label: 'Date Field', modelValue: '', format: 'DD/MM/YYYY', disablePickerInteraction: true },
499
+ })
500
+ const input = w.find('input')
501
+ await input.setValue('01/01/2023')
502
+ await input.trigger('blur')
503
+ await nextTick()
504
+ const emitted = w.emitted('update:modelValue')
505
+ expect(emitted).toBeTruthy()
506
+ expect(emitted && emitted[0]?.[0]).toBe('01/01/2023')
507
+ w.unmount()
508
+ })
509
+
510
+ it('synchronise selectedDates après saisie manuelle', async () => {
511
+ const input = evWrapper.find('input')
512
+ await input.setValue('01/01/2023')
513
+ await input.trigger('blur')
514
+ await nextTick()
515
+ expect(evWrapper.vm.selectedDates).not.toBeNull()
516
+ const d = evWrapper.vm.selectedDates
517
+ expect(d instanceof Date).toBe(true)
518
+ expect(d.getFullYear()).toBe(2023)
519
+ expect(d.getMonth()).toBe(0)
520
+ expect(d.getDate()).toBe(1)
521
+ })
522
+
523
+ it('accepte le format YYYY-MM-DD', async () => {
524
+ const w = mount(DatePicker, {
525
+ props: { label: 'Date Field', modelValue: '', format: 'YYYY-MM-DD' },
526
+ })
527
+ const input = w.find('input')
528
+ await input.setValue('2023-01-01')
529
+ await input.trigger('blur')
530
+ await nextTick()
531
+ const emitted = w.emitted('update:modelValue')
532
+ expect(emitted).toBeTruthy()
533
+ expect(emitted && emitted[0]?.[0]).toBe('2023-01-01')
534
+ w.unmount()
535
+ })
536
+
537
+ it('accepte les plages de dates en entrée', async () => {
538
+ const w = mount(DatePicker, {
539
+ props: { label: 'Date Field', modelValue: ['01/01/2023', '05/01/2023'], format: 'DD/MM/YYYY', displayRange: true },
540
+ })
541
+ await nextTick()
542
+ expect(w.find('input').element.value).toContain('01/01/2023')
543
+ expect(w.props('displayRange')).toBe(true)
544
+ w.unmount()
545
+ })
546
+
547
+ it('handleInputKeydown ne fait rien si readonly', async () => {
548
+ const w = mount(DatePicker, {
549
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', readonly: true },
550
+ })
551
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
552
+ ;(w.vm as any).handleInputKeydown(new KeyboardEvent('keydown', { key: 'Enter' }))
553
+ await nextTick()
554
+ expect(w.vm.isDatePickerVisible).toBe(false)
555
+ w.unmount()
556
+ })
557
+
558
+ it('handleInputKeydown Escape ferme le calendrier', async () => {
559
+ evWrapper.vm.isDatePickerVisible = true
560
+ await nextTick()
561
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
562
+ ;(evWrapper.vm as any).handleInputKeydown(new KeyboardEvent('keydown', { key: 'Escape' }))
563
+ await nextTick()
564
+ expect(evWrapper.vm.isDatePickerVisible).toBe(false)
565
+ })
566
+
567
+ it('onUpdateMonth met à jour currentMonth et currentMonthName', async () => {
568
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
569
+ ;(evWrapper.vm as any).onUpdateMonth('5')
570
+ await nextTick()
571
+ expect(evWrapper.vm.currentMonth).toBe('5')
572
+ expect(evWrapper.vm.currentMonthName).toBeTruthy()
573
+ })
574
+
575
+ it('onUpdateYear met à jour currentYear', async () => {
576
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
577
+ ;(evWrapper.vm as any).onUpdateYear('2030')
578
+ await nextTick()
579
+ expect(evWrapper.vm.currentYear).toBe('2030')
580
+ })
581
+
582
+ it('openDatePickerOnFocus émet focus', async () => {
583
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
584
+ ;(evWrapper.vm as any).openDatePickerOnFocus()
585
+ await nextTick()
586
+ expect(evWrapper.emitted('focus')).toBeTruthy()
587
+ })
588
+
589
+ it('openDatePickerOnIconClick ne fait rien si disabled', async () => {
590
+ const w = mount(DatePicker, {
591
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', disabled: true },
592
+ })
593
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
594
+ ;(w.vm as any).openDatePickerOnIconClick()
595
+ await nextTick()
596
+ expect(w.vm.isDatePickerVisible).toBe(false)
597
+ w.unmount()
598
+ })
599
+
600
+ it('openDatePickerOnIconClick ne fait rien si readonly', async () => {
601
+ const w = mount(DatePicker, {
602
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', readonly: true },
603
+ })
604
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
605
+ ;(w.vm as any).openDatePickerOnIconClick()
606
+ await nextTick()
607
+ expect(w.vm.isDatePickerVisible).toBe(false)
608
+ w.unmount()
609
+ })
610
+
611
+ it('valide les dates selon les règles personnalisées', async () => {
612
+ const w = mount(DatePicker, {
613
+ props: {
614
+ label: 'Date Field',
615
+ modelValue: '',
616
+ format: 'DD/MM/YYYY',
617
+ customRules: [{ type: 'isDateValid', options: {} }],
618
+ required: true,
619
+ },
620
+ })
621
+ await w.vm.validateOnSubmit()
622
+ await nextTick()
623
+ expect(w.vm.errorMessages.length).toBeGreaterThan(0)
624
+ w.unmount()
625
+ })
626
+ })
627
+
628
+ describe('DatePicker - Coverage branches', () => {
629
+ it('handleSelectToday selects today range when displayRange=true', async () => {
630
+ const w = mount(DatePicker, {
631
+ props: { label: 'Date', modelValue: undefined, format: 'DD/MM/YYYY', displayRange: true },
632
+ })
633
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
634
+ await (w.vm as any).handleSelectToday()
635
+ await flushPromises()
636
+ const selected = w.vm.selectedDates
637
+ expect(Array.isArray(selected)).toBe(true)
638
+ const emitted = w.emitted('update:modelValue')
639
+ expect(emitted).toBeTruthy()
640
+ w.unmount()
641
+ })
642
+
643
+ it('validateOnSubmit delegates to dateTextInputRef when noCalendar', async () => {
644
+ const w = mount(DatePicker, {
645
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', noCalendar: true, required: true },
646
+ })
647
+ const result = await w.vm.validateOnSubmit()
648
+ expect(typeof result === 'boolean' || result === undefined).toBe(true)
649
+ w.unmount()
650
+ })
651
+
652
+ it('validateOnSubmit delegates to complexDatePickerRef when useCombinedMode', async () => {
653
+ const w = mount(DatePicker, {
654
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', useCombinedMode: true, required: true },
655
+ })
656
+ const result = await w.vm.validateOnSubmit()
657
+ expect(typeof result === 'boolean' || result === undefined).toBe(true)
658
+ w.unmount()
659
+ })
660
+
661
+ it('handleInputKeydown Enter opens the date picker', async () => {
662
+ const w = mount(DatePicker, {
663
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY' },
664
+ })
665
+ expect(w.vm.isDatePickerVisible).toBe(false)
666
+ const event = new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })
667
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
668
+ await (w.vm as any).handleInputKeydown(event)
669
+ await nextTick()
670
+ expect(w.vm.isDatePickerVisible).toBe(true)
671
+ w.unmount()
672
+ })
673
+
674
+ it('handleInputBlur emits blur and validates', async () => {
675
+ const w = mount(DatePicker, {
676
+ props: { label: 'Date', modelValue: '01/01/2023', format: 'DD/MM/YYYY', required: true, isValidateOnBlur: true },
677
+ })
678
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
679
+ await (w.vm as any).handleInputBlur()
680
+ await flushPromises()
681
+ expect(w.emitted('blur')).toBeTruthy()
682
+ w.unmount()
683
+ })
684
+
685
+ it('handleInputBlur skips validation when isValidateOnBlur=false', async () => {
686
+ const w = mount(DatePicker, {
687
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY', required: true, isValidateOnBlur: false },
688
+ })
689
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
690
+ await (w.vm as any).handleInputBlur()
691
+ await flushPromises()
692
+ expect(w.emitted('blur')).toBeTruthy()
693
+ expect(w.vm.errorMessages.length).toBe(0)
694
+ w.unmount()
695
+ })
696
+
697
+ it('syncDisplayedMonthYearFromDate updates currentMonth and currentMonthName', async () => {
698
+ const w = mount(DatePicker, {
699
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY' },
700
+ })
701
+ w.vm.isDatePickerVisible = true
702
+ await nextTick()
703
+ const date = new Date(2024, 5, 15)
704
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
705
+ ;(w.vm as any).syncDisplayedMonthYearFromDate(date)
706
+ await nextTick()
707
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
708
+ expect((w.vm as any).currentMonth).toBe('5')
709
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
710
+ expect((w.vm as any).currentMonthName).toBeTruthy()
711
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
712
+ expect((w.vm as any).currentYear).toBe('2024')
713
+ w.unmount()
714
+ })
715
+
716
+ it('handleDateTextInputUpdate with null clears selectedDates', async () => {
717
+ const w = mount(DatePicker, {
718
+ props: { label: 'Date', modelValue: '01/01/2023', format: 'DD/MM/YYYY' },
719
+ })
720
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
721
+ await (w.vm as any).handleDateTextInputUpdate(null)
722
+ await flushPromises()
723
+ expect(w.vm.selectedDates).toBeNull()
724
+ w.unmount()
725
+ })
726
+
727
+ it('handleDateTextInputUpdate with array range sets selectedDates', async () => {
728
+ const w = mount(DatePicker, {
729
+ props: { label: 'Date', modelValue: undefined, format: 'DD/MM/YYYY', displayRange: true },
730
+ })
731
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
732
+ await (w.vm as any).handleDateTextInputUpdate(['01/01/2023', '05/01/2023'])
733
+ await flushPromises()
734
+ expect(w.vm.selectedDates).not.toBeNull()
735
+ expect(Array.isArray(w.vm.selectedDates)).toBe(true)
736
+ w.unmount()
737
+ })
738
+
739
+ it('watcher selectedDates resets currentMonthName to today when cleared', async () => {
740
+ const w = mount(DatePicker, {
741
+ props: { label: 'Date', modelValue: '01/06/2024', format: 'DD/MM/YYYY' },
742
+ })
743
+ await flushPromises()
744
+ w.vm.selectedDates = null
745
+ await nextTick()
746
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
747
+ expect((w.vm as any).currentMonthName).toBeTruthy()
748
+ w.unmount()
749
+ })
750
+
751
+ it('modelValue watcher syncs noCalendar from string (branch coverage)', async () => {
752
+ const w = mount(DatePicker, {
753
+ props: { label: 'Date', modelValue: '10/01/2024', format: 'DD/MM/YYYY', noCalendar: true },
754
+ })
755
+ await flushPromises()
756
+ await w.setProps({ modelValue: '15/03/2024' })
757
+ await flushPromises()
758
+ expect(w.exists()).toBe(true)
759
+ w.unmount()
760
+ })
761
+
762
+ it('modelValue watcher clears textInputValue when null in noCalendar mode', async () => {
763
+ const w = mount(DatePicker, {
764
+ props: { label: 'Date', modelValue: '15/03/2024', format: 'DD/MM/YYYY', noCalendar: true },
765
+ })
766
+ await flushPromises()
767
+ await w.setProps({ modelValue: '' })
768
+ await flushPromises()
769
+ expect(w.find('input').element.value).toBe('')
770
+ w.unmount()
771
+ })
772
+
773
+ it('handleClickOutside does nothing when calendar is closed', () => {
774
+ const w = mount(DatePicker, {
775
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY' },
776
+ })
777
+ const vm = w.vm as InstanceType<typeof DatePicker>
778
+ vm.isDatePickerVisible = false
779
+ const outside = document.createElement('div')
780
+ vm.handleClickOutside({ target: outside } as unknown as MouseEvent)
781
+ expect(w.emitted('closed')).toBeFalsy()
782
+ w.unmount()
783
+ })
784
+
785
+ it('handleClickOutside does nothing when click inside container', () => {
786
+ const w = mount(DatePicker, {
787
+ props: { label: 'Date', modelValue: '', format: 'DD/MM/YYYY' },
788
+ })
789
+ const vm = w.vm as InstanceType<typeof DatePicker>
790
+ vm.isDatePickerVisible = true
791
+ const container = w.find('.date-picker-container').element
792
+ vm.handleClickOutside({ target: container } as unknown as MouseEvent)
793
+ expect(w.emitted('closed')).toBeFalsy()
794
+ w.unmount()
795
+ })
796
+ })