@cnamts/synapse 1.0.22 → 1.0.24
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/AutocompleteFilter-BWLR3U7W.js +114 -0
- package/dist/AutocompleteFilter-D9jzRzAL.cjs +1 -0
- package/dist/{DateFilter-B5n-ZkLi.js → DateFilter-BpwFexzi.js} +1 -1
- package/dist/DateFilter-DTUl8hb1.cjs +1 -0
- package/dist/{NumberFilter-CtiZ9uj8.js → NumberFilter-Bz_NTdX9.js} +3 -3
- package/dist/NumberFilter-MAEojdk0.cjs +1 -0
- package/dist/PeriodFilter-CC4WgIhl.cjs +1 -0
- package/dist/{PeriodFilter-DzqiMb-b.js → PeriodFilter-DX_wy9g-.js} +1 -1
- package/dist/SelectFilter-BR3fvl-a.cjs +1 -0
- package/dist/SelectFilter-xqiPtPgX.js +135 -0
- package/dist/{TextFilter-BOFRNfcX.js → TextFilter-BBl3JFqK.js} +7 -7
- package/dist/TextFilter-CCfYFl5F.cjs +1 -0
- package/dist/apLightTheme-CFSRrjv2.cjs +1 -0
- package/dist/apLightTheme-D1P4jcD0.js +1231 -0
- 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 +7022 -9616
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproCheckbox/AmeliproCheckbox.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproCustomSelector/AmeliproCustomSelector.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +40 -40
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +61 -61
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7168 -9762
- package/dist/components/Amelipro/AmeliproStepper/AmeliproStepper.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +7506 -10100
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +22 -22
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +42 -42
- package/dist/components/Amelipro/StructureMenu/StructureTabs/StructureTabs.d.ts +2 -2
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +20 -498
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +130 -147
- package/dist/components/Customs/Selects/SyAutocomplete/locales.d.ts +5 -0
- package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +6 -6
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +13 -17
- package/dist/components/Customs/Selects/SySelect/locales.d.ts +1 -0
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +9 -9
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +29 -507
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +29 -507
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +64 -81
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +640 -780
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +322 -407
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +114 -156
- package/dist/components/DatePicker/composables/index.d.ts +1 -0
- package/dist/components/DatePicker/composables/useDatePickerFocusTrap.d.ts +11 -0
- package/dist/components/DatePicker/composables/useDateTextField.d.ts +4 -4
- package/dist/components/DatePicker/composables/useDateValidation.d.ts +3 -3
- package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
- package/dist/components/DatePicker/composables/useManualDateValidation.d.ts +2 -2
- 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 +6 -5
- package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +20 -28
- package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +3 -3
- package/dist/components/MonthPicker/MonthPicker.d.ts +1903 -0
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +1863 -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 +209 -271
- package/dist/components/NirField/locales.d.ts +10 -10
- package/dist/components/NirField/useNirValidation.d.ts +64 -0
- package/dist/components/NotificationBar/Notification/Notification.d.ts +3 -0
- package/dist/components/PasswordField/PasswordField.d.ts +9 -10
- package/dist/components/PeriodField/PeriodField.d.ts +1379 -1659
- package/dist/components/PhoneField/PhoneField.d.ts +90 -125
- package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +12 -12
- 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 +35 -15
- package/dist/components/SyTextArea/useDefaultValidationRules.d.ts +11 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +11 -8
- package/dist/components/Tables/SyTable/SyTable.d.ts +11 -8
- package/dist/components/Tables/common/SyTableFilter.d.ts +2 -3
- package/dist/components/Tables/common/SyTablePagination.d.ts +21 -23
- package/dist/components/Tables/common/filters/AutocompleteFilter.d.ts +120 -0
- package/dist/components/Tables/common/filters/locales.d.ts +0 -1
- package/dist/components/Tables/common/types.d.ts +19 -3
- package/dist/components/Tables/common/useClickableTableRow.d.ts +17 -0
- package/dist/components/Tables/common/usePagination.d.ts +3 -1
- package/dist/components/Tables/common/usePinnedColumns.d.ts +31 -0
- package/dist/components/Tables/common/useTableHeaders.d.ts +2 -0
- package/dist/components/Tables/common/useTableRowCheckboxAccessibility.d.ts +5 -0
- package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +6 -6
- package/dist/components/index.d.ts +1 -0
- package/dist/composables/date/useDatePickerAccessibility.d.ts +1 -1
- package/dist/composables/rules/useFieldValidation.d.ts +4 -4
- package/dist/composables/unifyValidation/useCustomValidation.d.ts +8 -0
- package/dist/composables/unifyValidation/useValidation.d.ts +102 -0
- package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +18 -0
- package/dist/composables/useFormFieldErrorHandling.d.ts +2 -2
- package/dist/composables/validation/useFormValidation.d.ts +11 -2
- package/dist/composables/validation/useValidation.d.ts +15 -9
- package/dist/design-system-v3.d.ts +2 -0
- package/dist/design-system-v3.js +196 -194
- package/dist/design-system-v3.umd.cjs +1 -1066
- package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +5 -0
- package/dist/{main-CEl4J8_T.js → main-BtTqyn4z.js} +16983 -15576
- package/dist/main-C1e3eoxd.cjs +1067 -0
- package/dist/synapse.css +1 -0
- package/dist/tooth-11-D3sLWv2n.cjs +1 -0
- package/dist/tooth-12-CXrLuH03.cjs +1 -0
- package/dist/tooth-13-BSfo5fpT.cjs +1 -0
- package/dist/tooth-14-DMzulx0h.cjs +1 -0
- package/dist/tooth-15-BKRFVi-9.cjs +1 -0
- package/dist/tooth-16-CpuxAbuM.cjs +1 -0
- package/dist/tooth-17-BPoahUdg.cjs +1 -0
- package/dist/tooth-18-DhHJz8sy.cjs +1 -0
- package/dist/tooth-21-Dgd5hn_X.cjs +1 -0
- package/dist/tooth-22-C2Tn19sB.cjs +1 -0
- package/dist/tooth-23-C9uaaSGb.cjs +1 -0
- package/dist/tooth-24-BrK9UGpf.cjs +1 -0
- package/dist/tooth-25-CE_EfGNp.cjs +1 -0
- package/dist/tooth-26-Ctv4i9Fy.cjs +1 -0
- package/dist/tooth-27-C5J7JkWM.cjs +1 -0
- package/dist/tooth-28-Z9oWqjo0.cjs +1 -0
- package/dist/tooth-31-BrYqmkTi.cjs +1 -0
- package/dist/tooth-32-BNNR0oCZ.cjs +1 -0
- package/dist/tooth-33-DuxvqO2J.cjs +1 -0
- package/dist/tooth-34-BCSCXMB6.cjs +1 -0
- package/dist/tooth-35-BLUXkX88.cjs +1 -0
- package/dist/tooth-36-IrKHYqlA.cjs +1 -0
- package/dist/tooth-37-BYqpdMwo.cjs +1 -0
- package/dist/tooth-38-B_eNXXdu.cjs +1 -0
- package/dist/tooth-41-Ddva4Ot8.cjs +1 -0
- package/dist/tooth-42-szcDqlM0.cjs +1 -0
- package/dist/tooth-43-B3ka6rQm.cjs +1 -0
- package/dist/tooth-44-CazyQucj.cjs +1 -0
- package/dist/tooth-45-B4HQtc8n.cjs +1 -0
- package/dist/tooth-46-BPM40gbG.cjs +1 -0
- package/dist/tooth-47-Dvr20dlh.cjs +1 -0
- package/dist/tooth-48-Bd8ljGsF.cjs +1 -0
- package/dist/tooth-51-OBpwCOF3.cjs +1 -0
- package/dist/tooth-52-aKxyHcmq.cjs +1 -0
- package/dist/tooth-53-vCwJjTOc.cjs +1 -0
- package/dist/tooth-54-DsWu2iFy.cjs +1 -0
- package/dist/tooth-55-BxC1X2Dn.cjs +1 -0
- package/dist/tooth-61-BbLvxMQi.cjs +1 -0
- package/dist/tooth-62-CmTkWczP.cjs +1 -0
- package/dist/tooth-63-DI7l_2qI.cjs +1 -0
- package/dist/tooth-64-B21sOsJh.cjs +1 -0
- package/dist/tooth-65-D2ZC2VEr.cjs +1 -0
- package/dist/tooth-71-D473PPO5.cjs +1 -0
- package/dist/tooth-72-Drh1wnNu.cjs +1 -0
- package/dist/tooth-73-DzlwYI23.cjs +1 -0
- package/dist/tooth-74-8aGvcZPg.cjs +1 -0
- package/dist/tooth-75-BFK7At_r.cjs +1 -0
- package/dist/tooth-81-BZmR-I0M.cjs +1 -0
- package/dist/tooth-82-euVfUUZV.cjs +1 -0
- package/dist/tooth-83-KV010j64.cjs +1 -0
- package/dist/tooth-84-BBg1RjhZ.cjs +1 -0
- package/dist/tooth-85-Cr-kc1wM.cjs +1 -0
- package/dist/vuetifyConfig.js +561 -0
- package/dist/vuetifyConfig.umd.cjs +1 -0
- package/package.json +18 -6
- package/src/assets/apTokens.scss +2 -2
- package/src/assets/overrides/_btns.scss +2 -0
- package/src/assets/overrides/_forms.scss +9 -0
- package/src/assets/overrides/_icons.scss +41 -4
- package/src/assets/overrides/_tables.scss +19 -0
- package/src/assets/overrides/_typography.scss +0 -10
- 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/AmeliproAutoCompleteField/__tests__/__snapshots__/AmeliproAutoCompleteField.spec.ts.snap +2 -2
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.mdx +3 -1
- package/src/components/Amelipro/AmeliproPagination/AmeliproPagination.stories.ts +8 -0
- package/src/components/Amelipro/AmeliproTextArea/__tests__/__snapshots__/AmeliproTextArea.spec.ts.snap +2 -2
- 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/accessibilite/Accessibility.mdx +86 -8
- package/src/components/Captcha/tests/Captcha.spec.ts +0 -29
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +14 -122
- package/src/components/ChipList/ChipList.stories.ts +0 -15
- package/src/components/ChipList/ChipList.vue +5 -1
- package/src/components/ChipList/accessibilite/Accessibility.mdx +83 -10
- package/src/components/ChipList/tests/ChipList.a11y.spec.ts +41 -0
- package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +124 -10
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +379 -93
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +162 -84
- 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 +377 -9
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +27 -13
- package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +9 -10
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +4 -4
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +8 -9
- package/src/components/Customs/Selects/SyInputSelect/tests/SyInputSelect.spec.ts +10 -10
- package/src/components/Customs/Selects/SySelect/SySelect.vue +60 -14
- package/src/components/Customs/Selects/SySelect/locales.ts +1 -0
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +54 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +6 -9
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +10 -16
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +16 -11
- package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +35 -0
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.a11y.spec.ts +134 -2
- package/src/components/Customs/SyForm/SyForm.stories.ts +31 -5
- 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/SyRadioGroup/SyRadioGroup.vue +4 -7
- package/src/components/Customs/SyTextField/SyTextField.mdx +1 -1
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +29 -27
- package/src/components/Customs/SyTextField/SyTextField.vue +174 -159
- package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +67 -9
- package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +47 -0
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +155 -10
- package/src/components/DataList/accessibilite/Accessibility.mdx +79 -11
- package/src/components/DataListGroup/accessibilite/Accessibility.mdx +80 -11
- package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +62 -58
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +330 -223
- package/src/components/DatePicker/CalendarMode/accessibilite/Accessibility.mdx +82 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.a11y.spec.ts +141 -0
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +2 -56
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +195 -159
- package/src/components/DatePicker/ComplexDatePicker/accessibilite/Accessibility.mdx +76 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +10 -10
- package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +8 -8
- package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +106 -8
- package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +12 -11
- package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +12 -12
- package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +0 -12
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +63 -57
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +3 -0
- package/src/components/DatePicker/DateTextInput/accessibilite/Accessibility.mdx +66 -0
- package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +52 -1
- package/src/components/DatePicker/composables/index.ts +1 -0
- package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +109 -65
- package/src/components/DatePicker/composables/tests/useDatePickerFocusTrap.spec.ts +138 -0
- package/src/components/DatePicker/composables/tests/useDateValidation.spec.ts +74 -18
- package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +39 -0
- package/src/components/DatePicker/composables/tests/useManualDateValidation.spec.ts +91 -0
- package/src/components/DatePicker/composables/useCalendarKeyboardNavigation.ts +442 -36
- package/src/components/DatePicker/composables/useDatePickerFocusTrap.ts +92 -0
- package/src/components/DatePicker/composables/useDateTextField.ts +7 -6
- package/src/components/DatePicker/composables/useDateValidation.ts +36 -35
- package/src/components/DatePicker/composables/useInputBlurHandler.ts +3 -3
- package/src/components/DatePicker/composables/useManualDateValidation.ts +6 -2
- package/src/components/DiacriticPicker/accessibilite/Accessibility.mdx +76 -8
- 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.stories.ts +14 -2
- 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/Logo/accessibilite/Accessibility.mdx +73 -11
- package/src/components/LogoBrandSection/accessibilite/Accessibility.mdx +85 -9
- package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +74 -8
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +163 -0
- package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +3 -1
- package/src/components/LunarCalendar/useLunarCalendarValidation.ts +4 -5
- 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 +1249 -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 +70 -6
- package/src/components/NirField/NirField.vue +64 -260
- package/src/components/NirField/accessibilite/Accessibility.mdx +2 -2
- package/src/components/NirField/locales.ts +1 -1
- package/src/components/NirField/tests/NirField.spec.ts +6 -0
- package/src/components/NirField/useNirValidation.ts +271 -0
- 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/PasswordField/PasswordField.stories.ts +4 -4
- package/src/components/PasswordField/PasswordField.vue +18 -24
- package/src/components/PasswordField/tests/PasswordField.spec.ts +6 -3
- package/src/components/PeriodField/PeriodField.stories.ts +4 -4
- package/src/components/PeriodField/PeriodField.vue +57 -57
- package/src/components/PeriodField/__tests__/PeriodField.async.spec.ts +32 -0
- package/src/components/PeriodField/accessibilite/Accessibility.mdx +68 -8
- package/src/components/PeriodField/tests/PeriodField.spec.ts +28 -2
- package/src/components/PhoneField/PhoneField.vue +5 -6
- package/src/components/PhoneField/tests/PhoneField.spec.ts +1 -0
- package/src/components/RangeField/RangeField.vue +6 -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/SyTextArea.stories.ts +138 -2
- package/src/components/SyTextArea/SyTextArea.vue +53 -23
- package/src/components/SyTextArea/accessibilite/Accessibility.mdx +80 -8
- package/src/components/SyTextArea/tests/SyTextArea.a11y.spec.ts +151 -0
- package/src/components/SyTextArea/tests/SyTextArea.spec.ts +126 -3
- package/src/components/SyTextArea/useDefaultValidationRules.ts +74 -0
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +25 -0
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +673 -1
- package/src/components/Tables/SyServerTable/SyServerTable.vue +148 -91
- package/src/components/Tables/SyServerTable/tests/SyServerTable.a11y.spec.ts +58 -0
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +122 -0
- package/src/components/Tables/SyTable/SyTable.mdx +25 -0
- package/src/components/Tables/SyTable/SyTable.stories.ts +452 -1
- package/src/components/Tables/SyTable/SyTable.vue +130 -56
- package/src/components/Tables/SyTable/tests/SyTable.a11y.spec.ts +57 -0
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +108 -0
- package/src/components/Tables/common/SyTableFilter.vue +22 -2
- package/src/components/Tables/common/TableHeader.vue +5 -1
- package/src/components/Tables/common/filters/AutocompleteFilter.vue +160 -0
- package/src/components/Tables/common/filters/NumberFilter.vue +1 -1
- package/src/components/Tables/common/filters/SelectFilter.vue +10 -11
- package/src/components/Tables/common/filters/TextFilter.vue +1 -1
- package/src/components/Tables/common/filters/getFilterComponent.ts +8 -1
- package/src/components/Tables/common/filters/locales.ts +0 -1
- package/src/components/Tables/common/filters/tests/AutocompleteFilter.a11y.spec.ts +110 -0
- package/src/components/Tables/common/filters/tests/AutocompleteFilter.spec.ts +203 -0
- package/src/components/Tables/common/filters/tests/SelectFilter.a11y.spec.ts +104 -0
- package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +152 -16
- package/src/components/Tables/common/tableFilterUtils.ts +3 -0
- package/src/components/Tables/common/tableStyles.scss +48 -4
- package/src/components/Tables/common/tests/filterByRange.spec.ts +2 -1
- package/src/components/Tables/common/types.ts +13 -4
- package/src/components/Tables/common/useClickableTableRow.ts +103 -0
- package/src/components/Tables/common/usePagination.ts +13 -0
- package/src/components/Tables/common/usePinnedColumns.ts +237 -0
- package/src/components/Tables/common/useTableHeaders.ts +3 -3
- package/src/components/Tables/common/useTableRowCheckboxAccessibility.ts +41 -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/date/tests/useDatePickerAccessibility.spec.ts +2 -6
- package/src/composables/date/useDatePickerAccessibility.ts +42 -207
- package/src/composables/rules/tests/useFieldValidation.spec.ts +120 -120
- package/src/composables/rules/useFieldValidation.ts +34 -17
- package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +601 -0
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +2048 -0
- package/src/composables/unifyValidation/tests/useVuetifyValidation.spec.ts +184 -0
- package/src/composables/unifyValidation/useCustomValidation.ts +95 -0
- package/src/composables/unifyValidation/useValidation.ts +190 -0
- package/src/composables/unifyValidation/useVuetifyValidation.ts +54 -0
- package/src/composables/useFormFieldErrorHandling.ts +15 -9
- package/src/composables/validation/tests/useFormValidation.spec.ts +14 -0
- package/src/composables/validation/tests/useValidation.spec.ts +116 -21
- package/src/composables/validation/useFormValidation.ts +20 -13
- package/src/composables/validation/useValidatable.ts +8 -1
- package/src/composables/validation/useValidation.ts +135 -99
- package/src/composantsVuetify/Introduction.mdx +48 -0
- package/src/composantsVuetify/VBtn/VBtn.mdx +72 -0
- package/src/composantsVuetify/VBtn/v-btn.stories.ts +121 -0
- package/src/composantsVuetify/VTooltip/VTooltip.mdx +32 -0
- package/src/composantsVuetify/VTooltip/v-tooltip.stories.ts +95 -0
- package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -1
- package/src/designTokens/tokens/cnam/cnamSemantic.ts +2 -2
- package/src/stories/Components/Components.stories.ts +74 -9
- package/src/stories/Demarrer/Accueil.stories.ts +3 -3
- package/src/stories/GuideDuDev/Amelipro.mdx +15 -0
- package/src/stories/GuideDuDev/Amelipro.stories.ts +209 -0
- package/src/stories/GuideDuDev/vuetifyOptions.mdx +3 -3
- package/dist/SelectFilter-BOYlF7rX.js +0 -136
- package/dist/style.css +0 -1
- package/src/components/DatePicker/Accessibilite.mdx +0 -14
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
|
|
194
194
|
const iconColor = computed(() => {
|
|
195
195
|
if (hasError.value || Boolean(isRequired.value) || props.errorMessages.length > 0) return 'error'
|
|
196
|
-
return 'rgb(
|
|
196
|
+
return 'rgb(var(--v-theme-iconBase));'
|
|
197
197
|
})
|
|
198
198
|
|
|
199
199
|
const variant = computed(() => {
|
|
@@ -286,7 +286,10 @@
|
|
|
286
286
|
emit('update:modelValue', props.multiple ? [] : null)
|
|
287
287
|
|
|
288
288
|
// Garder la liste ouverte après une suppression et réinitialiser la navigation au clavier
|
|
289
|
-
|
|
289
|
+
const target = event?.target as HTMLElement | undefined
|
|
290
|
+
const listElement = list.value?.$el as HTMLElement | undefined
|
|
291
|
+
const isClickFromList = Boolean(listElement && target && listElement.contains(target))
|
|
292
|
+
if (event?.type === 'keydown' || isClickFromList) {
|
|
290
293
|
if (!isOpen.value) {
|
|
291
294
|
isOpen.value = true
|
|
292
295
|
}
|
|
@@ -414,6 +417,11 @@
|
|
|
414
417
|
return ''
|
|
415
418
|
}
|
|
416
419
|
|
|
420
|
+
// If inline labels are shown, return empty string to hide input text
|
|
421
|
+
if (hasMultipleSelections.value) {
|
|
422
|
+
return ''
|
|
423
|
+
}
|
|
424
|
+
|
|
417
425
|
// For multiple mode, show default option text when nothing is selected
|
|
418
426
|
if (props.multiple) {
|
|
419
427
|
if (!selectedItem.value || (Array.isArray(selectedItem.value) && selectedItem.value.length === 0)) {
|
|
@@ -457,6 +465,10 @@
|
|
|
457
465
|
return props.chips && props.multiple && Array.isArray(selectedItem.value) && selectedItem.value.length > 0
|
|
458
466
|
})
|
|
459
467
|
|
|
468
|
+
const hasMultipleSelections = computed(() => {
|
|
469
|
+
return !props.chips && props.multiple && Array.isArray(selectedItem.value) && (selectedItem.value as unknown[]).length > 0
|
|
470
|
+
})
|
|
471
|
+
|
|
460
472
|
const hasSelectionToClear = computed(() => {
|
|
461
473
|
return props.multiple
|
|
462
474
|
? (((selectedItem.value as unknown[] | null | undefined)?.length) ?? 0) > 0
|
|
@@ -904,7 +916,10 @@
|
|
|
904
916
|
<template #activator="{ props: activatorProps }">
|
|
905
917
|
<div
|
|
906
918
|
class="sy-select"
|
|
907
|
-
:class="{
|
|
919
|
+
:class="{
|
|
920
|
+
'sy-select--clearable': props.clearable,
|
|
921
|
+
'sy-select--with-chips': hasChips,
|
|
922
|
+
}"
|
|
908
923
|
>
|
|
909
924
|
<VTextField
|
|
910
925
|
:id="inputId"
|
|
@@ -920,7 +935,7 @@
|
|
|
920
935
|
:rules="isRequired && !props.disableErrorHandling ? ['Le champ est requis.'] : []"
|
|
921
936
|
:bg-color="props.bgColor"
|
|
922
937
|
:density="props.density"
|
|
923
|
-
:active="hasChips || isOpen"
|
|
938
|
+
:active="hasChips || hasMultipleSelections || isOpen"
|
|
924
939
|
readonly
|
|
925
940
|
:hide-details="props.hideMessages && !showHelpTextAsMessage"
|
|
926
941
|
:hint="showHelpTextAsMessage ? props.helpText : ''"
|
|
@@ -955,12 +970,23 @@
|
|
|
955
970
|
size="small"
|
|
956
971
|
class="ma-1"
|
|
957
972
|
closable
|
|
958
|
-
:close-label="
|
|
959
|
-
@click:close="removeChip(item)"
|
|
973
|
+
:close-label="locales.removeChip(getChipText(item))"
|
|
974
|
+
@click:close.stop.prevent="removeChip(item)"
|
|
975
|
+
@keydown.enter.capture.stop.prevent="(event) => (event.target as HTMLElement | null)?.closest('.v-chip__close') && removeChip(item)"
|
|
976
|
+
@keydown.space.capture.stop.prevent="(event) => (event.target as HTMLElement | null)?.closest('.v-chip__close') && removeChip(item)"
|
|
960
977
|
>
|
|
961
978
|
{{ getChipText(item) }}
|
|
962
979
|
</VChip>
|
|
963
980
|
</div>
|
|
981
|
+
<template v-else-if="hasMultipleSelections">
|
|
982
|
+
<span
|
|
983
|
+
v-for="item in (selectedItem as unknown[])"
|
|
984
|
+
:key="props.returnObject && item ? String((item as ItemType)[props.valueKey]) : String(item)"
|
|
985
|
+
class="sy-select__label"
|
|
986
|
+
>
|
|
987
|
+
{{ getChipText(item) }}
|
|
988
|
+
</span>
|
|
989
|
+
</template>
|
|
964
990
|
<!-- Prepend -->
|
|
965
991
|
<template
|
|
966
992
|
v-if="$slots.prepend || props.prependIcon || props.prependTooltip"
|
|
@@ -1123,8 +1149,6 @@
|
|
|
1123
1149
|
</template>
|
|
1124
1150
|
|
|
1125
1151
|
<style scoped lang="scss">
|
|
1126
|
-
@use '@/assets/tokens';
|
|
1127
|
-
|
|
1128
1152
|
.sy-select-container {
|
|
1129
1153
|
display: flex;
|
|
1130
1154
|
flex-direction: column;
|
|
@@ -1136,12 +1160,12 @@
|
|
|
1136
1160
|
|
|
1137
1161
|
:deep(.v-input__prepend > .v-icon__svg),
|
|
1138
1162
|
:deep(.v-input__append > .v-icon__svg) {
|
|
1139
|
-
fill: rgb(
|
|
1163
|
+
fill: rgb(var(--v-theme-iconBase));
|
|
1140
1164
|
}
|
|
1141
1165
|
|
|
1142
1166
|
:deep(.v-input__prepend .v-icon:focus-visible),
|
|
1143
1167
|
:deep(.v-input__append .v-icon:focus-visible) {
|
|
1144
|
-
outline: 2px solid
|
|
1168
|
+
outline: 2px solid rgb(var(--v-theme-accentPrimary));
|
|
1145
1169
|
outline-offset: 2px;
|
|
1146
1170
|
opacity: 1;
|
|
1147
1171
|
}
|
|
@@ -1192,7 +1216,7 @@
|
|
|
1192
1216
|
/* Ensure focus styles match selection styles for keyboard navigation */
|
|
1193
1217
|
.v-list-item:focus-visible,
|
|
1194
1218
|
.v-list-item.keyboard-focused {
|
|
1195
|
-
outline: 2px solid
|
|
1219
|
+
outline: 2px solid rgb(var(--v-theme-accentPrimary));
|
|
1196
1220
|
outline-offset: -2px;
|
|
1197
1221
|
background-color: rgb(0 0 0 / 8%);
|
|
1198
1222
|
}
|
|
@@ -1219,14 +1243,19 @@
|
|
|
1219
1243
|
.v-icon.arrow {
|
|
1220
1244
|
position: absolute;
|
|
1221
1245
|
right: 10px;
|
|
1222
|
-
color:
|
|
1246
|
+
color: rgb(var(--v-theme-iconBase));
|
|
1223
1247
|
}
|
|
1224
1248
|
|
|
1225
1249
|
.sy-select__clear-icon {
|
|
1226
|
-
color:
|
|
1250
|
+
color: rgb(var(--v-theme-iconBase)) !important;
|
|
1227
1251
|
opacity: var(--v-medium-emphasis-opacity) !important;
|
|
1228
1252
|
}
|
|
1229
1253
|
|
|
1254
|
+
/* Style spécifique pour les chips */
|
|
1255
|
+
:deep(.v-chip .v-chip__close .v-icon__svg) {
|
|
1256
|
+
fill: inherit !important;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1230
1259
|
.sy-select__clear-button {
|
|
1231
1260
|
position: absolute;
|
|
1232
1261
|
background: transparent;
|
|
@@ -1249,9 +1278,21 @@
|
|
|
1249
1278
|
margin: 2px;
|
|
1250
1279
|
}
|
|
1251
1280
|
|
|
1281
|
+
.sy-select__label {
|
|
1282
|
+
align-self: center;
|
|
1283
|
+
white-space: nowrap;
|
|
1284
|
+
flex-shrink: 0;
|
|
1285
|
+
font-size: inherit;
|
|
1286
|
+
|
|
1287
|
+
&:not(:last-of-type)::after {
|
|
1288
|
+
content: ',';
|
|
1289
|
+
margin-right: 4px;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1252
1293
|
.sy-select :deep(.v-field__input) {
|
|
1253
1294
|
opacity: 1;
|
|
1254
|
-
color:
|
|
1295
|
+
color: rgb(var(--v-theme-iconBase)) !important;
|
|
1255
1296
|
cursor: pointer;
|
|
1256
1297
|
caret-color: transparent;
|
|
1257
1298
|
padding-right: 25px;
|
|
@@ -1274,4 +1315,9 @@
|
|
|
1274
1315
|
position: absolute;
|
|
1275
1316
|
white-space: nowrap;
|
|
1276
1317
|
}
|
|
1318
|
+
|
|
1319
|
+
.sy-select--with-chips :deep(.v-field__input input) {
|
|
1320
|
+
position: absolute;
|
|
1321
|
+
z-index: -1;
|
|
1322
|
+
}
|
|
1277
1323
|
</style>
|
|
@@ -964,6 +964,60 @@ describe('SySelect.vue', () => {
|
|
|
964
964
|
|
|
965
965
|
wrapper.unmount()
|
|
966
966
|
})
|
|
967
|
+
|
|
968
|
+
it('removes chip when Enter key is pressed on chip close button', async () => {
|
|
969
|
+
const items = [
|
|
970
|
+
{ text: 'Option 1', value: '1' },
|
|
971
|
+
{ text: 'Option 2', value: '2' },
|
|
972
|
+
]
|
|
973
|
+
const wrapper = mount(SySelect, {
|
|
974
|
+
props: {
|
|
975
|
+
items,
|
|
976
|
+
multiple: true,
|
|
977
|
+
chips: true,
|
|
978
|
+
modelValue: ['1', '2'],
|
|
979
|
+
textKey: 'text',
|
|
980
|
+
valueKey: 'value',
|
|
981
|
+
},
|
|
982
|
+
attachTo: document.body,
|
|
983
|
+
})
|
|
984
|
+
|
|
985
|
+
await wrapper.vm.$nextTick()
|
|
986
|
+
const closeButton = wrapper.find('.v-chip__close')
|
|
987
|
+
closeButton.element.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true }))
|
|
988
|
+
await wrapper.vm.$nextTick()
|
|
989
|
+
|
|
990
|
+
expect(wrapper.emitted()['update:modelValue']?.[0]).toEqual([['2']])
|
|
991
|
+
|
|
992
|
+
wrapper.unmount()
|
|
993
|
+
})
|
|
994
|
+
|
|
995
|
+
it('removes chip when Space key is pressed on chip close button', async () => {
|
|
996
|
+
const items = [
|
|
997
|
+
{ text: 'Option 1', value: '1' },
|
|
998
|
+
{ text: 'Option 2', value: '2' },
|
|
999
|
+
]
|
|
1000
|
+
const wrapper = mount(SySelect, {
|
|
1001
|
+
props: {
|
|
1002
|
+
items,
|
|
1003
|
+
multiple: true,
|
|
1004
|
+
chips: true,
|
|
1005
|
+
modelValue: ['1', '2'],
|
|
1006
|
+
textKey: 'text',
|
|
1007
|
+
valueKey: 'value',
|
|
1008
|
+
},
|
|
1009
|
+
attachTo: document.body,
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
await wrapper.vm.$nextTick()
|
|
1013
|
+
const closeButton = wrapper.find('.v-chip__close')
|
|
1014
|
+
closeButton.element.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true, cancelable: true }))
|
|
1015
|
+
await wrapper.vm.$nextTick()
|
|
1016
|
+
|
|
1017
|
+
expect(wrapper.emitted()['update:modelValue']?.[0]).toEqual([['2']])
|
|
1018
|
+
|
|
1019
|
+
wrapper.unmount()
|
|
1020
|
+
})
|
|
967
1021
|
})
|
|
968
1022
|
|
|
969
1023
|
describe('keyboard navigation', () => {
|
|
@@ -83,9 +83,6 @@
|
|
|
83
83
|
const isSubmitted = ref(false)
|
|
84
84
|
|
|
85
85
|
const validation = useValidation({
|
|
86
|
-
customRules: props.customRules,
|
|
87
|
-
warningRules: props.customWarningRules,
|
|
88
|
-
successRules: props.customSuccessRules,
|
|
89
86
|
showSuccessMessages: props.showSuccessMessages,
|
|
90
87
|
fieldIdentifier: props.label,
|
|
91
88
|
disableErrorHandling: props.disableErrorHandling,
|
|
@@ -135,7 +132,7 @@
|
|
|
135
132
|
return model.value as (string | number) | null
|
|
136
133
|
}
|
|
137
134
|
|
|
138
|
-
const validateField = (value: (string | number) | (string | number)[] | null) => {
|
|
135
|
+
const validateField = async (value: (string | number) | (string | number)[] | null) => {
|
|
139
136
|
if (props.readonly) {
|
|
140
137
|
validation.clearValidation()
|
|
141
138
|
return true
|
|
@@ -146,7 +143,7 @@
|
|
|
146
143
|
return true
|
|
147
144
|
}
|
|
148
145
|
|
|
149
|
-
const result = validation.validateField(
|
|
146
|
+
const result = await validation.validateField(
|
|
150
147
|
value,
|
|
151
148
|
[...defaultRules.value, ...props.customRules],
|
|
152
149
|
props.customWarningRules,
|
|
@@ -155,18 +152,18 @@
|
|
|
155
152
|
return !result.hasError
|
|
156
153
|
}
|
|
157
154
|
|
|
158
|
-
const validateOnSubmit = () => {
|
|
155
|
+
const validateOnSubmit = async () => {
|
|
159
156
|
isSubmitted.value = true
|
|
160
|
-
return validateField(getValidationValue())
|
|
157
|
+
return await validateField(getValidationValue())
|
|
161
158
|
}
|
|
162
159
|
|
|
163
160
|
const checkErrorOnBlur = () => {
|
|
164
161
|
validateField(getValidationValue())
|
|
165
162
|
}
|
|
166
163
|
|
|
167
|
-
watch(model, (newValue) => {
|
|
164
|
+
watch(model, async (newValue) => {
|
|
168
165
|
if (!props.isValidateOnBlur || isSubmitted.value) {
|
|
169
|
-
validateField(newValue as (string | number) | (string | number)[] | null)
|
|
166
|
+
await validateField(newValue as (string | number) | (string | number)[] | null)
|
|
170
167
|
}
|
|
171
168
|
})
|
|
172
169
|
|
|
@@ -5,7 +5,7 @@ import { fn } from '@storybook/test'
|
|
|
5
5
|
|
|
6
6
|
// Interface pour typer correctement le composant SyCheckbox avec sa méthode validateOnSubmit
|
|
7
7
|
interface SyCheckboxInstance {
|
|
8
|
-
validateOnSubmit: () => boolean
|
|
8
|
+
validateOnSubmit: () => Promise<boolean>
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
const meta = {
|
|
@@ -171,9 +171,6 @@ export const Indeterminate: Story = {
|
|
|
171
171
|
template: `<SyCheckbox v-model="checked" :indeterminate="indeterminate" v-bind="args" label="Case à cocher indéterminée" />`,
|
|
172
172
|
}),
|
|
173
173
|
parameters: {
|
|
174
|
-
a11y: {
|
|
175
|
-
disable: true,
|
|
176
|
-
},
|
|
177
174
|
sourceCode: [
|
|
178
175
|
{
|
|
179
176
|
name: 'Template',
|
|
@@ -207,9 +204,6 @@ Cette case à cocher est dans un état indéterminé, généralement utilisé lo
|
|
|
207
204
|
|
|
208
205
|
export const WithControlsIds: Story = {
|
|
209
206
|
parameters: {
|
|
210
|
-
a11y: {
|
|
211
|
-
disable: true,
|
|
212
|
-
},
|
|
213
207
|
sourceCode: [
|
|
214
208
|
{
|
|
215
209
|
name: 'Template',
|
|
@@ -702,11 +696,11 @@ const rules = [
|
|
|
702
696
|
},
|
|
703
697
|
]
|
|
704
698
|
|
|
705
|
-
const validateForm = () => {
|
|
699
|
+
const validateForm = async (): Promise<void> => {
|
|
706
700
|
if (!checkbox.value || !checkbox2.value) return
|
|
707
701
|
hasError.value = true
|
|
708
|
-
const isValid = checkbox.value.validateOnSubmit()
|
|
709
|
-
const isValid2 = checkbox2.value.validateOnSubmit()
|
|
702
|
+
const isValid = await checkbox.value.validateOnSubmit()
|
|
703
|
+
const isValid2 = await checkbox2.value.validateOnSubmit()
|
|
710
704
|
if (isValid && isValid2) {
|
|
711
705
|
formSubmitted.value = true
|
|
712
706
|
hasError.value = false
|
|
@@ -735,18 +729,18 @@ Cette case à cocher utilise des règles de validation personnalisées et valide
|
|
|
735
729
|
const hasError = ref(false)
|
|
736
730
|
|
|
737
731
|
// Revalider quand les valeurs changent
|
|
738
|
-
watch([checked, checked2], () => {
|
|
732
|
+
watch([checked, checked2], async () => {
|
|
739
733
|
if (hasError.value && checkbox.value && checkbox2.value) {
|
|
740
|
-
checkbox.value.validateOnSubmit()
|
|
741
|
-
checkbox2.value.validateOnSubmit()
|
|
734
|
+
await checkbox.value.validateOnSubmit()
|
|
735
|
+
await checkbox2.value.validateOnSubmit()
|
|
742
736
|
}
|
|
743
737
|
})
|
|
744
738
|
|
|
745
|
-
const validateForm = () => {
|
|
739
|
+
const validateForm = async (): Promise<void> => {
|
|
746
740
|
if (!checkbox.value || !checkbox2.value) return
|
|
747
741
|
hasError.value = true
|
|
748
|
-
const isValid = checkbox.value.validateOnSubmit()
|
|
749
|
-
const isValid2 = checkbox2.value.validateOnSubmit()
|
|
742
|
+
const isValid = await checkbox.value.validateOnSubmit()
|
|
743
|
+
const isValid2 = await checkbox2.value.validateOnSubmit()
|
|
750
744
|
if (isValid && isValid2) {
|
|
751
745
|
formSubmitted.value = true
|
|
752
746
|
hasError.value = false
|
|
@@ -102,9 +102,6 @@
|
|
|
102
102
|
const isSubmitted = ref(false)
|
|
103
103
|
|
|
104
104
|
const validation = useValidation({
|
|
105
|
-
customRules: props.customRules,
|
|
106
|
-
warningRules: props.customWarningRules,
|
|
107
|
-
successRules: props.customSuccessRules,
|
|
108
105
|
showSuccessMessages: props.showSuccessMessages,
|
|
109
106
|
fieldIdentifier: props.label,
|
|
110
107
|
disableErrorHandling: props.disableErrorHandling,
|
|
@@ -135,7 +132,7 @@
|
|
|
135
132
|
: [],
|
|
136
133
|
)
|
|
137
134
|
|
|
138
|
-
const validateField = (value: boolean | null) => {
|
|
135
|
+
const validateField = async (value: boolean | null) => {
|
|
139
136
|
// Si en lecture seule ou si la valeur est null et non requise, pas de validation
|
|
140
137
|
if (props.readonly) {
|
|
141
138
|
validation.clearValidation()
|
|
@@ -157,7 +154,7 @@
|
|
|
157
154
|
}
|
|
158
155
|
|
|
159
156
|
// Validation standard
|
|
160
|
-
const result = validation.validateField(
|
|
157
|
+
const result = await validation.validateField(
|
|
161
158
|
value,
|
|
162
159
|
[...defaultRules.value, ...props.customRules],
|
|
163
160
|
props.customWarningRules,
|
|
@@ -175,11 +172,11 @@
|
|
|
175
172
|
validateField(model.value)
|
|
176
173
|
}
|
|
177
174
|
|
|
178
|
-
watch(model, (newValue) => {
|
|
175
|
+
watch(model, async (newValue) => {
|
|
179
176
|
if (!props.isValidateOnBlur) {
|
|
180
177
|
// Si le formulaire a été soumis et que la valeur change, on valide à nouveau
|
|
181
178
|
if (isSubmitted.value) {
|
|
182
|
-
const isValid = validateField(newValue)
|
|
179
|
+
const isValid = await validateField(newValue)
|
|
183
180
|
if (isValid) {
|
|
184
181
|
// La validation a réussi, effacer les erreurs
|
|
185
182
|
validation.clearValidation()
|
|
@@ -187,7 +184,7 @@
|
|
|
187
184
|
}
|
|
188
185
|
else {
|
|
189
186
|
// Comportement normal (hors soumission)
|
|
190
|
-
const isValid = validateField(newValue)
|
|
187
|
+
const isValid = await validateField(newValue)
|
|
191
188
|
// Si la validation réussit, s'assurer que les erreurs sont effacées
|
|
192
189
|
if (isValid && validation.hasError.value) {
|
|
193
190
|
validation.clearValidation()
|
|
@@ -206,7 +203,7 @@
|
|
|
206
203
|
|
|
207
204
|
const ariaChecked = computed(() => {
|
|
208
205
|
if (internalIndeterminate.value) return 'mixed'
|
|
209
|
-
return model.value ? 'true' :
|
|
206
|
+
return model.value ? 'true' : 'false'
|
|
210
207
|
})
|
|
211
208
|
|
|
212
209
|
const labelColor = computed(() => {
|
|
@@ -243,9 +240,17 @@
|
|
|
243
240
|
const removeAriaAttributes = () => {
|
|
244
241
|
nextTick(() => {
|
|
245
242
|
if (checkboxRef.value) {
|
|
246
|
-
const checkboxInput = checkboxRef.value.$el
|
|
243
|
+
const checkboxInput = checkboxRef.value.$el?.querySelector('input[type="checkbox"]')
|
|
247
244
|
if (checkboxInput) {
|
|
248
|
-
|
|
245
|
+
// Supprimer aria-disabled="false" car il est redondant
|
|
246
|
+
if (checkboxInput.getAttribute('aria-disabled') === 'false') {
|
|
247
|
+
checkboxInput.removeAttribute('aria-disabled')
|
|
248
|
+
}
|
|
249
|
+
// Supprimer aria-checked natif de Vuetify pour éviter les conflits
|
|
250
|
+
// Notre composant gère aria-checked au niveau du wrapper VCheckbox
|
|
251
|
+
if (checkboxInput.hasAttribute('aria-checked')) {
|
|
252
|
+
checkboxInput.removeAttribute('aria-checked')
|
|
253
|
+
}
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
256
|
})
|
|
@@ -79,6 +79,23 @@ import '@/stories/styles/shared.css';
|
|
|
79
79
|
</div>
|
|
80
80
|
</div>
|
|
81
81
|
|
|
82
|
+
<div className="aria-management-section">
|
|
83
|
+
<h2>Gestion des attributs ARIA</h2>
|
|
84
|
+
<p>
|
|
85
|
+
Pour garantir la conformité ARIA, le composant SyCheckbox gère activement les conflits potentiels
|
|
86
|
+
avec l'implémentation native de Vuetify :
|
|
87
|
+
</p>
|
|
88
|
+
<ul>
|
|
89
|
+
<li><strong>Suppression des attributs conflictuels</strong> : Les attributs ARIA natifs de Vuetify sont automatiquement supprimés de l'élément input pour éviter les doublons</li>
|
|
90
|
+
<li><strong>Gestion centralisée</strong> : L'attribut <code>aria-checked</code> est géré au niveau du composant SyCheckbox et non au niveau de l'input natif</li>
|
|
91
|
+
<li><strong>Conformité garantie</strong> : Cette approche garantit que l'attribut <code>aria-checked</code> reflète toujours l'état réel du composant (true, false ou mixed)</li>
|
|
92
|
+
</ul>
|
|
93
|
+
<p>
|
|
94
|
+
Cette gestion préventive évite les erreurs d'audit d'accessibilité qui pourraient survenir
|
|
95
|
+
lorsque plusieurs attributs ARIA contradictoires sont présents sur le même élément.
|
|
96
|
+
</p>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
82
99
|
<div className="tri-state-section">
|
|
83
100
|
<h2>Fonctionnalité tri-état (indéterminé)</h2>
|
|
84
101
|
<p>
|
|
@@ -190,6 +207,7 @@ import '@/stories/styles/shared.css';
|
|
|
190
207
|
|
|
191
208
|
.criteria-section h2,
|
|
192
209
|
.demo-section h2,
|
|
210
|
+
.aria-management-section h2,
|
|
193
211
|
.tri-state-section h2,
|
|
194
212
|
.parent-child-section h2,
|
|
195
213
|
.best-practices h2,
|
|
@@ -243,6 +261,23 @@ import '@/stories/styles/shared.css';
|
|
|
243
261
|
margin-bottom: 40px;
|
|
244
262
|
}
|
|
245
263
|
|
|
264
|
+
.aria-management-section {
|
|
265
|
+
background-color: #fff9e6;
|
|
266
|
+
padding: 20px;
|
|
267
|
+
border-radius: 8px;
|
|
268
|
+
margin-bottom: 30px;
|
|
269
|
+
border-left: 5px solid #ff9800;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.aria-management-section ul {
|
|
273
|
+
padding-left: 20px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.aria-management-section li {
|
|
277
|
+
margin-bottom: 8px;
|
|
278
|
+
line-height: 1.5;
|
|
279
|
+
}
|
|
280
|
+
|
|
246
281
|
.tri-state-section,
|
|
247
282
|
.parent-child-section {
|
|
248
283
|
background-color: #f0f7ff;
|
|
@@ -6,21 +6,153 @@ import { axe } from 'vitest-axe'
|
|
|
6
6
|
import { assertNoA11yViolations } from '@tests/unit/accessibility/axeUtils'
|
|
7
7
|
import SyCheckbox from '../SyCheckbox.vue'
|
|
8
8
|
|
|
9
|
-
//
|
|
9
|
+
// Scénarios d'accessibilité : cases à cocher avec différents états et configurations.
|
|
10
10
|
|
|
11
11
|
describe('SyCheckbox – accessibility (axe)', () => {
|
|
12
12
|
it('has no obvious axe violations for required checkbox with label', async () => {
|
|
13
13
|
const wrapper = mount(SyCheckbox, {
|
|
14
14
|
props: {
|
|
15
|
-
label: 'J
|
|
15
|
+
label: 'J\'accepte les conditions générales',
|
|
16
16
|
modelValue: false,
|
|
17
17
|
required: true,
|
|
18
18
|
},
|
|
19
19
|
})
|
|
20
20
|
|
|
21
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
22
|
+
await wrapper.vm.$nextTick()
|
|
23
|
+
await wrapper.vm.$nextTick()
|
|
24
|
+
|
|
21
25
|
const results = await axe(wrapper.element as HTMLElement)
|
|
22
26
|
assertNoA11yViolations(results, 'SyCheckbox – required labelled checkbox', {
|
|
23
27
|
ignoreRules: ['region'],
|
|
24
28
|
})
|
|
25
29
|
})
|
|
30
|
+
|
|
31
|
+
it('has no axe violations for indeterminate checkbox (aria-checked="mixed")', async () => {
|
|
32
|
+
const wrapper = mount(SyCheckbox, {
|
|
33
|
+
props: {
|
|
34
|
+
label: 'Sélection partielle',
|
|
35
|
+
modelValue: false,
|
|
36
|
+
indeterminate: true,
|
|
37
|
+
controlsIds: ['child-1', 'child-2', 'child-3'],
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
42
|
+
await wrapper.vm.$nextTick()
|
|
43
|
+
await wrapper.vm.$nextTick()
|
|
44
|
+
|
|
45
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
46
|
+
assertNoA11yViolations(results, 'SyCheckbox – indeterminate checkbox', {
|
|
47
|
+
ignoreRules: ['region'],
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('has no axe violations for checked checkbox with aria-checked="true"', async () => {
|
|
52
|
+
const wrapper = mount(SyCheckbox, {
|
|
53
|
+
props: {
|
|
54
|
+
label: 'Option activée',
|
|
55
|
+
modelValue: true,
|
|
56
|
+
required: false,
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
61
|
+
await wrapper.vm.$nextTick()
|
|
62
|
+
await wrapper.vm.$nextTick()
|
|
63
|
+
|
|
64
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
65
|
+
assertNoA11yViolations(results, 'SyCheckbox – checked checkbox', {
|
|
66
|
+
ignoreRules: ['region'],
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('has no axe violations for unchecked checkbox with aria-checked="false"', async () => {
|
|
71
|
+
const wrapper = mount(SyCheckbox, {
|
|
72
|
+
props: {
|
|
73
|
+
label: 'Option désactivée',
|
|
74
|
+
modelValue: false,
|
|
75
|
+
required: false,
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
80
|
+
await wrapper.vm.$nextTick()
|
|
81
|
+
await wrapper.vm.$nextTick()
|
|
82
|
+
|
|
83
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
84
|
+
assertNoA11yViolations(results, 'SyCheckbox – unchecked checkbox', {
|
|
85
|
+
ignoreRules: ['region'],
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('has no axe violations for disabled checkbox', async () => {
|
|
90
|
+
const wrapper = mount(SyCheckbox, {
|
|
91
|
+
props: {
|
|
92
|
+
label: 'Option désactivée',
|
|
93
|
+
modelValue: true,
|
|
94
|
+
disabled: true,
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
99
|
+
await wrapper.vm.$nextTick()
|
|
100
|
+
await wrapper.vm.$nextTick()
|
|
101
|
+
|
|
102
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
103
|
+
assertNoA11yViolations(results, 'SyCheckbox – disabled checkbox', {
|
|
104
|
+
ignoreRules: ['region'],
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('has no axe violations for checkbox with custom aria-label', async () => {
|
|
109
|
+
const wrapper = mount(SyCheckbox, {
|
|
110
|
+
props: {
|
|
111
|
+
ariaLabel: 'Case à cocher personnalisée',
|
|
112
|
+
modelValue: false,
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
117
|
+
await wrapper.vm.$nextTick()
|
|
118
|
+
await wrapper.vm.$nextTick()
|
|
119
|
+
|
|
120
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
121
|
+
assertNoA11yViolations(results, 'SyCheckbox – checkbox with aria-label', {
|
|
122
|
+
ignoreRules: ['region'],
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('has no axe violations for checkbox with aria-labelledby', async () => {
|
|
127
|
+
// Créer un conteneur pour le test
|
|
128
|
+
const container = document.createElement('div')
|
|
129
|
+
document.body.appendChild(container)
|
|
130
|
+
|
|
131
|
+
// Créer un élément avec l'ID référencé
|
|
132
|
+
const labelElement = document.createElement('div')
|
|
133
|
+
labelElement.id = 'custom-label-id'
|
|
134
|
+
labelElement.textContent = 'Libellé personnalisé'
|
|
135
|
+
container.appendChild(labelElement)
|
|
136
|
+
|
|
137
|
+
const wrapper = mount(SyCheckbox, {
|
|
138
|
+
props: {
|
|
139
|
+
ariaLabelledby: 'custom-label-id',
|
|
140
|
+
modelValue: false,
|
|
141
|
+
},
|
|
142
|
+
attachTo: container,
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// Attendre que removeAriaAttributes soit exécuté
|
|
146
|
+
await wrapper.vm.$nextTick()
|
|
147
|
+
await wrapper.vm.$nextTick()
|
|
148
|
+
|
|
149
|
+
const results = await axe(container as HTMLElement)
|
|
150
|
+
assertNoA11yViolations(results, 'SyCheckbox – checkbox with aria-labelledby', {
|
|
151
|
+
ignoreRules: ['region'],
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
// Nettoyer
|
|
155
|
+
wrapper.unmount()
|
|
156
|
+
document.body.removeChild(container)
|
|
157
|
+
})
|
|
26
158
|
})
|