@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.
- package/dist/{DateFilter-B5n-ZkLi.js → DateFilter-Dc-gSGwk.js} +1 -1
- package/dist/{NumberFilter-CtiZ9uj8.js → NumberFilter-vP38Wp6j.js} +1 -1
- package/dist/{PeriodFilter-DzqiMb-b.js → PeriodFilter-Ba1uYUnT.js} +1 -1
- package/dist/{SelectFilter-BOYlF7rX.js → SelectFilter-BioGT6Nn.js} +1 -1
- package/dist/{TextFilter-BOFRNfcX.js → TextFilter-B84dpnoq.js} +1 -1
- package/dist/components/Accordion/Accordion.d.ts +13 -2
- package/dist/components/Accordion/composables/useAccordionState.d.ts +2 -1
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +16 -16
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +1 -1
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +22 -1
- package/dist/components/Customs/Selects/SyAutocomplete/locales.d.ts +5 -0
- package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +1 -1
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +1 -1
- package/dist/components/Customs/Selects/SySelect/locales.d.ts +1 -0
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +1 -1
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +1 -1
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1 -1
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +5 -2
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +13 -9
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +7 -5
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +2 -1
- package/dist/components/ErrorPage/ErrorPage.d.ts +3 -1
- package/dist/components/FileList/UploadItem/UploadItem.d.ts +6 -0
- package/dist/components/FileList/UploadItem/locales.d.ts +1 -4
- package/dist/components/FileUpload/FileUploadContent.d.ts +2 -0
- package/dist/components/FileUpload/validateFiles.d.ts +2 -1
- package/dist/components/HeaderBar/HeaderBar.d.ts +2 -1
- package/dist/components/HeaderBar/HeaderLogo/HeaderLogo.d.ts +2 -1
- package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +2 -1
- package/dist/components/MonthPicker/MonthPicker.d.ts +1939 -0
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1899 -0
- package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +21 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.d.ts +21 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.d.ts +12 -0
- package/dist/components/MonthPicker/MonthPickerVisual/MonthSelector.d.ts +11 -0
- package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.d.ts +6 -0
- package/dist/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.d.ts +14 -0
- package/dist/components/MonthPicker/MonthPickerVisual/YearSelector.d.ts +14 -0
- package/dist/components/MonthPicker/MonthPickerVisual/useMonthGrid.d.ts +9 -0
- package/dist/components/MonthPicker/MonthPickerVisual/useYearGrid.d.ts +8 -0
- package/dist/components/MonthPicker/MonthPickerVisual/utils.d.ts +8 -0
- package/dist/components/MonthPicker/locales.d.ts +12 -0
- package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +25 -0
- package/dist/components/NirField/NirField.d.ts +3 -1
- package/dist/components/NotificationBar/Notification/Notification.d.ts +3 -0
- package/dist/components/PasswordField/PasswordField.d.ts +1 -1
- package/dist/components/PeriodField/PeriodField.d.ts +29 -21
- package/dist/components/PhoneField/PhoneField.d.ts +2 -1
- package/dist/components/SyBtnMenu/SyBtnMenu.d.ts +1 -1
- package/dist/components/SyHeading/SyHeading.a11y.test.d.ts +1 -0
- package/dist/components/SyHeading/SyHeading.d.ts +4 -2
- package/dist/components/SyHeading/SyHeading.test.d.ts +1 -0
- package/dist/components/SyTextArea/SyTextArea.d.ts +1 -1
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +4 -4
- package/dist/components/Tables/SyTable/SyTable.d.ts +4 -4
- package/dist/components/Tables/common/SyTablePagination.d.ts +6 -6
- package/dist/components/index.d.ts +1 -0
- package/dist/design-system-v3.js +102 -99
- package/dist/design-system-v3.umd.cjs +126 -126
- package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +5 -0
- package/dist/{main-CEl4J8_T.js → main-aLKwdMi1.js} +11167 -10522
- package/dist/main.d.ts +1 -0
- package/dist/style.css +1 -1
- package/package.json +10 -4
- package/src/assets/apTokens.scss +2 -2
- package/src/assets/overrides/_btns.scss +8 -0
- package/src/assets/overrides/_forms.scss +9 -0
- package/src/assets/overrides/_icons.scss +38 -9
- package/src/assets/overrides/_tables.scss +19 -0
- package/src/components/Accordion/Accordion.mdx +23 -9
- package/src/components/Accordion/Accordion.stories.ts +153 -3
- package/src/components/Accordion/Accordion.vue +7 -6
- package/src/components/Accordion/composables/__tests__/useAccordionState.spec.ts +40 -12
- package/src/components/Accordion/composables/useAccordionState.ts +3 -4
- package/src/components/Accordion/tests/accordion.spec.ts +131 -19
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.mdx +3 -1
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.stories.ts +8 -0
- package/src/components/BackBtn/accessibilite/Accessibility.mdx +62 -10
- package/src/components/BackToTopBtn/BackToTopBtn.stories.ts +9 -3
- package/src/components/BackToTopBtn/accessibilite/Accessibility.mdx +86 -6
- package/src/components/Captcha/tests/Captcha.spec.ts +0 -29
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +2 -110
- package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +133 -10
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +379 -93
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +144 -83
- package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibilite.stories.ts +40 -1
- package/src/components/Customs/Selects/SyAutocomplete/accessibilite/Accessibility.mdx +7 -1
- package/src/components/Customs/Selects/SyAutocomplete/locales.ts +5 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +96 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +234 -9
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +13 -3
- package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +9 -10
- package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -3
- package/src/components/Customs/Selects/SySelect/locales.ts +1 -0
- package/src/components/Customs/SyIcon/SyIcon.vue +1 -1
- package/src/components/Customs/SyIcon/tests/SyIcon.a11y.spec.ts +20 -0
- package/src/components/Customs/SyIconButton/SyIconButton.mdx +46 -0
- package/src/components/Customs/SyIconButton/SyIconButton.stories.ts +184 -0
- package/src/components/Customs/SyIconButton/SyIconButton.vue +38 -0
- package/src/components/Customs/SyIconButton/accessibilite/Accessibility.mdx +64 -0
- package/src/components/Customs/SyIconButton/tests/SyIconButton.a11y.spec.ts +87 -0
- package/src/components/Customs/SyIconButton/tests/SyIconButton.spec.ts +152 -0
- package/src/components/Customs/SyIconButton/tests/__snapshots__/SyIconButton.spec.ts.snap +61 -0
- package/src/components/Customs/SyPagination/SyPagination.vue +5 -5
- package/src/components/Customs/SyTextField/SyTextField.vue +20 -2
- package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +67 -9
- package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +15 -0
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +36 -0
- package/src/components/DataList/accessibilite/Accessibility.mdx +79 -11
- package/src/components/DataListGroup/accessibilite/Accessibility.mdx +80 -11
- package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +25 -0
- package/src/components/ErrorPage/ErrorPage.stories.ts +113 -19
- package/src/components/ErrorPage/ErrorPage.vue +17 -2
- package/src/components/ErrorPage/tests/ErrorPage.a11y.spec.ts +17 -0
- package/src/components/ErrorPage/tests/ErrorPage.spec.ts +21 -1
- package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +0 -1
- package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +23 -0
- package/src/components/FileList/FileList.stories.ts +51 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +13 -6
- package/src/components/FileList/UploadItem/locales.ts +3 -12
- package/src/components/FileList/accessibilite/Accessibility.mdx +3 -0
- package/src/components/FileUpload/FileUpload.vue +2 -1
- package/src/components/FileUpload/FileUploadContent.vue +2 -1
- package/src/components/FileUpload/tests/FileUpload.spec.ts +47 -0
- package/src/components/FileUpload/validateFiles.ts +5 -2
- package/src/components/FranceConnectBtn/accessibilite/Accessibility.mdx +62 -9
- package/src/components/HeaderBar/HeaderBar.vue +2 -1
- package/src/components/HeaderBar/HeaderLogo/HeaderLogo.vue +2 -1
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +2 -1
- package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +74 -8
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +163 -0
- package/src/components/MaintenancePage/MaintenancePage.vue +1 -1
- package/src/components/MaintenancePage/tests/MaintenancePage.spec.ts +4 -5
- package/src/components/MaintenancePage/tests/__snapshots__/MaintenancePage.spec.ts.snap +0 -1
- package/src/components/MonthPicker/MonthPicker.mdx +35 -0
- package/src/components/MonthPicker/MonthPicker.stories.ts +527 -0
- package/src/components/MonthPicker/MonthPicker.vue +79 -0
- package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +89 -0
- package/src/components/MonthPicker/MonthPickerText/useTextField.ts +27 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisual.vue +154 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthPickerVisualProps.ts +13 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +137 -0
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +60 -0
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +149 -0
- package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +143 -0
- package/src/components/MonthPicker/MonthPickerVisual/useMonthGrid.ts +45 -0
- package/src/components/MonthPicker/MonthPickerVisual/useYearGrid.ts +45 -0
- package/src/components/MonthPicker/MonthPickerVisual/utils.ts +17 -0
- package/src/components/MonthPicker/accessibilite/Accessibility.mdx +59 -0
- package/src/components/MonthPicker/locales.ts +12 -0
- package/src/components/MonthPicker/tests/MonthPicker.a11y.spec.ts +71 -0
- package/src/components/MonthPicker/tests/MonthPicker.spec.ts +1248 -0
- package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +2545 -0
- package/src/components/MonthPicker/useMonthPickerValidation.ts +30 -0
- package/src/components/NirField/NirField.mdx +1 -2
- package/src/components/NirField/NirField.stories.ts +66 -6
- package/src/components/NotFoundPage/tests/NotFoundPage.spec.ts +2 -3
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +22 -14
- package/src/components/NotificationBar/Notification/Notification.vue +3 -1
- package/src/components/NotificationBar/NotificationBar.stories.ts +154 -0
- package/src/components/NotificationBar/tests/NotificationBar.a11y.spec.ts +26 -0
- package/src/components/NotificationBar/tests/NotificationBar.spec.ts +60 -0
- package/src/components/RangeField/accessibilite/Accessibility.mdx +79 -11
- package/src/components/SkipLink/tests/SkipLink.a11y.spec.ts +23 -0
- package/src/components/StatusPage/StatusPage.stories.ts +118 -0
- package/src/components/StatusPage/StatusPage.vue +5 -3
- package/src/components/StatusPage/tests/StatusPage.a11y.spec.ts +22 -0
- package/src/components/StatusPage/tests/StatusPage.spec.ts +22 -0
- package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +22 -14
- package/src/components/SubHeader/tests/SubHeader.a11y.spec.ts +20 -0
- package/src/components/SyAlert/SyAlert.vue +1 -0
- package/src/components/SyAlert/accessibilite/Accessibility.mdx +79 -9
- package/src/components/SyAlert/tests/SyAlert.a11y.spec.ts +23 -0
- package/src/components/SyHeading/SyHeading.a11y.test.ts +149 -0
- package/src/components/SyHeading/SyHeading.test.ts +115 -0
- package/src/components/SyHeading/SyHeading.vue +5 -3
- package/src/components/SyTextArea/accessibilite/Accessibility.mdx +80 -8
- package/src/components/SyTextArea/tests/SyTextArea.a11y.spec.ts +151 -0
- package/src/components/ToolbarContainer/tests/ToolbarContainer.a11y.spec.ts +126 -0
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +2 -2
- package/src/components/index.ts +1 -0
- package/src/composables/useFormFieldErrorHandling.ts +11 -2
- package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -1
- package/src/main.ts +2 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ValidationRule } from '@/composables/validation/useValidation'
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
export type ValidationProps = {
|
|
5
|
+
customRules?: ValidationRule[]
|
|
6
|
+
customWarningRules?: ValidationRule[]
|
|
7
|
+
customSuccessRules?: ValidationRule[]
|
|
8
|
+
errorMessages?: string[] | null
|
|
9
|
+
warningMessages?: string[] | null
|
|
10
|
+
successMessages?: string[] | null
|
|
11
|
+
hasError?: boolean
|
|
12
|
+
hasWarning?: boolean
|
|
13
|
+
hasSuccess?: boolean
|
|
14
|
+
showSuccessMessages?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useMonthPickerValidation(props: ValidationProps) {
|
|
18
|
+
return computed(() => ({
|
|
19
|
+
customRules: props.customRules,
|
|
20
|
+
customWarningRules: props.customWarningRules,
|
|
21
|
+
customSuccessRules: props.customSuccessRules,
|
|
22
|
+
errorMessages: props.errorMessages,
|
|
23
|
+
warningMessages: props.warningMessages,
|
|
24
|
+
successMessages: props.successMessages,
|
|
25
|
+
hasError: props.hasError,
|
|
26
|
+
hasWarning: props.hasWarning,
|
|
27
|
+
hasSuccess: props.hasSuccess,
|
|
28
|
+
showSuccessMessages: props.showSuccessMessages,
|
|
29
|
+
}))
|
|
30
|
+
}
|
|
@@ -65,8 +65,7 @@ import NirField from './NirField.vue';
|
|
|
65
65
|
|
|
66
66
|
Le composant `NirField` utilise des règles de validation par défaut pour le numéro NIR et la Clé. Voici les règles de validation par défaut :
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
<h4 id="ancre-nirtype">Pour le numéro NIR</h4>
|
|
70
69
|
- Props: `nirType` à simple (par defaut) d'après le [repo](https://github.com/assurance-maladie-digital/nir-validation) :
|
|
71
70
|
|
|
72
71
|
- Le 1er chiffre (1er composant) permet d'identifier le sexe de l'assuré (1 pour un homme et 2 pour une femme) ;
|
|
@@ -878,9 +878,6 @@ export const WithNirTooltip: Story = {
|
|
|
878
878
|
nirTooltipPosition: 'prepend',
|
|
879
879
|
},
|
|
880
880
|
parameters: {
|
|
881
|
-
a11y: {
|
|
882
|
-
disable: true,
|
|
883
|
-
},
|
|
884
881
|
docs: {
|
|
885
882
|
description: {
|
|
886
883
|
story: `
|
|
@@ -929,9 +926,6 @@ export const WithKeyTooltip: Story = {
|
|
|
929
926
|
keyTooltipPosition: 'append',
|
|
930
927
|
},
|
|
931
928
|
parameters: {
|
|
932
|
-
a11y: {
|
|
933
|
-
disable: true,
|
|
934
|
-
},
|
|
935
929
|
docs: {
|
|
936
930
|
description: {
|
|
937
931
|
story: `
|
|
@@ -1394,4 +1388,70 @@ const value = ref('')
|
|
|
1394
1388
|
},
|
|
1395
1389
|
],
|
|
1396
1390
|
},
|
|
1391
|
+
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
export const ComplexNirType: Story = {
|
|
1395
|
+
args: {
|
|
1396
|
+
modelValue: '712125233333340',
|
|
1397
|
+
required: false,
|
|
1398
|
+
numberLabel: 'Numéro de sécurité sociale',
|
|
1399
|
+
keyLabel: 'Clé',
|
|
1400
|
+
displayKey: true,
|
|
1401
|
+
nirType: 'complexe',
|
|
1402
|
+
},
|
|
1403
|
+
parameters: {
|
|
1404
|
+
sourceCode: [
|
|
1405
|
+
{
|
|
1406
|
+
name: 'Template',
|
|
1407
|
+
code: `
|
|
1408
|
+
<template>
|
|
1409
|
+
<NirField
|
|
1410
|
+
v-model="value"
|
|
1411
|
+
:required="false"
|
|
1412
|
+
numberLabel="Numéro de sécurité sociale"
|
|
1413
|
+
keyLabel="Clé"
|
|
1414
|
+
:nirType="complexe"
|
|
1415
|
+
:displayKey="true"
|
|
1416
|
+
/>
|
|
1417
|
+
</template>
|
|
1418
|
+
`,
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
name: 'Script',
|
|
1422
|
+
code: `
|
|
1423
|
+
<script setup lang="ts">
|
|
1424
|
+
import { NirField } from '@cnamts/synapse'
|
|
1425
|
+
import { ref } from 'vue'
|
|
1426
|
+
|
|
1427
|
+
const value = ref('184027512345674')
|
|
1428
|
+
|
|
1429
|
+
return { value }
|
|
1430
|
+
</script>
|
|
1431
|
+
`,
|
|
1432
|
+
},
|
|
1433
|
+
],
|
|
1434
|
+
},
|
|
1435
|
+
render: () => ({
|
|
1436
|
+
components: { NirField },
|
|
1437
|
+
setup() {
|
|
1438
|
+
const value = ref('712125233333340')
|
|
1439
|
+
|
|
1440
|
+
return { value }
|
|
1441
|
+
},
|
|
1442
|
+
template: `
|
|
1443
|
+
<div>
|
|
1444
|
+
<p class="mt-2">Cet exemple montre l'utilisation d'un NIR de type complexe<br/>(commençant par 7).</p>
|
|
1445
|
+
<p class="mb-4">Pour plus d'informations sur le NirType voir la <a href="/?path=/docs/composants-formulaires-nirfield--docs#ancre-nirtype">documentation</a>.</p>
|
|
1446
|
+
</div>
|
|
1447
|
+
<NirField
|
|
1448
|
+
v-model="value"
|
|
1449
|
+
:required="false"
|
|
1450
|
+
numberLabel="Numéro de sécurité sociale"
|
|
1451
|
+
keyLabel="Clé"
|
|
1452
|
+
nirType="complexe"
|
|
1453
|
+
:displayKey="true"
|
|
1454
|
+
/>
|
|
1455
|
+
`,
|
|
1456
|
+
}),
|
|
1397
1457
|
}
|
|
@@ -115,13 +115,12 @@ describe('NotFoundPage', () => {
|
|
|
115
115
|
expect(img.attributes('src')).toBe('/custom.svg')
|
|
116
116
|
})
|
|
117
117
|
|
|
118
|
-
it('
|
|
118
|
+
it('uses a generated uniqueId', async () => {
|
|
119
119
|
const wrapper = mount(NotFoundPage)
|
|
120
120
|
await flushPromises()
|
|
121
121
|
await wrapper.vm.$nextTick()
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
expect(statusPage.props('uniqueId')).toBeDefined()
|
|
123
|
+
expect(wrapper.find('.vd-page-container').attributes('id')).toMatch(/^[-a-z0-9]+-container$/)
|
|
125
124
|
})
|
|
126
125
|
|
|
127
126
|
it('passes a custom uniqueId prop to StatusPage', async () => {
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`NotFoundPage > display the support ID if provided in the url 1`] = `
|
|
4
|
-
<div
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
<div
|
|
5
|
+
class="
|
|
6
|
+
d-flex
|
|
7
|
+
justify-center
|
|
8
|
+
px-14
|
|
9
|
+
py-10
|
|
10
|
+
vd-page-container
|
|
11
|
+
"
|
|
12
|
+
id="v-0-container"
|
|
13
|
+
>
|
|
11
14
|
<div
|
|
12
15
|
class="
|
|
13
16
|
bg-transparent
|
|
14
17
|
v-sheet
|
|
15
18
|
v-theme--light
|
|
16
19
|
"
|
|
20
|
+
id="v-0-content"
|
|
17
21
|
style="width: 800px;"
|
|
18
22
|
>
|
|
19
23
|
<div class="
|
|
@@ -149,19 +153,23 @@ exports[`NotFoundPage > display the support ID if provided in the url 1`] = `
|
|
|
149
153
|
`;
|
|
150
154
|
|
|
151
155
|
exports[`NotFoundPage > renders correctly 1`] = `
|
|
152
|
-
<div
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
<div
|
|
157
|
+
class="
|
|
158
|
+
d-flex
|
|
159
|
+
justify-center
|
|
160
|
+
px-14
|
|
161
|
+
py-10
|
|
162
|
+
vd-page-container
|
|
163
|
+
"
|
|
164
|
+
id="v-0-container"
|
|
165
|
+
>
|
|
159
166
|
<div
|
|
160
167
|
class="
|
|
161
168
|
bg-transparent
|
|
162
169
|
v-sheet
|
|
163
170
|
v-theme--light
|
|
164
171
|
"
|
|
172
|
+
id="v-0-content"
|
|
165
173
|
style="width: 800px;"
|
|
166
174
|
>
|
|
167
175
|
<div class="
|
|
@@ -74,7 +74,9 @@
|
|
|
74
74
|
decorative
|
|
75
75
|
/>
|
|
76
76
|
|
|
77
|
-
<span class="notification__message">
|
|
77
|
+
<span class="notification__message">
|
|
78
|
+
<slot :notification="props.notification">{{ notification.message }}</slot>
|
|
79
|
+
</span>
|
|
78
80
|
<div
|
|
79
81
|
class="d-flex ga-2 notification__actions"
|
|
80
82
|
:class="notification.message.length > 50 ? 'action-section-long-text' : 'action-section-short-text'"
|
|
@@ -408,6 +408,160 @@ CustomCloseBtnText.parameters = {
|
|
|
408
408
|
],
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
+
export const DefaultSlot: Story = (args) => {
|
|
412
|
+
return {
|
|
413
|
+
components: { NotificationBar, VBtn },
|
|
414
|
+
setup() {
|
|
415
|
+
const { addNotification } = useNotificationService()
|
|
416
|
+
|
|
417
|
+
const envoyerNotification = () => {
|
|
418
|
+
const notification: Notification = {
|
|
419
|
+
id: Date.now().toString(),
|
|
420
|
+
message: 'Notification avec contenu principal personnalisé.',
|
|
421
|
+
type: 'info',
|
|
422
|
+
timeout: -1,
|
|
423
|
+
}
|
|
424
|
+
addNotification(notification)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return { args, envoyerNotification }
|
|
428
|
+
},
|
|
429
|
+
template: `
|
|
430
|
+
<div class="d-flex flex-wrap align-center justify-center">
|
|
431
|
+
<NotificationBar v-bind="args">
|
|
432
|
+
<template #default="{ notification }">
|
|
433
|
+
Contenu personnalisé pour <strong>{{ notification.id }}</strong>
|
|
434
|
+
</template>
|
|
435
|
+
</NotificationBar>
|
|
436
|
+
<VBtn
|
|
437
|
+
color="primary"
|
|
438
|
+
@click="envoyerNotification()"
|
|
439
|
+
class="ma-6"
|
|
440
|
+
>
|
|
441
|
+
Afficher la notification
|
|
442
|
+
</VBtn>
|
|
443
|
+
</div>
|
|
444
|
+
`,
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
DefaultSlot.args = {
|
|
449
|
+
...Default.args,
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
DefaultSlot.parameters = {
|
|
453
|
+
sourceCode: [
|
|
454
|
+
{
|
|
455
|
+
name: 'Template',
|
|
456
|
+
code: `
|
|
457
|
+
<NotificationBar>
|
|
458
|
+
<template #default="{ notification }">
|
|
459
|
+
Contenu personnalisé pour <strong>{{ notification.id }}</strong>
|
|
460
|
+
</template>
|
|
461
|
+
</NotificationBar>
|
|
462
|
+
`,
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
name: 'Script',
|
|
466
|
+
code: `
|
|
467
|
+
<script setup lang="ts">
|
|
468
|
+
import { NotificationBar, useNotificationService } from '@cnamts/synapse'
|
|
469
|
+
|
|
470
|
+
const { addNotification } = useNotificationService()
|
|
471
|
+
|
|
472
|
+
const envoyerNotification = () => {
|
|
473
|
+
addNotification({
|
|
474
|
+
id: Date.now().toString(),
|
|
475
|
+
message: 'Notification avec contenu principal personnalisé.',
|
|
476
|
+
type: 'info',
|
|
477
|
+
timeout: -1,
|
|
478
|
+
})
|
|
479
|
+
}
|
|
480
|
+
</script>
|
|
481
|
+
`,
|
|
482
|
+
},
|
|
483
|
+
],
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
export const ActionSlot: Story = (args) => {
|
|
487
|
+
return {
|
|
488
|
+
components: { NotificationBar, VBtn },
|
|
489
|
+
setup() {
|
|
490
|
+
const { addNotification } = useNotificationService()
|
|
491
|
+
|
|
492
|
+
const envoyerNotification = () => {
|
|
493
|
+
const notification: Notification = {
|
|
494
|
+
id: Date.now().toString(),
|
|
495
|
+
message: 'Notification avec contenu personnalisé via slot.',
|
|
496
|
+
type: 'info',
|
|
497
|
+
timeout: -1,
|
|
498
|
+
}
|
|
499
|
+
addNotification(notification)
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return { args, envoyerNotification }
|
|
503
|
+
},
|
|
504
|
+
template: `
|
|
505
|
+
<div class="d-flex flex-wrap align-center justify-center">
|
|
506
|
+
<NotificationBar v-bind="args">
|
|
507
|
+
<template #action>
|
|
508
|
+
<VBtn variant="outlined">
|
|
509
|
+
Voir le détail
|
|
510
|
+
</VBtn>
|
|
511
|
+
</template>
|
|
512
|
+
</NotificationBar>
|
|
513
|
+
<VBtn
|
|
514
|
+
color="primary"
|
|
515
|
+
@click="envoyerNotification()"
|
|
516
|
+
class="ma-6"
|
|
517
|
+
>
|
|
518
|
+
Afficher la notification
|
|
519
|
+
</VBtn>
|
|
520
|
+
</div>
|
|
521
|
+
`,
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
ActionSlot.args = {
|
|
526
|
+
...Default.args,
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
ActionSlot.parameters = {
|
|
530
|
+
sourceCode: [
|
|
531
|
+
{
|
|
532
|
+
name: 'Template',
|
|
533
|
+
code: `
|
|
534
|
+
<NotificationBar>
|
|
535
|
+
<template #action>
|
|
536
|
+
<VBtn variant="outlined">
|
|
537
|
+
Voir le détail
|
|
538
|
+
</VBtn>
|
|
539
|
+
</template>
|
|
540
|
+
</NotificationBar>
|
|
541
|
+
`,
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
name: 'Script',
|
|
545
|
+
code: `
|
|
546
|
+
<script setup lang="ts">
|
|
547
|
+
import { NotificationBar, useNotificationService } from '@cnamts/synapse'
|
|
548
|
+
|
|
549
|
+
const { addNotification } = useNotificationService()
|
|
550
|
+
|
|
551
|
+
const envoyerNotification = () => {
|
|
552
|
+
addNotification({
|
|
553
|
+
id: Date.now().toString(),
|
|
554
|
+
message: 'Notification avec contenu personnalisé via slot.',
|
|
555
|
+
type: 'info',
|
|
556
|
+
timeout: -1,
|
|
557
|
+
})
|
|
558
|
+
}
|
|
559
|
+
</script>
|
|
560
|
+
`,
|
|
561
|
+
},
|
|
562
|
+
],
|
|
563
|
+
}
|
|
564
|
+
|
|
411
565
|
export const Customization: Story = Default.bind({})
|
|
412
566
|
Customization.args = {
|
|
413
567
|
...Default.args,
|
|
@@ -41,6 +41,32 @@ describe('NotificationBar – accessibility (axe)', () => {
|
|
|
41
41
|
vi.restoreAllMocks()
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
+
it('has no obvious axe violations with default slot content', async () => {
|
|
45
|
+
const notification: Notification = {
|
|
46
|
+
id: '1',
|
|
47
|
+
message: 'Message original',
|
|
48
|
+
type: 'info',
|
|
49
|
+
timeout: -1,
|
|
50
|
+
icon: null,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
useNotificationService().notificationQueue.value = [notification]
|
|
54
|
+
|
|
55
|
+
const wrapper = mount(NotificationBar, {
|
|
56
|
+
attachTo: document.body,
|
|
57
|
+
slots: {
|
|
58
|
+
default: '<span>Contenu personnalisé via slot default</span>',
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
const results = await axe(document.body)
|
|
63
|
+
assertNoA11yViolations(results, 'NotificationBar – default slot content', {
|
|
64
|
+
ignoreRules: ['region'],
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
wrapper.unmount()
|
|
68
|
+
})
|
|
69
|
+
|
|
44
70
|
it('has no obvious axe violations with visible info notification', async () => {
|
|
45
71
|
const notification: Notification = {
|
|
46
72
|
id: '1',
|
|
@@ -186,6 +186,66 @@ describe('NotificationBar.vue', () => {
|
|
|
186
186
|
expect(wrapper.html()).not.toContain('Test message 1')
|
|
187
187
|
})
|
|
188
188
|
|
|
189
|
+
it('should render default slot content instead of message', async () => {
|
|
190
|
+
const notification: Notification = {
|
|
191
|
+
id: '1',
|
|
192
|
+
message: 'Message original',
|
|
193
|
+
type: 'info',
|
|
194
|
+
timeout: -1,
|
|
195
|
+
icon: null,
|
|
196
|
+
}
|
|
197
|
+
notificationServiceMock.notificationQueue.value = [notification]
|
|
198
|
+
|
|
199
|
+
const wrapper = mount(NotificationBar, {
|
|
200
|
+
slots: {
|
|
201
|
+
default: '<span>Contenu personnalisé</span>',
|
|
202
|
+
},
|
|
203
|
+
})
|
|
204
|
+
vi.runAllTimers()
|
|
205
|
+
await nextTick()
|
|
206
|
+
|
|
207
|
+
expect(wrapper.html()).toContain('Contenu personnalisé')
|
|
208
|
+
expect(wrapper.html()).not.toContain('Message original')
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('should expose notification slotProp in default slot', async () => {
|
|
212
|
+
const notification: Notification = {
|
|
213
|
+
id: 'abc',
|
|
214
|
+
message: 'Message original',
|
|
215
|
+
type: 'info',
|
|
216
|
+
timeout: -1,
|
|
217
|
+
icon: null,
|
|
218
|
+
}
|
|
219
|
+
notificationServiceMock.notificationQueue.value = [notification]
|
|
220
|
+
|
|
221
|
+
const wrapper = mount(NotificationBar, {
|
|
222
|
+
slots: {
|
|
223
|
+
default: `<template #default="{ notification }"><span>id: {{ notification.id }}</span></template>`,
|
|
224
|
+
},
|
|
225
|
+
})
|
|
226
|
+
vi.runAllTimers()
|
|
227
|
+
await nextTick()
|
|
228
|
+
|
|
229
|
+
expect(wrapper.html()).toContain('id: abc')
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('should fall back to message when no default slot is provided', async () => {
|
|
233
|
+
const notification: Notification = {
|
|
234
|
+
id: '1',
|
|
235
|
+
message: 'Message fallback',
|
|
236
|
+
type: 'info',
|
|
237
|
+
timeout: -1,
|
|
238
|
+
icon: null,
|
|
239
|
+
}
|
|
240
|
+
notificationServiceMock.notificationQueue.value = [notification]
|
|
241
|
+
|
|
242
|
+
const wrapper = mount(NotificationBar)
|
|
243
|
+
vi.runAllTimers()
|
|
244
|
+
await nextTick()
|
|
245
|
+
|
|
246
|
+
expect(wrapper.html()).toContain('Message fallback')
|
|
247
|
+
})
|
|
248
|
+
|
|
189
249
|
it('should compute action', async () => {
|
|
190
250
|
const notification: Notification = {
|
|
191
251
|
id: '1',
|
|
@@ -1,15 +1,83 @@
|
|
|
1
|
-
import { Meta,
|
|
2
|
-
import * as
|
|
3
|
-
import '@/
|
|
1
|
+
import { Meta, Primary } from '@storybook/blocks';
|
|
2
|
+
import * as RangeFieldStories from '../RangeField.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={RangeFieldStories}/>
|
|
6
14
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
<AccessibilityGuideLayout
|
|
16
|
+
componentName="RangeField"
|
|
17
|
+
iconSrc={AccessibilityIcon}
|
|
18
|
+
apgHref="https://www.w3.org/WAI/ARIA/apg/patterns/slider/"
|
|
19
|
+
>
|
|
20
|
+
<div class="mt-8">
|
|
21
|
+
<p>Rapport d'audit manuel : <a href="/audits/RangeField.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/908" target="_blank" style={{color:'#0C41BD'}}>issue #908</a>)</p>
|
|
23
|
+
</div>
|
|
10
24
|
|
|
25
|
+
<CriteriaSection>
|
|
26
|
+
<CriteriaCard icon="🔍" title="Structure sémantique et regroupement">
|
|
27
|
+
<ul>
|
|
28
|
+
<li><strong>Fieldset/Legend</strong> : Utilisation de <code><fieldset></code> et <code><legend></code> lorsque <code>fieldsetLabel</code> est fourni pour regrouper sémantiquement les champs</li>
|
|
29
|
+
<li><strong>Double entrée</strong> : Composant hybride avec slider visuel et champs textuels pour une accessibilité maximale</li>
|
|
30
|
+
<li><strong>Labels explicites</strong> : Champs texte avec labels personnalisables via <code>textFieldMinLabel</code> et <code>textFieldMaxLabel</code></li>
|
|
31
|
+
</ul>
|
|
32
|
+
</CriteriaCard>
|
|
11
33
|
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
<CriteriaCard icon="⌨️" title="Navigation et interaction clavier">
|
|
35
|
+
<ul>
|
|
36
|
+
<li><strong>Input numérique</strong> : Champs texte avec <code>inputmode="numeric"</code> pour optimiser le clavier mobile</li>
|
|
37
|
+
<li><strong>Validation synchrone</strong> : Mise à jour bidirectionnelle entre slider et champs texte pour une cohérence immédiate</li>
|
|
38
|
+
<li><strong>Contraintes logiques</strong> : Validation automatique pour garantir min ≤ max avec corrections appropriées</li>
|
|
39
|
+
</ul>
|
|
40
|
+
</CriteriaCard>
|
|
41
|
+
|
|
42
|
+
<CriteriaCard icon="🎨" title="Masque saisie et formatage">
|
|
43
|
+
<ul>
|
|
44
|
+
<li><strong>vMaska</strong> : Masque de saisie personnalisé pour gérer nombres négatifs et décimaux</li>
|
|
45
|
+
<li><strong>Pattern flexible</strong> : Support des formats comme "-123.45" avec tokens adaptés</li>
|
|
46
|
+
<li><strong>Clamp automatique</strong> : Correction des valeurs hors limites avec <code>clamp()</code></li>
|
|
47
|
+
</ul>
|
|
48
|
+
</CriteriaCard>
|
|
49
|
+
|
|
50
|
+
<CriteriaCard icon="📱" title="Responsive et adaptabilité">
|
|
51
|
+
<ul>
|
|
52
|
+
<li><strong>Layout adaptatif</strong> : Orientation des champs qui passe de horizontal à vertical sur mobile</li>
|
|
53
|
+
<li><strong>Display Vuetify</strong> : Utilisation de <code>useDisplay()</code> pour détecter les tailles d'écran</li>
|
|
54
|
+
<li><strong>Options personnalisables</strong> : Composant entièrement configurable via <code>useCustomizableOptions</code></li>
|
|
55
|
+
</ul>
|
|
56
|
+
</CriteriaCard>
|
|
57
|
+
</CriteriaSection>
|
|
58
|
+
|
|
59
|
+
<DemoSection componentName="RangeField">
|
|
60
|
+
<Primary />
|
|
61
|
+
</DemoSection>
|
|
62
|
+
|
|
63
|
+
<BestPracticesSection>
|
|
64
|
+
<ul>
|
|
65
|
+
<li><strong>Labels descriptifs</strong> : Utilisez des labels clairs pour les champs min/max ("Prix minimum", "Âge maximum")</li>
|
|
66
|
+
<li><strong>Fieldset cohérent</strong> : Regroupez les champs avec un <code>fieldsetLabel</code> pertinent ("Fourchette de prix", "Plage d'âge")</li>
|
|
67
|
+
<li><strong>Valeurs par défaut</strong> : Initialisez toujours <code>modelValue</code> avec une plage valide [min, max]</li>
|
|
68
|
+
<li><strong>Step approprié</strong> : Choisissez un <code>step</code> logique (1 pour les entiers, 0.1 pour les décimales)</li>
|
|
69
|
+
<li><strong>Validation côté serveur</strong> : Complétez la validation client avec des vérifications serveur pour la sécurité</li>
|
|
70
|
+
<li><strong>Feedback utilisateur</strong> : Ajoutez des messages d'aide ou d'erreur pour guider l'utilisateur</li>
|
|
71
|
+
</ul>
|
|
72
|
+
</BestPracticesSection>
|
|
73
|
+
|
|
74
|
+
<ResourcesSection>
|
|
75
|
+
<ul>
|
|
76
|
+
<li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/slider/" target="_blank" rel="noopener noreferrer">Guide des pratiques WAI-ARIA : Sliders</a></li>
|
|
77
|
+
<li><a href="https://www.w3.org/WAI/WCAG21/quickref/" target="_blank" rel="noopener noreferrer">Référence rapide WCAG 2.1</a></li>
|
|
78
|
+
<li><a href="https://accessibilite.numerique.gouv.fr/methode/criteres-et-tests/#11.9" target="_blank" rel="noopener noreferrer">RGAA Critère 11.9 : Champs de saisie numérique</a></li>
|
|
79
|
+
<li><a href="https://developer.mozilla.org/fr/docs/Web/HTML/Element/Input/number" target="_blank" rel="noopener noreferrer">MDN : Champs input number et inputmode</a></li>
|
|
80
|
+
</ul>
|
|
81
|
+
</ResourcesSection>
|
|
82
|
+
|
|
83
|
+
</AccessibilityGuideLayout>
|
|
@@ -0,0 +1,23 @@
|
|
|
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 SkipLink from '../SkipLink.vue'
|
|
8
|
+
|
|
9
|
+
describe('SkipLink – accessibility (axe)', () => {
|
|
10
|
+
it('has no obvious axe violations', async () => {
|
|
11
|
+
const wrapper = mount(SkipLink, {
|
|
12
|
+
props: {
|
|
13
|
+
links: [
|
|
14
|
+
{ label: 'Aller au contenu', href: '#main' },
|
|
15
|
+
{ label: 'Aller à la navigation', href: '#nav' },
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
21
|
+
assertNoA11yViolations(results, 'SkipLink – default state')
|
|
22
|
+
})
|
|
23
|
+
})
|