@cnamts/synapse 1.0.22 → 1.0.23

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 (190) hide show
  1. package/dist/{DateFilter-B5n-ZkLi.js → DateFilter-Dc-gSGwk.js} +1 -1
  2. package/dist/{NumberFilter-CtiZ9uj8.js → NumberFilter-vP38Wp6j.js} +1 -1
  3. package/dist/{PeriodFilter-DzqiMb-b.js → PeriodFilter-Ba1uYUnT.js} +1 -1
  4. package/dist/{SelectFilter-BOYlF7rX.js → SelectFilter-BioGT6Nn.js} +1 -1
  5. package/dist/{TextFilter-BOFRNfcX.js → TextFilter-B84dpnoq.js} +1 -1
  6. package/dist/components/Accordion/Accordion.d.ts +13 -2
  7. package/dist/components/Accordion/composables/useAccordionState.d.ts +2 -1
  8. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7 -7
  9. package/dist/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.d.ts +1 -1
  10. package/dist/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.d.ts +1 -1
  11. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +1 -1
  12. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7 -7
  13. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +16 -16
  14. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +1 -1
  15. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +1 -1
  16. package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +22 -1
  17. package/dist/components/Customs/Selects/SyAutocomplete/locales.d.ts +5 -0
  18. package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +1 -1
  19. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +1 -1
  20. package/dist/components/Customs/Selects/SySelect/locales.d.ts +1 -0
  21. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +1 -1
  22. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +1 -1
  23. package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1 -1
  24. package/dist/components/Customs/SyTextField/SyTextField.d.ts +5 -2
  25. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +13 -9
  26. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +7 -5
  27. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +2 -1
  28. package/dist/components/ErrorPage/ErrorPage.d.ts +3 -1
  29. package/dist/components/FileList/UploadItem/UploadItem.d.ts +6 -0
  30. package/dist/components/FileList/UploadItem/locales.d.ts +1 -4
  31. package/dist/components/FileUpload/FileUploadContent.d.ts +2 -0
  32. package/dist/components/FileUpload/validateFiles.d.ts +2 -1
  33. package/dist/components/HeaderBar/HeaderBar.d.ts +2 -1
  34. package/dist/components/HeaderBar/HeaderLogo/HeaderLogo.d.ts +2 -1
  35. package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +2 -1
  36. package/dist/components/MonthPicker/MonthPicker.d.ts +1939 -0
  37. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1899 -0
  38. package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +21 -0
  39. package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.d.ts +21 -0
  40. package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.d.ts +12 -0
  41. package/dist/components/MonthPicker/MonthPickerVisual/MonthSelector.d.ts +11 -0
  42. package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.d.ts +6 -0
  43. package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.d.ts +14 -0
  44. package/dist/components/MonthPicker/MonthPickerVisual/YearSelector.d.ts +14 -0
  45. package/dist/components/MonthPicker/MonthPickerVisual/useMonthGrid.d.ts +9 -0
  46. package/dist/components/MonthPicker/MonthPickerVisual/useYearGrid.d.ts +8 -0
  47. package/dist/components/MonthPicker/MonthPickerVisual/utils.d.ts +8 -0
  48. package/dist/components/MonthPicker/locales.d.ts +12 -0
  49. package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +25 -0
  50. package/dist/components/NirField/NirField.d.ts +3 -1
  51. package/dist/components/NotificationBar/Notification/Notification.d.ts +3 -0
  52. package/dist/components/PasswordField/PasswordField.d.ts +1 -1
  53. package/dist/components/PeriodField/PeriodField.d.ts +29 -21
  54. package/dist/components/PhoneField/PhoneField.d.ts +2 -1
  55. package/dist/components/SyBtnMenu/SyBtnMenu.d.ts +1 -1
  56. package/dist/components/SyHeading/SyHeading.a11y.test.d.ts +1 -0
  57. package/dist/components/SyHeading/SyHeading.d.ts +4 -2
  58. package/dist/components/SyHeading/SyHeading.test.d.ts +1 -0
  59. package/dist/components/SyTextArea/SyTextArea.d.ts +1 -1
  60. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +4 -4
  61. package/dist/components/Tables/SyTable/SyTable.d.ts +4 -4
  62. package/dist/components/Tables/common/SyTablePagination.d.ts +6 -6
  63. package/dist/components/index.d.ts +1 -0
  64. package/dist/design-system-v3.js +102 -99
  65. package/dist/design-system-v3.umd.cjs +126 -126
  66. package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +5 -0
  67. package/dist/{main-CEl4J8_T.js → main-aLKwdMi1.js} +11167 -10522
  68. package/dist/main.d.ts +1 -0
  69. package/dist/style.css +1 -1
  70. package/package.json +10 -4
  71. package/src/assets/apTokens.scss +2 -2
  72. package/src/assets/overrides/_btns.scss +8 -0
  73. package/src/assets/overrides/_forms.scss +9 -0
  74. package/src/assets/overrides/_icons.scss +38 -9
  75. package/src/assets/overrides/_tables.scss +19 -0
  76. package/src/components/Accordion/Accordion.mdx +23 -9
  77. package/src/components/Accordion/Accordion.stories.ts +153 -3
  78. package/src/components/Accordion/Accordion.vue +7 -6
  79. package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +40 -12
  80. package/src/components/Accordion/composables/useAccordionState.ts +3 -4
  81. package/src/components/Accordion/tests/accordion.spec.ts +131 -19
  82. package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.mdx +3 -1
  83. package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.stories.ts +8 -0
  84. package/src/components/BackBtn/accessibilite/Accessibility.mdx +62 -10
  85. package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +9 -3
  86. package/src/components/BackToTopBtn/accessibilite/Accessibility.mdx +86 -6
  87. package/src/components/Captcha/tests/Captcha.spec.ts +0 -29
  88. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +2 -110
  89. package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +133 -10
  90. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +379 -93
  91. package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +144 -83
  92. package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibilite.stories.ts +40 -1
  93. package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibility.mdx +7 -1
  94. package/src/components/Customs/Selects/SyAutocomplete/locales.ts +5 -0
  95. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +96 -0
  96. package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +234 -9
  97. package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +13 -3
  98. package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +9 -10
  99. package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -3
  100. package/src/components/Customs/Selects/SySelect/locales.ts +1 -0
  101. package/src/components/Customs/SyIcon/SyIcon.vue +1 -1
  102. package/src/components/Customs/SyIcon/tests/SyIcon.a11y.spec.ts +20 -0
  103. package/src/components/Customs/SyIconButton/SyIconButton.mdx +46 -0
  104. package/src/components/Customs/SyIconButton/SyIconButton.stories.ts +184 -0
  105. package/src/components/Customs/SyIconButton/SyIconButton.vue +38 -0
  106. package/src/components/Customs/SyIconButton/accessibilite/Accessibility.mdx +64 -0
  107. package/src/components/Customs/SyIconButton/tests/SyIconButton.a11y.spec.ts +87 -0
  108. package/src/components/Customs/SyIconButton/tests/SyIconButton.spec.ts +152 -0
  109. package/src/components/Customs/SyIconButton/tests/__snapshots__/SyIconButton.spec.ts.snap +61 -0
  110. package/src/components/Customs/SyPagination/SyPagination.vue +5 -5
  111. package/src/components/Customs/SyTextField/SyTextField.vue +20 -2
  112. package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +67 -9
  113. package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +15 -0
  114. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +36 -0
  115. package/src/components/DataList/accessibilite/Accessibility.mdx +79 -11
  116. package/src/components/DataListGroup/accessibilite/Accessibility.mdx +80 -11
  117. package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +25 -0
  118. package/src/components/ErrorPage/ErrorPage.stories.ts +113 -19
  119. package/src/components/ErrorPage/ErrorPage.vue +17 -2
  120. package/src/components/ErrorPage/tests/ErrorPage.a11y.spec.ts +17 -0
  121. package/src/components/ErrorPage/tests/ErrorPage.spec.ts +21 -1
  122. package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +0 -1
  123. package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +23 -0
  124. package/src/components/FileList/FileList.stories.ts +51 -1
  125. package/src/components/FileList/UploadItem/UploadItem.vue +13 -6
  126. package/src/components/FileList/UploadItem/locales.ts +3 -12
  127. package/src/components/FileList/accessibilite/Accessibility.mdx +3 -0
  128. package/src/components/FileUpload/FileUpload.vue +2 -1
  129. package/src/components/FileUpload/FileUploadContent.vue +2 -1
  130. package/src/components/FileUpload/tests/FileUpload.spec.ts +47 -0
  131. package/src/components/FileUpload/validateFiles.ts +5 -2
  132. package/src/components/FranceConnectBtn/accessibilite/Accessibility.mdx +62 -9
  133. package/src/components/HeaderBar/HeaderBar.vue +2 -1
  134. package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -1
  135. package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
  136. package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +74 -8
  137. package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +163 -0
  138. package/src/components/MaintenancePage/MaintenancePage.vue +1 -1
  139. package/src/components/MaintenancePage/tests/MaintenancePage.spec.ts +4 -5
  140. package/src/components/MaintenancePage/tests/__snapshots__/MaintenancePage.spec.ts.snap +0 -1
  141. package/src/components/MonthPicker/MonthPicker.mdx +35 -0
  142. package/src/components/MonthPicker/MonthPicker.stories.ts +527 -0
  143. package/src/components/MonthPicker/MonthPicker.vue +79 -0
  144. package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +89 -0
  145. package/src/components/MonthPicker/MonthPickerText/useTextField.ts +27 -0
  146. package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.vue +154 -0
  147. package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.ts +13 -0
  148. package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +137 -0
  149. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +60 -0
  150. package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +149 -0
  151. package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +143 -0
  152. package/src/components/MonthPicker/MonthPickerVisual/useMonthGrid.ts +45 -0
  153. package/src/components/MonthPicker/MonthPickerVisual/useYearGrid.ts +45 -0
  154. package/src/components/MonthPicker/MonthPickerVisual/utils.ts +17 -0
  155. package/src/components/MonthPicker/accessibilite/Accessibility.mdx +59 -0
  156. package/src/components/MonthPicker/locales.ts +12 -0
  157. package/src/components/MonthPicker/tests/MonthPicker.a11y.spec.ts +71 -0
  158. package/src/components/MonthPicker/tests/MonthPicker.spec.ts +1248 -0
  159. package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +2545 -0
  160. package/src/components/MonthPicker/useMonthPickerValidation.ts +30 -0
  161. package/src/components/NirField/NirField.mdx +1 -2
  162. package/src/components/NirField/NirField.stories.ts +66 -6
  163. package/src/components/NotFoundPage/tests/NotFoundPage.spec.ts +2 -3
  164. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +22 -14
  165. package/src/components/NotificationBar/Notification/Notification.vue +3 -1
  166. package/src/components/NotificationBar/NotificationBar.stories.ts +154 -0
  167. package/src/components/NotificationBar/tests/NotificationBar.a11y.spec.ts +26 -0
  168. package/src/components/NotificationBar/tests/NotificationBar.spec.ts +60 -0
  169. package/src/components/RangeField/accessibilite/Accessibility.mdx +79 -11
  170. package/src/components/SkipLink/tests/SkipLink.a11y.spec.ts +23 -0
  171. package/src/components/StatusPage/StatusPage.stories.ts +118 -0
  172. package/src/components/StatusPage/StatusPage.vue +5 -3
  173. package/src/components/StatusPage/tests/StatusPage.a11y.spec.ts +22 -0
  174. package/src/components/StatusPage/tests/StatusPage.spec.ts +22 -0
  175. package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +22 -14
  176. package/src/components/SubHeader/tests/SubHeader.a11y.spec.ts +20 -0
  177. package/src/components/SyAlert/SyAlert.vue +1 -0
  178. package/src/components/SyAlert/accessibilite/Accessibility.mdx +79 -9
  179. package/src/components/SyAlert/tests/SyAlert.a11y.spec.ts +23 -0
  180. package/src/components/SyHeading/SyHeading.a11y.test.ts +149 -0
  181. package/src/components/SyHeading/SyHeading.test.ts +115 -0
  182. package/src/components/SyHeading/SyHeading.vue +5 -3
  183. package/src/components/SyTextArea/accessibilite/Accessibility.mdx +80 -8
  184. package/src/components/SyTextArea/tests/SyTextArea.a11y.spec.ts +151 -0
  185. package/src/components/ToolbarContainer/tests/ToolbarContainer.a11y.spec.ts +126 -0
  186. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +2 -2
  187. package/src/components/index.ts +1 -0
  188. package/src/composables/useFormFieldErrorHandling.ts +11 -2
  189. package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -1
  190. package/src/main.ts +2 -0
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import { computed } from 'vue'
3
3
 
4
- const props = defineProps<{
5
- level: 1 | 2 | 3 | 4 | 5 | 6
6
- }>()
4
+ const props = withDefaults(defineProps<{
5
+ level?: 1 | 2 | 3 | 4 | 5 | 6
6
+ }>(), {
7
+ level: 2,
8
+ })
7
9
 
8
10
  const tag = computed(() => `h${props.level}`)
9
11
  </script>
@@ -1,10 +1,82 @@
1
- import { Meta, Story } from '@storybook/addon-docs';
2
- import * as SyTextArea from '../SyTextArea.stories';
3
- import '@/stories/styles/shared.css';
1
+ import { Meta, Primary } from '@storybook/blocks';
2
+ import * as Stories from '../SyTextArea.stories.ts';
3
+ import AccessibilityIcon from '@/common/imgs/accessibility-svgrepo-com.svg';
4
+ import {
5
+ AccessibilityGuideLayout,
6
+ CriteriaSection,
7
+ CriteriaCard,
8
+ DemoSection,
9
+ BestPracticesSection,
10
+ ResourcesSection,
11
+ } from '@/stories/accessibility/AccessibilityGuideLayout.mdx';
4
12
 
5
- <Meta of={SyTextArea} />
13
+ <Meta of={Stories} />
6
14
 
7
- <div className="header">
8
- <h1>Accessibilité</h1>
9
- <p>Cette page sera bientôt disponible</p>
10
- </div>
15
+ <AccessibilityGuideLayout
16
+ componentName="SyTextArea"
17
+ iconSrc={AccessibilityIcon}
18
+ apgHref="https://www.w3.org/WAI/ARIA/apg/patterns/textinput/"
19
+ >
20
+
21
+ <CriteriaSection>
22
+ <CriteriaCard icon="🔍" title="Structure sémantique et attributs">
23
+ <ul>
24
+ <li><strong>Élément textarea natif</strong> : Utilisation de <code>&lt;textarea&gt;</code> via VTextarea pour une sémantique correcte adaptée aux textes multilignes.</li>
25
+ <li><strong>Labels explicites</strong> : Gestion automatique du <code>aria-label</code> basé sur la prop <code>label</code>. L'attribut <code>aria-required</code> est ajouté si le champ est requis.</li>
26
+ <li><strong>Association avec les messages</strong> : Implémentation native de <code>aria-describedby</code> par Vuetify pour lier le champ à ses messages d'erreur.</li>
27
+ <li><strong>Validation accessible</strong> : Les messages d'erreur sont automatiquement associés au textarea via les attributs ARIA.</li>
28
+ </ul>
29
+ </CriteriaCard>
30
+
31
+ <CriteriaCard icon="⌨️" title="Navigation et interaction clavier">
32
+ <ul>
33
+ <li><strong>Focus natif</strong> : Le textarea est naturellement focusable via <kbd>Tab</kbd> et permet la navigation dans le contenu avec les flèches.</li>
34
+ <li><strong>Saisie multiligne</strong> : Support natif des sauts de ligne avec <kbd>Entrée</kbd> et navigation entre les lignes avec les flèches directionnelles.</li>
35
+ <li><strong>Défilement automatique</strong> : Le composant gère automatiquement le défilement lorsque le contenu dépasse la hauteur visible.</li>
36
+ <li><strong>Indicateur de focus</strong> : Styles de focus visibles conformes aux standards d'accessibilité.</li>
37
+ </ul>
38
+ </CriteriaCard>
39
+
40
+ <CriteriaCard icon="🎨" title="Styles et états visuels">
41
+ <ul>
42
+ <li><strong>Contrastes garantis</strong> : Couleurs distinctes pour les états erreur et validation respectant les critères WCAG.</li>
43
+ <li><strong>États cohérents</strong> : Changements visuels clairs entre les états normal, erreur et focus.</li>
44
+ <li><strong>Zone de saisie claire</strong> : Délimitation visuelle évidente de la zone de saisie multiligne.</li>
45
+ <li><strong>Styles personnalisables</strong> : Support des variantes (outlined, filled) et couleurs personnalisées tout en maintenant l'accessibilité.</li>
46
+ </ul>
47
+ </CriteriaCard>
48
+
49
+ <CriteriaCard icon="📝" title="Validation et contraintes">
50
+ <ul>
51
+ <li><strong>Champ requis</strong> : Validation automatique avec message "Ce champ est requis" lorsque <code>required</code> est true.</li>
52
+ <li><strong>Limite de lignes</strong> : Validation du nombre maximum de lignes avec message d'erreur spécifique via la prop <code>maxLines</code>.</li>
53
+ <li><strong>Règles personnalisées</strong> : Support des règles de validation personnalisées avec messages d'erreur accessibles.</li>
54
+ <li><strong>Validation au blur</strong> : Déclenchement de la validation lors de la perte de focus pour une expérience utilisateur optimale.</li>
55
+ </ul>
56
+ </CriteriaCard>
57
+ </CriteriaSection>
58
+
59
+ <DemoSection componentName="SyTextArea">
60
+ <Primary />
61
+ </DemoSection>
62
+
63
+ <BestPracticesSection>
64
+ <ul>
65
+ <li><strong>Labels descriptifs</strong> : Utilisez toujours un <code>label</code> clair qui indique la nature du contenu attendu (ex: "Description", "Commentaires").</li>
66
+ <li><strong>Limites appropriées</strong> : Définissez une <code>maxLines</code> raisonnable pour guider l'utilisateur sans trop contraindre la saisie.</li>
67
+ <li><strong>Messages d'erreur utiles</strong> : Complétez les règles de validation avec des messages spécifiques qui aident à corriger la saisie.</li>
68
+ <li><strong>Évitez les placeholders comme seuls indicateurs</strong> : Le placeholder disparaît lors de la saisie, il doit compléter le label mais pas le remplacer.</li>
69
+ <li><strong>Traitement du texte</strong> : Utilisez les options de traitement (<code>trim</code>, <code>normalize</code>, <code>replaceTabs</code>) pour améliorer la qualité des données saisies.</li>
70
+ <li><strong>Saisie confortable</strong> : Assurez-vous que la hauteur du textarea est suffisante pour une saisie confortable du contenu attendu.</li>
71
+ </ul>
72
+ </BestPracticesSection>
73
+
74
+ <ResourcesSection>
75
+ <ul>
76
+ <li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/textinput/" target="_blank" rel="noopener noreferrer">Guide des pratiques WAI-ARIA : Champs de texte</a></li>
77
+ <li><a href="https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#11.9" target="_blank" rel="noopener noreferrer">RGAA : Champs de formulaire</a></li>
78
+ <li><a href="https://www.w3.org/WAI/WCAG21/Techniques/html/H91.html" target="_blank" rel="noopener noreferrer">WCAG Technique H91 : Utiliser les éléments HTML sémantiques</a></li>
79
+ <li><a href="https://developer.mozilla.org/fr/docs/Web/HTML/Element/textarea" target="_blank" rel="noopener noreferrer">MDN : Élément textarea</a></li>
80
+ </ul>
81
+ </ResourcesSection>
82
+ </AccessibilityGuideLayout>
@@ -0,0 +1,151 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { describe, it } from 'vitest'
4
+ import { mount } from '@vue/test-utils'
5
+ import { axe } from 'vitest-axe'
6
+ import { assertNoA11yViolations } from '@tests/unit/accessibility/axeUtils'
7
+ import SyTextArea from '../SyTextArea.vue'
8
+
9
+ describe('SyTextArea – accessibility (axe)', () => {
10
+ it('has no obvious axe violations with default props', async () => {
11
+ const wrapper = mount(SyTextArea, {
12
+ props: {
13
+ label: 'Description',
14
+ },
15
+ modelValue: '',
16
+ })
17
+
18
+ const results = await axe(wrapper.element as HTMLElement)
19
+ assertNoA11yViolations(results, 'SyTextArea - default props', {
20
+ ignoreRules: ['region'],
21
+ })
22
+ })
23
+
24
+ it('has no obvious axe violations with value', async () => {
25
+ const wrapper = mount(SyTextArea, {
26
+ props: {
27
+ label: 'Description',
28
+ },
29
+ modelValue: 'Ceci est une description',
30
+ })
31
+
32
+ const results = await axe(wrapper.element as HTMLElement)
33
+ assertNoA11yViolations(results, 'SyTextArea - with value', {
34
+ ignoreRules: ['region'],
35
+ })
36
+ })
37
+
38
+ it('has no obvious axe violations with required field', async () => {
39
+ const wrapper = mount(SyTextArea, {
40
+ props: {
41
+ label: 'Description',
42
+ required: true,
43
+ },
44
+ modelValue: '',
45
+ })
46
+
47
+ const results = await axe(wrapper.element as HTMLElement)
48
+ assertNoA11yViolations(results, 'SyTextArea - required field', {
49
+ ignoreRules: ['region'],
50
+ })
51
+ })
52
+
53
+ it('has no obvious axe violations with error messages', async () => {
54
+ const wrapper = mount(SyTextArea, {
55
+ props: {
56
+ label: 'Description',
57
+ required: true,
58
+ },
59
+ modelValue: '',
60
+ })
61
+
62
+ // Trigger validation
63
+ await wrapper.find('textarea').trigger('blur')
64
+
65
+ const results = await axe(wrapper.element as HTMLElement)
66
+ assertNoA11yViolations(results, 'SyTextArea - with errors', {
67
+ ignoreRules: ['region'],
68
+ })
69
+ })
70
+
71
+ it('has no obvious axe violations with max lines constraint', async () => {
72
+ const wrapper = mount(SyTextArea, {
73
+ props: {
74
+ label: 'Description',
75
+ maxLines: 3,
76
+ },
77
+ modelValue: 'Ligne 1\nLigne 2\nLigne 3\nLigne 4',
78
+ })
79
+
80
+ // Trigger validation
81
+ await wrapper.find('textarea').trigger('blur')
82
+
83
+ const results = await axe(wrapper.element as HTMLElement)
84
+ assertNoA11yViolations(results, 'SyTextArea - with max lines violation', {
85
+ ignoreRules: ['region'],
86
+ })
87
+ })
88
+
89
+ it('has no obvious axe violations with custom rules', async () => {
90
+ const wrapper = mount(SyTextArea, {
91
+ props: {
92
+ label: 'Description',
93
+ rules: [(value: string) => value.length >= 10 || 'Minimum 10 caractères'],
94
+ },
95
+ modelValue: 'Court',
96
+ })
97
+
98
+ // Trigger validation
99
+ await wrapper.find('textarea').trigger('blur')
100
+
101
+ const results = await axe(wrapper.element as HTMLElement)
102
+ assertNoA11yViolations(results, 'SyTextArea - with custom rules', {
103
+ ignoreRules: ['region'],
104
+ })
105
+ })
106
+
107
+ it('has no obvious axe violations with different variant', async () => {
108
+ const wrapper = mount(SyTextArea, {
109
+ props: {
110
+ label: 'Description',
111
+ variant: 'filled',
112
+ },
113
+ modelValue: 'Texte de test',
114
+ })
115
+
116
+ const results = await axe(wrapper.element as HTMLElement)
117
+ assertNoA11yViolations(results, 'SyTextArea - filled variant', {
118
+ ignoreRules: ['region'],
119
+ })
120
+ })
121
+
122
+ it('has no obvious axe violations with custom color', async () => {
123
+ const wrapper = mount(SyTextArea, {
124
+ props: {
125
+ label: 'Description',
126
+ color: 'secondary',
127
+ },
128
+ modelValue: 'Texte de test',
129
+ })
130
+
131
+ const results = await axe(wrapper.element as HTMLElement)
132
+ assertNoA11yViolations(results, 'SyTextArea - custom color', {
133
+ ignoreRules: ['region'],
134
+ })
135
+ })
136
+
137
+ it('has no obvious axe violations with background color', async () => {
138
+ const wrapper = mount(SyTextArea, {
139
+ props: {
140
+ label: 'Description',
141
+ bgColor: 'grey-lighten-2',
142
+ },
143
+ modelValue: 'Texte de test',
144
+ })
145
+
146
+ const results = await axe(wrapper.element as HTMLElement)
147
+ assertNoA11yViolations(results, 'SyTextArea - background color', {
148
+ ignoreRules: ['region'],
149
+ })
150
+ })
151
+ })
@@ -0,0 +1,126 @@
1
+ import { describe, it, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { axe } from 'vitest-axe'
4
+ import { assertNoA11yViolations } from '@tests/unit/accessibility/axeUtils'
5
+ import ToolbarContainer from '../ToolbarContainer.vue'
6
+
7
+ // Scénario d'accessibilité : barre d'outils avec des boutons de navigation
8
+ // Le composant doit avoir un rôle toolbar et gérer la navigation au clavier
9
+ describe('ToolbarContainer – accessibility (axe)', () => {
10
+ it('should not have any axe violations with default buttons', async () => {
11
+ const wrapper = mount(ToolbarContainer, {
12
+ slots: {
13
+ default: `
14
+ <VBtn>Action 1</VBtn>
15
+ <VBtn>Action 2</VBtn>
16
+ <VBtn>Action 3</VBtn>
17
+ `,
18
+ },
19
+ attachTo: document.body,
20
+ })
21
+
22
+ const results = await axe(wrapper.element)
23
+ assertNoA11yViolations(results, 'ToolbarContainer with default buttons')
24
+ })
25
+
26
+ it('should not have any axe violations with custom content', async () => {
27
+ const wrapper = mount(ToolbarContainer, {
28
+ slots: {
29
+ default: `
30
+ <div>
31
+ <VBtn icon="mdi-plus" aria-label="Ajouter"></VBtn>
32
+ <VBtn icon="mdi-minus" aria-label="Retirer"></VBtn>
33
+ <button aria-label="Action personnalisée">Custom Button</button>
34
+ </div>
35
+ `,
36
+ },
37
+ attachTo: document.body,
38
+ })
39
+
40
+ const results = await axe(wrapper.element)
41
+ assertNoA11yViolations(results, 'ToolbarContainer with custom content')
42
+ })
43
+
44
+ it('should not have any axe violations with disabled buttons', async () => {
45
+ const wrapper = mount(ToolbarContainer, {
46
+ slots: {
47
+ default: `
48
+ <VBtn>Action 1</VBtn>
49
+ <VBtn disabled>Action 2</VBtn>
50
+ <VBtn>Action 3</VBtn>
51
+ `,
52
+ },
53
+ attachTo: document.body,
54
+ })
55
+
56
+ const results = await axe(wrapper.element)
57
+ assertNoA11yViolations(results, 'ToolbarContainer with disabled buttons')
58
+ })
59
+
60
+ it('should not have any axe violations with links and buttons', async () => {
61
+ const wrapper = mount(ToolbarContainer, {
62
+ slots: {
63
+ default: `
64
+ <VBtn>Action Button</VBtn>
65
+ <a href="#home" aria-label="Accueil">Home Link</a>
66
+ <input type="text" placeholder="Rechercher" aria-label="Recherche" />
67
+ `,
68
+ },
69
+ attachTo: document.body,
70
+ })
71
+
72
+ const results = await axe(wrapper.element)
73
+ assertNoA11yViolations(results, 'ToolbarContainer with mixed focusable elements')
74
+ })
75
+
76
+ it('should have proper toolbar role and attributes', async () => {
77
+ const wrapper = mount(ToolbarContainer, {
78
+ slots: {
79
+ default: `
80
+ <VBtn>Action 1</VBtn>
81
+ <VBtn>Action 2</VBtn>
82
+ `,
83
+ },
84
+ attachTo: document.body,
85
+ })
86
+
87
+ const toolbar = wrapper.find('.sy-toolbar')
88
+
89
+ expect(toolbar.exists()).toBe(true)
90
+ expect(toolbar.attributes('role')).toBe('toolbar')
91
+ expect(toolbar.attributes('tabindex')).toBe('0')
92
+
93
+ const results = await axe(wrapper.element)
94
+ assertNoA11yViolations(results, 'ToolbarContainer role and attributes')
95
+ })
96
+
97
+ it('should handle keyboard navigation accessibility', async () => {
98
+ const wrapper = mount(ToolbarContainer, {
99
+ slots: {
100
+ default: `
101
+ <VBtn>Action 1</VBtn>
102
+ <VBtn>Action 2</VBtn>
103
+ <VBtn>Action 3</VBtn>
104
+ `,
105
+ },
106
+ attachTo: document.body,
107
+ })
108
+
109
+ const toolbar = wrapper.find('.sy-toolbar')
110
+ const buttons = wrapper.findAll('button.v-btn')
111
+
112
+ // Vérifier que les boutons ont le tabindex approprié
113
+ expect(buttons[0]?.attributes('tabindex')).toBe('-1')
114
+ expect(buttons[1]?.attributes('tabindex')).toBe('-1')
115
+ expect(buttons[2]?.attributes('tabindex')).toBe('-1')
116
+
117
+ // Simuler le focus sur la toolbar
118
+ await toolbar.trigger('focus')
119
+
120
+ // Après le focus, le premier bouton devrait être focusable
121
+ expect(buttons[0]?.attributes('tabindex')).toBe('0')
122
+
123
+ const results = await axe(wrapper.element)
124
+ assertNoA11yViolations(results, 'ToolbarContainer keyboard navigation')
125
+ })
126
+ })
@@ -123,7 +123,7 @@ exports[`UploadWorkflow > render the upload list 1`] = `
123
123
  data-no-activator=""
124
124
  >
125
125
  <span>
126
- Importer
126
+ Importer le fichier
127
127
  </span>
128
128
  </span>
129
129
  <!---->
@@ -239,7 +239,7 @@ exports[`UploadWorkflow > render the upload list 1`] = `
239
239
  data-no-activator=""
240
240
  >
241
241
  <span>
242
- Importer
242
+ Importer le fichier
243
243
  </span>
244
244
  </span>
245
245
  <!---->
@@ -61,6 +61,7 @@ export { default as SyTextField } from './Customs/SyTextField/SyTextField.vue'
61
61
  export { default as DiacriticPicker } from './DiacriticPicker/DiacriticPicker.vue'
62
62
  export { default as FileUpload } from './FileUpload/FileUpload.vue'
63
63
  export { default as LunarCalendar } from './LunarCalendar/LunarCalendar.vue'
64
+ export { default as MonthPicker } from './MonthPicker/MonthPicker.vue'
64
65
  export { default as NirField } from './NirField/NirField.vue'
65
66
  export * from './NirField/nirValidation'
66
67
  export { default as PasswordField } from './PasswordField/PasswordField.vue'
@@ -73,11 +73,14 @@ export const useFormFieldErrorHandling = (
73
73
 
74
74
  const validateField = (value: unknown) => {
75
75
  if (props.disableErrorHandling) {
76
+ validation.clearValidation()
76
77
  return true
77
78
  }
78
79
 
79
- // Ne pas valider si la valeur est null/undefined et non requise
80
- if (value == null && !props.required) {
80
+ const isEmptyArray = Array.isArray(value) && value.length === 0
81
+
82
+ // Ne pas valider si la valeur est vide et non requise
83
+ if ((value == null || isEmptyArray) && !props.required) {
81
84
  validation.clearValidation()
82
85
  return true
83
86
  }
@@ -108,6 +111,12 @@ export const useFormFieldErrorHandling = (
108
111
  }
109
112
  })
110
113
 
114
+ watch(() => props.disableErrorHandling, (isDisabled) => {
115
+ if (isDisabled) {
116
+ validation.clearValidation()
117
+ }
118
+ })
119
+
111
120
  watch([() => props.required, () => props.label], () => {
112
121
  // Re-valider quand les règles changent
113
122
  if (modelValue.value != null) {
@@ -5,7 +5,12 @@ export const cnamContextualTokens = {
5
5
  text: '#333333',
6
6
  icon: '#666666',
7
7
  overlay: 'rgba(0, 0, 0, 0.5)',
8
- interactive: '#007bff',
8
+ interactive: '#fff',
9
+ interactiveHover: '#E7ECF5',
10
+ interactivePressed: '#CED9EB',
11
+ interactiveFocus: '#E7ECF5',
12
+ interactiveDisabled: '#fff',
13
+ interactiveHoverOnSelected: '#CED9EB',
9
14
  },
10
15
  gap: {
11
16
  0: '0',
package/src/main.ts CHANGED
@@ -5,3 +5,5 @@ export * from './services'
5
5
  export * from './composables'
6
6
  export * from './utils/rules'
7
7
  export * from './utils'
8
+
9
+ export { createVuetifyInstance } from './vuetifyConfig'