@cnamts/synapse 1.0.6 → 1.0.8
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-BlOpwEVq.js → DateFilter-DkqG0pmr.js} +1 -1
- package/dist/{NumberFilter-BPUXE4wY.js → NumberFilter-Ck7AwD39.js} +1 -1
- package/dist/{PeriodFilter-B2yx329_.js → PeriodFilter-LRI6YpgU.js} +1 -1
- package/dist/{SelectFilter-CedKn1oV.js → SelectFilter-DPc70Jk7.js} +1 -1
- package/dist/{TextFilter-DkhJjRtR.js → TextFilter-DRQL7uD8.js} +1 -1
- package/dist/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.d.ts +116 -0
- package/dist/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
- package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +220 -0
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +68 -0
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +70 -0
- package/dist/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.d.ts +204 -0
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +26 -26
- package/dist/components/Amelipro/AmeliproBadge/AmeliproBadge.d.ts +59 -0
- package/dist/components/Amelipro/AmeliproBtn/AmeliproBtn.d.ts +3 -3
- package/dist/components/Amelipro/AmeliproCaptcha/AmeliproCaptcha.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +214 -0
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.d.ts +70 -0
- package/dist/components/Amelipro/AmeliproCarousel/types.d.ts +7 -0
- package/dist/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.d.ts +125 -0
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIllustratedDataTile/AmeliproIllustratedDataTile.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproResultList/AmeliproResultList.d.ts +164 -0
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +27 -27
- package/dist/components/Amelipro/AmeliproStateTile/AmeliproStateTile.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +32 -32
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproTooltips/AmeliproTooltips.d.ts +2 -2
- package/dist/components/ChipList/ChipList.d.ts +4 -0
- package/dist/components/ChipList/locales.d.ts +4 -2
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +8 -8
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +329 -1296
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +0 -1
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +2 -0
- package/dist/components/Customs/SyTabs/SyTabs.d.ts +71 -0
- package/dist/components/Customs/SyTabs/config.d.ts +17 -0
- package/dist/components/Customs/SyTabs/types.d.ts +11 -0
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +9 -9
- package/dist/components/DataList/DataList.d.ts +1 -1
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +4811 -240
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +52 -33
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -10
- package/dist/components/DatePicker/composables/useDateInputEditing.d.ts +1 -0
- package/dist/components/DatePicker/composables/useTodayButton.d.ts +1 -0
- package/dist/components/DialogBox/DialogBox.d.ts +219 -0
- package/dist/components/HeaderLoading/HeaderLoading.d.ts +27 -0
- package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +110 -3
- package/dist/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.d.ts +19 -1
- package/dist/components/LangBtn/LangBtn.d.ts +2 -2
- package/dist/components/NirField/NirField.d.ts +18 -18
- package/dist/components/PeriodField/PeriodField.d.ts +10766 -1620
- package/dist/components/PhoneField/PhoneField.d.ts +1866 -2
- package/dist/components/PhoneField/indicatifs.d.ts +1 -0
- package/dist/components/PhoneField/locales.d.ts +1 -0
- package/dist/components/RangeField/RangeField.d.ts +1 -1
- package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +1 -1
- package/dist/components/SubHeader/SubHeader.d.ts +8 -0
- package/dist/components/SubHeader/locales.d.ts +1 -0
- package/dist/components/SyTextArea/SyTextArea.d.ts +6 -6
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -4
- package/dist/components/Tables/SyTable/SyTable.d.ts +5 -4
- package/dist/components/Tables/common/SyTablePagination.d.ts +333 -1296
- package/dist/components/Tables/common/organizeColumns/OrganizeColumns.d.ts +2 -2
- package/dist/components/Tables/common/types.d.ts +2 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/design-system-v3.js +173 -164
- package/dist/design-system-v3.umd.cjs +286 -263
- package/dist/{main-BXPFSAB4.js → main-DXMoMtj5.js} +13176 -11457
- package/dist/services/NotificationService.d.ts +1 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/amelipro/icons.ts +38 -11
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.mdx +20 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.stories.ts +135 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/AmeliproAccordionGroup.vue +107 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/AmeliproAccordionGroup.spec.ts +37 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/__tests__/__snapshots__/AmeliproAccordionGroup.spec.ts.snap +513 -0
- package/src/components/Amelipro/AmeliproAccordionGroup/types.d.ts +4 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.mdx +16 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +300 -0
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +288 -0
- package/src/components/Amelipro/AmeliproAccordionList/__tests__/AmeliproAccordionList.spec.ts +38 -0
- package/src/components/Amelipro/AmeliproAccordionList/__tests__/__snapshots__/AmeliproAccordionList.spec.ts.snap +1712 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.mdx +19 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +68 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +66 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.vue +145 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/AmeliproAccordionResultTemplate.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/__tests__/__snapshots__/AmeliproAccordionResultTemplate.spec.ts.snap +127 -0
- package/src/components/Amelipro/AmeliproAccordionResult/__tests__/AmeliproAccordionResult.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproAccordionResult/__tests__/__snapshots__/AmeliproAccordionResult.spec.ts.snap +123 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.mdx +20 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +273 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +275 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/AmeliproAccordionResultList.spec.ts +38 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/__tests__/__snapshots__/AmeliproAccordionResultList.spec.ts.snap +1593 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.mdx +15 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.stories.ts +54 -0
- package/src/components/Amelipro/AmeliproBadge/AmeliproBadge.vue +76 -0
- package/src/components/Amelipro/AmeliproBadge/__tests__/AmeliproBadge.spec.ts +20 -0
- package/src/components/Amelipro/AmeliproBadge/__tests__/__snapshots__/AmeliproBadge.spec.ts.snap +19 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.mdx +15 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.stories.ts +191 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarousel.vue +263 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/AmeliproCarouselItem.vue +93 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/AmeliproCarouselItem.spec.ts +24 -0
- package/src/components/Amelipro/AmeliproCarousel/AmeliproCarouselItem/__tests__/__snapshots__/AmeliproCarouselItem.spec.ts.snap +43 -0
- package/src/components/Amelipro/AmeliproCarousel/__tests__/AmeliproCarousel.spec.ts +40 -0
- package/src/components/Amelipro/AmeliproCarousel/__tests__/__snapshots__/AmeliproCarousel.spec.ts.snap +342 -0
- package/src/components/Amelipro/AmeliproCarousel/types.d.ts +8 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.mdx +18 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.stories.ts +67 -0
- package/src/components/Amelipro/AmeliproClickableTile/AmeliproClickableTile.vue +233 -0
- package/src/components/Amelipro/AmeliproClickableTile/tests/AmeliproClickableTile.spec.ts +21 -0
- package/src/components/Amelipro/AmeliproClickableTile/tests/__snapshots__/AmeliproClickableTile.spec.ts.snap +140 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeader.vue +7 -1
- package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +5 -4
- package/src/components/Amelipro/AmeliproIcon/iconList.ts +6 -0
- package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +5 -4
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.mdx +15 -0
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.stories.ts +264 -0
- package/src/components/Amelipro/AmeliproResultList/AmeliproResultList.vue +231 -0
- package/src/components/Amelipro/AmeliproResultList/__tests__/AmeliproResultList.spec.ts +37 -0
- package/src/components/Amelipro/AmeliproResultList/__tests__/__snapshots__/AmeliproResultList.spec.ts.snap +434 -0
- package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +6 -5
- package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +23 -26
- package/src/components/Amelipro/AmeliproTileBtn/AmeliproTileBtn.stories.ts +2 -2
- package/src/components/ChipList/Accessibilite.stories.ts +4 -0
- package/src/components/ChipList/ChipList.vue +185 -42
- package/src/components/ChipList/locales.ts +4 -2
- package/src/components/ChipList/tests/chipList.spec.ts +7 -4
- package/src/components/Customs/Selects/SelectOverview.mdx +34 -66
- package/src/components/Customs/Selects/SyBtnSelect/SyBtnSelect.stories.ts +10 -10
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.mdx +3 -0
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +14 -0
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +14 -6
- package/src/components/Customs/Selects/SySelect/SySelect.vue +268 -205
- package/src/components/Customs/Selects/SySelect/composables/tests/useSySelectKeyboard.spec.ts +0 -10
- package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +0 -5
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +184 -25
- package/src/components/Customs/SyCheckbox/SyCheckbox.mdx +3 -1
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +165 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +28 -9
- package/src/components/Customs/SyTabs/Accessibilite.mdx +309 -0
- package/src/components/Customs/SyTabs/SyTabs.mdx +117 -0
- package/src/components/Customs/SyTabs/SyTabs.stories.ts +354 -0
- package/src/components/Customs/SyTabs/SyTabs.vue +413 -0
- package/src/components/Customs/SyTabs/config.ts +17 -0
- package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +425 -0
- package/src/components/Customs/SyTabs/types.ts +12 -0
- package/src/components/Customs/SyTextField/SyTextField.mdx +3 -0
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +142 -1
- package/src/components/Customs/SyTextField/SyTextField.vue +19 -16
- package/src/components/DataList/DataList.vue +47 -49
- package/src/components/DataListGroup/DataListGroup.vue +1 -1
- package/src/components/DataListItem/DataListItem.vue +67 -63
- package/src/components/DataListItem/tests/DataListItem.spec.ts +2 -2
- package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +3 -3
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +49 -13
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +412 -649
- package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +215 -0
- package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +218 -0
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.mdx +2 -0
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
- package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +218 -0
- package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +281 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.events.spec.ts +17 -4
- package/src/components/DatePicker/DateTextInput/DateTextInput.range.spec.ts +111 -18
- package/src/components/DatePicker/DateTextInput/DateTextInput.spec.ts +238 -6
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +716 -757
- package/src/components/DatePicker/composables/tests/useDateInputEditing.spec.ts +4 -4
- package/src/components/DatePicker/composables/tests/useDisplayedDateString.spec.ts +17 -10
- package/src/components/DatePicker/composables/useDateInputEditing.ts +52 -22
- package/src/components/DatePicker/composables/useDisplayedDateString.ts +18 -4
- package/src/components/DatePicker/composables/useTodayButton.ts +13 -1
- package/src/components/DatePicker/utils/dateFormattingUtils.ts +79 -14
- package/src/components/DialogBox/DialogBox.stories.ts +12 -0
- package/src/components/DialogBox/DialogBox.vue +16 -11
- package/src/components/DialogBox/tests/DialogBox.spec.ts +22 -0
- package/src/components/HeaderLoading/Accessibilite.mdx +429 -8
- package/src/components/HeaderLoading/Accessibilite.stories.ts +4 -0
- package/src/components/HeaderLoading/HeaderLoading.vue +59 -0
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.mdx +17 -2
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.stories.ts +91 -2
- package/src/components/HeaderNavigationBar/HeaderNavigationBar.vue +37 -1
- package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +284 -21
- package/src/components/HeaderNavigationBar/tests/HeaderNavigationBar.spec.ts +2 -2
- package/src/components/NirField/NirField.mdx +3 -0
- package/src/components/NirField/NirField.vue +10 -1
- package/src/components/NirField/tests/NirField.spec.ts +81 -0
- package/src/components/NotificationBar/NotificationBar.stories.ts +128 -2
- package/src/components/NotificationBar/NotificationBar.vue +16 -1
- package/src/components/NotificationBar/tests/NotificationBar.spec.ts +65 -0
- package/src/components/PasswordField/PasswordField.mdx +3 -0
- package/src/components/PeriodField/PeriodField.mdx +2 -0
- package/src/components/PeriodField/PeriodField.stories.ts +195 -0
- package/src/components/PhoneField/Accessibilite.stories.ts +4 -0
- package/src/components/PhoneField/PhoneField.mdx +3 -1
- package/src/components/PhoneField/PhoneField.stories.ts +285 -1
- package/src/components/PhoneField/PhoneField.vue +228 -95
- package/src/components/PhoneField/indicatifs.ts +102 -102
- package/src/components/PhoneField/locales.ts +1 -0
- package/src/components/PhoneField/tests/PhoneField.spec.ts +419 -2
- package/src/components/SkipLink/SkipLink.vue +3 -31
- package/src/components/SkipLink/tests/skipLink.spec.ts +0 -21
- package/src/components/SubHeader/Accessibilite.stories.ts +8 -0
- package/src/components/SubHeader/SubHeader.mdx +1 -0
- package/src/components/SubHeader/SubHeader.stories.ts +179 -60
- package/src/components/SubHeader/SubHeader.vue +45 -15
- package/src/components/SubHeader/locales.ts +1 -0
- package/src/components/SyAlert/SyAlert.vue +6 -0
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +3 -10
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +242 -0
- package/src/components/Tables/SyServerTable/SyServerTable.vue +29 -10
- package/src/components/Tables/SyTable/SyTable.mdx +3 -10
- package/src/components/Tables/SyTable/SyTable.stories.ts +242 -0
- package/src/components/Tables/SyTable/SyTable.vue +2 -0
- package/src/components/Tables/common/SyTablePagination.vue +13 -6
- package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +6 -1
- package/src/components/Tables/common/tests/SyTablePagination.spec.ts +157 -0
- package/src/components/Tables/common/types.ts +2 -0
- package/src/components/index.ts +9 -0
- package/src/composables/useFilterable/useFilterable.ts +10 -0
- package/src/designTokens/tokens/amelipro/apColors.ts +1 -1
- package/src/designTokens/tokens/cnam/cnamSemantic.ts +3 -3
- package/src/services/NotificationService.ts +9 -0
- package/src/stories/Components/Components.stories.ts +1 -1
- package/src/stories/GuideDuDev/FormValidationGuide.mdx +342 -0
- package/src/stories/Templates/Templates.stories.ts +1 -1
- package/src/utils/functions/ameliproColors/ameliproColors.ts +1 -1
- package/dist/components/DataList/locales.d.ts +0 -3
- package/src/components/DataList/locales.ts +0 -3
- package/src/components/PhoneField/tests/PhoneField.additional.spec.ts +0 -266
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Meta, Canvas, Controls, Source, Story } from '@storybook/blocks';
|
|
2
|
+
import * as SyTabsStories from "./SyTabs.stories";
|
|
3
|
+
|
|
4
|
+
<Meta of={SyTabsStories} />
|
|
5
|
+
|
|
6
|
+
# SyTabs
|
|
7
|
+
|
|
8
|
+
Le composant `SyTabs` est un système de navigation par onglets conforme au Design System qui respecte les règles d'accessibilité <abbr title="Référentiel Général d'Amélioration de l'Accessibilité">RGAA</abbr>. Il permet d'organiser le contenu en sections navigables facilement via une interface à onglets.
|
|
9
|
+
|
|
10
|
+
Il implémente les fonctionnalités suivantes :
|
|
11
|
+
|
|
12
|
+
- Navigation complète au clavier
|
|
13
|
+
- Attributs ARIA appropriés
|
|
14
|
+
- Gestion du focus accessible
|
|
15
|
+
- Structure HTML sémantique
|
|
16
|
+
- Design personnalisable
|
|
17
|
+
|
|
18
|
+
<Canvas of={SyTabsStories.Default} />
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
<Controls of={SyTabsStories.Default} />
|
|
23
|
+
|
|
24
|
+
## Structure des données
|
|
25
|
+
|
|
26
|
+
Le composant `SyTabs` attend un tableau d'objets `TabItem` avec la structure suivante :
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
export interface TabItem {
|
|
30
|
+
label: string // Texte affiché dans l'onglet
|
|
31
|
+
value: string | number // Valeur unique utilisée pour v-model
|
|
32
|
+
content?: string // Contenu textuel de l'onglet (optionnel)
|
|
33
|
+
disabled?: boolean // État désactivé (optionnel)
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Accessibilité
|
|
38
|
+
|
|
39
|
+
Le composant `SyTabs` respecte les critères d'accessibilité RGAA suivants :
|
|
40
|
+
|
|
41
|
+
### Structure sémantique
|
|
42
|
+
|
|
43
|
+
- Utilise les éléments `<nav>`, `<ul>` et `<li>` pour une structure de navigation sémantique
|
|
44
|
+
- Associe chaque onglet à son panneau de contenu via les attributs `aria-controls` et `aria-labelledby`
|
|
45
|
+
- Utilise l'attribut `aria-label="Onglets de navigation"` sur l'élément `<nav>` pour identifier la navigation
|
|
46
|
+
|
|
47
|
+
### Rôles ARIA
|
|
48
|
+
|
|
49
|
+
- `role="tablist"` sur le conteneur de navigation
|
|
50
|
+
- `role="presentation"` sur les éléments de liste
|
|
51
|
+
- `role="tab"` sur les boutons d'onglets
|
|
52
|
+
- `role="tabpanel"` sur les panneaux de contenu
|
|
53
|
+
|
|
54
|
+
### États et propriétés
|
|
55
|
+
|
|
56
|
+
- `aria-selected="true|false"` indique l'onglet actif
|
|
57
|
+
- Attribut `hidden` sur les panneaux non actifs
|
|
58
|
+
- Focus visible avec outline adapté au design system
|
|
59
|
+
|
|
60
|
+
### Navigation au clavier
|
|
61
|
+
|
|
62
|
+
Le composant implémente toutes les interactions clavier recommandées par les [Pratiques Authoring WAI-ARIA 1.2](https://www.w3.org/WAI/ARIA/apg/patterns/tabpanel/) :
|
|
63
|
+
|
|
64
|
+
- **Flèches gauche/droite** : Navigation entre les onglets
|
|
65
|
+
- **Touches Home/End** : Accès au premier/dernier onglet
|
|
66
|
+
- **Entrée/Espace** : Activation de l'onglet
|
|
67
|
+
- **Échap** : Gestion du focus
|
|
68
|
+
|
|
69
|
+
### Contraste et visibilité
|
|
70
|
+
|
|
71
|
+
- Contraste suffisant entre le texte et le fond (minimum 4.5:1)
|
|
72
|
+
- Indication visuelle claire de l'onglet actif (changement de couleur et bordure)
|
|
73
|
+
- Focus visible conforme aux exigences RGAA
|
|
74
|
+
|
|
75
|
+
### Tests d'accessibilité
|
|
76
|
+
|
|
77
|
+
Le composant a été testé avec :
|
|
78
|
+
- Lecteurs d'écran (NVDA, VoiceOver)
|
|
79
|
+
- Navigation clavier
|
|
80
|
+
- Outils de vérification de contraste
|
|
81
|
+
|
|
82
|
+
<Canvas of={SyTabsStories.Default} />
|
|
83
|
+
|
|
84
|
+
## Personnalisation
|
|
85
|
+
|
|
86
|
+
Le composant peut être personnalisé via l'objet `vuetifyOptions` qui permet de modifier l'apparence des onglets :
|
|
87
|
+
|
|
88
|
+
> **Important** : Ces options de personnalisation doivent être passées via la prop `vuetifyOptions` et non comme props directes du composant. Par exemple, utilisez `:vuetify-options="{ sheet: { dense: true } }"` plutôt que `:sheet="{ dense: true }"`.
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
{
|
|
92
|
+
sheet: {
|
|
93
|
+
theme: 'default|dark|light', // Thème de l'arrière-plan
|
|
94
|
+
color: '#fff', // Couleur d'arrière-plan
|
|
95
|
+
dense: false // Mode compact
|
|
96
|
+
},
|
|
97
|
+
tabs: {
|
|
98
|
+
height: '48', // Hauteur des onglets
|
|
99
|
+
'show-arrows': true // Affichage des flèches de défilement
|
|
100
|
+
},
|
|
101
|
+
tab: {
|
|
102
|
+
'base-color': '#0C419A', // Couleur de base des onglets
|
|
103
|
+
'active-color': '#0C419A', // Couleur de l'onglet actif
|
|
104
|
+
'slider-color': '#0C419A', // Couleur de l'indicateur actif
|
|
105
|
+
'ripple': false // Effet de ripple
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
<Canvas of={SyTabsStories.CustomTheme} />
|
|
111
|
+
|
|
112
|
+
## Bonnes pratiques
|
|
113
|
+
|
|
114
|
+
- Limitez le nombre d'onglets pour éviter une surcharge cognitive
|
|
115
|
+
- Utilisez des libellés courts et descriptifs
|
|
116
|
+
- Assurez une cohérence visuelle entre les onglets et leur contenu
|
|
117
|
+
- Préservez l'état des onglets lors de la navigation entre pages si nécessaire
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
|
|
3
|
+
import SyTabs from './SyTabs.vue'
|
|
4
|
+
import { ref } from 'vue'
|
|
5
|
+
|
|
6
|
+
// Plus d'informations sur la configuration de Storybook pour Vue:
|
|
7
|
+
// https://storybook.js.org/docs/vue/writing-stories/introduction
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `SyTabs` est un composant de navigation par onglets accessible et personnalisable.
|
|
11
|
+
* Il permet d'organiser le contenu en sections navigables facilement via une interface à onglets.
|
|
12
|
+
* Le composant implémente toutes les bonnes pratiques d'accessibilité ARIA et supporte la navigation complète au clavier.
|
|
13
|
+
*/
|
|
14
|
+
const meta = {
|
|
15
|
+
title: 'Composants/Navigation/SyTabs',
|
|
16
|
+
component: SyTabs,
|
|
17
|
+
parameters: {
|
|
18
|
+
layout: 'fullscreen',
|
|
19
|
+
controls: { exclude: ['confirmationMessage'] },
|
|
20
|
+
},
|
|
21
|
+
argTypes: {
|
|
22
|
+
items: {
|
|
23
|
+
description: 'Liste des éléments à afficher dans les onglets',
|
|
24
|
+
control: 'object',
|
|
25
|
+
},
|
|
26
|
+
modelValue: {
|
|
27
|
+
description: 'Index ou valeur de l\'onglet actuellement sélectionné (utilisé avec v-model)',
|
|
28
|
+
control: 'text',
|
|
29
|
+
},
|
|
30
|
+
confirmTabChange: {
|
|
31
|
+
description: 'Si activé, une confirmation sera demandée avant de changer d\'onglet',
|
|
32
|
+
control: 'boolean',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
args: {
|
|
36
|
+
items: [
|
|
37
|
+
{ label: 'Onglet 1', value: 'tab1', content: 'Contenu de l\'onglet 1' },
|
|
38
|
+
{ label: 'Onglet 2', value: 'tab2', content: 'Contenu de l\'onglet 2' },
|
|
39
|
+
{ label: 'Onglet 3', value: 'tab3', content: 'Contenu de l\'onglet 3' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
} as Meta<typeof SyTabs>
|
|
43
|
+
|
|
44
|
+
export default meta
|
|
45
|
+
type Story = StoryObj<typeof meta>
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Exemple de base du composant SyTabs avec des onglets simples.
|
|
49
|
+
*/
|
|
50
|
+
export const Default: Story = {
|
|
51
|
+
args: {},
|
|
52
|
+
parameters: {
|
|
53
|
+
sourceCode: [
|
|
54
|
+
{
|
|
55
|
+
name: 'Template',
|
|
56
|
+
code: `<SyTabs :items="items" />`,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Script',
|
|
60
|
+
code: `
|
|
61
|
+
const items = [
|
|
62
|
+
{ label: 'Onglet 1', value: 'tab1', content: "Contenu de l'onglet 1" },
|
|
63
|
+
{ label: 'Onglet 2', value: 'tab2', content: "Contenu de l'onglet 2" },
|
|
64
|
+
{ label: 'Onglet 3', value: 'tab3', content: "Contenu de l'onglet 3" },
|
|
65
|
+
]
|
|
66
|
+
`,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Exemple avec v-model pour contrôler l'onglet actif de façon externe.
|
|
74
|
+
*/
|
|
75
|
+
export const WithVModel: Story = {
|
|
76
|
+
render: args => ({
|
|
77
|
+
components: { SyTabs },
|
|
78
|
+
setup() {
|
|
79
|
+
const activeTab = ref('tab2')
|
|
80
|
+
|
|
81
|
+
return { args, activeTab }
|
|
82
|
+
},
|
|
83
|
+
template: `
|
|
84
|
+
<div>
|
|
85
|
+
<div class="mb-4">
|
|
86
|
+
Onglet actif: {{ activeTab }}
|
|
87
|
+
<button
|
|
88
|
+
class="ml-4 px-2 py-1 bg-primary text-white rounded"
|
|
89
|
+
@click="activeTab = activeTab === 'tab1' ? 'tab2' : 'tab1'"
|
|
90
|
+
>
|
|
91
|
+
Changer d'onglet
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
<SyTabs v-model="activeTab" :items="args.items" />
|
|
95
|
+
</div>
|
|
96
|
+
`,
|
|
97
|
+
}),
|
|
98
|
+
parameters: {
|
|
99
|
+
sourceCode: [
|
|
100
|
+
{
|
|
101
|
+
name: 'Template',
|
|
102
|
+
code: `
|
|
103
|
+
<template>
|
|
104
|
+
<div>
|
|
105
|
+
<div class="mb-4">
|
|
106
|
+
Onglet actif: {{ activeTab }}
|
|
107
|
+
<button
|
|
108
|
+
class="ml-4 px-2 py-1 bg-primary text-white rounded"
|
|
109
|
+
@click="activeTab = activeTab === 'tab1' ? 'tab2' : 'tab1'"
|
|
110
|
+
>
|
|
111
|
+
Changer d'onglet
|
|
112
|
+
</button>
|
|
113
|
+
</div>
|
|
114
|
+
<SyTabs v-model="activeTab" :items="items" />
|
|
115
|
+
</div>
|
|
116
|
+
</template>`,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'Script',
|
|
120
|
+
code: `
|
|
121
|
+
<script setup>
|
|
122
|
+
import { ref } from 'vue'
|
|
123
|
+
|
|
124
|
+
const activeTab = ref('tab2')
|
|
125
|
+
const items = [
|
|
126
|
+
{ label: 'Onglet 1', value: 'tab1', content: "Contenu de l'onglet 1" },
|
|
127
|
+
{ label: 'Onglet 2', value: 'tab2', content: "Contenu de l'onglet 2" },
|
|
128
|
+
{ label: 'Onglet 3', value: 'tab3', content: "Contenu de l'onglet 3" }
|
|
129
|
+
]
|
|
130
|
+
</script>`,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Exemple avec slots personnalisés pour le contenu des onglets.
|
|
138
|
+
*/
|
|
139
|
+
export const WithCustomContent: Story = {
|
|
140
|
+
render: args => ({
|
|
141
|
+
components: { SyTabs },
|
|
142
|
+
setup() {
|
|
143
|
+
return { args }
|
|
144
|
+
},
|
|
145
|
+
template: `
|
|
146
|
+
<SyTabs :items="args.items">
|
|
147
|
+
<template #panel-0>
|
|
148
|
+
<div class="p-4 bg-info-light rounded">
|
|
149
|
+
<h3 class="text-h6 font-weight-bold">Contenu personnalisé pour l'onglet 1</h3>
|
|
150
|
+
<p>Vous pouvez utiliser des slots nommés <code>panel-{index}</code> pour personnaliser le contenu de chaque onglet.</p>
|
|
151
|
+
</div>
|
|
152
|
+
</template>
|
|
153
|
+
<template #panel-1>
|
|
154
|
+
<div class="p-4 bg-success-light rounded">
|
|
155
|
+
<h3 class="text-h6 font-weight-bold">Contenu personnalisé pour l'onglet 2</h3>
|
|
156
|
+
<p>Ce panneau utilise un style différent.</p>
|
|
157
|
+
</div>
|
|
158
|
+
</template>
|
|
159
|
+
</SyTabs>
|
|
160
|
+
`,
|
|
161
|
+
}),
|
|
162
|
+
parameters: {
|
|
163
|
+
sourceCode: [
|
|
164
|
+
{
|
|
165
|
+
name: 'Template',
|
|
166
|
+
code: `
|
|
167
|
+
<SyTabs :items="args.items">
|
|
168
|
+
<template #panel-0>
|
|
169
|
+
<div class="p-4 bg-info-light rounded">
|
|
170
|
+
<h3 class="text-h6 font-weight-bold">Contenu personnalisé pour l'onglet 1</h3>
|
|
171
|
+
<p>Vous pouvez utiliser des slots nommés <code>panel-{index}</code> pour personnaliser le contenu de chaque onglet.</p>
|
|
172
|
+
</div>
|
|
173
|
+
</template>
|
|
174
|
+
<template #panel-1>
|
|
175
|
+
<div class="p-4 bg-success-light rounded">
|
|
176
|
+
<h3 class="text-h6 font-weight-bold">Contenu personnalisé pour l'onglet 2</h3>
|
|
177
|
+
<p>Ce panneau utilise un style différent.</p>
|
|
178
|
+
</div>
|
|
179
|
+
</template>
|
|
180
|
+
</SyTabs>
|
|
181
|
+
`,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'Script',
|
|
185
|
+
code: `
|
|
186
|
+
|
|
187
|
+
`,
|
|
188
|
+
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Exemple avec de nombreux onglets pour démontrer le comportement de scrolling.
|
|
196
|
+
*/
|
|
197
|
+
export const ManyTabs: Story = {
|
|
198
|
+
args: {
|
|
199
|
+
items: Array.from({ length: 10 }, (_, i) => ({
|
|
200
|
+
label: `Onglet ${i + 1}`,
|
|
201
|
+
value: `tab${i + 1}`,
|
|
202
|
+
content: `Contenu de l'onglet ${i + 1}`,
|
|
203
|
+
})),
|
|
204
|
+
},
|
|
205
|
+
parameters: {
|
|
206
|
+
sourceCode: [
|
|
207
|
+
{
|
|
208
|
+
name: 'Template',
|
|
209
|
+
code: `<SyTabs :items="items" />`,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: 'Script',
|
|
213
|
+
code: `
|
|
214
|
+
// Création d'un grand nombre d'onglets pour tester le comportement de défilement
|
|
215
|
+
const items = Array.from({ length: 10 }, (_, i) => ({
|
|
216
|
+
label: \`Onglet \${i + 1}\`,
|
|
217
|
+
value: \`tab\${i + 1}\`,
|
|
218
|
+
content: \`Contenu de l'onglet \${i + 1}\`,
|
|
219
|
+
}))
|
|
220
|
+
`,
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Exemple avec des options de personnalisation du thème.
|
|
228
|
+
*/
|
|
229
|
+
export const CustomTheme: Story = {
|
|
230
|
+
render: args => ({
|
|
231
|
+
components: { SyTabs },
|
|
232
|
+
setup() {
|
|
233
|
+
return { args }
|
|
234
|
+
},
|
|
235
|
+
template: `
|
|
236
|
+
<SyTabs
|
|
237
|
+
:items="args.items"
|
|
238
|
+
:vuetifyOptions="{
|
|
239
|
+
sheet: { theme: 'dark', color: '#0C419A' },
|
|
240
|
+
tab: { 'base-color': '#ffffff', 'active-color': '#ffffff', 'slider-color': '#42b983' },
|
|
241
|
+
tabs: { height: '60' }
|
|
242
|
+
}"
|
|
243
|
+
/>
|
|
244
|
+
`,
|
|
245
|
+
}),
|
|
246
|
+
parameters: {
|
|
247
|
+
sourceCode: [
|
|
248
|
+
{
|
|
249
|
+
name: 'Template',
|
|
250
|
+
code: `
|
|
251
|
+
<SyTabs
|
|
252
|
+
:items="items"
|
|
253
|
+
:vuetifyOptions="{
|
|
254
|
+
sheet: { theme: 'dark', color: '#0C419A' },
|
|
255
|
+
tab: { 'base-color': '#ffffff', 'active-color': '#ffffff', 'slider-color': '#42b983' },
|
|
256
|
+
tabs: { height: '60' }
|
|
257
|
+
}"
|
|
258
|
+
/>
|
|
259
|
+
`,
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: 'Script',
|
|
263
|
+
code: `
|
|
264
|
+
<script setup>
|
|
265
|
+
const items = [
|
|
266
|
+
{ label: 'Onglet 1', value: 'tab1', content: "Contenu de l'onglet 1" },
|
|
267
|
+
{ label: 'Onglet 2', value: 'tab2', content: "Contenu de l'onglet 2" },
|
|
268
|
+
{ label: 'Onglet 3', value: 'tab3', content: "Contenu de l'onglet 3" },
|
|
269
|
+
]
|
|
270
|
+
</script>
|
|
271
|
+
`,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Exemple avec confirmation avant changement d'onglet.
|
|
279
|
+
* Démontre comment utiliser la propriété confirmTabChange et gérer l'événement confirm-tab-change.
|
|
280
|
+
*/
|
|
281
|
+
export const WithTabConfirmation: Story = {
|
|
282
|
+
render: args => ({
|
|
283
|
+
components: { SyTabs },
|
|
284
|
+
setup() {
|
|
285
|
+
return {
|
|
286
|
+
args,
|
|
287
|
+
showConfirmDialog: (message: string, callback: (confirmed: boolean) => void) => {
|
|
288
|
+
// Dans un cas réel, vous afficheriez une boîte de dialogue personnalisée
|
|
289
|
+
// Ici nous utilisons window.confirm pour la démonstration
|
|
290
|
+
const confirmed = window.confirm('Voulez-vous vraiment changer d\'onglet ?')
|
|
291
|
+
// Appelons le callback avec le résultat de la confirmation
|
|
292
|
+
callback(confirmed)
|
|
293
|
+
},
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
template: `
|
|
297
|
+
<div>
|
|
298
|
+
<div class="mb-4 pa-2 bg-warning-light">
|
|
299
|
+
<strong>Note :</strong> Essayez de changer d'onglet. Une boîte de dialogue de confirmation s'affichera.
|
|
300
|
+
</div>
|
|
301
|
+
|
|
302
|
+
<SyTabs
|
|
303
|
+
:items="args.items"
|
|
304
|
+
:confirmTabChange="true"
|
|
305
|
+
@confirm-tab-change="showConfirmDialog"
|
|
306
|
+
/>
|
|
307
|
+
</div>
|
|
308
|
+
`,
|
|
309
|
+
}),
|
|
310
|
+
parameters: {
|
|
311
|
+
sourceCode: [
|
|
312
|
+
{
|
|
313
|
+
name: 'Template',
|
|
314
|
+
code: `
|
|
315
|
+
<template>
|
|
316
|
+
<div>
|
|
317
|
+
<div class="mb-4 pa-2 bg-warning-light">
|
|
318
|
+
<strong>Note :</strong> Essayez de changer d'onglet. Une boîte de dialogue de confirmation s'affichera.
|
|
319
|
+
</div>
|
|
320
|
+
<SyTabs
|
|
321
|
+
:items="items"
|
|
322
|
+
:confirmTabChange="true"
|
|
323
|
+
@confirm-tab-change="showConfirmDialog"
|
|
324
|
+
/>
|
|
325
|
+
</div>
|
|
326
|
+
</template>
|
|
327
|
+
`,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: 'Script',
|
|
331
|
+
code: `
|
|
332
|
+
<script setup>
|
|
333
|
+
import { ref } from 'vue'
|
|
334
|
+
|
|
335
|
+
const items = [
|
|
336
|
+
{ label: 'Onglet 1', value: 'tab1', content: "Contenu de l'onglet 1" },
|
|
337
|
+
{ label: 'Onglet 2', value: 'tab2', content: "Contenu de l'onglet 2" },
|
|
338
|
+
{ label: 'Onglet 3', value: 'tab3', content: "Contenu de l'onglet 3" }
|
|
339
|
+
]
|
|
340
|
+
|
|
341
|
+
// Fonction pour afficher une boîte de dialogue de confirmation
|
|
342
|
+
function showConfirmDialog(message, callback) {
|
|
343
|
+
// Dans un cas réel, vous afficheriez une boîte de dialogue personnalisée
|
|
344
|
+
// Ici nous utilisons window.confirm pour la démonstration
|
|
345
|
+
const confirmed = window.confirm("Voulez-vous vraiment changer d'onglet ?")
|
|
346
|
+
// Appelons le callback avec le résultat de la confirmation
|
|
347
|
+
callback(confirmed)
|
|
348
|
+
}
|
|
349
|
+
</script>
|
|
350
|
+
`,
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
}
|