@cnamts/synapse 1.0.6 → 1.0.8

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 (235) hide show
  1. package/dist/{DateFilter-BlOpwEVq.js → DateFilter-DkqG0pmr.js} +1 -1
  2. package/dist/{NumberFilter-BPUXE4wY.js → NumberFilter-Ck7AwD39.js} +1 -1
  3. package/dist/{PeriodFilter-B2yx329_.js → PeriodFilter-LRI6YpgU.js} +1 -1
  4. package/dist/{SelectFilter-CedKn1oV.js → SelectFilter-DPc70Jk7.js} +1 -1
  5. package/dist/{TextFilter-DkhJjRtR.js → TextFilter-DRQL7uD8.js} +1 -1
  6. package/dist/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.d.ts +116 -0
  7. package/dist/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
  8. package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +220 -0
  9. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +68 -0
  10. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +70 -0
  11. package/dist/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.d.ts +204 -0
  12. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +26 -26
  13. package/dist/components/Amelipro/AmeliproBadge/AmeliproBadge.d.ts +59 -0
  14. package/dist/components/Amelipro/AmeliproBtn/AmeliproBtn.d.ts +3 -3
  15. package/dist/components/Amelipro/AmeliproCaptcha/AmeliproCaptcha.d.ts +1 -1
  16. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +214 -0
  17. package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.d.ts +70 -0
  18. package/dist/components/Amelipro/AmeliproCarousel/types.d.ts +7 -0
  19. package/dist/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.d.ts +125 -0
  20. package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +1 -1
  21. package/dist/components/Amelipro/AmeliproIllustratedDataTile/AmeliproIllustratedDataTile.d.ts +2 -2
  22. package/dist/components/Amelipro/AmeliproResultList/AmeliproResultList.d.ts +164 -0
  23. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +27 -27
  24. package/dist/components/Amelipro/AmeliproStateTile/AmeliproStateTile.d.ts +1 -1
  25. package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +1 -1
  26. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +32 -32
  27. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +6 -6
  28. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +7 -7
  29. package/dist/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.d.ts +1 -1
  30. package/dist/components/Amelipro/AmeliproTooltips/AmeliproTooltips.d.ts +2 -2
  31. package/dist/components/ChipList/ChipList.d.ts +4 -0
  32. package/dist/components/ChipList/locales.d.ts +4 -2
  33. package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +8 -8
  34. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +329 -1296
  35. package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +0 -1
  36. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +2 -0
  37. package/dist/components/Customs/SyTabs/SyTabs.d.ts +71 -0
  38. package/dist/components/Customs/SyTabs/config.d.ts +17 -0
  39. package/dist/components/Customs/SyTabs/types.d.ts +11 -0
  40. package/dist/components/Customs/SyTextField/SyTextField.d.ts +9 -9
  41. package/dist/components/DataList/DataList.d.ts +1 -1
  42. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +4811 -240
  43. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +52 -33
  44. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -10
  45. package/dist/components/DatePicker/composables/useDateInputEditing.d.ts +1 -0
  46. package/dist/components/DatePicker/composables/useTodayButton.d.ts +1 -0
  47. package/dist/components/DialogBox/DialogBox.d.ts +219 -0
  48. package/dist/components/HeaderLoading/HeaderLoading.d.ts +27 -0
  49. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +110 -3
  50. package/dist/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.d.ts +19 -1
  51. package/dist/components/LangBtn/LangBtn.d.ts +2 -2
  52. package/dist/components/NirField/NirField.d.ts +18 -18
  53. package/dist/components/PeriodField/PeriodField.d.ts +10766 -1620
  54. package/dist/components/PhoneField/PhoneField.d.ts +1866 -2
  55. package/dist/components/PhoneField/indicatifs.d.ts +1 -0
  56. package/dist/components/PhoneField/locales.d.ts +1 -0
  57. package/dist/components/RangeField/RangeField.d.ts +1 -1
  58. package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +1 -1
  59. package/dist/components/SubHeader/SubHeader.d.ts +8 -0
  60. package/dist/components/SubHeader/locales.d.ts +1 -0
  61. package/dist/components/SyTextArea/SyTextArea.d.ts +6 -6
  62. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -4
  63. package/dist/components/Tables/SyTable/SyTable.d.ts +5 -4
  64. package/dist/components/Tables/common/SyTablePagination.d.ts +333 -1296
  65. package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +2 -2
  66. package/dist/components/Tables/common/types.d.ts +2 -0
  67. package/dist/components/index.d.ts +9 -0
  68. package/dist/design-system-v3.js +173 -164
  69. package/dist/design-system-v3.umd.cjs +286 -263
  70. package/dist/{main-BXPFSAB4.js → main-DXMoMtj5.js} +13176 -11457
  71. package/dist/services/NotificationService.d.ts +1 -0
  72. package/dist/style.css +1 -1
  73. package/package.json +1 -1
  74. package/src/assets/amelipro/icons.ts +38 -11
  75. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.mdx +20 -0
  76. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.stories.ts +135 -0
  77. package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.vue +107 -0
  78. package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/AmeliproAccordionGroup.spec.ts +37 -0
  79. package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/__snapshots__/AmeliproAccordionGroup.spec.ts.snap +513 -0
  80. package/src/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
  81. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.mdx +16 -0
  82. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +300 -0
  83. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +288 -0
  84. package/src/components/Amelipro/AmeliproAccordionList/__tests__/AmeliproAccordionList.spec.ts +38 -0
  85. package/src/components/Amelipro/AmeliproAccordionList/__tests__/__snapshots__/AmeliproAccordionList.spec.ts.snap +1712 -0
  86. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.mdx +19 -0
  87. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +68 -0
  88. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +66 -0
  89. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.vue +145 -0
  90. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/AmeliproAccordionResultTemplate.spec.ts +24 -0
  91. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/__snapshots__/AmeliproAccordionResultTemplate.spec.ts.snap +127 -0
  92. package/src/components/Amelipro/AmeliproAccordionResult/__tests__/AmeliproAccordionResult.spec.ts +24 -0
  93. package/src/components/Amelipro/AmeliproAccordionResult/__tests__/__snapshots__/AmeliproAccordionResult.spec.ts.snap +123 -0
  94. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.mdx +20 -0
  95. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +273 -0
  96. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +275 -0
  97. package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/AmeliproAccordionResultList.spec.ts +38 -0
  98. package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/__snapshots__/AmeliproAccordionResultList.spec.ts.snap +1593 -0
  99. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.mdx +15 -0
  100. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.stories.ts +54 -0
  101. package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.vue +76 -0
  102. package/src/components/Amelipro/AmeliproBadge/__tests__/AmeliproBadge.spec.ts +20 -0
  103. package/src/components/Amelipro/AmeliproBadge/__tests__/__snapshots__/AmeliproBadge.spec.ts.snap +19 -0
  104. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.mdx +15 -0
  105. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.stories.ts +191 -0
  106. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.vue +263 -0
  107. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.vue +93 -0
  108. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/AmeliproCarouselItem.spec.ts +24 -0
  109. package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/__snapshots__/AmeliproCarouselItem.spec.ts.snap +43 -0
  110. package/src/components/Amelipro/AmeliproCarousel/__tests__/AmeliproCarousel.spec.ts +40 -0
  111. package/src/components/Amelipro/AmeliproCarousel/__tests__/__snapshots__/AmeliproCarousel.spec.ts.snap +342 -0
  112. package/src/components/Amelipro/AmeliproCarousel/types.d.ts +8 -0
  113. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.mdx +18 -0
  114. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.stories.ts +67 -0
  115. package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +233 -0
  116. package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.spec.ts +21 -0
  117. package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +140 -0
  118. package/src/components/Amelipro/AmeliproHeader/AmeliproHeader.vue +7 -1
  119. package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +5 -4
  120. package/src/components/Amelipro/AmeliproIcon/iconList.ts +6 -0
  121. package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +5 -4
  122. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.mdx +15 -0
  123. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.stories.ts +264 -0
  124. package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.vue +231 -0
  125. package/src/components/Amelipro/AmeliproResultList/__tests__/AmeliproResultList.spec.ts +37 -0
  126. package/src/components/Amelipro/AmeliproResultList/__tests__/__snapshots__/AmeliproResultList.spec.ts.snap +434 -0
  127. package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +6 -5
  128. package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +23 -26
  129. package/src/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.stories.ts +2 -2
  130. package/src/components/ChipList/Accessibilite.stories.ts +4 -0
  131. package/src/components/ChipList/ChipList.vue +185 -42
  132. package/src/components/ChipList/locales.ts +4 -2
  133. package/src/components/ChipList/tests/chipList.spec.ts +7 -4
  134. package/src/components/Customs/Selects/SelectOverview.mdx +34 -66
  135. package/src/components/Customs/Selects/SyBtnSelect/SyBtnSelect.stories.ts +10 -10
  136. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.mdx +3 -0
  137. package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +14 -0
  138. package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +14 -6
  139. package/src/components/Customs/Selects/SySelect/SySelect.vue +268 -205
  140. package/src/components/Customs/Selects/SySelect/composables/tests/useSySelectKeyboard.spec.ts +0 -10
  141. package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +0 -5
  142. package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +184 -25
  143. package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +3 -1
  144. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +165 -0
  145. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +28 -9
  146. package/src/components/Customs/SyTabs/Accessibilite.mdx +309 -0
  147. package/src/components/Customs/SyTabs/SyTabs.mdx +117 -0
  148. package/src/components/Customs/SyTabs/SyTabs.stories.ts +354 -0
  149. package/src/components/Customs/SyTabs/SyTabs.vue +413 -0
  150. package/src/components/Customs/SyTabs/config.ts +17 -0
  151. package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +425 -0
  152. package/src/components/Customs/SyTabs/types.ts +12 -0
  153. package/src/components/Customs/SyTextField/SyTextField.mdx +3 -0
  154. package/src/components/Customs/SyTextField/SyTextField.stories.ts +142 -1
  155. package/src/components/Customs/SyTextField/SyTextField.vue +19 -16
  156. package/src/components/DataList/DataList.vue +47 -49
  157. package/src/components/DataListGroup/DataListGroup.vue +1 -1
  158. package/src/components/DataListItem/DataListItem.vue +67 -63
  159. package/src/components/DataListItem/tests/DataListItem.spec.ts +2 -2
  160. package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +3 -3
  161. package/src/components/DatePicker/CalendarMode/DatePicker.vue +49 -13
  162. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +412 -649
  163. package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +215 -0
  164. package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +218 -0
  165. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.mdx +2 -0
  166. package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
  167. package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +218 -0
  168. package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +281 -0
  169. package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +17 -4
  170. package/src/components/DatePicker/DateTextInput/DateTextInput.range.spec.ts +111 -18
  171. package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +238 -6
  172. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +716 -757
  173. package/src/components/DatePicker/composables/tests/useDateInputEditing.spec.ts +4 -4
  174. package/src/components/DatePicker/composables/tests/useDisplayedDateString.spec.ts +17 -10
  175. package/src/components/DatePicker/composables/useDateInputEditing.ts +52 -22
  176. package/src/components/DatePicker/composables/useDisplayedDateString.ts +18 -4
  177. package/src/components/DatePicker/composables/useTodayButton.ts +13 -1
  178. package/src/components/DatePicker/utils/dateFormattingUtils.ts +79 -14
  179. package/src/components/DialogBox/DialogBox.stories.ts +12 -0
  180. package/src/components/DialogBox/DialogBox.vue +16 -11
  181. package/src/components/DialogBox/tests/DialogBox.spec.ts +22 -0
  182. package/src/components/HeaderLoading/Accessibilite.mdx +429 -8
  183. package/src/components/HeaderLoading/Accessibilite.stories.ts +4 -0
  184. package/src/components/HeaderLoading/HeaderLoading.vue +59 -0
  185. package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +17 -2
  186. package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +91 -2
  187. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +37 -1
  188. package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +284 -21
  189. package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +2 -2
  190. package/src/components/NirField/NirField.mdx +3 -0
  191. package/src/components/NirField/NirField.vue +10 -1
  192. package/src/components/NirField/tests/NirField.spec.ts +81 -0
  193. package/src/components/NotificationBar/NotificationBar.stories.ts +128 -2
  194. package/src/components/NotificationBar/NotificationBar.vue +16 -1
  195. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +65 -0
  196. package/src/components/PasswordField/PasswordField.mdx +3 -0
  197. package/src/components/PeriodField/PeriodField.mdx +2 -0
  198. package/src/components/PeriodField/PeriodField.stories.ts +195 -0
  199. package/src/components/PhoneField/Accessibilite.stories.ts +4 -0
  200. package/src/components/PhoneField/PhoneField.mdx +3 -1
  201. package/src/components/PhoneField/PhoneField.stories.ts +285 -1
  202. package/src/components/PhoneField/PhoneField.vue +228 -95
  203. package/src/components/PhoneField/indicatifs.ts +102 -102
  204. package/src/components/PhoneField/locales.ts +1 -0
  205. package/src/components/PhoneField/tests/PhoneField.spec.ts +419 -2
  206. package/src/components/SkipLink/SkipLink.vue +3 -31
  207. package/src/components/SkipLink/tests/skipLink.spec.ts +0 -21
  208. package/src/components/SubHeader/Accessibilite.stories.ts +8 -0
  209. package/src/components/SubHeader/SubHeader.mdx +1 -0
  210. package/src/components/SubHeader/SubHeader.stories.ts +179 -60
  211. package/src/components/SubHeader/SubHeader.vue +45 -15
  212. package/src/components/SubHeader/locales.ts +1 -0
  213. package/src/components/SyAlert/SyAlert.vue +6 -0
  214. package/src/components/Tables/SyServerTable/SyServerTable.mdx +3 -10
  215. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +242 -0
  216. package/src/components/Tables/SyServerTable/SyServerTable.vue +29 -10
  217. package/src/components/Tables/SyTable/SyTable.mdx +3 -10
  218. package/src/components/Tables/SyTable/SyTable.stories.ts +242 -0
  219. package/src/components/Tables/SyTable/SyTable.vue +2 -0
  220. package/src/components/Tables/common/SyTablePagination.vue +13 -6
  221. package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +6 -1
  222. package/src/components/Tables/common/tests/SyTablePagination.spec.ts +157 -0
  223. package/src/components/Tables/common/types.ts +2 -0
  224. package/src/components/index.ts +9 -0
  225. package/src/composables/useFilterable/useFilterable.ts +10 -0
  226. package/src/designTokens/tokens/amelipro/apColors.ts +1 -1
  227. package/src/designTokens/tokens/cnam/cnamSemantic.ts +3 -3
  228. package/src/services/NotificationService.ts +9 -0
  229. package/src/stories/Components/Components.stories.ts +1 -1
  230. package/src/stories/GuideDuDev/FormValidationGuide.mdx +342 -0
  231. package/src/stories/Templates/Templates.stories.ts +1 -1
  232. package/src/utils/functions/ameliproColors/ameliproColors.ts +1 -1
  233. package/dist/components/DataList/locales.d.ts +0 -3
  234. package/src/components/DataList/locales.ts +0 -3
  235. package/src/components/PhoneField/tests/PhoneField.additional.spec.ts +0 -266
@@ -0,0 +1,342 @@
1
+ import { Meta, Source } from '@storybook/addon-docs/blocks';
2
+
3
+ <Meta title="Guide Du Dev/Guide de Validation des Formulaires"/>
4
+
5
+ # Guide de Validation des Formulaires
6
+
7
+ Ce guide pratique explique comment utiliser le système de validation des formulaires du Design System dans vos applications.
8
+
9
+ ## Les bases de la validation
10
+
11
+ Le système de validation offre un mécanisme complet et intuitif pour valider les entrées utilisateur avec trois niveaux de retour :
12
+
13
+ - **Erreurs** 🔴 : Empêchent la soumission du formulaire
14
+ - **Avertissements** 🟠 : Informent l'utilisateur sans bloquer la soumission
15
+ - **Succès** 🟢 : Confirment la validité de l'entrée
16
+
17
+ ## Mise en place simple
18
+
19
+ Voici comment mettre en place une validation basique sur un champ :
20
+
21
+ <Source dark code={`
22
+ <template>
23
+ <SyTextField
24
+ v-model="email"
25
+ label="Email"
26
+ :custom-rules="emailRules"
27
+ />
28
+ </template>
29
+
30
+ <script setup>
31
+ import { ref } from 'vue';
32
+ import { SyTextField } from '@cnamts/synapse';
33
+
34
+ const email = ref('');
35
+
36
+ const emailRules = [
37
+ {
38
+ type: 'required',
39
+ options: { message: "L'email est obligatoire" }
40
+ },
41
+ {
42
+ type: 'email',
43
+ options: { message: "L'email n'est pas valide" }
44
+ }
45
+ ];
46
+ </script>
47
+ `}/>
48
+
49
+ ## Validation complète avec les 3 niveaux
50
+
51
+ Utilisez les différents types de règles pour une expérience utilisateur riche :
52
+
53
+ <Source dark code={`
54
+ <script setup>
55
+ import { ref } from 'vue'
56
+ import PasswordField from '@/components/PasswordField/PasswordField.vue'
57
+
58
+ const password = ref('')
59
+
60
+ // Règles d'erreur (bloquantes)
61
+ const passwordRules = [
62
+ {
63
+ type: 'required',
64
+ options: {
65
+ message: 'Le mot de passe est obligatoire',
66
+ },
67
+ },
68
+ {
69
+ type: 'minLength',
70
+ options: {
71
+ length: 8,
72
+ message: 'Le mot de passe doit contenir au moins 8 caractères',
73
+ // si pas de successMessage, le message par defaut est affiché
74
+ successMessage: 'Le mot de passe est sécurisé',
75
+ },
76
+ },
77
+ ]
78
+
79
+ // Règles d'avertissement (non-bloquantes)
80
+ const passwordWarningRules = [
81
+ {
82
+ type: 'custom',
83
+ options: {
84
+ validate: (value) => {
85
+ const hasSpecialChar = /[!@#$%^&*(),.?":{}|<>]/.test(value)
86
+ if (!hasSpecialChar) {
87
+ return 'Le mot de passe pourrait être plus fort avec des caractères spéciaux'
88
+ }
89
+ return true
90
+ },
91
+ fieldIdentifier: 'password',
92
+ },
93
+ },
94
+ ]
95
+
96
+ </script>
97
+
98
+ <template>
99
+ <PasswordField
100
+ v-model="password"
101
+ label="Mot de passe"
102
+ :custom-warning-rules="passwordWarningRules"
103
+ :custom-rules="passwordRules"
104
+ />
105
+ </template>
106
+
107
+ `}/>
108
+
109
+ ## Validation à la soumission avec validateOnSubmit
110
+
111
+ La méthode `validateOnSubmit` est essentielle pour valider l'ensemble du formulaire lors de sa soumission :
112
+
113
+ <Source dark code={`
114
+ <template>
115
+ <form @submit.prevent="handleSubmit">
116
+ <SyTextField
117
+ ref="emailField"
118
+ v-model="email"
119
+ label="Email"
120
+ :custom-rules="emailRules"
121
+ />
122
+
123
+ <PasswordField
124
+ ref="passwordField"
125
+ v-model="password"
126
+ label="Mot de passe"
127
+ type="password"
128
+ :custom-rules="passwordRules"
129
+ />
130
+
131
+ <VBtn type="submit">Se connecter</VBtn>
132
+
133
+ <p v-if="formError" class="error-message">{{ formError }}</p>
134
+ </form>
135
+ </template>
136
+
137
+ <script setup>
138
+ import { ref } from 'vue';
139
+ import { SyTextField, PasswordField } from '@cnamts/synapse';
140
+
141
+ const email = ref('');
142
+ const password = ref('');
143
+ const formError = ref('');
144
+
145
+ const emailField = ref();
146
+ const passwordField = ref();
147
+
148
+ const emailRules = [
149
+ { type: 'required', options: { message: "L'email est obligatoire" } },
150
+ { type: 'email', options: { message: "L'email n'est pas valide" } }
151
+ ];
152
+
153
+ const passwordRules = [
154
+ { type: 'required', options: { message: 'Le mot de passe est obligatoire' } }
155
+ ];
156
+
157
+ const handleSubmit = async () => {
158
+ formError.value = '';
159
+
160
+ // Validation de tous les champs
161
+ const isEmailValid = await emailField.value.validateOnSubmit();
162
+ const isPasswordValid = await passwordField.value.validateOnSubmit();
163
+
164
+ if (isEmailValid && isPasswordValid) {
165
+ // Soumettre le formulaire
166
+ console.log('Formulaire soumis avec succès !');
167
+ // loginUser(email.value, password.value);
168
+ } else {
169
+ formError.value = 'Veuillez corriger les erreurs dans le formulaire';
170
+ }
171
+ };
172
+ </script>
173
+ `}/>
174
+
175
+ ## Validation croisée entre champs
176
+
177
+ Parfois, la validation d'un champ dépend de la valeur d'un autre champ. Voici comment gérer ce cas :
178
+
179
+ <Source dark code={`
180
+ <template>
181
+ <form @submit.prevent="handleSubmit">
182
+ <PasswordField
183
+ ref="passwordField"
184
+ v-model="password"
185
+ label="Mot de passe"
186
+ type="password"
187
+ :custom-rules="passwordRules"
188
+ />
189
+
190
+ <PasswordField
191
+ ref="confirmPasswordField"
192
+ v-model="confirmPassword"
193
+ label="Confirmer le mot de passe"
194
+ type="password"
195
+ :custom-rules="confirmPasswordRules"
196
+ />
197
+
198
+ <VBtn type="submit">S'inscrire</VBtn>
199
+ </form>
200
+ </template>
201
+
202
+ <script setup>
203
+ import { ref, watch } from 'vue';
204
+ import { PasswordField } from '@cnamts/synapse';
205
+
206
+ const password = ref('');
207
+ const confirmPassword = ref('');
208
+
209
+ const passwordField = ref();
210
+ const confirmPasswordField = ref();
211
+
212
+ const passwordRules = [
213
+ { type: 'required', options: { message: 'Le mot de passe est obligatoire' } },
214
+ { type: 'minLength', options: { length: 8, message: 'Le mot de passe doit contenir au moins 8 caractères' } }
215
+ ];
216
+
217
+ const confirmPasswordRules = [
218
+ { type: 'required', options: { message: 'La confirmation du mot de passe est obligatoire' } },
219
+ {
220
+ type: 'custom',
221
+ options: {
222
+ validate: (value) => {
223
+ if (value !== password.value) {
224
+ return 'Les mots de passe ne correspondent pas';
225
+ }
226
+ return true;
227
+ }
228
+ }
229
+ }
230
+ ];
231
+
232
+ // Revalider la confirmation lorsque le mot de passe change
233
+ watch(password, () => {
234
+ if (confirmPassword.value && confirmPasswordField.value) {
235
+ // Forcer la validation du champ de confirmation
236
+ confirmPasswordField.value.validateOnSubmit();
237
+ }
238
+ });
239
+
240
+ const handleSubmit = async () => {
241
+ // Validation de tous les champs
242
+ const isPasswordValid = await passwordField.value.validateOnSubmit();
243
+ const isConfirmValid = await confirmPasswordField.value.validateOnSubmit();
244
+
245
+ if (isPasswordValid && isConfirmValid) {
246
+ // Soumettre le formulaire
247
+ console.log('Inscription réussie !');
248
+ }
249
+ };
250
+ </script>
251
+ `}/>
252
+
253
+ ## Composants avec validation intégrée
254
+
255
+ Plusieurs composants du Design System intègrent déjà la validation :
256
+
257
+ - **SyTextField** : Pour les champs texte
258
+ - **NirField** : Pour les numéros de sécurité sociale
259
+ - **DatePicker** : Pour les dates
260
+ - **PeriodField** : Pour les périodes (deux dates liées)
261
+ - **PasswordField** : Pour les mots de passe sécurisés
262
+
263
+ ### Exemple avec NirField
264
+
265
+ <Source dark code={`
266
+ <template>
267
+ <form @submit.prevent="handleSubmit">
268
+ <NirField
269
+ ref="nirFieldRef"
270
+ v-model="nirValue"
271
+ label="Numéro de sécurité sociale"
272
+ />
273
+
274
+ <SyButton type="submit">Valider</SyButton>
275
+ </form>
276
+ </template>
277
+
278
+ <script setup>
279
+ import { ref } from 'vue';
280
+ import { NirField, SyButton } from '@cnamts/synapse';
281
+
282
+ const nirValue = ref('');
283
+ const nirFieldRef = ref();
284
+
285
+ const handleSubmit = async () => {
286
+ const isValid = await nirFieldRef.value.validateOnSubmit();
287
+
288
+ if (isValid) {
289
+ console.log('NIR valide :', nirValue.value);
290
+ }
291
+ };
292
+ </script>
293
+ `}/>
294
+
295
+ ## Règles de validation disponibles
296
+
297
+ ### Règles génériques
298
+ - `required` : Champ obligatoire
299
+ - `minLength` / `maxLength` : Longueur minimale/maximale
300
+ - `min` / `max` : Valeur minimale/maximale pour les nombres
301
+ - `email` : Format d'email valide
302
+ - `matchPattern` : Correspondance à une expression régulière
303
+
304
+ ### Règles de dates
305
+ - `notBeforeToday` / `notAfterToday` : Date après/avant aujourd'hui
306
+ - `notBeforeDate` / `notAfterDate` : Date après/avant une date spécifique
307
+ - `notWeekend` : Jour ouvrable
308
+ - `isHolidayDay` : Jour non férié
309
+
310
+ ### Règles personnalisées
311
+ Utilisez le type `custom` avec une fonction `validate` pour créer vos propres règles :
312
+
313
+ <Source dark code={`
314
+ const customRule = {
315
+ type: 'custom',
316
+ options: {
317
+ validate: (value) => {
318
+ // Votre logique personnalisée
319
+ if (!condition) {
320
+ return 'Message d\'erreur personnalisé';
321
+ }
322
+ return true; // Valide
323
+ },
324
+ // Optionnel : traiter comme avertissement au lieu d'erreur
325
+ isWarning: false
326
+ }
327
+ };
328
+ `}/>
329
+
330
+ ## Bonnes pratiques
331
+
332
+ 1. **Validation progressive** : Validez pendant la saisie pour une rétroaction immédiate
333
+ 2. **Messages clairs** : Utilisez des messages d'erreur explicites et constructifs
334
+ 3. **Validation côté client ET serveur** : Ne vous fiez jamais uniquement à la validation côté client
335
+ 4. **Utilisez validateOnSubmit** : Assurez-vous que tous les champs sont validés à la soumission
336
+ 5. **Hiérarchisez les erreurs** : Affichez d'abord les erreurs les plus importantes
337
+ 6. **Utilisez les avertissements** pour les recommandations non-bloquantes
338
+ 7. **Célébrez la réussite** avec des messages de succès pour renforcer les bonnes pratiques
339
+
340
+ ## Conclusion
341
+
342
+ Le système de validation du Design System vous permet de créer des formulaires intuitifs avec des retours utilisateur riches. En combinant validation à la saisie et validation à la soumission, vous offrez une expérience utilisateur optimale tout en garantissant l'intégrité des données.
@@ -10,7 +10,7 @@ export const Header: StoryObj = {
10
10
  return {
11
11
  template: `
12
12
  <div class="mb-8">
13
- <h1 class="text-h4 font-weight-bold mb-4">Templates</h1>
13
+ <h1 class="mb-4">Templates</h1>
14
14
  <p class="text-body-1">Découvrez notre collection de templates conçus pour accélérer le développement de vos IHM.</p>
15
15
  </div>
16
16
  `,
@@ -14,7 +14,7 @@ export const AmeliproColors: AmeliproColorsTypes = {
14
14
  apGreendarken1: { hexColor: '#459B5A' },
15
15
  apGreendarken2: { hexColor: '#337343' },
16
16
  apGreenlighten1: { hexColor: '#78CE8D' },
17
- apGreenlighten2: { hexColor: '#DDF3F3' },
17
+ apGreenlighten2: { hexColor: '#DDF3E3' },
18
18
  apGrey: { hexColor: '#545859' },
19
19
  apGreydarken1: { hexColor: '#1A1B1B' },
20
20
  apGreylighten1: { hexColor: '#CCCDCE' },
@@ -1,3 +0,0 @@
1
- export declare const locales: {
2
- loadingLabel: string;
3
- };
@@ -1,3 +0,0 @@
1
- export const locales = {
2
- loadingLabel: 'Le contenu est en cours de chargement.',
3
- }
@@ -1,266 +0,0 @@
1
- import { mount } from '@vue/test-utils'
2
- import PhoneField from '../PhoneField.vue'
3
- import { describe, it, expect, beforeEach } from 'vitest'
4
- import { createVuetify } from 'vuetify'
5
- import * as components from 'vuetify/components'
6
- import * as directives from 'vuetify/directives'
7
- import { indicatifs } from '../indicatifs'
8
-
9
- const vuetify = createVuetify({
10
- components,
11
- directives,
12
- })
13
-
14
- // Tests supplémentaires pour le composant PhoneField
15
- describe('PhoneField - Additional Tests', () => {
16
- // Tests pour les différents formats d'affichage
17
- describe('Display formats', () => {
18
- let wrapper
19
-
20
- beforeEach(() => {
21
- wrapper = mount(PhoneField, {
22
- global: {
23
- plugins: [vuetify],
24
- },
25
- props: {
26
- withCountryCode: true,
27
- dialCodeModel: { code: '+33', abbreviation: 'FR', country: 'France', phoneLength: 10, mask: '## ## ## ## ##' },
28
- },
29
- })
30
- })
31
-
32
- it('formats display text as code by default', async () => {
33
- const select = wrapper.findComponent({ name: 'SySelect' })
34
- // Vérifier que le format d'affichage est bien le code
35
- const firstItem = select.props('items')[0]
36
- expect(firstItem.displayText).toBe(firstItem.code)
37
- })
38
-
39
- it('formats display text as code-abbreviation', async () => {
40
- await wrapper.setProps({ displayFormat: 'code-abbreviation' })
41
- const select = wrapper.findComponent({ name: 'SySelect' })
42
- const firstItem = select.props('items')[0]
43
- expect(firstItem.displayText).toBe(`${firstItem.code} (${firstItem.abbreviation})`)
44
- })
45
-
46
- it('formats display text as code-country', async () => {
47
- await wrapper.setProps({ displayFormat: 'code-country' })
48
- const select = wrapper.findComponent({ name: 'SySelect' })
49
- const firstItem = select.props('items')[0]
50
- expect(firstItem.displayText).toBe(`${firstItem.code} ${firstItem.country}`)
51
- })
52
-
53
- it('formats display text as country', async () => {
54
- await wrapper.setProps({ displayFormat: 'country' })
55
- const select = wrapper.findComponent({ name: 'SySelect' })
56
- const firstItem = select.props('items')[0]
57
- expect(firstItem.displayText).toBe(firstItem.country)
58
- })
59
-
60
- it('formats display text as abbreviation', async () => {
61
- await wrapper.setProps({ displayFormat: 'abbreviation' })
62
- const select = wrapper.findComponent({ name: 'SySelect' })
63
- const firstItem = select.props('items')[0]
64
- expect(firstItem.displayText).toBe(firstItem.abbreviation)
65
- })
66
- })
67
-
68
- // Tests pour l'initialisation avec un dialCode par défaut
69
- describe('Default dialCode initialization', () => {
70
- it('initializes with a default dialCode object', async () => {
71
- const defaultDialCode = { code: '+44', abbreviation: 'UK', country: 'United Kingdom', phoneLength: 11, mask: '#### ### ####' }
72
- const wrapper = mount(PhoneField, {
73
- global: {
74
- plugins: [vuetify],
75
- },
76
- props: {
77
- withCountryCode: true,
78
- dialCodeModel: defaultDialCode,
79
- },
80
- })
81
-
82
- await wrapper.vm.$nextTick()
83
-
84
- // Vérifier que le dialCode est correctement initialisé
85
- expect(wrapper.vm.dialCode).toBeDefined()
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
87
- expect((wrapper.vm.dialCode as any).code).toBe('+44')
88
- // Vérifier que le masque est appliqué (le format exact peut varier)
89
- expect(wrapper.vm.phoneMask).toBeDefined()
90
- // Vérifier que le counter est défini selon la phoneLength
91
- expect(wrapper.vm.counter).toBeDefined()
92
- })
93
-
94
- it('initializes with a default dialCode string', async () => {
95
- const wrapper = mount(PhoneField, {
96
- global: {
97
- plugins: [vuetify],
98
- },
99
- props: {
100
- withCountryCode: true,
101
- dialCodeModel: '+33',
102
- },
103
- })
104
-
105
- await wrapper.vm.$nextTick()
106
-
107
- // Vérifier que le dialCode est correctement initialisé
108
- expect(wrapper.vm.dialCode).toBe('+33')
109
- })
110
- })
111
-
112
- // Tests pour la désactivation de la gestion des erreurs
113
- describe('Error handling', () => {
114
- it('displays error messages by default when validation fails', async () => {
115
- const wrapper = mount(PhoneField, {
116
- global: {
117
- plugins: [vuetify],
118
- },
119
- props: {
120
- required: true,
121
- modelValue: '',
122
- isValidatedOnBlur: true,
123
- },
124
- })
125
-
126
- // Déclencher la validation
127
- await wrapper.vm.validateOnSubmit()
128
-
129
- // Vérifier que les erreurs sont affichées
130
- expect(wrapper.vm.hasError).toBe(true)
131
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
132
- expect((wrapper.vm as any).errors.length).toBeGreaterThan(0)
133
-
134
- // Vérifier que les erreurs sont passées au composant SyTextField
135
- const textField = wrapper.findComponent({ name: 'SyTextField' })
136
- expect(textField.props('errorMessages')).toBeTruthy()
137
- })
138
-
139
- it('initializes with disableErrorHandling prop', async () => {
140
- const wrapper = mount(PhoneField, {
141
- global: {
142
- plugins: [vuetify],
143
- },
144
- props: {
145
- required: true,
146
- modelValue: '',
147
- isValidatedOnBlur: true,
148
- disableErrorHandling: true,
149
- },
150
- })
151
-
152
- // Vérifier que la propriété disableErrorHandling est bien prise en compte
153
- // en vérifiant qu'elle est passée lors de l'initialisation du composable useValidation
154
- expect(wrapper.vm.validation).toBeDefined()
155
- })
156
- })
157
-
158
- // Tests pour la validation dans un contexte de formulaire
159
- describe('Form validation', () => {
160
- it('validates as part of a form submission', async () => {
161
- const wrapper = mount(PhoneField, {
162
- global: {
163
- plugins: [vuetify],
164
- },
165
- props: {
166
- required: true,
167
- modelValue: '',
168
- },
169
- })
170
-
171
- // Simuler une soumission de formulaire avec un champ vide
172
- const isValid = await wrapper.vm.validateOnSubmit()
173
- expect(isValid).toBe(false)
174
-
175
- // Mettre à jour la valeur et valider à nouveau
176
- await wrapper.setProps({ modelValue: '0123456789' })
177
- const isValidAfterUpdate = await wrapper.vm.validateOnSubmit()
178
- expect(isValidAfterUpdate).toBe(true)
179
- })
180
-
181
- it('validates country code as part of form submission', async () => {
182
- const wrapper = mount(PhoneField, {
183
- global: {
184
- plugins: [vuetify],
185
- },
186
- props: {
187
- required: true,
188
- modelValue: '0123456789',
189
- withCountryCode: true,
190
- countryCodeRequired: true,
191
- },
192
- })
193
-
194
- // Sans code pays, la validation échoue
195
- const isValidWithoutCountry = await wrapper.vm.validateOnSubmit()
196
- expect(isValidWithoutCountry).toBe(false)
197
-
198
- // Ajouter un code pays et valider à nouveau
199
- wrapper.vm.dialCode = { code: '+33', abbreviation: 'FR', country: 'France', phoneLength: 10, mask: '## ## ## ## ##' }
200
- await wrapper.vm.$nextTick()
201
-
202
- const isValidWithCountry = await wrapper.vm.validateOnSubmit()
203
- expect(isValidWithCountry).toBe(true)
204
- })
205
- })
206
-
207
- // Tests pour la gestion des indicatifs personnalisés
208
- describe('Custom indicatifs', () => {
209
- it('merges custom indicatifs with standard ones by default', () => {
210
- const customIndicatifs = [{ code: '+999', abbreviation: 'XX', country: 'Test Country', phoneLength: 8, mask: '## ## ## ##' }]
211
- const wrapper = mount(PhoneField, {
212
- global: {
213
- plugins: [vuetify],
214
- },
215
- props: {
216
- customIndicatifs,
217
- withCountryCode: true,
218
- },
219
- })
220
-
221
- // Vérifier que les indicatifs personnalisés sont ajoutés aux indicatifs standards
222
- expect(wrapper.vm.mergedDialCodes.length).toBe(indicatifs.length + customIndicatifs.length)
223
- expect(wrapper.vm.mergedDialCodes).toContainEqual(customIndicatifs[0])
224
- })
225
-
226
- it('uses only custom indicatifs when useCustomIndicatifsOnly is true', () => {
227
- const customIndicatifs = [{ code: '+999', abbreviation: 'XX', country: 'Test Country', phoneLength: 8, mask: '## ## ## ##' }]
228
- const wrapper = mount(PhoneField, {
229
- global: {
230
- plugins: [vuetify],
231
- },
232
- props: {
233
- customIndicatifs,
234
- useCustomIndicatifsOnly: true,
235
- withCountryCode: true,
236
- },
237
- })
238
-
239
- // Vérifier que seuls les indicatifs personnalisés sont utilisés
240
- expect(wrapper.vm.mergedDialCodes.length).toBe(customIndicatifs.length)
241
- expect(wrapper.vm.mergedDialCodes).toEqual(customIndicatifs)
242
- })
243
-
244
- it('updates phone mask and counter based on selected custom indicatif', async () => {
245
- const customIndicatifs = [{ code: '+999', abbreviation: 'XX', country: 'Test Country', phoneLength: 8, mask: '## ## ## ##' }]
246
- const wrapper = mount(PhoneField, {
247
- global: {
248
- plugins: [vuetify],
249
- },
250
- props: {
251
- customIndicatifs,
252
- useCustomIndicatifsOnly: true,
253
- withCountryCode: true,
254
- },
255
- })
256
-
257
- // Sélectionner l'indicatif personnalisé
258
- wrapper.vm.dialCode = customIndicatifs[0]
259
- await wrapper.vm.$nextTick()
260
-
261
- // Vérifier que le masque et le compteur sont mis à jour
262
- expect(wrapper.vm.phoneMask).toBe('## ## ## ##')
263
- expect(wrapper.vm.counter).toBe(8)
264
- })
265
- })
266
- })