@cnamts/synapse 1.0.20 → 1.0.21
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.
- package/dist/{DateFilter-XURUmpMl.js → DateFilter-uN8OURoP.js} +1 -1
- package/dist/{NumberFilter-BZc0O8wV.js → NumberFilter-sm1dQNQi.js} +1 -1
- package/dist/{PeriodFilter-ZNdXcl3p.js → PeriodFilter-Cklsxnh9.js} +1 -1
- package/dist/{SelectFilter-DshYU5OK.js → SelectFilter-CWefj27Z.js} +1 -1
- package/dist/{TextFilter-D_c5dRPl.js → TextFilter-Ddyj885L.js} +1 -1
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +160 -0
- package/dist/components/Customs/SyCheckBoxGroup/locales.d.ts +3 -0
- package/dist/components/Customs/SyCheckBoxGroup/types.d.ts +10 -0
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +1545 -2
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1495 -2
- package/dist/components/DeclarationAccessibilityPage/DeclarationAccessibilityPage.d.ts +60 -0
- package/dist/components/ErrorPage/ErrorPage.d.ts +1 -12
- package/dist/components/ErrorPage/locales.d.ts +18 -3
- package/dist/components/FileUpload/FileUpload.d.ts +2 -0
- package/dist/components/MaintenancePage/locales.d.ts +18 -2
- package/dist/components/NotFoundPage/locales.d.ts +20 -4
- package/dist/components/StatusPage/StatusPage.d.ts +39 -0
- package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +13 -3
- package/dist/components/index.d.ts +3 -0
- package/dist/design-system-v3.js +126 -123
- package/dist/design-system-v3.umd.cjs +163 -163
- package/dist/{main-CuI6xaPq.js → main-CWniLr0s.js} +15191 -14668
- package/dist/style.css +1 -1
- package/dist/utils/theme/index.d.ts +6 -0
- package/package.json +7 -4
- package/src/components/ContextualMenu/ContextualMenu.stories.ts +0 -3
- package/src/components/ContextualMenu/accessibilite/Accessibility.mdx +67 -11
- package/src/components/CookieBanner/CookieBanner.stories.ts +11 -20
- package/src/components/CookieBanner/CookieBanner.vue +20 -5
- package/src/components/CookieBanner/accessibilite/Accessibility.mdx +67 -11
- package/src/components/CookieBanner/tests/CookieBanner.spec.ts +48 -4
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.mdx +32 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +856 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +334 -0
- package/src/components/Customs/SyCheckBoxGroup/accessibilite/Accessibility.mdx +243 -0
- package/src/components/Customs/SyCheckBoxGroup/locales.ts +3 -0
- package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.a11y.spec.ts +30 -0
- package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.spec.ts +152 -0
- package/src/components/Customs/SyCheckBoxGroup/types.ts +10 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +16 -27
- package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +1 -1
- package/src/components/Customs/SyForm/SyForm.a11y.spec.ts +1 -1
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +16 -43
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +35 -11
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +43 -2
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +48 -21
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +98 -0
- package/src/components/DeclarationAccessibilityPage/DeclarationAccessibilityPage.mdx +83 -0
- package/src/components/DeclarationAccessibilityPage/DeclarationAccessibilityPage.stories.ts +502 -0
- package/src/components/DeclarationAccessibilityPage/DeclarationAccessibilityPage.vue +428 -0
- package/src/components/DeclarationAccessibilityPage/accessibilite/Accessibility.mdx +75 -0
- package/src/components/DeclarationAccessibilityPage/tests/DeclarationAccessibilityPage.a11y.spec.ts +53 -0
- package/src/components/DeclarationAccessibilityPage/tests/DeclarationAccessibilityPage.spec.ts +59 -0
- package/src/components/DiacriticPicker/DiacriticPicker.vue +20 -1
- package/src/components/ErrorPage/ErrorPage.mdx +6 -16
- package/src/components/ErrorPage/ErrorPage.stories.ts +16 -87
- package/src/components/ErrorPage/ErrorPage.vue +38 -125
- package/src/components/ErrorPage/accessibilite/Accessibility.mdx +68 -6
- package/src/components/ErrorPage/assets/error-ap.svg +1774 -0
- package/src/components/ErrorPage/locales.ts +21 -3
- package/src/components/ErrorPage/tests/ErrorPage.a11y.spec.ts +5 -13
- package/src/components/ErrorPage/tests/ErrorPage.spec.ts +2 -41
- package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +8 -266
- package/src/components/FileUpload/FileUpload.vue +5 -0
- package/src/components/FooterBar/FooterBar.stories.ts +18 -14
- package/src/components/FooterBar/defaultSocialMediaLinks.ts +6 -4
- package/src/components/MaintenancePage/MaintenancePage.mdx +1 -1
- package/src/components/MaintenancePage/MaintenancePage.vue +15 -7
- package/src/components/MaintenancePage/accessibilite/Accessibility.mdx +61 -6
- package/src/components/MaintenancePage/assets/maintenance-ap.svg +1718 -0
- package/src/components/MaintenancePage/locales.ts +24 -3
- package/src/components/MaintenancePage/tests/MaintenancePage.a11y.spec.ts +75 -3
- package/src/components/MaintenancePage/tests/MaintenancePage.spec.ts +42 -2
- package/src/components/MaintenancePage/tests/__snapshots__/MaintenancePage.spec.ts.snap +3 -2
- package/src/components/NotFoundPage/NotFoundPage.mdx +1 -1
- package/src/components/NotFoundPage/NotFoundPage.stories.ts +3 -3
- package/src/components/NotFoundPage/NotFoundPage.vue +16 -11
- package/src/components/NotFoundPage/accessibilite/Accessibility.mdx +78 -6
- package/src/components/NotFoundPage/assets/not-found-ap.svg +2061 -0
- package/src/components/NotFoundPage/locales.ts +24 -4
- package/src/components/NotFoundPage/tests/NotFoundPage.a11y.spec.ts +168 -4
- package/src/components/NotFoundPage/tests/NotFoundPage.spec.ts +100 -12
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +2 -2
- package/src/components/NotificationBar/NotificationBar.mdx +2 -2
- package/src/components/NotificationBar/accessibilite/Accessibility.mdx +68 -8
- package/src/components/PageContainer/tests/PageContainer.a11y.spec.ts +14 -7
- package/src/components/PhoneField/PhoneField.stories.ts +46 -38
- package/src/components/SocialMediaLinks/DefaultSocialMediaLinks.ts +6 -4
- package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +7 -5
- package/src/components/SocialMediaLinks/SocialMediaLinks.stories.ts +17 -13
- package/src/components/SocialMediaLinks/SocialMediaLinks.vue +9 -1
- package/src/components/SocialMediaLinks/accessibilite/Accessibility.mdx +63 -11
- package/src/components/SocialMediaLinks/tests/DefaultSocialMediaLinks.spec.ts +5 -5
- package/src/components/SocialMediaLinks/tests/SocialMediaLinks.a11y.spec.ts +59 -0
- package/src/components/SocialMediaLinks/tests/SocialMediaLinks.spec.ts +9 -7
- package/src/components/StatusPage/StatusPage.mdx +22 -0
- package/src/components/StatusPage/StatusPage.stories.ts +193 -0
- package/src/components/StatusPage/StatusPage.vue +145 -0
- package/src/components/StatusPage/accessibilite/Accessibility.mdx +81 -0
- package/src/components/StatusPage/tests/StatusPage.a11y.spec.ts +29 -0
- package/src/components/StatusPage/tests/StatusPage.spec.ts +50 -0
- package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +270 -0
- package/src/components/TableToolbar/TableToolbar.stories.ts +6 -6
- package/src/components/TableToolbar/TableToolbar.vue +1 -1
- package/src/components/TableToolbar/tests/__snapshots__/TableToolbar.spec.ts.snap +0 -5
- package/src/components/UploadWorkflow/UploadWorkflow.mdx +11 -1
- package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +107 -3
- package/src/components/UploadWorkflow/UploadWorkflow.vue +35 -24
- package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +48 -0
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +9 -5
- package/src/components/UploadWorkflow/useFileList.ts +7 -0
- package/src/components/index.ts +3 -0
- package/src/composables/rules/tests/useFieldValidation.spec.ts +39 -3
- package/src/composables/rules/useFieldValidation.ts +24 -9
- package/src/stories/Accessibilite/KitDePreAudit/Preaudit.mdx +7 -0
- package/src/utils/theme/index.ts +19 -0
- package/src/utils/theme/tests/useThemeLocales.spec.ts +245 -0
- package/dist/components/MaintenancePage/index.d.ts +0 -2
- package/src/components/Customs/SyPagination/tests/SyPagination.a11y.spec.ts +0 -27
- package/src/components/Customs/SyTabs/tests/SyTabs.a11y.spec.ts +0 -51
- package/src/components/DataListItem/tests/DataListItem.a11y.spec.ts +0 -31
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.a11y.spec.ts +0 -27
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.a11y.spec.ts +0 -26
- package/src/components/DatePicker/DateTextInput/tests/DateTextInput.a11y.spec.ts +0 -27
- package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +0 -26
- package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +0 -39
- package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.a11y.spec.ts +0 -45
- package/src/components/HeaderToolbar/tests/HeaderToolbar.a11y.spec.ts +0 -25
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +0 -31
- package/src/components/MaintenancePage/index.ts +0 -3
- package/src/components/PageContainer/Accessibilite/AccessibilityGuide.mdx +0 -0
- package/src/components/PaginatedTable/tests/PaginatedTable.a11y.spec.ts +0 -43
- package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -34
- /package/src/components/NotFoundPage/assets/{not-found.svg → not-found-cnam.svg} +0 -0
- /package/src/components/PageContainer/{Accessibilite → accessibilite}/Accessibility.mdx +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cnamts/synapse",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "CNAM DS v3",
|
|
6
6
|
"type": "module",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"lint:fix": "eslint \"src/**/*.{ts,vue}\" --fix && stylelint \"src/**/*.{css,scss,vue}\" --fix",
|
|
31
31
|
"test:unit": "vitest run --exclude='**/*.a11y.spec.ts'",
|
|
32
32
|
"test:a11y": "pnpm vitest run a11y.spec.ts",
|
|
33
|
+
"a11y:report": "node ./scripts/a11y-report.mjs",
|
|
33
34
|
"prepare": "husky",
|
|
34
35
|
"generate:changelog": "auto-changelog -o CHANGELOG-TEMP.md -p --starting-date 2024-10-10"
|
|
35
36
|
},
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"typescript": "~5.9.3",
|
|
100
101
|
"typescript-eslint": "^8.11.0",
|
|
101
102
|
"vite": "^5.3.5",
|
|
102
|
-
"vite-plugin-dts": "^4.
|
|
103
|
+
"vite-plugin-dts": "^4.5.4",
|
|
103
104
|
"vite-plugin-vuetify": "^2.1.1",
|
|
104
105
|
"vitest": "^3.2.4",
|
|
105
106
|
"vitest-axe": "^0.1.0",
|
|
@@ -129,7 +130,8 @@
|
|
|
129
130
|
"esbuild": "^0.25.0",
|
|
130
131
|
"parse5": "7.1.2",
|
|
131
132
|
"npm": "^11.8.1",
|
|
132
|
-
"undici": "^6.21.0"
|
|
133
|
+
"undici": "^6.21.0",
|
|
134
|
+
"rollup": "^4.59.0"
|
|
133
135
|
},
|
|
134
136
|
"pnpm": {
|
|
135
137
|
"overrides": {
|
|
@@ -138,7 +140,8 @@
|
|
|
138
140
|
"glob": ">=10.5.0",
|
|
139
141
|
"js-yaml": ">=4.1.1",
|
|
140
142
|
"parse5": "7.1.2",
|
|
141
|
-
"npm": "^11.8.1"
|
|
143
|
+
"npm": "^11.8.1",
|
|
144
|
+
"minimatch": ">=10.2.3"
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
}
|
|
@@ -1,15 +1,71 @@
|
|
|
1
|
-
import { Meta,
|
|
2
|
-
import * as
|
|
3
|
-
import '@/
|
|
1
|
+
import { Meta, Primary } from '@storybook/blocks';
|
|
2
|
+
import * as ContextualMenuStories from '../ContextualMenu.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
|
+
AuditSection,
|
|
12
|
+
} from '@/stories/accessibility/AccessibilityGuideLayout.mdx';
|
|
4
13
|
|
|
5
|
-
<Meta of={
|
|
14
|
+
<Meta of={ContextualMenuStories} />
|
|
6
15
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
16
|
+
<AccessibilityGuideLayout
|
|
17
|
+
componentName="ContextualMenu"
|
|
18
|
+
iconSrc={AccessibilityIcon}
|
|
19
|
+
>
|
|
20
|
+
<AuditSection>
|
|
21
|
+
<p>Rapport d’audit manuel : <a href="/audits/ContextualMenu.xlsx" style={{ color:'#0C41BD' }}>Voir le rapport</a></p>
|
|
22
|
+
<p style={{ color: 'grey', fontSize: '14px', marginTop: '0px' }}>Correctifs associés (<a href="https://github.com/assurance-maladie-digital/design-system-v3/issues/658" target="_blank" style={{color:'#0C41BD'}}>issue #658</a>)</p>
|
|
23
|
+
</AuditSection>
|
|
24
|
+
|
|
25
|
+
<CriteriaSection>
|
|
26
|
+
<CriteriaCard icon="🏷️" title="Structure sémantique claire">
|
|
27
|
+
<ul>
|
|
28
|
+
<li>Landmark <code><nav></code> avec <code>aria-label</code> obligatoire pour annoncer la zone.</li>
|
|
29
|
+
<li>Hiérarchie native <code>ul > li > a</code> pour les niveaux imbriqués, sans rôles ARIA détournés.</li>
|
|
30
|
+
<li>Utilisation de <code>aria-current</code> sur le lien actif pour signaler la section courante.</li>
|
|
31
|
+
</ul>
|
|
32
|
+
</CriteriaCard>
|
|
10
33
|
|
|
34
|
+
<CriteriaCard icon="⌨️" title="Navigation clavier native">
|
|
35
|
+
<ul>
|
|
36
|
+
<li>Parcours par <kbd>Tab</kbd>/<kbd>Maj+Tab</kbd> sur des liens standards, activation par <kbd>Entrée</kbd>.</li>
|
|
37
|
+
<li>Styles de focus visibles fournis par la feuille de style partagée et conservés sur tous les niveaux.</li>
|
|
38
|
+
<li>Activation via clic clavier ou souris met à jour le hash et synchronise l'état actif.</li>
|
|
39
|
+
</ul>
|
|
40
|
+
</CriteriaCard>
|
|
11
41
|
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
</
|
|
42
|
+
<CriteriaCard icon="🧭" title="Repères et correspondance contenu">
|
|
43
|
+
<ul>
|
|
44
|
+
<li>Chaque élément pointe vers une ancre <code>hash</code>; les sections ciblées doivent avoir des <code>id</code> uniques et, idéalement, <code>tabindex="-1"</code> pour recevoir le focus programmatique.</li>
|
|
45
|
+
<li>Gestion du hash : changement d'URL et état contrôlé via <code>v-model</code> pour refléter l'élément actif.</li>
|
|
46
|
+
<li>Support multi-niveaux via la propriété optionnelle <code>level</code> (1 à 6) générant des listes imbriquées.</li>
|
|
47
|
+
</ul>
|
|
48
|
+
</CriteriaCard>
|
|
49
|
+
</CriteriaSection>
|
|
50
|
+
|
|
51
|
+
<DemoSection componentName="ContextualMenu">
|
|
52
|
+
<Primary />
|
|
53
|
+
</DemoSection>
|
|
54
|
+
|
|
55
|
+
<BestPracticesSection>
|
|
56
|
+
<ul>
|
|
57
|
+
<li>Fournissez systématiquement un <code>ariaLabel</code> descriptif (ex. « Plan de page »).</li>
|
|
58
|
+
<li>Assurez-vous que chaque <code>hash</code> correspond à un <code>id</code> existant dans la page, avec un titre associé via <code>aria-labelledby</code>.</li>
|
|
59
|
+
<li>Respectez l'ordre logique du contenu et les niveaux <code>level</code> pour refléter la structure réelle du document.</li>
|
|
60
|
+
<li>Évitez de placer des éléments interactifs non liens à l'intérieur des entrées du menu.</li>
|
|
61
|
+
</ul>
|
|
62
|
+
</BestPracticesSection>
|
|
63
|
+
|
|
64
|
+
<ResourcesSection>
|
|
65
|
+
<ul>
|
|
66
|
+
<li><a href="https://www.w3.org/TR/WCAG22/#navigation-mechanisms" target="_blank" rel="noopener noreferrer">WCAG – Mécanismes de navigation</a></li>
|
|
67
|
+
<li><a href="https://www.w3.org/TR/WCAG22/#link-purpose-in-context" target="_blank" rel="noopener noreferrer">WCAG – Objet du lien</a></li>
|
|
68
|
+
<li><a href="https://www.w3.org/WAI/tutorials/page-structure/sections/" target="_blank" rel="noopener noreferrer">WAI – Structuration des pages et sections</a></li>
|
|
69
|
+
</ul>
|
|
70
|
+
</ResourcesSection>
|
|
71
|
+
</AccessibilityGuideLayout>
|
|
@@ -49,7 +49,7 @@ const meta = {
|
|
|
49
49
|
description: 'Événement émis lors de l\'acceptation des cookies',
|
|
50
50
|
table: {
|
|
51
51
|
category: 'Events',
|
|
52
|
-
type: { summary: '' },
|
|
52
|
+
type: { summary: 'Partial<{ functional: boolean; analytics: boolean }>' },
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
'onReject': {
|
|
@@ -57,7 +57,7 @@ const meta = {
|
|
|
57
57
|
description: 'Événement émis lors du refus des cookies',
|
|
58
58
|
table: {
|
|
59
59
|
category: 'Events',
|
|
60
|
-
type: { summary: '' },
|
|
60
|
+
type: { summary: 'Partial<{ functional: boolean; analytics: boolean }>' },
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
63
|
'onCustomize': {
|
|
@@ -68,6 +68,14 @@ const meta = {
|
|
|
68
68
|
type: { summary: '' },
|
|
69
69
|
},
|
|
70
70
|
},
|
|
71
|
+
'onSubmit': {
|
|
72
|
+
action: 'submit',
|
|
73
|
+
description: 'Événement émis lors de la sauvegarde des préférences personnalisées',
|
|
74
|
+
table: {
|
|
75
|
+
category: 'Events',
|
|
76
|
+
type: { summary: 'Partial<Preferences>' },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
71
79
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
72
80
|
// @ts-ignore- Object literal may only specify known properties
|
|
73
81
|
'onUpdate:modelValue': {
|
|
@@ -226,12 +234,10 @@ export const Default: Story = {
|
|
|
226
234
|
onAccept: { action: 'accept' },
|
|
227
235
|
onReject: { action: 'reject' },
|
|
228
236
|
onCustomize: { action: 'customize' },
|
|
237
|
+
onSubmit: { action: 'submit' },
|
|
229
238
|
},
|
|
230
239
|
args: {
|
|
231
240
|
items,
|
|
232
|
-
onAccept: fn(),
|
|
233
|
-
onReject: fn(),
|
|
234
|
-
onCustomize: fn(),
|
|
235
241
|
},
|
|
236
242
|
|
|
237
243
|
render: (args) => {
|
|
@@ -258,9 +264,6 @@ export const Default: Story = {
|
|
|
258
264
|
},
|
|
259
265
|
|
|
260
266
|
parameters: {
|
|
261
|
-
a11y: {
|
|
262
|
-
disable: true,
|
|
263
|
-
},
|
|
264
267
|
sourceCode: [
|
|
265
268
|
{
|
|
266
269
|
name: 'Template',
|
|
@@ -356,9 +359,6 @@ export const WithoutCookiesItems: Story = {
|
|
|
356
359
|
}
|
|
357
360
|
},
|
|
358
361
|
parameters: {
|
|
359
|
-
a11y: {
|
|
360
|
-
disable: true,
|
|
361
|
-
},
|
|
362
362
|
sourceCode: [
|
|
363
363
|
{
|
|
364
364
|
name: 'Template',
|
|
@@ -411,9 +411,6 @@ export const BannerDescriptionSlot: Story = {
|
|
|
411
411
|
}
|
|
412
412
|
},
|
|
413
413
|
parameters: {
|
|
414
|
-
a11y: {
|
|
415
|
-
disable: true,
|
|
416
|
-
},
|
|
417
414
|
sourceCode: [
|
|
418
415
|
{
|
|
419
416
|
name: 'Template',
|
|
@@ -520,9 +517,6 @@ export const CookiesDescriptionSlots: Story = {
|
|
|
520
517
|
}
|
|
521
518
|
},
|
|
522
519
|
parameters: {
|
|
523
|
-
a11y: {
|
|
524
|
-
disable: true,
|
|
525
|
-
},
|
|
526
520
|
sourceCode: [
|
|
527
521
|
{
|
|
528
522
|
name: 'Template',
|
|
@@ -619,9 +613,6 @@ export const Customization: Story = {
|
|
|
619
613
|
}
|
|
620
614
|
},
|
|
621
615
|
parameters: {
|
|
622
|
-
a11y: {
|
|
623
|
-
disable: true,
|
|
624
|
-
},
|
|
625
616
|
sourceCode: [
|
|
626
617
|
{
|
|
627
618
|
name: 'Template',
|
|
@@ -34,14 +34,29 @@
|
|
|
34
34
|
return display.smAndDown.value ? '100%' : 'auto'
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
+
const itemKeys = computed(() => Object.keys(props.items ?? {}) as (keyof CookiesItems)[])
|
|
38
|
+
|
|
39
|
+
type ConsentPayload = Partial<Record<keyof CookiesItems, boolean>>
|
|
40
|
+
|
|
41
|
+
function buildConsentPayload(value: boolean): ConsentPayload {
|
|
42
|
+
if (!props.items) {
|
|
43
|
+
return {}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return itemKeys.value.reduce<ConsentPayload>((payload, key) => {
|
|
47
|
+
payload[key] = value
|
|
48
|
+
return payload
|
|
49
|
+
}, {})
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
function reject(): void {
|
|
38
53
|
active.value = false
|
|
39
|
-
emits('reject')
|
|
54
|
+
emits('reject', buildConsentPayload(false))
|
|
40
55
|
}
|
|
41
56
|
|
|
42
57
|
function accept(): void {
|
|
43
58
|
active.value = false
|
|
44
|
-
emits('accept')
|
|
59
|
+
emits('accept', buildConsentPayload(true))
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
function customize(): void {
|
|
@@ -51,7 +66,7 @@
|
|
|
51
66
|
emits('customize')
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
function personalizeCookies(e:
|
|
69
|
+
function personalizeCookies(e: ConsentPayload) {
|
|
55
70
|
emits('submit', e)
|
|
56
71
|
showCookiesSelection.value = false
|
|
57
72
|
active.value = false
|
|
@@ -167,13 +182,13 @@
|
|
|
167
182
|
<VSheet
|
|
168
183
|
ref="vsheetRef"
|
|
169
184
|
v-bind="options.banner"
|
|
170
|
-
:aria-label="locales.label"
|
|
171
185
|
class="vd-cookie-banner"
|
|
172
186
|
>
|
|
173
187
|
<div
|
|
174
188
|
ref="bannerRef"
|
|
175
189
|
class="vd-cookie-banner__inner"
|
|
176
190
|
role="dialog"
|
|
191
|
+
:aria-label="locales.label"
|
|
177
192
|
>
|
|
178
193
|
<div class="d-flex align-start flex-nowrap pa-0 mb-6">
|
|
179
194
|
<h2
|
|
@@ -214,7 +229,7 @@
|
|
|
214
229
|
<Transition name="height">
|
|
215
230
|
<div v-if="showCookiesSelection && items">
|
|
216
231
|
<CookiesSelection
|
|
217
|
-
:items
|
|
232
|
+
:items="items"
|
|
218
233
|
@submit="personalizeCookies"
|
|
219
234
|
>
|
|
220
235
|
<template
|
|
@@ -1,15 +1,71 @@
|
|
|
1
|
-
import { Meta,
|
|
2
|
-
import * as
|
|
3
|
-
import '@/
|
|
1
|
+
import { Meta, Primary } from '@storybook/blocks';
|
|
2
|
+
import * as CookieBannerStories from '../CookieBanner.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={
|
|
13
|
+
<Meta of={CookieBannerStories}/>
|
|
6
14
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
<AccessibilityGuideLayout
|
|
16
|
+
componentName="CookieBanner"
|
|
17
|
+
iconSrc={AccessibilityIcon}
|
|
18
|
+
apgHref="https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/"
|
|
19
|
+
>
|
|
20
|
+
<div class="mt-6">
|
|
21
|
+
<p>Rapport d’audit manuel : <a href="/audits/Cookies.xlsx" style={{ color:'#0C41BD' }}>Voir le rapport</a></p>
|
|
22
|
+
<p style={{ color: 'grey', fontSize: '14px', marginTop: '0px' }}>Correctifs associés (<a href="https://github.com/assurance-maladie-digital/design-system-v3/issues/806" target="_blank" style={{color:'#0C41BD'}}>issue #806</a>)</p>
|
|
23
|
+
</div>
|
|
24
|
+
<CriteriaSection>
|
|
25
|
+
<CriteriaCard icon="🧭" title="Structure et nom accessible">
|
|
26
|
+
<ul>
|
|
27
|
+
<li><strong>Rôle</strong> : <code>role="dialog"</code> sur le conteneur principal de la bannière.</li>
|
|
28
|
+
<li><strong>Nom accessible</strong> : <code>aria-label="Gestion des cookies"</code> (ou <code>aria-labelledby</code> pointant vers le titre).</li>
|
|
29
|
+
<li><strong>Hiérarchie</strong> : le titre est exposé (<code>h2</code>) et peut être référencé par <code>aria-labelledby</code> si besoin.</li>
|
|
30
|
+
</ul>
|
|
31
|
+
</CriteriaCard>
|
|
10
32
|
|
|
33
|
+
<CriteriaCard icon="⌨️" title="Navigation clavier">
|
|
34
|
+
<ul>
|
|
35
|
+
<li>Gestion de la touche <kbd>Tab</kbd> pour boucler le focus dans la bannière.</li>
|
|
36
|
+
<li>Échappe (<kbd>Esc</kbd>) ferme la bannière ou revient depuis la personnalisation.</li>
|
|
37
|
+
<li>Focus initial sur le bouton de fermeture à l’ouverture.</li>
|
|
38
|
+
</ul>
|
|
39
|
+
</CriteriaCard>
|
|
11
40
|
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
</
|
|
41
|
+
<CriteriaCard icon="🦻" title="Événements et consentement">
|
|
42
|
+
<ul>
|
|
43
|
+
<li><strong>accept/reject</strong> : émettent les catégories configurables (via les items) et toujours <code>essentials: true</code> si fournis.</li>
|
|
44
|
+
<li><strong>submit</strong> : renvoie les préférences personnalisées + <code>essentials: true</code> le cas échéant.</li>
|
|
45
|
+
<li>Pas de chargement de cookies non essentiels avant l’<code>accept</code> ou <code>submit</code>.</li>
|
|
46
|
+
</ul>
|
|
47
|
+
</CriteriaCard>
|
|
48
|
+
</CriteriaSection>
|
|
49
|
+
|
|
50
|
+
<DemoSection componentName="CookieBanner">
|
|
51
|
+
<Primary />
|
|
52
|
+
</DemoSection>
|
|
53
|
+
|
|
54
|
+
<BestPracticesSection>
|
|
55
|
+
<ul>
|
|
56
|
+
<li>Ne surchargez pas la description : un paragraphe clair et concis.</li>
|
|
57
|
+
<li>Assurez un contraste suffisant des boutons et du fond de bannière.</li>
|
|
58
|
+
<li>Proposez un lien « En savoir plus » vers votre politique cookies.</li>
|
|
59
|
+
<li>Chargez les cookies non essentiels uniquement après <code>accept</code> ou <code>submit</code>.</li>
|
|
60
|
+
<li>Conservez la possibilité de rouvrir la bannière ou de modifier le choix ailleurs dans l’interface.</li>
|
|
61
|
+
</ul>
|
|
62
|
+
</BestPracticesSection>
|
|
63
|
+
|
|
64
|
+
<ResourcesSection>
|
|
65
|
+
<ul>
|
|
66
|
+
<li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/" target="_blank" rel="noopener noreferrer">APG : Alert dialog</a></li>
|
|
67
|
+
<li><a href="https://www.cnil.fr/fr/cookies-traceurs-que-dit-la-loi" target="_blank" rel="noopener noreferrer">CNIL : Cookies et traceurs</a></li>
|
|
68
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/quickref/" target="_blank" rel="noopener noreferrer">Référence rapide WCAG 2.1</a></li>
|
|
69
|
+
</ul>
|
|
70
|
+
</ResourcesSection>
|
|
71
|
+
</AccessibilityGuideLayout>
|
|
@@ -24,8 +24,14 @@ describe('CookieBanner', () => {
|
|
|
24
24
|
expect(wrapper.find('[data-test-id="customize"]').attributes('style')).toContain('100%')
|
|
25
25
|
})
|
|
26
26
|
|
|
27
|
-
it('emit a reject event
|
|
27
|
+
it('emit a reject event with payload built from provided items', async () => {
|
|
28
28
|
const wrapper = mount(CookieBanner, {
|
|
29
|
+
props: {
|
|
30
|
+
items: {
|
|
31
|
+
enessentials: [],
|
|
32
|
+
functional: [],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
29
35
|
global: {
|
|
30
36
|
stubs: {
|
|
31
37
|
Teleport: true,
|
|
@@ -35,11 +41,20 @@ describe('CookieBanner', () => {
|
|
|
35
41
|
|
|
36
42
|
await wrapper.find('[data-test-id="reject"]').trigger('click')
|
|
37
43
|
|
|
38
|
-
expect(wrapper.emitted()).
|
|
44
|
+
expect(wrapper.emitted('reject')?.[0]?.[0]).toEqual({
|
|
45
|
+
enessentials: false,
|
|
46
|
+
functional: false,
|
|
47
|
+
})
|
|
39
48
|
})
|
|
40
49
|
|
|
41
|
-
it('emit
|
|
50
|
+
it('emit an accept event with payload built from provided items', async () => {
|
|
42
51
|
const wrapper = mount(CookieBanner, {
|
|
52
|
+
props: {
|
|
53
|
+
items: {
|
|
54
|
+
functional: [],
|
|
55
|
+
analytics: [],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
43
58
|
global: {
|
|
44
59
|
stubs: {
|
|
45
60
|
Teleport: true,
|
|
@@ -49,7 +64,10 @@ describe('CookieBanner', () => {
|
|
|
49
64
|
|
|
50
65
|
await wrapper.find('[data-test-id="accept"]').trigger('click')
|
|
51
66
|
|
|
52
|
-
expect(wrapper.emitted()).
|
|
67
|
+
expect(wrapper.emitted('accept')?.[0]?.[0]).toEqual({
|
|
68
|
+
functional: true,
|
|
69
|
+
analytics: true,
|
|
70
|
+
})
|
|
53
71
|
})
|
|
54
72
|
|
|
55
73
|
it('does not close the dialog when the customize button is clicked and do not show the cookie form', async () => {
|
|
@@ -116,4 +134,30 @@ describe('CookieBanner', () => {
|
|
|
116
134
|
expect(wrapper.find('.vd-cookies-card').html()).toMatchSnapshot()
|
|
117
135
|
expect(wrapper.emitted()).toHaveProperty('customize')
|
|
118
136
|
})
|
|
137
|
+
|
|
138
|
+
it('emits submit payload coming from CookiesSelection without altering categories', async () => {
|
|
139
|
+
const wrapper = mount(CookieBanner, {
|
|
140
|
+
props: {
|
|
141
|
+
items: {
|
|
142
|
+
functional: [],
|
|
143
|
+
analytics: [],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
global: {
|
|
147
|
+
stubs: {
|
|
148
|
+
Teleport: true,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
await wrapper.find('[data-test-id="customize"]').trigger('click')
|
|
154
|
+
await wrapper.vm.$nextTick()
|
|
155
|
+
|
|
156
|
+
const selection = wrapper.findComponent({ name: 'CookiesSelection' })
|
|
157
|
+
selection.vm.$emit('submit', { functional: true })
|
|
158
|
+
|
|
159
|
+
expect(wrapper.emitted('submit')?.[0]?.[0]).toEqual({
|
|
160
|
+
functional: true,
|
|
161
|
+
})
|
|
162
|
+
})
|
|
119
163
|
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Meta, Canvas, Controls } from '@storybook/blocks';
|
|
2
|
+
import '../../../stories/styles/shared.css';
|
|
3
|
+
import * as SyCheckBoxGroupStories from './SyCheckBoxGroup.stories';
|
|
4
|
+
|
|
5
|
+
<Meta of={SyCheckBoxGroupStories} />
|
|
6
|
+
|
|
7
|
+
<div className="header">
|
|
8
|
+
<h1>SyCheckBoxGroup</h1>
|
|
9
|
+
<p>Le composant `SyCheckBoxGroup` est un groupe de cases à cocher basé sur `SyCheckbox`, conforme au style du Design System et qui respecte les règles d'accessibilité <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr>.</p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
Il étend les fonctionnalités de base avec :
|
|
13
|
+
|
|
14
|
+
- La gestion d’un groupe d’options via la prop `options`
|
|
15
|
+
- Un mode **sélection unique** (par défaut) ou **multiple** (`multiple`)
|
|
16
|
+
- Un système de validation avancé (erreur, avertissement, succès)
|
|
17
|
+
|
|
18
|
+
<Canvas of={SyCheckBoxGroupStories.Default} />
|
|
19
|
+
|
|
20
|
+
# API
|
|
21
|
+
|
|
22
|
+
<Controls of={SyCheckBoxGroupStories.Default} />
|
|
23
|
+
|
|
24
|
+
## Validation
|
|
25
|
+
|
|
26
|
+
Le composant supporte trois types de validation :
|
|
27
|
+
|
|
28
|
+
- Règles d'erreur standard (`customRules`)
|
|
29
|
+
- Règles d'avertissement (`customWarningRules`)
|
|
30
|
+
- Règles de succès (`customSuccessRules`)
|
|
31
|
+
|
|
32
|
+
<a href="/?path=/docs/guide-du-dev-guide-de-validation-des-formulaires--docs" className="action-link">Pour plus d'informations sur la validation, consultez le guide de validation des formulaires.</a>
|