@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
@@ -8,11 +8,12 @@
8
8
  import { useDateFormat } from '@/composables/date/useDateFormatDayjs'
9
9
  import { useDateInitialization, type DateValue, type DateInput } from '@/composables/date/useDateInitializationDayjs'
10
10
  import { useDatePickerAccessibility } from '@/composables/date/useDatePickerAccessibility'
11
- import { useWeekendDays, useTodayButton, useDatePickerViewMode, useDateSelection, useMonthButtonCustomization, useDisplayedDateString } from '../composables'
11
+ import { useWeekendDays, useTodayButton, useDatePickerViewMode, useDateSelection, useMonthButtonCustomization, useDisplayedDateString, useAsteriskDisplay } from '../composables'
12
12
  import { DATE_PICKER_MESSAGES } from '../constants/messages'
13
13
  import dayjs from 'dayjs'
14
14
  import customParseFormat from 'dayjs/plugin/customParseFormat'
15
15
  import { mdiCalendar } from '@mdi/js'
16
+ import { useHolidayDay } from '@/composables/date/useHolidayDay'
16
17
 
17
18
  // Initialiser les plugins dayjs
18
19
  dayjs.extend(customParseFormat)
@@ -21,6 +22,12 @@
21
22
  const { initializeSelectedDates } = useDateInitialization()
22
23
  const { updateAccessibility } = useDatePickerAccessibility()
23
24
 
25
+ // Variables pour suivre le mois et l'année actuellement affichés dans le DatePicker
26
+ const currentMonth = ref<string | null>(null)
27
+ const currentYear = ref<string | null>(null)
28
+ const currentMonthName = ref<string | null>(null)
29
+ const currentYearName = ref<string | null>(null)
30
+
24
31
  const props = withDefaults(defineProps<{
25
32
  modelValue?: DateInput
26
33
  label?: string
@@ -52,12 +59,15 @@
52
59
  hideDetails?: boolean | 'auto'
53
60
  displayWeekendDays?: boolean
54
61
  displayTodayButton?: boolean
62
+ displayHolidayDays?: boolean
55
63
  useCombinedMode?: boolean
56
64
  textFieldActivator?: boolean
65
+ displayAsterisk?: boolean
57
66
  period?: {
58
67
  min?: string
59
68
  max?: string
60
69
  }
70
+ autoClamp?: boolean
61
71
  }>(), {
62
72
  modelValue: undefined,
63
73
  label: DATE_PICKER_MESSAGES.LABEL_DEFAULT,
@@ -82,17 +92,20 @@
82
92
  width: '100%',
83
93
  disableErrorHandling: false,
84
94
  showSuccessMessages: true,
85
- bgColor: undefined,
95
+ bgColor: 'white',
86
96
  density: 'default',
87
97
  hideDetails: false,
88
98
  displayWeekendDays: true,
89
99
  displayTodayButton: true,
100
+ displayHolidayDays: true,
90
101
  useCombinedMode: false,
91
102
  textFieldActivator: false,
103
+ displayAsterisk: false,
92
104
  period: () => ({
93
105
  min: '',
94
106
  max: '',
95
107
  }),
108
+ autoClamp: false,
96
109
  })
97
110
 
98
111
  // La compatibilité entre isBirthDate et birthDate est gérée directement dans l'appel au composable
@@ -100,6 +113,7 @@
100
113
  // Utilisation des composables pour les fonctionnalités du DatePicker
101
114
  const { displayWeekendDays } = useWeekendDays(props)
102
115
  const { todayInString } = useTodayButton(props)
116
+ const { labelWithAsterisk } = useAsteriskDisplay(props)
103
117
 
104
118
  const selectedDates = ref<Date | Date[] | null>(
105
119
  initializeSelectedDates(props.modelValue as DateInput | null, props.format, props.dateFormatReturn),
@@ -140,6 +154,8 @@
140
154
  (e: 'closed'): void
141
155
  (e: 'focus'): void
142
156
  (e: 'blur'): void
157
+ (e: 'input', value: DateValue): void
158
+ (e: 'date-selected', value: DateValue): void
143
159
  }>()
144
160
 
145
161
  const isDatePickerVisible = ref(false)
@@ -244,6 +260,8 @@
244
260
  watch(selectedDates, (newValue) => {
245
261
  // Valider les dates
246
262
  validateDates()
263
+ // Marquer les jours fériés après la mise à jour des dates
264
+ markHolidayDays()
247
265
 
248
266
  // Mettre à jour le modèle si nécessaire
249
267
  if (newValue !== null) {
@@ -283,10 +301,6 @@
283
301
  'v-messages__message--warning': warningMessages.value.length > 0 && errorMessages.value.length < 1,
284
302
  })
285
303
 
286
- const inputStyle = computed(() => ({
287
- 'min-width': '100%',
288
- }))
289
-
290
304
  // Utilisation du composable pour gérer la sélection de dates
291
305
  const { updateSelectedDates, rangeBoundaryDates } = useDateSelection(
292
306
  parseDate,
@@ -494,9 +508,11 @@
494
508
 
495
509
  // todayInString est maintenant fourni par le composable useTodayButton
496
510
 
497
- // Utilisation du composable pour personnaliser le bouton du mois
511
+ // Utilisation du composable pour personnaliser les boutons du mois et de l'année
498
512
  const { customizeMonthButton, setupMonthButtonObserver } = useMonthButtonCustomization(
499
513
  () => isDatePickerVisible.value,
514
+ currentMonthName,
515
+ currentYearName,
500
516
  )
501
517
 
502
518
  onMounted(() => {
@@ -543,6 +559,90 @@
543
559
  }
544
560
  }
545
561
 
562
+ // Fonction pour mettre à jour le mois
563
+ const onUpdateMonth = (month: string) => {
564
+ // Éviter les mises à jour inutiles si le mois n'a pas changé
565
+ if (currentMonth.value === month) return
566
+ currentMonth.value = month
567
+ currentMonthName.value = dayjs().month(parseInt(month, 10)).format('MMMM')
568
+ handleMonthUpdate()
569
+ nextTick(() => {
570
+ if (isDatePickerVisible.value) {
571
+ customizeMonthButton()
572
+ markHolidayDays()
573
+ }
574
+ })
575
+ }
576
+
577
+ // Fonction pour mettre à jour l'année
578
+ const onUpdateYear = (year: string) => {
579
+ currentYear.value = year
580
+ currentYearName.value = year
581
+ markHolidayDays()
582
+
583
+ handleYearUpdate()
584
+ handleMonthUpdate()
585
+ nextTick(() => {
586
+ if (isDatePickerVisible.value) {
587
+ customizeMonthButton()
588
+ markHolidayDays()
589
+ }
590
+ })
591
+ }
592
+
593
+ // Propriété calculée pour récupérer les jours fériés de l'année courante
594
+ const holidays = computed(() => {
595
+ // Utiliser le composable useHolidayDay pour récupérer les jours fériés
596
+ const { getJoursFeries } = useHolidayDay()
597
+
598
+ // Convertir l'année en nombre, utiliser l'année courante comme valeur par défaut
599
+ const year = parseInt(currentYear.value || new Date().getFullYear().toString(), 10)
600
+
601
+ // Récupérer les jours fériés au format DD/MM/YYYY
602
+ const joursFeries = getJoursFeries(year)
603
+
604
+ // Tableau pour stocker les jours fériés
605
+ const holidayDates: Date[] = []
606
+
607
+ // Convertir les dates du format string en objets Date
608
+ joursFeries.forEach((dateStr) => {
609
+ const [day, month, yearStr] = dateStr.split('/')
610
+ // Mois -1 car les mois dans Date sont indexés à partir de 0
611
+ holidayDates.push(new Date(parseInt(yearStr), parseInt(month) - 1, parseInt(day)))
612
+ })
613
+
614
+ // Retourner le tableau des jours fériés
615
+ return holidayDates
616
+ })
617
+
618
+ // Fonction pour marquer les jours fériés dans le calendrier
619
+ const markHolidayDays = () => {
620
+ if (!props.displayHolidayDays) return
621
+ // Attendre que le DOM soit mis à jour
622
+ nextTick(() => {
623
+ // Récupérer l'année et le mois courants
624
+ const year = parseInt(currentYear.value || new Date().getFullYear().toString(), 10)
625
+ // Utiliser currentMonth.value !== null pour vérifier si la valeur est définie, même si c'est 0
626
+ const month = parseInt(currentMonth.value !== null ? currentMonth.value : new Date().getMonth().toString(), 10)
627
+
628
+ // Récupérer les jours fériés pour ce mois
629
+ const monthHolidays = holidays.value.filter((holiday) => {
630
+ // La comparaison doit tenir compte du fait que getMonth() retourne 0-11
631
+ return holiday.getMonth() === month
632
+ })
633
+
634
+ // Pour chaque jour férié, trouver l'élément DOM correspondant et ajouter la classe
635
+ monthHolidays.forEach((holiday) => {
636
+ const day = holiday.getDate()
637
+ const dateStr = `${year}-${String(month + 1).padStart(2, '0')}-${String(day).padStart(2, '0')}`
638
+ const dayElements = document.querySelectorAll(`[data-v-date="${dateStr}"]`)
639
+ dayElements.forEach((element) => {
640
+ element.classList.add('holiday-day')
641
+ })
642
+ })
643
+ })
644
+ }
645
+
546
646
  // Utilisation du composable pour gérer le mode d'affichage du DatePicker
547
647
  const { currentViewMode, handleViewModeUpdate, handleYearUpdate, handleMonthUpdate, resetViewMode } = useDatePickerViewMode(
548
648
  // Fonction qui retourne la valeur actuelle de isBirthDate (combinaison de isBirthDate et birthDate)
@@ -555,6 +655,10 @@
555
655
  }
556
656
 
557
657
  watch(isDatePickerVisible, async (isVisible) => {
658
+ if (isVisible) {
659
+ // Marquer les jours fériés lorsque le calendrier devient visible
660
+ markHolidayDays()
661
+ }
558
662
  if (!isVisible && props.isBirthDate) {
559
663
  // Réinitialiser le mode d'affichage au type birthdate
560
664
  resetViewMode()
@@ -712,37 +816,40 @@
712
816
  <template>
713
817
  <div
714
818
  class="date-picker-container"
715
- :style="inputStyle"
716
819
  >
717
820
  <template v-if="props.noCalendar">
718
821
  <DateTextInput
719
822
  ref="dateTextInputRef"
720
823
  v-model="textInputValue"
721
824
  :class="[getMessageClasses(), 'label-hidden-on-focus']"
722
- :date-format-return="props.dateFormatReturn"
723
- :format="props.format"
724
- :label="props.placeholder"
825
+ :label="labelWithAsterisk || ''"
725
826
  :placeholder="props.placeholder"
827
+ :format="props.format"
828
+ :date-format-return="props.dateFormatReturn"
726
829
  :required="props.required"
727
- :custom-rules="props.customRules"
728
- :custom-warning-rules="props.customWarningRules"
729
- :disabled="props.disabled"
730
- :readonly="props.readonly"
731
- :is-outlined="props.isOutlined"
830
+ :display-range="props.displayRange"
732
831
  :display-icon="props.displayIcon"
733
832
  :display-append-icon="props.displayAppendIcon"
734
833
  :display-prepend-icon="props.displayPrependIcon"
834
+ :custom-rules="props.customRules"
835
+ :custom-warning-rules="props.customWarningRules"
836
+ :disabled="props.disabled"
735
837
  :no-icon="props.noIcon"
838
+ :is-outlined="props.isOutlined"
839
+ :readonly="props.readonly"
840
+ :width="props.width"
736
841
  :disable-error-handling="props.disableErrorHandling"
737
842
  :show-success-messages="props.showSuccessMessages"
738
843
  :bg-color="props.bgColor"
844
+ :density="props.density"
739
845
  :hide-details="props.hideDetails"
740
- :display-range="props.displayRange"
741
- title="Date text input"
742
- @focus="emit('focus')"
743
- @blur="emit('blur')"
744
- @date-selected="handleDateTextInputSelection"
846
+ :period="props.period"
847
+ :auto-clamp="props.autoClamp"
848
+ :display-asterisk="props.displayAsterisk"
745
849
  @update:model-value="handleDateTextInputUpdate"
850
+ @date-selected="handleDateTextInputSelection"
851
+ @blur="handleInputBlur"
852
+ @focus="emit('focus')"
746
853
  />
747
854
  </template>
748
855
  <template v-else-if="props.useCombinedMode">
@@ -768,14 +875,20 @@
768
875
  :display-range="props.displayRange"
769
876
  :display-weekend-days="props.displayWeekendDays"
770
877
  :display-today-button="props.displayTodayButton"
878
+ :display-holiday-days="props.displayHolidayDays"
879
+ :display-asterisk="props.displayAsterisk"
771
880
  :show-week-number="props.showWeekNumber"
772
881
  :is-birth-date="props.isBirthDate || props.birthDate"
773
882
  :text-field-activator="props.textFieldActivator"
774
883
  :title="'Date text input'"
775
884
  :period="period"
885
+ :auto-clamp="props.autoClamp"
886
+ :label="props.label"
887
+ :placeholder="props.placeholder"
776
888
  @update:model-value="emit('update:modelValue', $event)"
777
889
  @focus="emit('focus')"
778
890
  @blur="emit('blur')"
891
+ @date-selected="emit('date-selected', $event)"
779
892
  />
780
893
  </template>
781
894
  <template v-else>
@@ -806,7 +919,9 @@
806
919
  :disabled="props.disabled"
807
920
  :disable-click-button="false"
808
921
  :readonly="true"
809
- :label="props.placeholder"
922
+ :label="labelWithAsterisk || ''"
923
+ :placeholder="props.placeholder"
924
+ :display-persistent-placeholder="true"
810
925
  :no-icon="props.noIcon"
811
926
  :prepend-icon="displayIcon && !displayAppendIcon ? 'calendar' : undefined"
812
927
  :variant-style="props.isOutlined ? 'outlined' : 'underlined'"
@@ -815,7 +930,9 @@
815
930
  :bg-color="props.bgColor"
816
931
  :density="props.density"
817
932
  :hide-details="props.hideDetails"
933
+ :display-asterisk="props.displayAsterisk"
818
934
  is-clearable
935
+ :auto-clamp="props.autoClamp"
819
936
  title="Date Picker"
820
937
  @click="openDatePickerOnClick"
821
938
  @focus="openDatePickerOnFocus"
@@ -838,10 +955,14 @@
838
955
  :class="displayWeekendDays ? 'weekend' : ''"
839
956
  :max="props.period?.max"
840
957
  :min="props.period?.min"
958
+ :display-holiday-days="props.displayHolidayDays"
841
959
  @update:view-mode="handleViewModeUpdate"
842
- @update:year="handleYearUpdate"
843
- @update:month="handleMonthUpdate"
960
+ @update:month="onUpdateMonth"
961
+ @update:year="onUpdateYear"
962
+ @click:date="updateSelectedDates"
844
963
  @update:model-value="updateDisplayFormattedDate"
964
+ @focus="markHolidayDays"
965
+ @update:month-year="markHolidayDays"
845
966
  >
846
967
  <template #title>
847
968
  Sélectionnez une date
@@ -883,6 +1004,13 @@
883
1004
  <style lang="scss" scoped>
884
1005
  @use '@/assets/tokens';
885
1006
 
1007
+ /* Style pour les jours fériés */
1008
+ :deep(.holiday-day) {
1009
+ background-color: rgb(255 193 7 / 10%);
1010
+ border: 2px dotted tokens.$neutral-black;
1011
+ border-radius: 50%;
1012
+ }
1013
+
886
1014
  /* Disable ripple effect on month and year buttons */
887
1015
  :deep(.v-date-picker-controls__month-btn),
888
1016
  :deep(.v-date-picker-controls__mode-btn) {
@@ -969,7 +1097,7 @@
969
1097
  }
970
1098
 
971
1099
  .date-picker-container {
972
- max-width: 100%;
1100
+ width: 100%;
973
1101
  position: relative;
974
1102
 
975
1103
  :deep(.v-date-picker) {
@@ -0,0 +1,189 @@
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 DatePicker from '../DatePicker.vue'
6
+
7
+ describe('DatePicker.vue - Events', () => {
8
+ let wrapper
9
+
10
+ beforeEach(() => {
11
+ wrapper = mount(DatePicker, {
12
+ global: {
13
+ plugins: [vuetify],
14
+ },
15
+ props: {
16
+ modelValue: '',
17
+ format: 'DD/MM/YYYY',
18
+ },
19
+ })
20
+ })
21
+
22
+ it('émet update:modelValue 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:modelValue')).toBeTruthy()
28
+ expect(wrapper.emitted('update:modelValue')[0]).toEqual(['01/01/2023'])
29
+ })
30
+
31
+ it('gère la visibilité du calendrier', async () => {
32
+ // Ouvrir le calendrier
33
+ await wrapper.find('.v-text-field').trigger('click')
34
+ await nextTick()
35
+
36
+ // Vérifier que le calendrier est visible
37
+ expect(wrapper.vm.isDatePickerVisible).toBe(true)
38
+
39
+ // Fermer le calendrier
40
+ wrapper.vm.isDatePickerVisible = false
41
+ await nextTick()
42
+
43
+ // Vérifier que le calendrier est fermé
44
+ expect(wrapper.vm.isDatePickerVisible).toBe(false)
45
+ })
46
+
47
+ it('accepte la saisie de dates', async () => {
48
+ const input = wrapper.find('input')
49
+
50
+ // Simuler la saisie de chiffres
51
+ await input.setValue('0101')
52
+ await nextTick()
53
+
54
+ // Vérifier que la valeur est bien prise en compte
55
+ expect(input.element.value).toContain('01')
56
+ })
57
+
58
+ it('permet la saisie manuelle même avec disablePickerInteraction', async () => {
59
+ // Créer un composant avec disablePickerInteraction à true
60
+ const wrapperWithDisabledPicker = mount(DatePicker, {
61
+ global: {
62
+ plugins: [vuetify],
63
+ },
64
+ props: {
65
+ modelValue: '',
66
+ format: 'DD/MM/YYYY',
67
+ disablePickerInteraction: true,
68
+ },
69
+ })
70
+
71
+ // Simuler une saisie dans l'input
72
+ const input = wrapperWithDisabledPicker.find('input')
73
+ await input.setValue('01/01/2023')
74
+ await input.trigger('blur')
75
+ await nextTick()
76
+
77
+ // Vérifier que l'événement update:modelValue est émis même avec disablePickerInteraction
78
+ const emitted = wrapperWithDisabledPicker.emitted('update:modelValue')
79
+ expect(emitted).toBeTruthy()
80
+ expect(emitted && emitted[0][0]).toBe('01/01/2023')
81
+ })
82
+
83
+ it('synchronise textInputValue et selectedDates', async () => {
84
+ const input = wrapper.find('input')
85
+ await input.setValue('01/01/2023')
86
+ await input.trigger('blur')
87
+ await nextTick()
88
+
89
+ // Vérifier que selectedDates est mis à jour
90
+ expect(wrapper.vm.selectedDates).not.toBeNull()
91
+ const selectedDate = wrapper.vm.selectedDates
92
+ expect(selectedDate instanceof Date).toBe(true)
93
+ expect(selectedDate.getFullYear()).toBe(2023)
94
+ expect(selectedDate.getMonth()).toBe(0) // Janvier (0-indexed)
95
+ expect(selectedDate.getDate()).toBe(1)
96
+ })
97
+
98
+ it('met à jour displayFormattedDate lors de la sélection d\'une date dans le calendrier', async () => {
99
+ // Ouvrir le calendrier
100
+ await wrapper.find('.v-text-field').trigger('click')
101
+ await nextTick()
102
+
103
+ // Simuler une sélection de date dans le VDatePicker
104
+ if (wrapper.vm.$refs.datePicker) {
105
+ // Simuler l'événement update:model-value du VDatePicker
106
+ const date = new Date(2023, 0, 1) // 1 janvier 2023
107
+ wrapper.vm.handleDatePickerInput(date)
108
+ await nextTick()
109
+
110
+ // Appeler updateDisplayFormattedDate comme le ferait le gestionnaire d'événements
111
+ wrapper.vm.updateDisplayFormattedDate()
112
+ await nextTick()
113
+
114
+ // Vérifier que displayFormattedDate est mis à jour correctement
115
+ expect(wrapper.vm.displayFormattedDate).toBe('01/01/2023')
116
+ }
117
+ })
118
+
119
+ it('accepte différents formats de date', async () => {
120
+ const wrapperWithDashFormat = mount(DatePicker, {
121
+ global: {
122
+ plugins: [vuetify],
123
+ },
124
+ props: {
125
+ modelValue: '',
126
+ format: 'YYYY-MM-DD',
127
+ },
128
+ })
129
+
130
+ const input = wrapperWithDashFormat.find('input')
131
+
132
+ // Simuler la saisie d'une date complète au format YYYY-MM-DD
133
+ await input.setValue('2023-01-01')
134
+ await input.trigger('blur')
135
+ await nextTick()
136
+
137
+ // Vérifier que l'événement update:modelValue est émis avec le bon format
138
+ const emitted = wrapperWithDashFormat.emitted('update:modelValue')
139
+ expect(emitted).toBeTruthy()
140
+ expect(emitted && emitted[0][0]).toBe('2023-01-01')
141
+ })
142
+
143
+ it('accepte les plages de dates en entrée', async () => {
144
+ const wrapperWithRange = mount(DatePicker, {
145
+ global: {
146
+ plugins: [vuetify],
147
+ },
148
+ props: {
149
+ modelValue: ['01/01/2023', '05/01/2023'],
150
+ format: 'DD/MM/YYYY',
151
+ displayRange: true,
152
+ },
153
+ })
154
+ await nextTick()
155
+
156
+ // Vérifier que l'input affiche la plage de dates
157
+ const input = wrapperWithRange.find('input')
158
+ expect(input.element.value).toContain('01/01/2023')
159
+
160
+ // Vérifier que la propriété displayRange est bien prise en compte
161
+ expect(wrapperWithRange.props('displayRange')).toBe(true)
162
+ })
163
+
164
+ it('valide les dates selon les règles personnalisées', async () => {
165
+ const customRule = {
166
+ type: 'isDateValid',
167
+ options: {},
168
+ }
169
+
170
+ const wrapperWithRules = mount(DatePicker, {
171
+ global: {
172
+ plugins: [vuetify],
173
+ },
174
+ props: {
175
+ modelValue: '',
176
+ format: 'DD/MM/YYYY',
177
+ customRules: [customRule],
178
+ required: true,
179
+ },
180
+ })
181
+
182
+ // Valider sans sélectionner de date
183
+ await wrapperWithRules.vm.validateOnSubmit()
184
+ await nextTick()
185
+
186
+ // Vérifier qu'une erreur de validation est affichée
187
+ expect(wrapperWithRules.vm.errorMessages.length).toBeGreaterThan(0)
188
+ })
189
+ })
@@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils'
2
2
  import { describe, it, expect, beforeEach, vi } from 'vitest'
3
3
  import { vuetify } from '@tests/unit/setup'
4
4
  import { nextTick } from 'vue'
5
- import DatePicker from './DatePicker.vue'
5
+ import DatePicker from '../DatePicker.vue'
6
6
 
7
7
  describe('DatePicker.vue', () => {
8
8
  let wrapper
@@ -19,20 +19,6 @@ describe('DatePicker.vue', () => {
19
19
  })
20
20
  })
21
21
 
22
- it('displays the placeholder text as label', () => {
23
- const placeholder = 'Sélectionner une date'
24
- const wrapper = mount(DatePicker, {
25
- global: {
26
- plugins: [vuetify],
27
- },
28
- props: { placeholder },
29
- })
30
-
31
- // Vérifier que le placeholder est affiché comme label
32
- const label = wrapper.find('label')
33
- expect(label.text()).toBe(placeholder)
34
- })
35
-
36
22
  it('emits update:modelValue event on date selection', async () => {
37
23
  const wrapper = mount(DatePicker, {
38
24
  global: {
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
2
  import DatePicker from '../DatePicker/DatePicker.vue'
3
3
  import { ref } from 'vue'
4
+ import { fn } from '@storybook/test'
4
5
 
5
6
  const meta = {
6
7
  title: 'Composants/Formulaires/DatePicker/DateInput/DateRange',
@@ -13,6 +14,7 @@ const meta = {
13
14
  parameters: {
14
15
  layout: 'fullscreen',
15
16
  controls: { exclude: ['modelValue'] },
17
+ actions: { argTypesRegex: '^on.*' },
16
18
  },
17
19
  argTypes: {
18
20
  placeholder: {
@@ -98,13 +100,17 @@ type Story = StoryObj<typeof meta>
98
100
 
99
101
  export const Default: Story = {
100
102
  args: {
101
- noCalendar: true,
102
- format: 'DD/MM/YYYY',
103
- placeholder: 'JJ/MM/AAAA - JJ/MM/AAAA',
104
- label: 'Période',
105
- displayRange: true,
106
- displayIcon: true,
107
- isOutlined: true,
103
+ 'noCalendar': true,
104
+ 'format': 'DD/MM/YYYY',
105
+ 'placeholder': 'JJ/MM/AAAA - JJ/MM/AAAA',
106
+ 'label': 'Période',
107
+ 'displayRange': true,
108
+ 'displayIcon': true,
109
+ 'isOutlined': true,
110
+ 'onUpdate:modelValue': fn(),
111
+ 'onFocus': fn(),
112
+ 'onBlur': fn(),
113
+ 'onClosed': fn(),
108
114
  },
109
115
  render(args) {
110
116
  const dateRange = ref<string | null>(null)
@@ -149,13 +155,17 @@ export const WithInitialValue: Story = {
149
155
  ],
150
156
  },
151
157
  args: {
152
- noCalendar: true,
153
- format: 'DD/MM/YYYY',
154
- placeholder: 'JJ/MM/AAAA - JJ/MM/AAAA',
155
- label: 'Période avec valeur initiale',
156
- displayRange: true,
157
- displayIcon: true,
158
- isOutlined: true,
158
+ 'noCalendar': true,
159
+ 'format': 'DD/MM/YYYY',
160
+ 'placeholder': 'JJ/MM/AAAA - JJ/MM/AAAA',
161
+ 'label': 'Période avec valeur initiale',
162
+ 'displayRange': true,
163
+ 'displayIcon': true,
164
+ 'isOutlined': true,
165
+ 'onUpdate:modelValue': fn(),
166
+ 'onFocus': fn(),
167
+ 'onBlur': fn(),
168
+ 'onClosed': fn(),
159
169
  },
160
170
  render(args) {
161
171
  const dateRange = ref<string | null>('01/06/2025 - 30/06/2025')