@cnamts/synapse 1.1.0 → 1.1.1

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 (202) hide show
  1. package/dist/{AutocompleteFilter-DXd4szWO.js → AutocompleteFilter-CGF33skz.js} +1 -1
  2. package/dist/{DateFilter-BD59Kgwf.js → DateFilter-D7-MsKtx.js} +1 -1
  3. package/dist/{NumberFilter-BSMZE7uw.js → NumberFilter-bjQPPfsj.js} +1 -1
  4. package/dist/{PeriodFilter-keUdSSk0.js → PeriodFilter-B3wJpK8-.js} +1 -1
  5. package/dist/{SelectFilter-Dhvvwazl.js → SelectFilter-BN6DbKAV.js} +1 -1
  6. package/dist/{TextFilter-CU8FpXz0.js → TextFilter-BffP0J2f.js} +1 -1
  7. package/dist/{apLightTheme2026-DbS7BPUf.js → apLightTheme2026-C4ygwMHC.js} +11 -11
  8. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +6 -6
  9. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +6 -6
  10. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +6 -6
  11. package/dist/components/Captcha/Captcha.d.ts +27 -16
  12. package/dist/components/Captcha/CaptchaForm.d.ts +29 -3
  13. package/dist/components/Captcha/types.d.ts +14 -0
  14. package/dist/components/Captcha/useCaptchaValidation.d.ts +37 -0
  15. package/dist/components/Customs/Selects/SelectBtnField/SelectBtnField.d.ts +33 -13
  16. package/dist/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.d.ts +23 -0
  17. package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +2 -2
  18. package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +2 -2
  19. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +17 -48
  20. package/dist/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.d.ts +29 -0
  21. package/dist/components/Customs/SyCheckBoxGroup/types.d.ts +46 -0
  22. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +16 -51
  23. package/dist/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.d.ts +27 -0
  24. package/dist/components/Customs/SyCheckbox/types.d.ts +49 -0
  25. package/dist/components/Customs/SyTextField/FieldState.d.ts +5 -0
  26. package/dist/components/Customs/SyTextField/useSyTextFieldValidation.d.ts +3 -3
  27. package/dist/components/DialogBox/DialogBox.d.ts +2 -0
  28. package/dist/components/DialogBox/locales.d.ts +1 -0
  29. package/dist/components/FilterSideBar/FilterSideBar.d.ts +4 -0
  30. package/dist/components/LunarCalendar/LunarCalendar.d.ts +43 -14
  31. package/dist/components/LunarCalendar/types.d.ts +35 -0
  32. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +11 -12
  33. package/dist/components/MonthPicker/MonthPicker.d.ts +72 -1747
  34. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +21 -1733
  35. package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +5 -0
  36. package/dist/components/MonthPicker/locales.d.ts +1 -0
  37. package/dist/components/MonthPicker/types.d.ts +11 -0
  38. package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +37 -24
  39. package/dist/components/NirField/NirField.d.ts +6 -4
  40. package/dist/components/NirField/useNirValidation.d.ts +7 -5
  41. package/dist/components/PageContainer/PageContainer.d.ts +8 -0
  42. package/dist/components/PasswordField/PasswordField.d.ts +2 -2
  43. package/dist/components/PasswordField/usePasswordFieldValidation.d.ts +2 -2
  44. package/dist/components/PhoneField/PhoneField.d.ts +960 -1938
  45. package/dist/components/PhoneField/indicatifs.d.ts +715 -8
  46. package/dist/components/PhoneField/locales.d.ts +7 -0
  47. package/dist/components/PhoneField/types.d.ts +29 -0
  48. package/dist/components/PhoneField/usePhoneFieldValidation.d.ts +45 -0
  49. package/dist/components/PhoneField/usePhoneIndicatifs.d.ts +947 -0
  50. package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +2 -2
  51. package/dist/composables/unifyValidation/documentationValidationProps.d.ts +1 -1
  52. package/dist/composables/unifyValidation/useValidation.d.ts +4 -5
  53. package/dist/design-system-v3.js +2 -2
  54. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +10 -10
  55. package/dist/designTokens/tokens/baseTokens.d.ts +18 -18
  56. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +10 -10
  57. package/dist/designTokens/tokens/pa/paLightTheme.d.ts +10 -10
  58. package/dist/designTokens/tokens/semanticTokens.d.ts +14 -14
  59. package/dist/{main-D8ryUoS5.js → main-C4wAktOs.js} +13718 -12991
  60. package/dist/synapse.css +1 -1
  61. package/dist/vuetifyConfig.js +1 -1
  62. package/package.json +7 -7
  63. package/src/assets/compat/_legacy-tokens.scss +91 -0
  64. package/src/assets/overrides/_utilities.scss +23 -0
  65. package/src/components/Accordion/Accordion.stories.ts +121 -1
  66. package/src/components/BackBtn/BackBtn.mdx +1 -1
  67. package/src/components/BackToTopBtn/BackToTopBtn.mdx +0 -1
  68. package/src/components/Captcha/Captcha.stories.ts +134 -31
  69. package/src/components/Captcha/Captcha.vue +95 -28
  70. package/src/components/Captcha/CaptchaForm.vue +51 -22
  71. package/src/components/Captcha/tests/Captcha.focus.spec.ts +214 -0
  72. package/src/components/Captcha/tests/Captcha.spec.ts +233 -24
  73. package/src/components/Captcha/tests/CaptchaForm.spec.ts +82 -0
  74. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +16 -42
  75. package/src/components/Captcha/types.ts +15 -0
  76. package/src/components/Captcha/useCaptchaValidation.ts +87 -0
  77. package/src/components/Captcha/validation/validation.stories.ts +1194 -0
  78. package/src/components/ChipList/ChipList.mdx +0 -1
  79. package/src/components/CollapsibleList/CollapsibleList.mdx +0 -1
  80. package/src/components/CookieBanner/CookieBanner.mdx +0 -1
  81. package/src/components/CopyBtn/CopyBtn.mdx +0 -1
  82. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +123 -439
  83. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +147 -41
  84. package/src/components/Customs/Selects/SelectBtnField/Validation/Validation.stories.ts +600 -0
  85. package/src/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.ts +87 -0
  86. package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +402 -33
  87. package/src/components/Customs/Selects/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +52 -38
  88. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +342 -162
  89. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +77 -129
  90. package/src/components/Customs/SyCheckBoxGroup/Validation/Validation.stories.ts +1008 -0
  91. package/src/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.ts +107 -0
  92. package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.spec.ts +180 -7
  93. package/src/components/Customs/SyCheckBoxGroup/types.ts +49 -0
  94. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +41 -161
  95. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +71 -148
  96. package/src/components/Customs/SyCheckbox/Validation/Validation.stories.ts +654 -0
  97. package/src/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.ts +105 -0
  98. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +106 -0
  99. package/src/components/Customs/SyCheckbox/tests/useSyCheckboxValidation.spec.ts +98 -0
  100. package/src/components/Customs/SyCheckbox/types.ts +51 -0
  101. package/src/components/Customs/SyTextField/FieldState.vue +50 -0
  102. package/src/components/Customs/SyTextField/SyTextField.vue +12 -9
  103. package/src/components/Customs/SyTextField/useSyTextFieldValidation.ts +2 -11
  104. package/src/components/DataList/DataList.mdx +0 -1
  105. package/src/components/DataListGroup/DataListGroup.mdx +0 -1
  106. package/src/components/DiacriticPicker/DiacriticPicker.mdx +0 -1
  107. package/src/components/DialogBox/DialogBox.mdx +0 -1
  108. package/src/components/DialogBox/DialogBox.stories.ts +399 -4
  109. package/src/components/DialogBox/DialogBox.vue +20 -0
  110. package/src/components/DialogBox/locales.ts +1 -0
  111. package/src/components/DialogBox/tests/DialogBox.spec.ts +73 -0
  112. package/src/components/DialogBox/tests/DialogBox.visual.cy.ts +24 -0
  113. package/src/components/ErrorPage/ErrorPage.mdx +1 -1
  114. package/src/components/ExternalLinks/ExternalLinks.mdx +0 -1
  115. package/src/components/FileList/FileList.mdx +0 -1
  116. package/src/components/FilterInline/FilterInline.mdx +0 -1
  117. package/src/components/FilterSideBar/FilterSideBar.mdx +8 -1
  118. package/src/components/FilterSideBar/FilterSideBar.stories.ts +133 -1
  119. package/src/components/FilterSideBar/FilterSideBar.vue +19 -2
  120. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +55 -0
  121. package/src/components/FooterBar/FooterBar.mdx +0 -1
  122. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +0 -1
  123. package/src/components/HeaderBar/HeaderBar.mdx +0 -1
  124. package/src/components/HeaderLoading/HeaderLoading.mdx +0 -1
  125. package/src/components/LangBtn/LangBtn.mdx +0 -1
  126. package/src/components/Logo/Logo.mdx +1 -1
  127. package/src/components/LunarCalendar/LunarCalendar.mdx +6 -9
  128. package/src/components/LunarCalendar/LunarCalendar.stories.ts +243 -46
  129. package/src/components/LunarCalendar/LunarCalendar.vue +61 -26
  130. package/src/components/LunarCalendar/Validation/Validation.stories.ts +717 -0
  131. package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +1 -1
  132. package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +197 -6
  133. package/src/components/LunarCalendar/tests/useLunarCalendarValidation.spec.ts +287 -0
  134. package/src/components/LunarCalendar/types.ts +39 -0
  135. package/src/components/LunarCalendar/useLunarCalendarValidation.ts +115 -39
  136. package/src/components/MonthPicker/MonthPicker.stories.ts +38 -281
  137. package/src/components/MonthPicker/MonthPicker.vue +66 -17
  138. package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +44 -20
  139. package/src/components/MonthPicker/MonthPickerText/useTextField.ts +5 -0
  140. package/src/components/MonthPicker/Validation/Validation.stories.ts +1117 -0
  141. package/src/components/MonthPicker/locales.ts +1 -0
  142. package/src/components/MonthPicker/tests/MonthPicker.spec.ts +353 -2
  143. package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +12 -8
  144. package/src/components/MonthPicker/types.ts +16 -0
  145. package/src/components/MonthPicker/useMonthPickerValidation.ts +64 -27
  146. package/src/components/NirField/NirField.mdx +120 -66
  147. package/src/components/NirField/NirField.stories.ts +216 -0
  148. package/src/components/NirField/useNirValidation.ts +16 -17
  149. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +263 -245
  150. package/src/components/NotificationBar/NotificationBar.mdx +0 -1
  151. package/src/components/PageContainer/PageContainer.mdx +0 -1
  152. package/src/components/PageContainer/PageContainer.stories.ts +170 -2
  153. package/src/components/PageContainer/PageContainer.vue +63 -8
  154. package/src/components/PageContainer/tests/__snapshots__/PageContainer.spec.ts.snap +19 -11
  155. package/src/components/PaginatedTable/PaginatedTable.mdx +0 -1
  156. package/src/components/PeriodField/PeriodField.mdx +0 -1
  157. package/src/components/PhoneField/PhoneField.mdx +2 -3
  158. package/src/components/PhoneField/PhoneField.stories.ts +227 -410
  159. package/src/components/PhoneField/PhoneField.vue +204 -438
  160. package/src/components/PhoneField/indicatifs.ts +1 -1
  161. package/src/components/PhoneField/locales.ts +7 -0
  162. package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -1
  163. package/src/components/PhoneField/tests/PhoneField.spec.ts +517 -220
  164. package/src/components/PhoneField/types.ts +30 -0
  165. package/src/components/PhoneField/usePhoneFieldValidation.ts +119 -0
  166. package/src/components/PhoneField/usePhoneIndicatifs.ts +89 -0
  167. package/src/components/PhoneField/validation/validation.stories.ts +717 -0
  168. package/src/components/RangeField/RangeField.mdx +0 -1
  169. package/src/components/RatingPicker/RatingPicker.mdx +0 -1
  170. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +0 -1
  171. package/src/components/StatusPage/StatusPage.vue +1 -0
  172. package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +248 -230
  173. package/src/components/SubHeader/SubHeader.mdx +5 -6
  174. package/src/components/Tables/common/tests/SyTableFilter.spec.ts +11 -12
  175. package/src/components/UploadWorkflow/UploadWorkflow.mdx +0 -1
  176. package/src/components/UserMenuBtn/UserMenuBtn.mdx +0 -1
  177. package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +177 -0
  178. package/src/composables/unifyValidation/documentationValidationProps.ts +1 -1
  179. package/src/composables/unifyValidation/tests/useValidation.spec.ts +13 -1
  180. package/src/composables/unifyValidation/useValidation.ts +37 -33
  181. package/src/composantsVuetify/VCard/VCard.mdx +4 -0
  182. package/src/composantsVuetify/VCard/v-card.stories.ts +93 -1
  183. package/src/composantsVuetify/VCarousel/VCarousel.mdx +74 -0
  184. package/src/composantsVuetify/VCarousel/v-carousel.stories.ts +531 -0
  185. package/src/composantsVuetify/VNavigationDrawer/VNavgationDrawer.mdx +53 -0
  186. package/src/composantsVuetify/VNavigationDrawer/v-navigation-drawer.stories.ts +310 -0
  187. package/src/composantsVuetify/VSlideGroup/VSlideGroup.mdx +105 -0
  188. package/src/composantsVuetify/VSlideGroup/v-slide-group.stories.ts +463 -0
  189. package/src/designTokens/tokens/baseColors.ts +1 -1
  190. package/src/designTokens/tokens/baseTokens.ts +18 -18
  191. package/src/stories/Components/Components.stories.ts +34 -1
  192. package/src/stories/Demarrer/Releases.stories.ts +16 -2
  193. package/src/stories/DesignTokens/Arrondis.mdx +1 -1
  194. package/src/stories/DesignTokens/Correspondances.mdx +219 -0
  195. package/src/stories/DesignTokens/UtiliserLesTokens.mdx +235 -0
  196. package/src/stories/DesignTokens/colors.stories.ts +569 -569
  197. package/src/stories/GuideDuDev/Amelipro.stories.ts +335 -267
  198. package/dist/components/LunarCalendar/useLunarCalendarRules.d.ts +0 -5
  199. package/dist/components/PhoneField/tests/types.d.ts +0 -18
  200. package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +0 -184
  201. package/src/components/LunarCalendar/useLunarCalendarRules.ts +0 -96
  202. package/src/components/PhoneField/tests/types.d.ts +0 -19
@@ -1,14 +1,14 @@
1
1
  import { fn } from '@storybook/test'
2
- import { nextTick, ref } from 'vue'
3
2
  import MonthPicker from './MonthPicker.vue'
4
3
  import type { Meta, StoryObj } from '@storybook/vue3'
5
4
  import type SyTextField from '../Customs/SyTextField/SyTextField.vue'
6
- import SyForm from '../Customs/SyForm/SyForm.vue'
5
+ import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps'
7
6
 
8
7
  const meta: Meta<typeof MonthPicker> = {
9
8
  title: 'Composants/Formulaires/MonthPicker',
10
9
  component: MonthPicker,
11
10
  argTypes: {
11
+ ...getValidationDocumentation('base'),
12
12
  'modelValue': {
13
13
  control: 'text',
14
14
  description: 'Valeur du sélecteur de mois au format "MM/YYYY".',
@@ -19,7 +19,29 @@ const meta: Meta<typeof MonthPicker> = {
19
19
  'locales': {
20
20
  description: 'Objet de traduction pour le sélecteur de mois. Par défaut, les traductions françaises sont utilisées.',
21
21
  table: {
22
- type: { summary: 'object' },
22
+ type: {
23
+ summary: 'object',
24
+ detail: `{
25
+ btnLabel: string,
26
+ headerSelectYear: string,
27
+ headerSelectMonth: string,
28
+ yearSelectorLabel: string,
29
+ monthSelectorLabel: string,
30
+ yearBtnLabelSelected: (selectedYear: string) => string,
31
+ yearBtnLabelUnselected: (selectedYear: string) => string,
32
+ monthBtnLabelSelected: (selectedMonth: string) => string,
33
+ monthBtnLabelUnselected: (selectedMonth: string) => string,
34
+ fieldRequired: (label: string) => string,
35
+ }`,
36
+ },
37
+ },
38
+ },
39
+ 'clearable': {
40
+ control: 'boolean',
41
+ description: 'Affiche un bouton permettant de vider le champ',
42
+ table: {
43
+ type: { summary: 'boolean' },
44
+ category: 'props',
23
45
  },
24
46
  },
25
47
  'minYear': {
@@ -85,109 +107,20 @@ const meta: Meta<typeof MonthPicker> = {
85
107
  },
86
108
  },
87
109
  'hint': {
88
- description: 'Texte d’aide affiché sous le champ de saisie.',
110
+ description: 'Texte d’aide affiché sous le champ de saisie lorsque le champ est focus.',
89
111
  control: 'text',
90
112
  table: {
91
113
  type: { summary: 'string' },
92
114
  category: 'props',
93
115
  },
94
116
  },
95
- 'customRules': {
96
- description: 'Règles de validation personnalisées pour les erreurs.',
97
- table: {
98
- type: { summary: 'ValidationRule[]' },
99
- category: 'props',
100
- },
101
- },
102
- 'customWarningRules': {
103
- description: 'Règles de validation personnalisées pour les avertissements.',
104
- table: {
105
- type: { summary: 'ValidationRule[]' },
106
- category: 'props',
107
- },
108
- },
109
- 'customSuccessRules': {
110
- description: 'Règles de validation personnalisées pour les succès.',
111
- table: {
112
- type: { summary: 'ValidationRule[]' },
113
- category: 'props',
114
- },
115
- category: 'validation',
116
- },
117
- 'errorMessages': {
118
- description: 'Messages d’erreur personnalisés à afficher lorsque la validation échoue. Peut être une chaîne de caractères ou un tableau de chaînes.',
119
- control: 'text',
120
- table: {
121
- type: { summary: 'string | string[]' },
122
- category: 'props',
123
- },
124
- },
125
- 'warningMessages': {
126
- description: 'Messages d’avertissement personnalisés à afficher lorsque la validation génère un avertissement. Peut être une chaîne de caractères ou un tableau de chaînes.',
127
- control: 'text',
128
- table: {
129
- type: { summary: 'string | string[]' },
130
- category: 'props',
131
- },
132
- },
133
- 'successMessages': {
134
- description: 'Messages de succès personnalisés à afficher lorsque la validation réussit. Peut être une chaîne de caractères ou un tableau de chaînes.',
117
+ 'helpText': {
118
+ description: 'Texte d’aide permanent affiché sous le champ de saisie.',
135
119
  control: 'text',
136
120
  table: {
137
- type: { summary: 'string | string[]' },
138
- category: 'props',
139
- },
140
- },
141
- 'hasError': {
142
- description: 'Indique si le champ est en état d’erreur. Utilisé pour forcer l’affichage des messages d’erreur.',
143
- control: 'boolean',
144
- table: {
145
- type: { summary: 'boolean' },
146
- category: 'props',
147
- },
148
- },
149
- 'hasWarning': {
150
- description: 'Indique si le champ est en état d’avertissement. Utilisé pour forcer l’affichage des messages d’avertissement.',
151
- control: 'boolean',
152
- table: {
153
- type: { summary: 'boolean' },
154
- category: 'props',
155
- },
156
- },
157
- 'hasSuccess': {
158
- description: 'Indique si le champ est en état de succès. Utilisé pour forcer l’affichage des messages de succès.',
159
- control: 'boolean',
160
- table: {
161
- type: { summary: 'boolean' },
162
- category: 'props',
163
- },
164
- },
165
- 'showSuccessMessages': {
166
- description: 'Indique si les messages de succès doivent être affichés.',
167
- control: 'boolean',
168
- table: {
169
- type: { summary: 'boolean' },
170
- category: 'props',
171
- },
172
- },
173
- 'disabled': {
174
- description: 'Indique si le champ de saisie est désactivé. Lorsqu’il est désactivé, le sélecteur de mois ne peut pas être ouvert et aucune interaction n’est possible.',
175
- control: 'boolean',
176
- table: {
177
- type: { summary: 'boolean' },
178
- defaultValue: { summary: 'false' },
179
- category: 'props',
180
- },
181
- },
182
- 'readonly': {
183
- description: 'Indique si le champ de saisie est en lecture seule. Lorsqu’il est en lecture seule, le sélecteur de mois peut être ouvert pour afficher la valeur sélectionnée, mais aucune modification n’est possible.',
184
- control: 'boolean',
185
- table: {
186
- type: { summary: 'boolean' },
187
- defaultValue: { summary: 'false' },
121
+ type: { summary: 'string' },
188
122
  category: 'props',
189
123
  },
190
- category: 'props',
191
124
  },
192
125
  'onUpdate:modelValue': {
193
126
  action: 'update:modelValue',
@@ -271,26 +204,16 @@ export const Default: Story = {
271
204
  },
272
205
  }
273
206
 
274
- export const MonthValidation: Story = {
207
+ export const Required: Story = {
275
208
  args: {
276
- 'modelValue': '11/2025',
209
+ 'modelValue': '',
277
210
  'label': 'Début du projet',
211
+ 'required': true,
212
+ 'displayAsterisk': true,
213
+ 'width': '400px',
278
214
  'onUpdate:modelValue': fn(),
279
215
  'onUpdate:open': fn(),
280
216
  },
281
- play: async ({ canvasElement }) => {
282
- const input = canvasElement.querySelector('input') as HTMLInputElement
283
- const currentDate = new Date()
284
-
285
- setTimeout(async () => {
286
- input.focus()
287
- const futureYear = currentDate.getFullYear() + 6
288
- input.value = `11/${futureYear}`
289
- input.dispatchEvent(new Event('input'))
290
- await nextTick()
291
- input.dispatchEvent(new Event('blur'))
292
- }, 100)
293
- },
294
217
  parameters: {
295
218
  sourceCode: [
296
219
  {
@@ -300,8 +223,9 @@ export const MonthValidation: Story = {
300
223
  <MonthPicker
301
224
  v-model="selectedMonth"
302
225
  label="Début du projet"
303
- :custom-rules
304
- :custom-warning-rules
226
+ width="400px"
227
+ required
228
+ display-asterisk
305
229
  />
306
230
  </template>
307
231
  `,
@@ -312,114 +236,12 @@ export const MonthValidation: Story = {
312
236
  import { MonthPicker } from '@cnamts/synapse'
313
237
  import { ref } from 'vue'
314
238
 
315
- const selectedMonth = ref('11/2025')
316
-
317
- const customRules = [
318
- {
319
- type: 'required',
320
- options: {
321
- message: 'Ce champ est requis.',
322
- },
323
- },
324
- {
325
- type: 'custom',
326
- options: {
327
- validate: (value: string) => {
328
- const [month] = value.split('/').map(Number)
329
- if (
330
- !value ||
331
- !month ||
332
- !/^\\d{2}\\/\\d{4}$/.test(value) ||
333
- month < 1 ||
334
- month > 12
335
- ) {
336
- return false
337
- }
338
- return true
339
- },
340
- message: 'Format de mois invalide.',
341
- },
342
- },
343
- ]
344
-
345
- const customWarningRules = [{
346
- type: 'custom',
347
- options: {
348
- validate: (value: string) => {
349
- const [month, year] = value.split('/').map(Number) as [number, number]
350
- const currentDate = new Date()
351
- const currentYear = currentDate.getFullYear()
352
- const currentMonth = currentDate.getMonth() + 1
353
- if (year > currentYear + 5 || (year === currentYear + 5 && month > currentMonth)) {
354
- return false
355
- }
356
- return true
357
- },
358
- warningMessage: 'La date est plus de 5 ans dans le futur.',
359
- },
360
- }]
239
+ const selectedMonth = ref('')
361
240
  </script>
362
241
  `,
363
242
  },
364
243
  ],
365
244
  },
366
- render: args => ({
367
- components: { MonthPicker },
368
- setup() {
369
- const customRules = [
370
- {
371
- type: 'required',
372
- options: {
373
- message: 'Ce champ est requis.',
374
- },
375
- },
376
- {
377
- type: 'custom',
378
- options: {
379
- validate: (value: string) => {
380
- const [month] = value.split('/').map(Number)
381
- if (
382
- !month
383
- || !/^\d{2}\/\d{4}$/.test(value)
384
- || month < 1
385
- || month > 12
386
- ) {
387
- return false
388
- }
389
- return true
390
- },
391
- message: 'Format de mois invalide.',
392
- },
393
- },
394
- ]
395
-
396
- const customWarningRules = [{
397
- type: 'custom',
398
- options: {
399
- validate: (value: string) => {
400
- const [month, year] = value.split('/').map(Number) as [number, number]
401
- const currentDate = new Date()
402
- const currentYear = currentDate.getFullYear()
403
- const currentMonth = currentDate.getMonth() + 1
404
- if (year > currentYear + 5 || (year === currentYear + 5 && month > currentMonth)) {
405
- return false
406
- }
407
- return true
408
- },
409
- warningMessage: 'La date est plus de 5 ans dans le futur.',
410
- },
411
- }]
412
- return { args, customRules, customWarningRules }
413
- },
414
- template: `
415
- <MonthPicker
416
- v-bind="args"
417
- :custom-rules="customRules"
418
- :custom-warning-rules="customWarningRules"
419
- width="400px"
420
- />
421
- `,
422
- }),
423
245
  }
424
246
 
425
247
  export const CustomDisplayedYears: Story = {
@@ -460,68 +282,3 @@ export const CustomDisplayedYears: Story = {
460
282
  ],
461
283
  },
462
284
  }
463
-
464
- export const Form: Story = {
465
- args: {
466
- modelValue: '',
467
- label: 'Début du projet',
468
- width: '400px',
469
- },
470
- parameters: {
471
- sourceCode: [
472
- {
473
- name: 'Template',
474
- code: `
475
- <template>
476
- <SyForm @submit="handleSubmit">
477
- <MonthPicker
478
- v-model="selectedMonth"
479
- label="Début du projet"
480
- width="400px"
481
- :custom-rules="[{ type: 'required', options: { message: 'Ce champ est requis.' } }]"
482
- />
483
- <VBtn type="submit" color="primary" class="mt-4">Soumettre</VBtn>
484
- </SyForm>
485
- </template>
486
- `,
487
- }, {
488
- name: 'Script',
489
- code: `
490
- <script setup lang="ts">
491
- import { MonthPicker, SyForm } from '@cnamts/synapse'
492
- import { ref } from 'vue'
493
-
494
- const selectedMonth = ref('')
495
-
496
- const handleSubmit = (e: { isValid: boolean }) => {
497
- alert(e.isValid ? 'Le formulaire est valide.' : 'Le formulaire est invalide.')
498
- }
499
- </script>
500
- `,
501
- },
502
- ],
503
- },
504
- render: args => ({
505
- components: { MonthPicker, SyForm },
506
- setup() {
507
- const selectedMonth = ref('')
508
-
509
- const handleSubmit = (e: { isValid: boolean }) => {
510
- alert(e.isValid ? 'Le formulaire est valide.' : 'Le formulaire est invalide.')
511
- }
512
-
513
- return { args, selectedMonth, handleSubmit }
514
- },
515
- template: `
516
- <SyForm @submit="handleSubmit">
517
- <MonthPicker
518
- v-bind="args"
519
- v-model="selectedMonth"
520
- width="400px"
521
- :custom-rules="[{ type: 'required', options: { message: 'Ce champ est requis.' } }]"
522
- />
523
- <VBtn type="submit" color="primary" class="mt-4">Soumettre</VBtn>
524
- </SyForm>
525
- `,
526
- }),
527
- }
@@ -1,27 +1,25 @@
1
1
  <script lang="ts" setup>
2
- import { computed, provide, ref, useAttrs, type ComponentPublicInstance } from 'vue'
2
+ import { computed, provide, ref, toRef, useAttrs, type ComponentPublicInstance } from 'vue'
3
3
  import MonthPickerInput from './MonthPickerText/MonthPickerInput.vue'
4
4
  import MonthPickerVisual from './MonthPickerVisual/MonthPickerVisual.vue'
5
5
  import { watch } from 'vue'
6
6
  import { locales as defaultLocales, localesKey } from './locales'
7
- import { defaultTextFieldProps, useTextField, type TextFieldProps } from './MonthPickerText/useTextField'
8
- import { defaultMonthPickerVisualProps, type MonthPickerVisualProps } from './MonthPickerVisual/MonthPickerVisualProps'
9
- import { useMonthPickerValidation, type ValidationProps } from './useMonthPickerValidation'
7
+ import { defaultTextFieldProps, useTextField } from './MonthPickerText/useTextField'
8
+ import { defaultMonthPickerVisualProps } from './MonthPickerVisual/MonthPickerVisualProps'
9
+ import { useMonthPickerValidation } from './useMonthPickerValidation'
10
+ import { validationPropsDefaults } from '@/composables/unifyValidation/useValidation'
11
+ import type { MonthPickerProps } from './types'
10
12
 
11
- const props = withDefaults(defineProps<{
12
- modelValue?: string
13
- locales?: typeof defaultLocales
14
- disabled?: boolean
15
- readonly?: boolean
16
- } & TextFieldProps & ValidationProps & Partial<MonthPickerVisualProps>>(), {
13
+ const props = withDefaults(defineProps<MonthPickerProps>(), {
17
14
  modelValue: undefined,
18
15
  locales: () => defaultLocales,
19
- hint: 'Format MM/AAAA',
20
- showSuccessMessages: false,
16
+ helpText: 'Format MM/AAAA',
17
+ ...validationPropsDefaults,
21
18
  ...defaultMonthPickerVisualProps,
22
19
  ...defaultTextFieldProps,
23
20
  disabled: false,
24
21
  readonly: false,
22
+ displayAsterisk: false,
25
23
  })
26
24
 
27
25
  provide(localesKey, computed(() => props.locales))
@@ -50,6 +48,58 @@
50
48
  emits('update:modelValue', newValue)
51
49
  }
52
50
  })
51
+
52
+ const focused = ref(false)
53
+
54
+ const { errors, warnings, successes, hasError, hasWarning, hasSuccess, validate, clearValidation } = useMonthPickerValidation({
55
+ modelValue: internalValue,
56
+ readonly: toRef(props, 'readonly'),
57
+ disabled: toRef(props, 'disabled'),
58
+ required: toRef(props, 'required'),
59
+ isValidateOnBlur: toRef(props, 'isValidateOnBlur'),
60
+ showSuccessMessages: toRef(props, 'showSuccessMessages'),
61
+ disableErrorHandling: toRef(props, 'disableErrorHandling'),
62
+ useVuetifyValidation: toRef(props, 'useVuetifyValidation'),
63
+ label: toRef(props, 'label'),
64
+ rules: toRef(props, 'rules'),
65
+ customRules: toRef(props, 'customRules'),
66
+ customWarningRules: toRef(props, 'customWarningRules'),
67
+ customSuccessRules: toRef(props, 'customSuccessRules'),
68
+ errorMessages: toRef(props, 'errorMessages'),
69
+ warningMessages: toRef(props, 'warningMessages'),
70
+ successMessages: toRef(props, 'successMessages'),
71
+ hasErrorProp: toRef(props, 'hasError'),
72
+ hasWarningProp: toRef(props, 'hasWarning'),
73
+ hasSuccessProp: toRef(props, 'hasSuccess'),
74
+ maxErrors: toRef(props, 'maxErrors'),
75
+ focused,
76
+ locales: toRef(props, 'locales'),
77
+ })
78
+
79
+ const inputProps = computed(() => ({
80
+ ...attrs,
81
+ ...useTextField(props).value,
82
+ required: props.required,
83
+ displayAsterisk: props.displayAsterisk,
84
+ errorMessages: errors.value,
85
+ warningMessages: warnings.value,
86
+ successMessages: successes.value,
87
+ hasError: hasError.value,
88
+ hasWarning: hasWarning.value,
89
+ hasSuccess: hasSuccess.value,
90
+ showSuccessMessages: props.showSuccessMessages,
91
+ }))
92
+
93
+ defineExpose({
94
+ errors,
95
+ warnings,
96
+ successes,
97
+ hasError,
98
+ hasWarning,
99
+ hasSuccess,
100
+ validateOnSubmit: validate,
101
+ clearValidation,
102
+ })
53
103
  </script>
54
104
 
55
105
  <template>
@@ -57,11 +107,9 @@
57
107
  <MonthPickerInput
58
108
  ref="textInput"
59
109
  v-model="internalValue"
60
- v-bind="{
61
- ...attrs,
62
- ...useTextField(props).value,
63
- ...useMonthPickerValidation(props).value
64
- }"
110
+ v-bind="inputProps"
111
+ @focus="focused = true"
112
+ @blur="focused = false"
65
113
  />
66
114
  <MonthPickerVisual
67
115
  v-model="internalValue"
@@ -74,6 +122,7 @@
74
122
  :disabled
75
123
  :readonly
76
124
  @update:open="emits('update:open', $event)"
125
+ @update:model-value="validate"
77
126
  />
78
127
  </div>
79
128
  </template>
@@ -3,48 +3,58 @@
3
3
  import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue'
4
4
  import { mdiCalendar } from '@mdi/js'
5
5
  import { vMaska } from 'maska/vue'
6
- import { nextTick, inject, ref, watch } from 'vue'
6
+ import { inject, ref, useId, watch } from 'vue'
7
7
  import { locales as defaultLocales, localesKey } from '../locales'
8
8
  import type { TextFieldProps } from './useTextField'
9
9
  import { useTextField } from './useTextField'
10
- import { useMonthPickerValidation, type ValidationProps } from '../useMonthPickerValidation'
11
10
 
12
- const props = defineProps<{
11
+ const props = withDefaults(defineProps<{
13
12
  modelValue: string | undefined
14
- } & TextFieldProps & ValidationProps>()
13
+ errorMessages?: string[] | null
14
+ warningMessages?: string[] | null
15
+ successMessages?: string[] | null
16
+ hasError?: boolean
17
+ hasWarning?: boolean
18
+ hasSuccess?: boolean
19
+ required?: boolean
20
+ displayAsterisk?: boolean
21
+ hideDetails?: boolean
22
+ } & TextFieldProps>(), {
23
+ errorMessages: null,
24
+ warningMessages: null,
25
+ successMessages: null,
26
+ hasError: false,
27
+ hasWarning: false,
28
+ hasSuccess: false,
29
+ required: false,
30
+ displayAsterisk: false,
31
+ hideDetails: false,
32
+ })
15
33
 
16
34
  const emits = defineEmits<{
17
35
  (e: 'update:modelValue', value: string | undefined): void
18
36
  }>()
19
37
 
20
38
  const locales = inject<typeof defaultLocales>(localesKey)!
21
- const input = ref<InstanceType<typeof SyTextField>>()
22
39
 
23
40
  const mask = '##/####'
24
41
 
25
42
  const innerValue = ref<string | undefined>(props.modelValue)
43
+ const focused = ref(false)
44
+
26
45
  watch(
27
46
  () => props.modelValue,
28
47
  async (newValue) => {
29
- const shouldValidate = newValue !== innerValue.value
30
48
  innerValue.value = newValue
31
- if (shouldValidate) {
32
- await nextTick()
33
- input.value?.validateOnSubmit()
34
- }
35
49
  },
36
50
  )
37
51
 
38
52
  watch(innerValue, async (newValue) => {
39
- if (newValue?.length === mask.length) {
40
- await nextTick()
41
- input.value?.validateOnSubmit()
42
- }
43
-
44
53
  emits('update:modelValue', newValue)
45
54
  })
46
55
 
47
56
  const toggleBtn = ref<HTMLButtonElement | null>(null)
57
+ const uniqueName = useId()
48
58
  defineExpose({
49
59
  toggleBtn,
50
60
  })
@@ -52,13 +62,22 @@
52
62
 
53
63
  <template>
54
64
  <SyTextField
55
- ref="input"
56
65
  v-model="innerValue"
57
66
  v-maska="mask"
58
- v-bind="{
59
- ...useTextField(props).value,
60
- ...useMonthPickerValidation(props).value
61
- }"
67
+ v-bind="useTextField(props).value"
68
+ :name="uniqueName"
69
+ :error-messages="props.errorMessages"
70
+ :warning-messages="props.warningMessages"
71
+ :success-messages="props.successMessages"
72
+ :has-error="props.hasError"
73
+ :has-warning="props.hasWarning"
74
+ :has-success="props.hasSuccess"
75
+ :required="props.required"
76
+ :disable-error-handling="true"
77
+ :hide-details="props.hideDetails"
78
+ :display-asterisk="props.required && props.displayAsterisk"
79
+ @focus="focused = true"
80
+ @blur="focused = false"
62
81
  >
63
82
  <template #append>
64
83
  <button
@@ -86,4 +105,9 @@
86
105
  color: rgb(var(--v-theme-warning, 96, 72, 14));
87
106
  }
88
107
 
108
+ :deep(.v-field__clearable .v-icon__svg) {
109
+ fill: rgb(var(--v-theme-iconBase)) !important;
110
+ opacity: var(--v-medium-emphasis-opacity) !important;
111
+ }
112
+
89
113
  </style>
@@ -4,15 +4,18 @@ export type TextFieldProps = {
4
4
  label: string
5
5
  density?: 'default' | 'comfortable' | 'compact'
6
6
  hint?: string | false
7
+ helpText?: string
7
8
  placeholder?: string
8
9
  disabled?: boolean
9
10
  readonly?: boolean
11
+ clearable?: boolean
10
12
  }
11
13
 
12
14
  export const defaultTextFieldProps = {
13
15
  density: 'default',
14
16
  disabled: false,
15
17
  readonly: false,
18
+ clearable: false,
16
19
  } as const satisfies Partial<TextFieldProps>
17
20
 
18
21
  export function useTextField(props: TextFieldProps) {
@@ -20,8 +23,10 @@ export function useTextField(props: TextFieldProps) {
20
23
  label: props.label,
21
24
  density: props.density,
22
25
  hint: props.hint || undefined,
26
+ helpText: props.helpText || undefined,
23
27
  placeholder: props.placeholder,
24
28
  disabled: props.disabled ? true : undefined,
25
29
  readonly: props.readonly ? true : undefined,
30
+ clearable: props.clearable,
26
31
  }))
27
32
  }