@cnamts/synapse 1.0.19 → 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-CeVuSfJ9.js → DateFilter-uN8OURoP.js} +1 -1
- package/dist/{NumberFilter-C8PAu_sw.js → NumberFilter-sm1dQNQi.js} +1 -1
- package/dist/{PeriodFilter-UMUaxx3d.js → PeriodFilter-Cklsxnh9.js} +1 -1
- package/dist/{SelectFilter-CqZl8CYt.js → SelectFilter-CWefj27Z.js} +1 -1
- package/dist/{TextFilter-D_RhhNOh.js → TextFilter-Ddyj885L.js} +1 -1
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +4 -4
- package/dist/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.d.ts +17 -7
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +4 -4
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +4 -4
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +2416 -0
- package/dist/components/Customs/Selects/SyAutocomplete/types.d.ts +5 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/ariaManager.d.ts +14 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/useItemUtils.d.ts +16 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.d.ts +28 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.d.ts +12 -0
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +2 -0
- 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/SyIcon/SyIcon.d.ts +2 -1
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +1495 -2
- package/dist/components/DatePicker/composables/useDateSelection.d.ts +1 -0
- 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/PaginatedTable/PaginatedTable.d.ts +1 -1
- package/dist/components/PaginatedTable/Pagination.d.ts +17 -0
- package/dist/components/StatusPage/StatusPage.d.ts +39 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -5
- package/dist/components/Tables/SyTable/SyTable.d.ts +5 -5
- package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +13 -3
- package/dist/components/index.d.ts +4 -0
- package/dist/components/types.d.ts +15 -0
- package/dist/composables/useFormFieldErrorHandling.d.ts +31 -0
- package/dist/design-system-v3.js +126 -122
- package/dist/design-system-v3.umd.cjs +325 -314
- package/dist/{main-B39UVv5p.js → main-CWniLr0s.js} +15837 -14587
- package/dist/modules.d.ts +6 -0
- package/dist/style.css +1 -1
- package/dist/utils/theme/index.d.ts +6 -0
- package/package.json +12 -10
- package/src/assets/amelipro/icons.ts +166 -153
- package/src/components/Accordion/Accordion.mdx +4 -1
- package/src/components/Accordion/{Accessibilite/AccessibilityGuide.mdx → accessibilite/Accessibility.mdx} +2 -2
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.stories.ts +73 -14
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +119 -27
- package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.a11y.spec.ts +304 -0
- package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.spec.ts +435 -9
- package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +60 -0
- package/src/components/Amelipro/AmeliproIcon/__tests__/AmeliproIcon.spec.ts +1 -1
- package/src/components/Amelipro/AmeliproIcon/iconList.ts +2 -0
- package/src/components/BackBtn/BackBtn.vue +5 -4
- package/src/components/BackBtn/accessibilite/Accessibility.mdx +15 -0
- package/src/components/BackToTopBtn/BackToTopBtn.vue +6 -3
- package/src/components/BackToTopBtn/accessibilite/Accessibility.mdx +15 -0
- package/src/components/Captcha/Captcha.vue +5 -1
- package/src/components/Captcha/CaptchaAlert.vue +9 -7
- package/src/components/Captcha/accessibilite/Accessibility.mdx +10 -0
- package/src/components/ChipList/accessibilite/Accessibility.mdx +15 -0
- package/src/components/CollapsibleList/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +8 -6
- package/src/components/Common/IconSlot/IconSlot.vue +1 -1
- package/src/components/ContextualMenu/ContextualMenu.stories.ts +0 -3
- package/src/components/ContextualMenu/accessibilite/Accessibility.mdx +71 -0
- package/src/components/CookieBanner/CookieBanner.stories.ts +11 -20
- package/src/components/CookieBanner/CookieBanner.vue +20 -5
- package/src/components/CookieBanner/accessibilite/Accessibility.mdx +71 -0
- package/src/components/CookieBanner/tests/CookieBanner.spec.ts +48 -4
- package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +5 -4
- package/src/components/CopyBtn/CopyBtn.vue +6 -3
- package/src/components/CopyBtn/accessibilite/Accessibility.mdx +15 -0
- package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +15 -0
- package/src/components/Customs/Selects/SelectOverview.mdx +112 -1
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.mdx +52 -0
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +979 -0
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +653 -0
- package/src/components/Customs/Selects/{SySelect → SyAutocomplete/accessibilite}/Accessibilite.stories.ts +7 -38
- package/src/components/Customs/Selects/{SySelect/Accessibilite.mdx → SyAutocomplete/accessibilite/Accessibility.mdx} +15 -20
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.a11y.spec.ts +72 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +345 -0
- package/src/components/Customs/Selects/SyAutocomplete/types.ts +7 -0
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +180 -0
- package/src/components/Customs/Selects/SyAutocomplete/utils/useItemUtils.ts +46 -0
- package/src/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.ts +107 -0
- package/src/components/Customs/Selects/SyAutocomplete/utils/useSelectionLogic.ts +74 -0
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +13 -9
- package/src/components/Customs/Selects/SyInputSelect/accessibilite/Accessibility.mdx +12 -0
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +43 -34
- package/src/components/Customs/Selects/SySelect/SySelect.vue +19 -2
- package/src/components/Customs/Selects/SySelect/accessibilite/Accessibility.mdx +274 -0
- package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +21 -16
- 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.mdx → accessibilite/Accessibility.mdx} +3 -3
- package/src/components/Customs/SyForm/SyForm.a11y.spec.ts +1 -1
- package/src/components/Customs/SyForm/accessibilite/Accessibility.mdx +10 -0
- package/src/components/Customs/SyIcon/SyIcon.mdx +4 -1
- package/src/components/Customs/SyIcon/SyIcon.vue +4 -3
- package/src/components/Customs/SyIcon/{Accessibilite.stories.ts → accessibilite/Accessibilite.stories.ts} +3 -3
- package/src/components/Customs/SyIcon/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +2 -2
- package/src/components/Customs/SyPagination/SyPagination.mdx +4 -2
- package/src/components/Customs/SyPagination/accessibilite/Accessibility.mdx +10 -0
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +16 -43
- package/src/components/Customs/SyRadioGroup/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +2 -2
- package/src/components/Customs/SyTabs/SyTabs.mdx +4 -2
- package/src/components/Customs/SyTabs/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +2 -2
- package/src/components/Customs/SyTextField/SyTextField.mdx +1 -2
- package/src/components/Customs/SyTextField/SyTextField.vue +13 -0
- package/src/components/Customs/SyTextField/accessibilite/Accessibility.mdx +15 -0
- package/src/components/DataList/accessibilite/Accessibility.mdx +15 -0
- package/src/components/DataListGroup/accessibilite/Accessibility.mdx +14 -0
- package/src/components/DatePicker/Accessibilite.mdx +1 -1
- package/src/components/DatePicker/Accessibilite.stories.ts +1 -1
- package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +7 -4
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +49 -13
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +43 -2
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +297 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +48 -21
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +98 -0
- package/src/components/DatePicker/composables/useDateSelection.ts +5 -0
- package/src/components/DatePicker/docExamples/BidirectionalComplexValidation.vue +273 -0
- package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +4 -4
- package/src/components/DatePicker/docExamples/DatePickerValidationExamples.vue +10 -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/DiacriticPicker/accessibilite/Accessibility.mdx +10 -0
- package/src/components/DialogBox/accessibilite/Accessibility.mdx +15 -0
- package/src/components/DownloadBtn/DownloadBtn.vue +5 -4
- package/src/components/DownloadBtn/accessibilite/Accessibility.mdx +15 -0
- 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 +77 -0
- 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/ExternalLinks/accessibilite/Accessibility.mdx +15 -0
- package/src/components/FileList/UploadItem/UploadItem.vue +25 -20
- package/src/components/FileList/accessibilite/Accessibility.mdx +12 -0
- package/src/components/FilePreview/accessibilite/Accessibility.mdx +12 -0
- package/src/components/FileUpload/FileUpload.vue +5 -0
- package/src/components/FileUpload/FileUploadContent.vue +5 -4
- package/src/components/FileUpload/accessibilite/Accessibility.mdx +12 -0
- package/src/components/FilterInline/FilterInline.vue +5 -4
- package/src/components/FilterInline/accessibilite/Accessibility.mdx +12 -0
- package/src/components/FilterSideBar/accessibilite/Accessibility.mdx +15 -0
- package/src/components/FooterBar/FooterBar.stories.ts +18 -14
- package/src/components/FooterBar/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +3 -4
- package/src/components/FooterBar/defaultSocialMediaLinks.ts +6 -4
- package/src/components/FranceConnectBtn/FranceConnectBtn.vue +6 -5
- package/src/components/FranceConnectBtn/accessibilite/Accessibility.mdx +15 -0
- package/src/components/FranceConnectBtn/tests/__snapshots__/FranceConnectBtn.spec.ts.snap +3 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/accessibilite/Accessibility.mdx +15 -0
- package/src/components/HeaderBar/accessibilite/Accessibility.mdx +15 -0
- package/src/components/HeaderBar/{Usages.mdx → usages/Usages.mdx} +2 -2
- package/src/components/HeaderLoading/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +9 -5
- package/src/components/HeaderToolbar/accessibilite/Accessibility.mdx +15 -0
- package/src/components/LangBtn/LangBtn.vue +5 -4
- package/src/components/LangBtn/accessibilite/Accessibility.mdx +15 -0
- package/src/components/Logo/accessibilite/Accessibility.mdx +17 -0
- package/src/components/LogoBrandSection/accessibilite/Accessibility.mdx +12 -0
- package/src/components/LunarCalendar/accessibilite/Accessibility.mdx +10 -0
- package/src/components/MaintenancePage/MaintenancePage.mdx +1 -1
- package/src/components/MaintenancePage/MaintenancePage.vue +15 -7
- package/src/components/MaintenancePage/accessibilite/Accessibility.mdx +70 -0
- 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/NirField/accessibilite/Accessibility.mdx +15 -0
- 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 +87 -0
- 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/Notification/Notification.vue +1 -1
- package/src/components/NotificationBar/NotificationBar.mdx +2 -2
- package/src/components/NotificationBar/accessibilite/Accessibility.mdx +75 -0
- package/src/components/PageContainer/{AccessibilityGuide.mdx → accessibilite/Accessibility.mdx} +7 -4
- package/src/components/PageContainer/tests/PageContainer.a11y.spec.ts +14 -7
- package/src/components/PaginatedTable/PaginatedTable.vue +27 -47
- package/src/components/PaginatedTable/Pagination.vue +93 -0
- package/src/components/PaginatedTable/accessibilite/Accessibility.mdx +12 -0
- package/src/components/PasswordField/PasswordField.vue +2 -1
- package/src/components/PasswordField/accessibilite/Accessibility.mdx +108 -0
- package/src/components/PeriodField/accessibilite/Accessibility.mdx +12 -0
- package/src/components/PhoneField/PhoneField.stories.ts +46 -38
- package/src/components/PhoneField/accessibilite/Accessibility.mdx +15 -0
- package/src/components/RangeField/accessibilite/Accessibility.mdx +15 -0
- package/src/components/RatingPicker/accessibilite/Accessibility.mdx +15 -0
- package/src/components/SearchListField/SearchListField.vue +6 -3
- package/src/components/SearchListField/accessibilite/Accessibility.mdx +15 -0
- package/src/components/SkipLink/{Accessibilite.mdx → accessibilite/Accessibility.mdx} +7 -4
- 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 +67 -0
- 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/SubHeader/accessibilite/Accessibility.mdx +15 -0
- package/src/components/SyAlert/SyAlert.vue +6 -6
- package/src/components/SyAlert/accessibilite/Accessibility.mdx +12 -0
- package/src/components/SyTextArea/accessibilite/Accessibility.mdx +10 -0
- package/src/components/TableToolbar/TableToolbar.stories.ts +6 -6
- package/src/components/TableToolbar/TableToolbar.vue +7 -4
- package/src/components/TableToolbar/accessibilite/Accessibility.mdx +12 -0
- package/src/components/TableToolbar/tests/__snapshots__/TableToolbar.spec.ts.snap +0 -5
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +4 -1
- package/src/components/Tables/SyServerTable/accessibilite/Accessibility.mdx +10 -0
- package/src/components/Tables/SyTable/SyTable.mdx +4 -1
- package/src/components/Tables/SyTable/accessibilite/Accessibility.mdx +10 -0
- package/src/components/Tables/common/TableHeader.vue +3 -1
- package/src/components/Tables/common/organizeColumns/OrganizeColumns.vue +18 -14
- package/src/components/ToolbarContainer/ToolbarContainer.mdx +2 -1
- package/src/components/ToolbarContainer/ToolbarContainer.stories.ts +563 -420
- package/src/components/ToolbarContainer/accessibilite/Accessibility.mdx +69 -0
- 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/accessibilite/Accessibility.mdx +12 -0
- 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/Usages/Usages.vue +3 -2
- package/src/components/UserMenuBtn/UserMenuBtn.vue +7 -5
- package/src/components/UserMenuBtn/accessibilite/Accessibility.mdx +12 -0
- package/src/components/index.ts +5 -0
- package/src/components/types.ts +10 -0
- package/src/composables/rules/tests/useFieldValidation.spec.ts +39 -3
- package/src/composables/rules/useFieldValidation.ts +31 -9
- package/src/composables/useFormFieldErrorHandling.ts +141 -0
- package/src/modules.d.ts +6 -0
- 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/BackBtn/Accessibilite.mdx +0 -14
- package/src/components/BackBtn/Accessibilite.stories.ts +0 -30
- package/src/components/BackToTopBtn/Accessibilite.mdx +0 -14
- package/src/components/BackToTopBtn/Accessibilite.stories.ts +0 -31
- package/src/components/ChipList/Accessibilite.mdx +0 -14
- package/src/components/ChipList/Accessibilite.stories.ts +0 -31
- package/src/components/CollapsibleList/Accessibilite.stories.ts +0 -29
- package/src/components/ContextualMenu/Accessibilite.mdx +0 -13
- package/src/components/ContextualMenu/Accessibilite.stories.ts +0 -29
- package/src/components/CookieBanner/Accessibilite.mdx +0 -13
- package/src/components/CookieBanner/Accessibilite.stories.ts +0 -30
- package/src/components/CopyBtn/Accessibilite.mdx +0 -13
- package/src/components/CopyBtn/Accessibilite.stories.ts +0 -29
- package/src/components/Customs/Selects/SelectBtnField/Accessibilite.mdx +0 -14
- package/src/components/Customs/Selects/SelectBtnField/Accessibilite.stories.ts +0 -29
- package/src/components/Customs/Selects/SyInputSelect/Accessibilite.mdx +0 -13
- package/src/components/Customs/Selects/SyInputSelect/Accessibilite.stories.ts +0 -25
- 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/Customs/SyTextField/Accessibilite.mdx +0 -14
- package/src/components/Customs/SyTextField/Accessibilite.stories.ts +0 -34
- package/src/components/DataList/Accessibilite.mdx +0 -13
- package/src/components/DataList/Accessibilite.stories.ts +0 -29
- package/src/components/DataListGroup/Accessibilite.mdx +0 -13
- package/src/components/DataListGroup/Accessibilite.stories.ts +0 -29
- 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/DialogBox/Accessibilite.mdx +0 -14
- package/src/components/DialogBox/Accessibilite.stories.ts +0 -29
- package/src/components/DownloadBtn/Accessibilite.mdx +0 -14
- package/src/components/DownloadBtn/Accessibilite.stories.ts +0 -29
- package/src/components/DownloadBtn/tests/DownloadBtn.a11y.spec.ts +0 -26
- package/src/components/ErrorPage/Accessibilite.mdx +0 -13
- package/src/components/ErrorPage/Accessibilite.stories.ts +0 -36
- package/src/components/ExternalLinks/Accessibilite.mdx +0 -18
- package/src/components/ExternalLinks/Accessibilite.stories.ts +0 -62
- package/src/components/ExternalLinks/tests/ExternalLinks.a11y.spec.ts +0 -39
- package/src/components/FileList/Accessibilite.mdx +0 -13
- package/src/components/FileList/Accessibilite.stories.ts +0 -26
- package/src/components/FilePreview/Accessibilite.mdx +0 -14
- package/src/components/FilePreview/Accessibilite.stories.ts +0 -26
- package/src/components/FileUpload/Accessibilite.mdx +0 -13
- package/src/components/FileUpload/Accessibilite.stories.ts +0 -26
- package/src/components/FilterInline/Accessibilite.mdx +0 -15
- package/src/components/FilterInline/Accessibilite.stories.ts +0 -26
- package/src/components/FilterSideBar/Accessibilite.mdx +0 -13
- package/src/components/FilterSideBar/Accessibilite.stories.ts +0 -30
- package/src/components/FooterBar/Accessibilite.stories.ts +0 -26
- package/src/components/FranceConnectBtn/Accessibilite.mdx +0 -13
- package/src/components/FranceConnectBtn/Accessibilite.stories.ts +0 -30
- package/src/components/HeaderBar/Accessibilite.mdx +0 -13
- package/src/components/HeaderBar/Accessibilite.stories.ts +0 -31
- package/src/components/HeaderBar/HeaderBurgerMenu/Accessibilite.mdx +0 -13
- package/src/components/HeaderBar/HeaderBurgerMenu/Accessibilite.stories.ts +0 -30
- package/src/components/HeaderLoading/Accessibilite.stories.ts +0 -31
- package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.a11y.spec.ts +0 -45
- package/src/components/HeaderToolbar/Accessibilite.mdx +0 -13
- package/src/components/HeaderToolbar/Accessibilite.stories.ts +0 -36
- package/src/components/HeaderToolbar/tests/HeaderToolbar.a11y.spec.ts +0 -25
- package/src/components/LangBtn/Accessibilite.mdx +0 -13
- package/src/components/LangBtn/Accessibilite.stories.ts +0 -32
- package/src/components/Logo/Accessibilite.mdx +0 -13
- package/src/components/Logo/Accessibilite.stories.ts +0 -30
- package/src/components/LogoBrandSection/Accessibilite.mdx +0 -13
- package/src/components/LogoBrandSection/Accessibilite.stories.ts +0 -26
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +0 -31
- package/src/components/MaintenancePage/Accessibilite.mdx +0 -13
- package/src/components/MaintenancePage/Accessibilite.stories.ts +0 -36
- package/src/components/MaintenancePage/index.ts +0 -3
- package/src/components/NirField/Accessibilite.mdx +0 -13
- package/src/components/NirField/Accessibilite.stories.ts +0 -31
- package/src/components/NotFoundPage/Accessibilite.mdx +0 -13
- package/src/components/NotFoundPage/Accessibilite.stories.ts +0 -36
- package/src/components/NotificationBar/Accessibilite.mdx +0 -13
- package/src/components/NotificationBar/Accessibilite.stories.ts +0 -30
- package/src/components/PageContainer/Accessibilite.mdx +0 -13
- package/src/components/PageContainer/Accessibilite.stories.ts +0 -30
- package/src/components/PaginatedTable/Accessibilite.mdx +0 -13
- package/src/components/PaginatedTable/Accessibilite.stories.ts +0 -26
- package/src/components/PaginatedTable/tests/PaginatedTable.a11y.spec.ts +0 -43
- package/src/components/PasswordField/Accessibilite.mdx +0 -13
- package/src/components/PasswordField/Accessibilite.stories.ts +0 -121
- package/src/components/PeriodField/Accessibilite.mdx +0 -13
- package/src/components/PeriodField/Accessibilite.stories.ts +0 -27
- package/src/components/PhoneField/Accessibilite.mdx +0 -13
- package/src/components/PhoneField/Accessibilite.stories.ts +0 -32
- package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -34
- package/src/components/RangeField/Accessibilite.mdx +0 -13
- package/src/components/RangeField/Accessibilite.stories.ts +0 -32
- package/src/components/RatingPicker/Accessibilite.mdx +0 -13
- package/src/components/RatingPicker/Accessibilite.stories.ts +0 -30
- package/src/components/SearchListField/Accessibilite.mdx +0 -13
- package/src/components/SearchListField/Accessibilite.stories.ts +0 -30
- package/src/components/SkipLink/Accessibilite.stories.ts +0 -36
- package/src/components/SocialMediaLinks/Accessibilite.mdx +0 -13
- package/src/components/SocialMediaLinks/Accessibilite.stories.ts +0 -36
- package/src/components/SubHeader/Accessibilite.mdx +0 -13
- package/src/components/SubHeader/Accessibilite.stories.ts +0 -36
- package/src/components/SyAlert/Accessibilite.mdx +0 -13
- package/src/components/SyAlert/Accessibilite.stories.ts +0 -30
- package/src/components/TableToolbar/Accessibilite.mdx +0 -13
- package/src/components/TableToolbar/Accessibilite.stories.ts +0 -26
- package/src/components/UploadWorkflow/Accessibilite.mdx +0 -13
- package/src/components/UploadWorkflow/Accessibilite.stories.ts +0 -26
- package/src/components/UserMenuBtn/Accessibilite.mdx +0 -13
- package/src/components/UserMenuBtn/Accessibilite.stories.ts +0 -25
- /package/src/components/HeaderBar/{Usages.stories.ts → usages/Usages.stories.ts} +0 -0
- /package/src/components/NotFoundPage/assets/{not-found.svg → not-found-cnam.svg} +0 -0
- /package/src/components/SyBtnMenu/accessibilite/{AccessibilityGuide.mdx → Accessibility.mdx} +0 -0
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import { VIcon, VTable } from 'vuetify/components'
|
|
2
1
|
import type { StoryObj } from '@storybook/vue3'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const checkIcon = mdiCheckboxMarkedCircle
|
|
2
|
+
import { mdiKeyboard } from '@mdi/js'
|
|
6
3
|
|
|
7
4
|
const keyboardIcon = mdiKeyboard
|
|
8
5
|
|
|
9
6
|
export default {
|
|
10
|
-
title: 'Composants/Formulaires/Selects/
|
|
7
|
+
title: 'Composants/Formulaires/Selects/SyAutocomplete/Accessibility',
|
|
11
8
|
}
|
|
12
9
|
|
|
13
|
-
// Story masquée qui n'apparaît que dans le MDX
|
|
14
10
|
export const ComboboxKeyboardNavigation: StoryObj = {
|
|
15
11
|
tags: ['!dev'],
|
|
16
12
|
render: () => {
|
|
17
13
|
return {
|
|
18
|
-
components: { VTable, VIcon },
|
|
19
14
|
setup() {
|
|
20
15
|
const keyboardData = [
|
|
21
16
|
{
|
|
@@ -38,6 +33,10 @@ export const ComboboxKeyboardNavigation: StoryObj = {
|
|
|
38
33
|
touche: 'Échap',
|
|
39
34
|
action: 'Ferme le menu sans modifier la sélection',
|
|
40
35
|
},
|
|
36
|
+
{
|
|
37
|
+
touche: 'Saisie de texte',
|
|
38
|
+
action: 'Filtre les options en temps réel basé sur le texte saisi',
|
|
39
|
+
},
|
|
41
40
|
{
|
|
42
41
|
touche: 'Caractères imprimables',
|
|
43
42
|
action: 'Déplace le focus sur l\'option commençant par le(s) caractère(s) saisi(s)',
|
|
@@ -48,7 +47,7 @@ export const ComboboxKeyboardNavigation: StoryObj = {
|
|
|
48
47
|
template: `
|
|
49
48
|
<div>
|
|
50
49
|
<h3><v-icon :icon="keyboardIcon" style="margin-right: 8px;"/>Navigation au clavier</h3>
|
|
51
|
-
<p>Le composant
|
|
50
|
+
<p>Le composant SyAutocomplete implémente le pattern de navigation au clavier recommandé par le W3C pour les combobox avec auto-complétion.</p>
|
|
52
51
|
<v-table density="compact" style="margin-top: 16px;">
|
|
53
52
|
<thead>
|
|
54
53
|
<tr>
|
|
@@ -69,33 +68,3 @@ export const ComboboxKeyboardNavigation: StoryObj = {
|
|
|
69
68
|
}
|
|
70
69
|
},
|
|
71
70
|
}
|
|
72
|
-
|
|
73
|
-
export const Legende: StoryObj = {
|
|
74
|
-
args: {
|
|
75
|
-
icon: checkIcon,
|
|
76
|
-
},
|
|
77
|
-
render: (args) => {
|
|
78
|
-
return {
|
|
79
|
-
components: { VIcon },
|
|
80
|
-
setup() {
|
|
81
|
-
return { args }
|
|
82
|
-
},
|
|
83
|
-
template: `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<div class="mt-4">
|
|
87
|
-
<p>Rapport d’audit manuel : <a href="/audits/SySelect.xlsx" style="color:#0C41BD;">Voir le
|
|
88
|
-
rapport</a></p>
|
|
89
|
-
<p style="color: grey; font-size: 14px">Correctifs associés (<a
|
|
90
|
-
href="https://github.com/assurance-maladie-digital/design-system-v3/issues/787" target="_blank"
|
|
91
|
-
style="color:#0C41BD;"
|
|
92
|
-
>issue #787</a>, <a
|
|
93
|
-
href="https://github.com/assurance-maladie-digital/design-system-v3/issues/931" target="_blank"
|
|
94
|
-
style="color:#0C41BD;"
|
|
95
|
-
>issue #931</a>)</p>
|
|
96
|
-
</div>
|
|
97
|
-
`,
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
tags: ['!dev'],
|
|
101
|
-
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Meta, Story } from '@storybook/addon-docs';
|
|
2
|
-
import * as
|
|
2
|
+
import * as AutocompleteStories from '../SyAutocomplete.stories';
|
|
3
|
+
import * as AccessStories from './Accessibilite.stories';
|
|
3
4
|
import AccessibilityIcon from '@/common/imgs/accessibility-svgrepo-com.svg';
|
|
4
|
-
import '
|
|
5
|
+
import '@/stories/styles/shared.css';
|
|
5
6
|
|
|
6
|
-
<Meta of={
|
|
7
|
+
<Meta of={AutocompleteStories} name="Accessibility" />
|
|
7
8
|
|
|
8
9
|
<div className="accessibility-guide">
|
|
9
|
-
<h1>Guide d'Accessibilité du Composant
|
|
10
|
+
<h1>Guide d'Accessibilité du Composant SyAutocomplete</h1>
|
|
10
11
|
|
|
11
12
|
<div className="intro-section">
|
|
12
13
|
<img
|
|
@@ -15,8 +16,8 @@ import '../../../../stories/styles/shared.css';
|
|
|
15
16
|
className="accessibility-icon"
|
|
16
17
|
/>
|
|
17
18
|
<p className="intro-text">
|
|
18
|
-
Le composant
|
|
19
|
-
notamment le modèle <a href="https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-
|
|
19
|
+
Le composant SyAutocomplete a été conçu en suivant rigoureusement les recommandations d'accessibilité du W3C,
|
|
20
|
+
notamment le modèle <a href="https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-autocomplete-list/" target="_blank" rel="noopener noreferrer">WAI-ARIA pour les combobox avec auto-complétion</a>.
|
|
20
21
|
Ce guide détaille comment notre implémentation respecte ces standards et garantit une expérience utilisateur inclusive.
|
|
21
22
|
</p>
|
|
22
23
|
</div>
|
|
@@ -32,8 +33,9 @@ import '../../../../stories/styles/shared.css';
|
|
|
32
33
|
<ul>
|
|
33
34
|
<li><strong>Rôles ARIA appropriés</strong> : <code>role="combobox"</code> sur l'input, <code>role="listbox"</code> sur le menu déroulant</li>
|
|
34
35
|
<li><strong>Relations entre éléments</strong> : <code>aria-controls</code> pour lier le combobox au listbox</li>
|
|
35
|
-
<li><strong>Type d'interaction</strong> : <code>aria-haspopup="listbox"</code> et <code>aria-autocomplete="list"</code
|
|
36
|
+
<li><strong>Type d'interaction</strong> : <code>aria-haspopup="listbox"</code> et <code>aria-autocomplete="list"</code> pour indiquer l'auto-complétion</li>
|
|
36
37
|
<li><strong>État du menu</strong> : <code>aria-expanded</code> indique si le menu est ouvert ou fermé</li>
|
|
38
|
+
<li><strong>Prévention de l'auto-complétion navigateur</strong> : <code>autocomplete="off"</code> pour éviter les conflits avec l'auto-complétion native du navigateur</li>
|
|
37
39
|
</ul>
|
|
38
40
|
</div>
|
|
39
41
|
|
|
@@ -46,6 +48,7 @@ import '../../../../stories/styles/shared.css';
|
|
|
46
48
|
<li><strong>Flèches haut/bas</strong> : Navigation entre les options sans modifier la sélection</li>
|
|
47
49
|
<li><strong>Entrée</strong> : Sélection de l'option active et fermeture du menu</li>
|
|
48
50
|
<li><strong>Échap</strong> : Fermeture du menu sans modifier la sélection</li>
|
|
51
|
+
<li><strong>Saisie de texte</strong> : Filtrage dynamique des options basé sur le texte saisi</li>
|
|
49
52
|
<li><strong>Caractères imprimables</strong> : Navigation vers l'option commençant par le(s) caractère(s) saisi(s)</li>
|
|
50
53
|
</ul>
|
|
51
54
|
</div>
|
|
@@ -60,6 +63,7 @@ import '../../../../stories/styles/shared.css';
|
|
|
60
63
|
<li><strong>Option sélectionnée</strong> : <code>aria-selected="true"</code> sur l'option sélectionnée</li>
|
|
61
64
|
<li><strong>État de validation</strong> : <code>aria-required="true"</code> et <code>aria-invalid="true"</code> pour les champs obligatoires et en erreur</li>
|
|
62
65
|
<li><strong>Scroll automatique</strong> : Les options sont automatiquement scrollées dans la vue lors de la navigation</li>
|
|
66
|
+
<li><strong>Annonces dynamiques</strong> : Mise à jour des annonces pour les technologies d'assistance lors du filtrage</li>
|
|
63
67
|
</ul>
|
|
64
68
|
</div>
|
|
65
69
|
</div>
|
|
@@ -72,28 +76,19 @@ import '../../../../stories/styles/shared.css';
|
|
|
72
76
|
<div className="implementation-section">
|
|
73
77
|
<h2>Spécificités d'implémentation</h2>
|
|
74
78
|
<p>
|
|
75
|
-
Conformément aux recommandations WAI-ARIA pour les combobox
|
|
79
|
+
Conformément aux recommandations WAI-ARIA pour les combobox avec auto-complétion, notre implémentation :
|
|
76
80
|
</p>
|
|
77
81
|
<ul>
|
|
78
82
|
<li>Maintient le focus DOM sur l'input combobox pendant toute l'interaction</li>
|
|
79
83
|
<li>Utilise <code>aria-activedescendant</code> pour indiquer l'option active aux technologies d'assistance</li>
|
|
80
84
|
<li>Sépare clairement la navigation (flèches) de la sélection (Entrée)</li>
|
|
81
85
|
<li>Gère correctement les états visuels et programmatiques des options</li>
|
|
86
|
+
<li>Implémente un filtrage en temps réel des options basé sur la saisie utilisateur</li>
|
|
87
|
+
<li>Désactive l'auto-complétion du navigateur pour éviter les conflits</li>
|
|
82
88
|
</ul>
|
|
83
89
|
</div>
|
|
84
90
|
</div>
|
|
85
91
|
|
|
86
|
-
<div className="accessibility-guide">
|
|
87
|
-
<div className="header">
|
|
88
|
-
<h1>Accessibilité</h1>
|
|
89
|
-
<p>Informations sur l'accessibilité du composant</p>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
<Story of={AccessStories.Legende} />
|
|
93
|
-
<br />
|
|
94
|
-
|
|
95
|
-
</div>
|
|
96
|
-
|
|
97
92
|
<style>
|
|
98
93
|
{
|
|
99
94
|
`
|
|
@@ -209,4 +204,4 @@ import '../../../../stories/styles/shared.css';
|
|
|
209
204
|
}
|
|
210
205
|
`
|
|
211
206
|
}
|
|
212
|
-
</style>
|
|
207
|
+
</style>
|
|
@@ -0,0 +1,72 @@
|
|
|
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 SyAutocomplete from '../SyAutocomplete.vue'
|
|
8
|
+
|
|
9
|
+
const items = [
|
|
10
|
+
{ text: 'Option 1', value: '1' },
|
|
11
|
+
{ text: 'Option 2', value: '2' },
|
|
12
|
+
{ text: 'Option 3', value: '3' },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
describe('SyAutocomplete – accessibility (axe)', () => {
|
|
16
|
+
it('has no obvious axe violations for basic autocomplete', async () => {
|
|
17
|
+
const wrapper = mount(SyAutocomplete, {
|
|
18
|
+
props: {
|
|
19
|
+
modelValue: null,
|
|
20
|
+
items,
|
|
21
|
+
label: 'Choisir une option',
|
|
22
|
+
textKey: 'text',
|
|
23
|
+
valueKey: 'value',
|
|
24
|
+
required: true,
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
29
|
+
assertNoA11yViolations(results, 'SyAutocomplete – basic field', {
|
|
30
|
+
ignoreRules: ['region'],
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('has no obvious axe violations for multiple selection', async () => {
|
|
35
|
+
const wrapper = mount(SyAutocomplete, {
|
|
36
|
+
props: {
|
|
37
|
+
modelValue: [],
|
|
38
|
+
items,
|
|
39
|
+
label: 'Choisir plusieurs options',
|
|
40
|
+
textKey: 'text',
|
|
41
|
+
valueKey: 'value',
|
|
42
|
+
multiple: true,
|
|
43
|
+
required: true,
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
48
|
+
assertNoA11yViolations(results, 'SyAutocomplete – multiple selection', {
|
|
49
|
+
ignoreRules: ['region'],
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('has no obvious axe violations for chips display', async () => {
|
|
54
|
+
const wrapper = mount(SyAutocomplete, {
|
|
55
|
+
props: {
|
|
56
|
+
modelValue: [items[0]!.value],
|
|
57
|
+
items,
|
|
58
|
+
label: 'Options sélectionnées',
|
|
59
|
+
textKey: 'text',
|
|
60
|
+
valueKey: 'value',
|
|
61
|
+
multiple: true,
|
|
62
|
+
chips: true,
|
|
63
|
+
required: true,
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
68
|
+
assertNoA11yViolations(results, 'SyAutocomplete – chips display', {
|
|
69
|
+
ignoreRules: ['region'],
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
})
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
2
|
+
import { mount, flushPromises } from '@vue/test-utils'
|
|
3
|
+
import { VMenu, VChip } from 'vuetify/components'
|
|
4
|
+
|
|
5
|
+
import SyAutocomplete from '../SyAutocomplete.vue'
|
|
6
|
+
import SyTextField from '@/components/Customs/SyTextField/SyTextField.vue'
|
|
7
|
+
|
|
8
|
+
describe('SyAutocomplete', () => {
|
|
9
|
+
let wrapper: ReturnType<typeof mount<typeof SyAutocomplete>>
|
|
10
|
+
const menuId = 'sy-autocomplete-menu-test'
|
|
11
|
+
|
|
12
|
+
const getMenu = () => document.body.querySelector(`#${menuId}`)
|
|
13
|
+
const getOption = (index: number) => document.body.querySelector(`#${menuId}-option-${index}`)
|
|
14
|
+
const isMenuOverlayActive = () => !!document.body.querySelector(`.v-overlay--active #${menuId}`)
|
|
15
|
+
const getInputEl = () => {
|
|
16
|
+
const el = document.getElementById(`${menuId}-input`)
|
|
17
|
+
if (!el) return null
|
|
18
|
+
if (el instanceof HTMLInputElement) return el
|
|
19
|
+
return el.querySelector('input') as HTMLInputElement | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const items = [
|
|
23
|
+
{ text: 'Option 1', value: '1' },
|
|
24
|
+
{ text: 'Option 2', value: '2' },
|
|
25
|
+
{ text: 'Option 3', value: '3' },
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
wrapper = mount(SyAutocomplete, {
|
|
30
|
+
props: {
|
|
31
|
+
modelValue: null,
|
|
32
|
+
items,
|
|
33
|
+
label: 'Test Autocomplete',
|
|
34
|
+
textKey: 'text',
|
|
35
|
+
valueKey: 'value',
|
|
36
|
+
menuId,
|
|
37
|
+
},
|
|
38
|
+
attachTo: document.body,
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
afterEach(() => {
|
|
43
|
+
wrapper.unmount()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('renders correctly with default props', () => {
|
|
47
|
+
expect(wrapper.exists()).toBe(true)
|
|
48
|
+
expect(wrapper.findComponent(VMenu).exists()).toBe(true)
|
|
49
|
+
expect(getMenu()).toBeNull() // Menu closed by default
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('opens menu when input is clicked', async () => {
|
|
53
|
+
const input = wrapper.find('input')
|
|
54
|
+
await input.trigger('click')
|
|
55
|
+
await flushPromises()
|
|
56
|
+
await wrapper.vm.$nextTick()
|
|
57
|
+
expect(getMenu()).not.toBeNull()
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('filters items based on search', async () => {
|
|
61
|
+
await wrapper.setProps({ modelValue: '1' })
|
|
62
|
+
await wrapper.vm.$nextTick()
|
|
63
|
+
expect(wrapper.vm.search).toBe('Option 1')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('emits update:modelValue when item is selected', async () => {
|
|
67
|
+
wrapper.vm.selectItem('1')
|
|
68
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
69
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['1'])
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('supports multiple selection', async () => {
|
|
73
|
+
wrapper.unmount()
|
|
74
|
+
wrapper = mount(SyAutocomplete, {
|
|
75
|
+
props: {
|
|
76
|
+
modelValue: [],
|
|
77
|
+
items,
|
|
78
|
+
multiple: true,
|
|
79
|
+
label: 'Test Multiple',
|
|
80
|
+
textKey: 'text',
|
|
81
|
+
valueKey: 'value',
|
|
82
|
+
menuId,
|
|
83
|
+
},
|
|
84
|
+
attachTo: document.body,
|
|
85
|
+
})
|
|
86
|
+
const input = wrapper.find('input')
|
|
87
|
+
await input.trigger('click')
|
|
88
|
+
await flushPromises()
|
|
89
|
+
await wrapper.vm.$nextTick()
|
|
90
|
+
|
|
91
|
+
const option0 = getOption(0)
|
|
92
|
+
expect(option0).not.toBeNull()
|
|
93
|
+
option0?.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, button: 0 }))
|
|
94
|
+
await flushPromises()
|
|
95
|
+
await wrapper.vm.$nextTick()
|
|
96
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([['1']])
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
it('clears typed query after selecting an item in multiple mode without chips', async () => {
|
|
100
|
+
wrapper.unmount()
|
|
101
|
+
wrapper = mount(SyAutocomplete, {
|
|
102
|
+
props: {
|
|
103
|
+
modelValue: [],
|
|
104
|
+
items,
|
|
105
|
+
multiple: true,
|
|
106
|
+
chips: false,
|
|
107
|
+
label: 'Test Multiple No Chips',
|
|
108
|
+
textKey: 'text',
|
|
109
|
+
valueKey: 'value',
|
|
110
|
+
menuId,
|
|
111
|
+
},
|
|
112
|
+
attachTo: document.body,
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
// User types a query
|
|
116
|
+
const textField = wrapper.findComponent(SyTextField)
|
|
117
|
+
expect(textField.exists()).toBe(true)
|
|
118
|
+
textField.vm.$emit('update:modelValue', 'Opt')
|
|
119
|
+
await flushPromises()
|
|
120
|
+
await wrapper.vm.$nextTick()
|
|
121
|
+
|
|
122
|
+
// Select first option
|
|
123
|
+
const option0 = getOption(0)
|
|
124
|
+
expect(option0).not.toBeNull()
|
|
125
|
+
option0?.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true, button: 0 }))
|
|
126
|
+
await flushPromises()
|
|
127
|
+
await wrapper.vm.$nextTick()
|
|
128
|
+
|
|
129
|
+
// Some environments can emit a follow-up input event with the previous DOM value.
|
|
130
|
+
// Ensure it doesn't re-populate the query after selection.
|
|
131
|
+
textField.vm.$emit('update:modelValue', 'Option 1, Opt')
|
|
132
|
+
await flushPromises()
|
|
133
|
+
await wrapper.vm.$nextTick()
|
|
134
|
+
|
|
135
|
+
// Query should be cleared, leaving only selected label prefix in input
|
|
136
|
+
expect(wrapper.vm.search).toBe('')
|
|
137
|
+
expect(getInputEl()!.value).toBe('Option 1, ')
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('displays chips in multiple mode', async () => {
|
|
141
|
+
wrapper.unmount()
|
|
142
|
+
wrapper = mount(SyAutocomplete, {
|
|
143
|
+
props: {
|
|
144
|
+
modelValue: items.slice(0, 1),
|
|
145
|
+
items,
|
|
146
|
+
multiple: true,
|
|
147
|
+
chips: true,
|
|
148
|
+
returnObject: true,
|
|
149
|
+
label: 'Test Chips',
|
|
150
|
+
textKey: 'text',
|
|
151
|
+
valueKey: 'value',
|
|
152
|
+
},
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
await wrapper.vm.$nextTick()
|
|
156
|
+
const chips = wrapper.findAllComponents(VChip)
|
|
157
|
+
expect(chips.length).toBe(1)
|
|
158
|
+
expect(chips[0]!.text()).toBe('Option 1')
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('removes chip when close button is clicked', async () => {
|
|
162
|
+
wrapper.unmount()
|
|
163
|
+
wrapper = mount(SyAutocomplete, {
|
|
164
|
+
props: {
|
|
165
|
+
modelValue: items.slice(0, 1),
|
|
166
|
+
items,
|
|
167
|
+
multiple: true,
|
|
168
|
+
chips: true,
|
|
169
|
+
returnObject: true,
|
|
170
|
+
label: 'Test Chips',
|
|
171
|
+
textKey: 'text',
|
|
172
|
+
valueKey: 'value',
|
|
173
|
+
},
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
await wrapper.vm.$nextTick()
|
|
177
|
+
const chip = wrapper.findComponent(VChip)
|
|
178
|
+
await chip.vm.$emit('click:close')
|
|
179
|
+
await wrapper.vm.$nextTick()
|
|
180
|
+
|
|
181
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([[]])
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('shows clear button when clearable and has selection', async () => {
|
|
185
|
+
wrapper.unmount()
|
|
186
|
+
wrapper = mount(SyAutocomplete, {
|
|
187
|
+
props: {
|
|
188
|
+
modelValue: items[0],
|
|
189
|
+
items,
|
|
190
|
+
clearable: true,
|
|
191
|
+
label: 'Test Clear',
|
|
192
|
+
textKey: 'text',
|
|
193
|
+
valueKey: 'value',
|
|
194
|
+
},
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
await wrapper.vm.$nextTick()
|
|
198
|
+
const clearButton = wrapper.find('button[aria-label="Réinitialiser la sélection"]')
|
|
199
|
+
expect(clearButton.exists()).toBe(true)
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('clears selection when clear button is clicked', async () => {
|
|
203
|
+
wrapper.unmount()
|
|
204
|
+
wrapper = mount(SyAutocomplete, {
|
|
205
|
+
props: {
|
|
206
|
+
modelValue: items[0],
|
|
207
|
+
items,
|
|
208
|
+
clearable: true,
|
|
209
|
+
label: 'Test Clear',
|
|
210
|
+
textKey: 'text',
|
|
211
|
+
valueKey: 'value',
|
|
212
|
+
},
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
await wrapper.vm.$nextTick()
|
|
216
|
+
const clearButton = wrapper.find('button[aria-label="Réinitialiser la sélection"]')
|
|
217
|
+
await clearButton.trigger('click')
|
|
218
|
+
await wrapper.vm.$nextTick()
|
|
219
|
+
|
|
220
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual([null])
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('validates field with custom rules', async () => {
|
|
224
|
+
wrapper.unmount()
|
|
225
|
+
const customRule = {
|
|
226
|
+
type: 'custom',
|
|
227
|
+
options: {
|
|
228
|
+
validate: value => Array.isArray(value) && value.length >= 2,
|
|
229
|
+
message: 'Sélectionnez au moins 2 éléments',
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
wrapper = mount(SyAutocomplete, {
|
|
234
|
+
props: {
|
|
235
|
+
modelValue: items.slice(0, 1),
|
|
236
|
+
items,
|
|
237
|
+
multiple: true,
|
|
238
|
+
label: 'Test Validation',
|
|
239
|
+
textKey: 'text',
|
|
240
|
+
valueKey: 'value',
|
|
241
|
+
customRules: [customRule],
|
|
242
|
+
},
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
await wrapper.vm.$nextTick()
|
|
246
|
+
await wrapper.find('input').trigger('blur')
|
|
247
|
+
await wrapper.vm.$nextTick()
|
|
248
|
+
|
|
249
|
+
const messages = wrapper.find('.v-messages')
|
|
250
|
+
expect(messages.text()).toContain('Sélectionnez au moins 2 éléments')
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it('handles keyboard navigation', async () => {
|
|
254
|
+
await wrapper.vm.$nextTick()
|
|
255
|
+
await flushPromises()
|
|
256
|
+
|
|
257
|
+
const inputEl = getInputEl()
|
|
258
|
+
expect(inputEl).not.toBeNull()
|
|
259
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
|
|
260
|
+
await flushPromises()
|
|
261
|
+
await wrapper.vm.$nextTick()
|
|
262
|
+
expect(getMenu()).not.toBeNull()
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
it('selects item on enter key', async () => {
|
|
266
|
+
await wrapper.vm.$nextTick()
|
|
267
|
+
await flushPromises()
|
|
268
|
+
|
|
269
|
+
const inputEl = getInputEl()
|
|
270
|
+
expect(inputEl).not.toBeNull()
|
|
271
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
|
|
272
|
+
await flushPromises()
|
|
273
|
+
await wrapper.vm.$nextTick()
|
|
274
|
+
expect(getMenu()).not.toBeNull()
|
|
275
|
+
|
|
276
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))
|
|
277
|
+
await flushPromises()
|
|
278
|
+
await wrapper.vm.$nextTick()
|
|
279
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
280
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['1'])
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
it('closes menu on escape', async () => {
|
|
284
|
+
const input = wrapper.find('input')
|
|
285
|
+
await input.trigger('click') // Open menu
|
|
286
|
+
await flushPromises()
|
|
287
|
+
await wrapper.vm.$nextTick()
|
|
288
|
+
expect(getMenu()).not.toBeNull()
|
|
289
|
+
expect(isMenuOverlayActive()).toBe(true)
|
|
290
|
+
|
|
291
|
+
const inputEl = getInputEl()
|
|
292
|
+
expect(inputEl).not.toBeNull()
|
|
293
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))
|
|
294
|
+
await flushPromises()
|
|
295
|
+
await wrapper.vm.$nextTick()
|
|
296
|
+
// Vuetify VMenu keeps teleported content mounted; check overlay visibility instead of DOM removal
|
|
297
|
+
expect(getMenu()).not.toBeNull()
|
|
298
|
+
expect(isMenuOverlayActive()).toBe(false)
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
it('selects and deselects items in multiple mode (mouse + keyboard)', async () => {
|
|
302
|
+
wrapper.unmount()
|
|
303
|
+
wrapper = mount(SyAutocomplete, {
|
|
304
|
+
props: {
|
|
305
|
+
modelValue: [],
|
|
306
|
+
items,
|
|
307
|
+
multiple: true,
|
|
308
|
+
label: 'Test Multiple',
|
|
309
|
+
textKey: 'text',
|
|
310
|
+
valueKey: 'value',
|
|
311
|
+
menuId,
|
|
312
|
+
},
|
|
313
|
+
attachTo: document.body,
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
// Keyboard: select + deselect option 0 in multiple mode
|
|
317
|
+
const inputEl = getInputEl()
|
|
318
|
+
expect(inputEl).not.toBeNull()
|
|
319
|
+
inputEl?.focus()
|
|
320
|
+
await flushPromises()
|
|
321
|
+
await wrapper.vm.$nextTick()
|
|
322
|
+
|
|
323
|
+
// ArrowDown opens the menu and sets the active option to 0
|
|
324
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
|
|
325
|
+
await flushPromises()
|
|
326
|
+
await wrapper.vm.$nextTick()
|
|
327
|
+
await flushPromises()
|
|
328
|
+
await wrapper.vm.$nextTick()
|
|
329
|
+
expect(getMenu()).not.toBeNull()
|
|
330
|
+
|
|
331
|
+
// Select option 0
|
|
332
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))
|
|
333
|
+
await flushPromises()
|
|
334
|
+
await wrapper.vm.$nextTick()
|
|
335
|
+
let option0 = getOption(0)
|
|
336
|
+
expect(option0?.getAttribute('aria-selected')).toBe('true')
|
|
337
|
+
|
|
338
|
+
// Deselect option 0
|
|
339
|
+
inputEl?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))
|
|
340
|
+
await flushPromises()
|
|
341
|
+
await wrapper.vm.$nextTick()
|
|
342
|
+
option0 = getOption(0)
|
|
343
|
+
expect(option0?.getAttribute('aria-selected')).toBe('false')
|
|
344
|
+
})
|
|
345
|
+
})
|