@cnamts/synapse 1.0.1 → 1.0.2

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 (217) hide show
  1. package/README.md +1 -1
  2. package/dist/{DateFilter-BmRuzQ9Z.js → DateFilter-YWOTbfeL.js} +1 -1
  3. package/dist/{NumberFilter-CnIPDHqx.js → NumberFilter-DMmMgALM.js} +1 -1
  4. package/dist/{PeriodFilter-CZwZ8CnQ.js → PeriodFilter-Bok5BHcn.js} +1 -1
  5. package/dist/SelectFilter-BKud2WhN.js +136 -0
  6. package/dist/{TextFilter-DTxZHJwX.js → TextFilter-DvMf2thH.js} +1 -1
  7. package/dist/components/Accordion/Accordion.d.ts +2 -1
  8. package/dist/components/Accordion/composables/useAccordionGroupCommunication.d.ts +5 -0
  9. package/dist/components/Accordion/composables/useAccordionKeyboardNavigation.d.ts +12 -0
  10. package/dist/components/Accordion/composables/useAccordionState.d.ts +13 -0
  11. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +85 -0
  12. package/dist/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
  13. package/dist/components/Customs/SySelect/SySelect.d.ts +33 -13
  14. package/dist/components/Customs/SyTextField/SyTextField.d.ts +2 -2
  15. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +1585 -1452
  16. package/dist/components/DatePicker/DatePicker/DatePicker.d.ts +16 -2
  17. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +3 -1
  18. package/dist/components/DatePicker/composables/index.d.ts +2 -0
  19. package/dist/components/DatePicker/composables/useAsteriskDisplay.d.ts +14 -0
  20. package/dist/components/DatePicker/composables/useDateAutoClamp.d.ts +16 -0
  21. package/dist/components/DatePicker/composables/useDateRangeInput.d.ts +1 -1
  22. package/dist/components/DatePicker/composables/useDisplayedDateString.d.ts +3 -0
  23. package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +1 -0
  24. package/dist/components/DatePicker/composables/useMonthButtonCustomization.d.ts +5 -2
  25. package/dist/components/NirField/NirField.d.ts +7 -3
  26. package/dist/components/NirField/nirValidation.d.ts +1 -1
  27. package/dist/components/PasswordField/PasswordField.d.ts +2 -0
  28. package/dist/components/PeriodField/PeriodField.d.ts +52 -8
  29. package/dist/components/PhoneField/PhoneField.d.ts +2 -2
  30. package/dist/components/RangeField/RangeField.d.ts +2 -0
  31. package/dist/components/SearchListField/SearchListField.d.ts +9 -0
  32. package/dist/components/SyTextArea/SyTextArea.d.ts +2 -0
  33. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +14 -9
  34. package/dist/components/Tables/SyTable/SyTable.d.ts +12 -7
  35. package/dist/components/Tables/common/SyTablePagination.d.ts +1636 -0
  36. package/dist/components/Tables/common/TableHeader.d.ts +2 -20
  37. package/dist/components/Tables/common/filters/SelectFilter.d.ts +5 -5
  38. package/dist/components/Tables/common/filters/getFilterComponent.d.ts +1 -0
  39. package/dist/components/Tables/common/filters/locales.d.ts +4 -0
  40. package/dist/components/Tables/common/filters/logics/date.d.ts +1 -0
  41. package/dist/components/Tables/common/filters/logics/number.d.ts +1 -0
  42. package/dist/components/Tables/common/filters/logics/period.d.ts +1 -0
  43. package/dist/components/Tables/common/filters/logics/select.d.ts +1 -0
  44. package/dist/components/Tables/common/filters/logics/text.d.ts +1 -0
  45. package/dist/components/Tables/common/locales.d.ts +21 -0
  46. package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +267 -0
  47. package/dist/components/Tables/common/organizeColumns/sortHeaders.d.ts +2 -0
  48. package/dist/components/Tables/common/tableFilterUtils.d.ts +1 -0
  49. package/dist/components/Tables/common/tableStorageUtils.d.ts +41 -1
  50. package/dist/components/Tables/common/tableUtils.d.ts +42 -5
  51. package/dist/components/Tables/common/types.d.ts +19 -8
  52. package/dist/components/Tables/common/usePagination.d.ts +22 -0
  53. package/dist/components/Tables/common/useTableCheckbox.d.ts +20 -0
  54. package/dist/components/Tables/common/useTableHeaders.d.ts +76 -0
  55. package/dist/components/Tables/common/useTableItems.d.ts +24 -0
  56. package/dist/components/Tables/common/useTableOptions.d.ts +18 -0
  57. package/dist/components/ToolbarContainer/ToolbarContainer.d.ts +11 -0
  58. package/dist/components/UserMenuBtn/UserMenuBtn.d.ts +9 -2
  59. package/dist/components/index.d.ts +8 -6
  60. package/dist/design-system-v3.js +58 -56
  61. package/dist/design-system-v3.umd.cjs +22 -22
  62. package/dist/main-Cx8qG7YR.js +16344 -0
  63. package/dist/stories/Accessibilite/Vuetify/VuetifyItems.d.ts +14 -2
  64. package/dist/stories/DesignTokens/StylesTypographiques.stories.new.d.ts +8 -0
  65. package/dist/stories/DesignTokens/TypographyDisplay.d.ts +28 -0
  66. package/dist/stories/DesignTokens/vue-shims.d.ts +6 -0
  67. package/dist/style.css +1 -1
  68. package/package.json +1 -1
  69. package/src/common/imgs/accessibility-svgrepo-com.svg +4 -0
  70. package/src/components/Accordion/Accessibilite/AccessibilityGuide.mdx +249 -0
  71. package/src/components/Accordion/Accordion.vue +48 -76
  72. package/src/components/Accordion/composables/__tests__/useAccordionGroupCommunication.spec.ts +146 -0
  73. package/src/components/Accordion/composables/__tests__/useAccordionKeyboardNavigation.spec.ts +209 -0
  74. package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +144 -0
  75. package/src/components/Accordion/composables/useAccordionGroupCommunication.ts +52 -0
  76. package/src/components/Accordion/composables/useAccordionKeyboardNavigation.ts +111 -0
  77. package/src/components/Accordion/composables/useAccordionState.ts +59 -0
  78. package/src/components/Accordion/tests/__snapshots__/accordion.spec.ts.snap +3 -0
  79. package/src/components/Customs/SyCheckbox/Accessibilite.mdx +303 -0
  80. package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +50 -0
  81. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +630 -0
  82. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +326 -0
  83. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +201 -0
  84. package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +1 -0
  85. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +8 -1
  86. package/src/components/Customs/SySelect/SySelect.stories.ts +160 -0
  87. package/src/components/Customs/SySelect/SySelect.vue +291 -32
  88. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +230 -0
  89. package/src/components/Customs/SyTextField/SyTextField.stories.ts +3 -2
  90. package/src/components/Customs/SyTextField/SyTextField.vue +19 -8
  91. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +241 -31
  92. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +305 -57
  93. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.events.spec.ts +161 -0
  94. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +4 -2
  95. package/src/components/DatePicker/DatePicker/DatePicker.stories.ts +259 -137
  96. package/src/components/DatePicker/DatePicker/DatePicker.vue +153 -25
  97. package/src/components/DatePicker/DatePicker/tests/DatePicker.events.spec.ts +189 -0
  98. package/src/components/DatePicker/DatePicker/{DatePicker.spec.ts → tests/DatePicker.spec.ts} +1 -15
  99. package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +24 -14
  100. package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +148 -0
  101. package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +3 -1
  102. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +200 -5
  103. package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +241 -31
  104. package/src/components/DatePicker/composables/index.ts +2 -0
  105. package/src/components/DatePicker/composables/tests/useDateAutoClamp.spec.ts +190 -0
  106. package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +182 -4
  107. package/src/components/DatePicker/composables/tests/useMonthButtonCustomization.spec.ts +105 -80
  108. package/src/components/DatePicker/composables/useAsteriskDisplay.ts +31 -0
  109. package/src/components/DatePicker/composables/useDateAutoClamp.ts +136 -0
  110. package/src/components/DatePicker/composables/useDateRangeInput.ts +21 -18
  111. package/src/components/DatePicker/composables/useDisplayedDateString.ts +13 -1
  112. package/src/components/DatePicker/composables/useInputBlurHandler.ts +84 -20
  113. package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +149 -51
  114. package/src/components/DiacriticPicker/DiacriticPicker.stories.ts +10 -0
  115. package/src/components/ErrorPage/Accessibilite.stories.ts +8 -0
  116. package/src/components/ErrorPage/ErrorPage.vue +12 -6
  117. package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +4 -4
  118. package/src/components/NirField/NirField.mdx +22 -9
  119. package/src/components/NirField/NirField.stories.ts +26 -2
  120. package/src/components/NirField/NirField.vue +209 -22
  121. package/src/components/NirField/nirValidation.ts +17 -3
  122. package/src/components/NirField/tests/NirField.spec.ts +2 -2
  123. package/src/components/NotFoundPage/Accessibilite.stories.ts +8 -0
  124. package/src/components/NotFoundPage/NotFoundPage.vue +2 -1
  125. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +8 -6
  126. package/src/components/PaginatedTable/PaginatedTable.mdx +2 -0
  127. package/src/components/PasswordField/PasswordField.stories.ts +4 -0
  128. package/src/components/PasswordField/PasswordField.vue +3 -0
  129. package/src/components/PeriodField/PeriodField.vue +2 -0
  130. package/src/components/PhoneField/PhoneField.stories.ts +15 -15
  131. package/src/components/PhoneField/PhoneField.vue +1 -1
  132. package/src/components/RangeField/RangeField.stories.ts +9 -0
  133. package/src/components/RangeField/RangeField.vue +4 -0
  134. package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +12 -0
  135. package/src/components/SearchListField/SearchListField.vue +5 -0
  136. package/src/components/SyTextArea/SyTextArea.vue +3 -0
  137. package/src/components/SyTextArea/tests/SyTextArea.spec.ts +0 -1
  138. package/src/components/Tables/SyServerTable/FilterRules.stories.ts +632 -15
  139. package/src/components/Tables/SyServerTable/SyServerTable.mdx +15 -5
  140. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +2844 -1377
  141. package/src/components/Tables/SyServerTable/SyServerTable.vue +155 -66
  142. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +256 -4
  143. package/src/components/Tables/SyTable/FilterRules.stories.ts +183 -0
  144. package/src/components/Tables/SyTable/SyTable.mdx +14 -4
  145. package/src/components/Tables/SyTable/SyTable.stories.ts +1265 -477
  146. package/src/components/Tables/SyTable/SyTable.vue +152 -72
  147. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +366 -4
  148. package/src/components/Tables/common/SyTableFilter.vue +3 -56
  149. package/src/components/Tables/common/SyTablePagination.vue +375 -0
  150. package/src/components/Tables/common/TableHeader.vue +10 -26
  151. package/src/components/Tables/common/filters/SelectFilter.vue +131 -22
  152. package/src/components/Tables/common/filters/getFilterComponent.ts +54 -0
  153. package/src/components/Tables/common/filters/locales.ts +4 -0
  154. package/src/components/Tables/common/filters/logics/date.ts +12 -0
  155. package/src/components/Tables/common/filters/logics/number.ts +48 -0
  156. package/src/components/Tables/common/filters/logics/period.ts +25 -0
  157. package/src/components/Tables/common/filters/logics/select.ts +27 -0
  158. package/src/components/Tables/common/filters/logics/tests/TextFilterLogic.spec.ts +177 -0
  159. package/src/components/Tables/common/filters/logics/text.ts +62 -0
  160. package/src/components/Tables/common/filters/tests/TextFilter.spec.ts +11 -11
  161. package/src/components/Tables/common/locales.ts +24 -0
  162. package/src/components/Tables/common/organizeColumns/OrganizeColumns.vue +269 -0
  163. package/src/components/Tables/common/organizeColumns/sortHeaders.ts +9 -0
  164. package/src/components/Tables/common/tableFilterUtils.ts +43 -295
  165. package/src/components/Tables/common/tableStorageUtils.ts +27 -2
  166. package/src/components/Tables/common/tableStyles.scss +26 -0
  167. package/src/components/Tables/common/tableUtils.ts +3 -16
  168. package/src/components/Tables/common/tests/SyTablePagination.spec.ts +170 -0
  169. package/src/components/Tables/common/tests/filterByRange.spec.ts +215 -0
  170. package/src/components/Tables/common/tests/tableFilterUtils.spec.ts +0 -14
  171. package/src/components/Tables/common/tests/tableUtils.spec.ts +7 -51
  172. package/src/components/Tables/common/types.ts +17 -6
  173. package/src/components/Tables/common/usePagination.ts +83 -0
  174. package/src/components/Tables/common/useTableCheckbox.ts +58 -0
  175. package/src/components/Tables/common/useTableHeaders.ts +88 -0
  176. package/src/components/Tables/common/useTableItems.ts +87 -0
  177. package/src/components/Tables/common/useTableOptions.ts +93 -0
  178. package/src/components/ToolbarContainer/ToolbarContainer.mdx +16 -0
  179. package/src/components/ToolbarContainer/ToolbarContainer.stories.ts +675 -0
  180. package/src/components/ToolbarContainer/ToolbarContainer.vue +128 -0
  181. package/src/components/ToolbarContainer/tests/ToolbarContainer.spec.ts +156 -0
  182. package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +74 -0
  183. package/src/components/UserMenuBtn/UserMenuBtn.vue +19 -17
  184. package/src/components/index.ts +8 -6
  185. package/src/stories/Accessibilite/Aculturation/AuditDesignSystem.mdx +293 -20
  186. package/src/stories/Accessibilite/Aculturation/SensibilisationAccessibilite.mdx +448 -54
  187. package/src/stories/Accessibilite/Audit/RGAA.mdx +231 -23
  188. package/src/stories/Accessibilite/Avancement/Avancement.mdx +591 -7
  189. package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +139 -38
  190. package/src/stories/Accessibilite/Introduction.mdx +258 -18
  191. package/src/stories/Accessibilite/KitDePreAudit/Echantillonnage.mdx +221 -31
  192. package/src/stories/Accessibilite/KitDePreAudit/Introduction.mdx +204 -22
  193. package/src/stories/Accessibilite/KitDePreAudit/Outils/Introduction.mdx +537 -24
  194. package/src/stories/Accessibilite/KitDePreAudit/Outils/LecteursDEcran.mdx +577 -70
  195. package/src/stories/Accessibilite/KitDePreAudit/Outils/Tanaguru.mdx +382 -31
  196. package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +419 -81
  197. package/src/stories/Accessibilite/Vuetify/Vuetify.mdx +132 -6
  198. package/src/stories/Accessibilite/Vuetify/Vuetify.stories.ts +370 -146
  199. package/src/stories/Accessibilite/Vuetify/VuetifyItems.ts +35 -57
  200. package/src/stories/Demarrer/Accueil.stories.ts +20 -5
  201. package/src/stories/DesignTokens/StylesTypographiques.mdx +10 -9
  202. package/src/stories/DesignTokens/StylesTypographiques.stories.new.ts +397 -0
  203. package/src/stories/DesignTokens/StylesTypographiques.stories.ts +397 -0
  204. package/src/stories/DesignTokens/TypographyDisplay.vue +155 -0
  205. package/src/stories/DesignTokens/vue-shims.d.ts +6 -0
  206. package/src/stories/GuideDuDev/LesBreackingChanges.mdx +0 -2
  207. package/src/stories/GuideDuDev/MigrationDepuisBridge.mdx +1 -1
  208. package/src/stories/GuideDuDev/MigrationDepuisVue2.mdx +1 -1
  209. package/src/stories/GuideDuDev/PortailAgent.mdx +10 -0
  210. package/src/stories/GuideDuDev/PortailAgent.stories.ts +506 -0
  211. package/src/stories/GuideDuDev/Theme.mdx +41 -0
  212. package/dist/SelectFilter-Cj-GW2Cc.js +0 -97
  213. package/dist/main-WDqeoGM-.js +0 -14788
  214. package/src/components/PaginatedTable/tests/__snapshots__/PaginatedTable.spec.ts.snap +0 -886
  215. package/src/components/Tables/SyServerTable/tests/__snapshots__/SyServerTable.spec.ts.snap +0 -521
  216. package/src/components/Tables/SyTable/tests/__snapshots__/SyTable.spec.ts.snap +0 -521
  217. package/src/stories/DesignTokens/ThemePA.mdx +0 -35
@@ -0,0 +1,148 @@
1
+ import { mount } from '@vue/test-utils'
2
+ import { describe, it, expect, beforeEach } from 'vitest'
3
+ import { vuetify } from '@tests/unit/setup'
4
+ import { nextTick } from 'vue'
5
+ import DateTextInput from './DateTextInput.vue'
6
+
7
+ describe('DateTextInput.vue - Events', () => {
8
+ let wrapper
9
+
10
+ beforeEach(() => {
11
+ wrapper = mount(DateTextInput, {
12
+ global: {
13
+ plugins: [vuetify],
14
+ },
15
+ props: {
16
+ modelValue: '',
17
+ format: 'DD/MM/YYYY',
18
+ },
19
+ })
20
+ })
21
+
22
+ it('émet update:model-value lors de la saisie d\'une date valide', async () => {
23
+ const input = wrapper.find('input')
24
+ await input.setValue('01/01/2023')
25
+ await input.trigger('blur')
26
+
27
+ expect(wrapper.emitted('update:model-value')).toBeTruthy()
28
+ expect(wrapper.emitted('update:model-value')[0]).toEqual(['01/01/2023'])
29
+ })
30
+
31
+ it('émet date-selected lors de la sélection d\'une date valide', async () => {
32
+ const input = wrapper.find('input')
33
+ await input.setValue('01/01/2023')
34
+ await input.trigger('blur')
35
+
36
+ expect(wrapper.emitted('date-selected')).toBeTruthy()
37
+ expect(wrapper.emitted('date-selected')[0]).toEqual(['01/01/2023'])
38
+ })
39
+
40
+ it('émet focus lors du focus sur l\'input', async () => {
41
+ const input = wrapper.find('input')
42
+ await input.trigger('focus')
43
+
44
+ expect(wrapper.emitted('focus')).toBeTruthy()
45
+ })
46
+
47
+ it('émet blur lors de la perte de focus', async () => {
48
+ const input = wrapper.find('input')
49
+ await input.trigger('focus')
50
+ await input.trigger('blur')
51
+
52
+ expect(wrapper.emitted('blur')).toBeTruthy()
53
+ })
54
+
55
+ it('émet input lors de la saisie', async () => {
56
+ const input = wrapper.find('input')
57
+ await input.setValue('01/01')
58
+
59
+ // Dans l'implémentation réelle, l'événement peut être nommé différemment ou géré autrement
60
+ // Vérifions plutôt que la valeur est correctement mise à jour
61
+ expect(input.element.value).toContain('01/01')
62
+ })
63
+
64
+ it('formate automatiquement la date pendant la saisie', async () => {
65
+ const input = wrapper.find('input')
66
+
67
+ // Simuler la saisie de chiffres sans séparateurs
68
+ await input.setValue('0101')
69
+ await nextTick()
70
+
71
+ // Vérifier que le séparateur a été ajouté automatiquement
72
+ // Le composant peut ajouter des placeholders (_) pour les parties manquantes
73
+ expect(input.element.value).toContain('01/01')
74
+ })
75
+
76
+ it('supporte différents séparateurs selon le format', async () => {
77
+ const wrapperWithDashFormat = mount(DateTextInput, {
78
+ global: {
79
+ plugins: [vuetify],
80
+ },
81
+ props: {
82
+ modelValue: '',
83
+ format: 'YYYY-MM-DD',
84
+ },
85
+ })
86
+
87
+ const input = wrapperWithDashFormat.find('input')
88
+
89
+ // Simuler la saisie de chiffres sans séparateurs
90
+ await input.setValue('2023')
91
+ await nextTick()
92
+
93
+ // Vérifier que le bon séparateur a été ajouté automatiquement
94
+ // Le composant peut ajouter des placeholders (_) pour les parties manquantes
95
+ expect(input.element.value).toContain('2023-')
96
+ })
97
+
98
+ it('gère correctement les plages de dates', async () => {
99
+ const wrapperWithRange = mount(DateTextInput, {
100
+ global: {
101
+ plugins: [vuetify],
102
+ },
103
+ props: {
104
+ modelValue: '',
105
+ format: 'DD/MM/YYYY',
106
+ displayRange: true,
107
+ },
108
+ })
109
+
110
+ const input = wrapperWithRange.find('input')
111
+
112
+ // Simuler la saisie d'une plage de dates
113
+ await input.setValue('01/01/2023 - 05/01/2023')
114
+ await input.trigger('blur')
115
+
116
+ // Vérifier que l'événement est émis avec un tableau de deux dates
117
+ const emitted = wrapperWithRange.emitted('update:model-value')
118
+ expect(emitted).toBeTruthy()
119
+ expect(emitted && emitted[0][0]).toEqual(['01/01/2023', '05/01/2023'])
120
+ })
121
+
122
+ it('valide les dates selon les règles personnalisées', async () => {
123
+ const customRule = {
124
+ type: 'isDateValid',
125
+ options: {},
126
+ }
127
+
128
+ const wrapperWithRules = mount(DateTextInput, {
129
+ global: {
130
+ plugins: [vuetify],
131
+ },
132
+ props: {
133
+ modelValue: '',
134
+ format: 'DD/MM/YYYY',
135
+ customRules: [customRule],
136
+ required: true,
137
+ },
138
+ })
139
+
140
+ const input = wrapperWithRules.find('input')
141
+ await input.setValue('')
142
+ await input.trigger('blur')
143
+
144
+ // Vérifier qu'une erreur de validation est affichée
145
+ await nextTick()
146
+ expect(wrapperWithRules.find('.v-messages__message').exists()).toBe(true)
147
+ })
148
+ })
@@ -38,7 +38,7 @@ describe('DateTextInput.vue', () => {
38
38
  await input.trigger('blur')
39
39
  await wrapper.vm.$nextTick()
40
40
  const textField = wrapper.findComponent(SyTextField)
41
- console.log(textField.props('errorMessages'))
41
+
42
42
  expect(textField.props('errorMessages')).toContain('Format de date invalide (DD/MM/YYYY)')
43
43
  })
44
44
 
@@ -135,6 +135,8 @@ describe('DateTextInput.vue', () => {
135
135
  })
136
136
 
137
137
  it('handles invalid dates correctly', async () => {
138
+ // Désactiver l'autoClamp pour ce test spécifique
139
+ await wrapper.setProps({ autoClamp: false })
138
140
  const input = wrapper.find('input')
139
141
  await input.setValue('31/02/2025')
140
142
  await input.trigger('blur')
@@ -5,7 +5,7 @@
5
5
  import { useValidation, type ValidationRule, type ValidationResult } from '@/composables/validation/useValidation'
6
6
  import dayjs from 'dayjs'
7
7
  import customParseFormat from 'dayjs/plugin/customParseFormat'
8
- import { useDateRangeInput, useDateRangeValidation, useDateFormatValidation, useDateValidation, useDateInputEditing, useManualDateValidation } from '../composables'
8
+ import { useDateRangeInput, useDateRangeValidation, useDateFormatValidation, useDateValidation, useDateInputEditing, useManualDateValidation, useDateAutoClamp } from '../composables'
9
9
  import { type DateObjectValue } from '../types'
10
10
  import { useDateFormat } from '@/composables/date/useDateFormatDayjs'
11
11
  import { type DateValue } from '@/composables/date/useDateInitializationDayjs'
@@ -34,6 +34,7 @@
34
34
  showSuccessMessages?: boolean
35
35
  bgColor?: string
36
36
  displayRange?: boolean
37
+ autoClamp?: boolean
37
38
  }>(), {
38
39
  modelValue: null,
39
40
  placeholder: DATE_PICKER_MESSAGES.PLACEHOLDER_DEFAULT,
@@ -52,8 +53,9 @@
52
53
  displayPrependIcon: true,
53
54
  disableErrorHandling: false,
54
55
  showSuccessMessages: true,
55
- bgColor: undefined,
56
+ bgColor: 'white',
56
57
  displayRange: false,
58
+ autoClamp: true,
57
59
  })
58
60
 
59
61
  const emit = defineEmits<{
@@ -127,6 +129,9 @@
127
129
  // Utilisation des composables pour la gestion des plages de dates
128
130
  const { parseDate, formatDate } = useDateFormat()
129
131
 
132
+ // Utilisation du composable pour l'auto-clamping des dates invalides
133
+ const { autoClampDate } = useDateAutoClamp()
134
+
130
135
  // Référence pour stocker les dates sélectionnées (pour le mode plage)
131
136
  const selectedDates = ref<DateObjectValue>(null)
132
137
 
@@ -388,11 +393,101 @@
388
393
  return
389
394
  }
390
395
 
396
+ // Appliquer l'auto-clamping si activé
397
+ if (props.autoClamp) {
398
+ // Pour les plages de dates, traiter chaque partie séparément
399
+ if (props.displayRange && newValue.includes(' - ')) {
400
+ const parts = newValue.split(' - ')
401
+ const startDateStr = parts[0]?.trim() || ''
402
+ const endDateStr = parts[1]?.trim() || ''
403
+
404
+ // Appliquer l'auto-clamping à chaque partie si nécessaire
405
+ let adjusted = false
406
+ let clampedStart = startDateStr
407
+ let clampedEnd = endDateStr
408
+
409
+ if (startDateStr) {
410
+ const startResult = autoClampDate(startDateStr, props.format)
411
+ if (startResult.adjusted) {
412
+ clampedStart = startResult.clampedDate
413
+ adjusted = true
414
+ }
415
+ }
416
+
417
+ if (endDateStr) {
418
+ const endResult = autoClampDate(endDateStr, props.format)
419
+ if (endResult.adjusted) {
420
+ clampedEnd = endResult.clampedDate
421
+ adjusted = true
422
+ }
423
+ }
424
+
425
+ // Si un ajustement a été fait, mettre à jour la valeur
426
+ if (adjusted) {
427
+ const clampedValue = clampedEnd
428
+ ? `${clampedStart} - ${clampedEnd}`
429
+ : clampedStart
430
+ newValue = clampedValue
431
+ inputValue.value = clampedValue
432
+
433
+ // Mettre à jour le modèle avec les dates ajustées
434
+ const startDate = clampedStart ? parseDate(clampedStart, props.format) : null
435
+ const endDate = clampedEnd ? parseDate(clampedEnd, props.format) : null
436
+
437
+ if (startDate) {
438
+ // Mettre à jour les dates sélectionnées
439
+ if (endDate) {
440
+ selectedDates.value = [startDate, endDate]
441
+
442
+ // Formater les dates pour le modèle
443
+ const format = props.dateFormatReturn || props.format
444
+ const formattedStartDate = formatDate(startDate, format)
445
+ const formattedEndDate = formatDate(endDate, format)
446
+
447
+ // Émettre la plage de dates mise à jour
448
+ emit('update:model-value', [formattedStartDate, formattedEndDate])
449
+ }
450
+ else {
451
+ selectedDates.value = [startDate]
452
+
453
+ // Émettre la date de début mise à jour
454
+ const format = props.dateFormatReturn || props.format
455
+ const formattedStartDate = formatDate(startDate, format)
456
+ emit('update:model-value', formattedStartDate)
457
+ }
458
+ }
459
+ }
460
+ }
461
+ else {
462
+ // Pour une date unique
463
+ const result = autoClampDate(newValue, props.format)
464
+ if (result.adjusted) {
465
+ newValue = result.clampedDate
466
+ inputValue.value = result.clampedDate
467
+
468
+ // Mettre à jour le modèle avec la date ajustée
469
+ const date = parseDate(result.clampedDate, props.format)
470
+ if (date) {
471
+ const formattedDate = props.dateFormatReturn && props.dateFormatReturn !== props.format
472
+ ? formatDate(date, props.dateFormatReturn)
473
+ : formatDate(date, props.format)
474
+ emit('update:model-value', formattedDate)
475
+ }
476
+ }
477
+ }
478
+ }
479
+
391
480
  const input = inputRef.value?.$el.querySelector('input')
392
481
  const cursorPos = input?.selectionStart || 0
393
482
 
394
483
  // Utiliser le composable de plage de dates si le mode plage est activé
395
484
  if (props.displayRange) {
485
+ // S'assurer que newValue est une chaîne de caractères
486
+ if (typeof newValue !== 'string') {
487
+ // Si newValue n'est pas une chaîne, on ne peut pas appliquer le formatage
488
+ return
489
+ }
490
+
396
491
  // Appliquer le formatage automatique aux dates saisies
397
492
  const cleanedInput = newValue.replace(/[^\d]/g, '')
398
493
  let formattedInput = ''
@@ -628,7 +723,104 @@
628
723
  const handleBlur = () => {
629
724
  isFocused.value = false
630
725
  hasInteracted.value = true
631
- emit('blur')
726
+
727
+ // Vérifier si la valeur est vide
728
+ if (inputValue.value) {
729
+ const validation = validateDateFormat(inputValue.value)
730
+ if (validation.isValid) {
731
+ // Si le format est valide, la date est également valide grâce à notre correction dans useDateFormatValidation
732
+ const formattedDate = props.dateFormatReturn
733
+ ? dayjs(inputValue.value, props.format).format(props.dateFormatReturn)
734
+ : inputValue.value
735
+ emit('update:model-value', formattedDate)
736
+ }
737
+ else {
738
+ // Si le format n'est pas valide ou si la date est invalide, ajouter le message d'erreur
739
+ clearValidation()
740
+ errors.value.push(validation.message)
741
+ emit('update:model-value', props.modelValue)
742
+ }
743
+ }
744
+
745
+ // Appliquer l'auto-clamping au moment du blur si activé
746
+ if (props.autoClamp) {
747
+ // Pour les plages de dates, traiter chaque partie séparément
748
+ if (props.displayRange && inputValue.value.includes(' - ')) {
749
+ const parts = inputValue.value.split(' - ')
750
+ const startDateStr = parts[0]?.trim() || ''
751
+ const endDateStr = parts[1]?.trim() || ''
752
+
753
+ // Appliquer l'auto-clamping à chaque partie si nécessaire
754
+ let adjusted = false
755
+ let clampedStart = startDateStr
756
+ let clampedEnd = endDateStr
757
+
758
+ if (startDateStr) {
759
+ const startResult = autoClampDate(startDateStr, props.format)
760
+ if (startResult.adjusted) {
761
+ clampedStart = startResult.clampedDate
762
+ adjusted = true
763
+ }
764
+ }
765
+
766
+ if (endDateStr) {
767
+ const endResult = autoClampDate(endDateStr, props.format)
768
+ if (endResult.adjusted) {
769
+ clampedEnd = endResult.clampedDate
770
+ adjusted = true
771
+ }
772
+ }
773
+
774
+ // Si un ajustement a été fait, mettre à jour la valeur
775
+ if (adjusted) {
776
+ const clampedValue = clampedEnd
777
+ ? `${clampedStart} - ${clampedEnd}`
778
+ : clampedStart
779
+ inputValue.value = clampedValue
780
+ }
781
+ }
782
+ else {
783
+ // Pour une date unique
784
+ const result = autoClampDate(inputValue.value, props.format)
785
+ if (result.adjusted) {
786
+ inputValue.value = result.clampedDate
787
+ }
788
+ }
789
+
790
+ // Après avoir appliqué l'autoClamp, mettre à jour le modèle
791
+ if (props.displayRange) {
792
+ // Utiliser directement parseRangeInput pour analyser la plage de dates
793
+ // sans passer par handleRangeInput qui peut causer des erreurs
794
+ const [startDate, endDate] = parseRangeInput(inputValue.value)
795
+
796
+ // Mettre à jour le modèle avec les dates analysées si la plage est complète
797
+ if (startDate) {
798
+ const returnFormat = props.dateFormatReturn || props.format
799
+ if (endDate) {
800
+ // Plage complète avec deux dates
801
+ const modelValue: [string, string] = [
802
+ formatDate(startDate, returnFormat),
803
+ formatDate(endDate, returnFormat),
804
+ ]
805
+ emit('update:model-value', modelValue)
806
+ }
807
+ // Sinon, on ne met pas à jour le modèle car on n'a qu'une date partielle
808
+ }
809
+ }
810
+ else {
811
+ // Traiter une date unique
812
+ const date = parseDate(inputValue.value, props.format)
813
+ if (date) {
814
+ const formattedDate = props.dateFormatReturn && props.dateFormatReturn !== props.format
815
+ ? formatDate(date, props.dateFormatReturn)
816
+ : formatDate(date, props.format)
817
+ emit('update:model-value', formattedDate)
818
+ }
819
+ }
820
+
821
+ // Valider les règles avec la valeur ajustée
822
+ validateRules(inputValue.value)
823
+ }
632
824
 
633
825
  // Traitement spécifique pour les plages de dates
634
826
  if (props.displayRange && inputValue.value) {
@@ -725,6 +917,7 @@
725
917
  if (errors.value.length === 0) {
726
918
  validateRules(inputValue.value || '')
727
919
  }
920
+ emit('blur')
728
921
  }
729
922
 
730
923
  const isValidating = ref(false)
@@ -831,9 +1024,10 @@
831
1024
  }"
832
1025
  :disabled="props.disabled"
833
1026
  :error-messages="errorMessages"
834
- :label="props.label || props.placeholder"
1027
+ :label="props.label || ''"
1028
+ :placeholder="props.placeholder"
835
1029
  :no-icon="props.noIcon"
836
- :prepend-icon="displayIcon && !displayPrependIcon ? 'calendar' : undefined"
1030
+ :prepend-icon="displayIcon && displayPrependIcon && !displayAppendIcon ? 'calendar' : undefined"
837
1031
  :readonly="props.readonly"
838
1032
  :variant-style="props.isOutlined ? 'outlined' : 'underlined'"
839
1033
  :warning-messages="warningMessages"
@@ -841,6 +1035,7 @@
841
1035
  :bg-color="props.bgColor"
842
1036
  color="primary"
843
1037
  is-clearable
1038
+ :display-persistent-placeholder="true"
844
1039
  :aria-label="ariaLabel || props.placeholder"
845
1040
  title="Date text input"
846
1041
  @focus="handleFocus"