@cnamts/synapse 1.0.6 → 1.0.7
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-CHDLz2EO.js} +1 -1
- package/dist/{NumberFilter-BPUXE4wY.js → NumberFilter-DXNQ4Uls.js} +1 -1
- package/dist/{PeriodFilter-B2yx329_.js → PeriodFilter-C8Qf3Jcn.js} +1 -1
- package/dist/{SelectFilter-CedKn1oV.js → SelectFilter-B2Ejs4Cb.js} +1 -1
- package/dist/{TextFilter-DkhJjRtR.js → TextFilter-CfR5_A1S.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 +445 -8
- 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 +448 -7
- 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 +288 -261
- package/dist/{main-BXPFSAB4.js → main-C66C1BkG.js} +12984 -11291
- 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 +18 -15
- package/src/components/Customs/Selects/SyBtnSelect/SyBtnSelect.stories.ts +10 -10
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +13 -5
- package/src/components/Customs/Selects/SySelect/SySelect.vue +108 -37
- 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 +350 -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 +276 -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/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 +429 -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/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/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
|
@@ -1,14 +1,435 @@
|
|
|
1
|
-
import { Meta, Story } from '@storybook/
|
|
1
|
+
import { Meta, Title, Subtitle, Description, Primary, Controls, Stories, Canvas, Source, Story } from '@storybook/blocks';
|
|
2
2
|
import * as AccessStories from './Accessibilite.stories.ts';
|
|
3
|
+
import * as HeaderLoadingStories from './HeaderLoading.stories.ts';
|
|
4
|
+
import AccessibilityIcon from '@/common/imgs/accessibility-svgrepo-com.svg';
|
|
3
5
|
|
|
4
6
|
<Meta of={AccessStories} />
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<
|
|
8
|
+
<div className="accessibility-guide">
|
|
9
|
+
<Title>Guide d'Accessibilité du Composant HeaderLoading</Title>
|
|
10
|
+
|
|
11
|
+
<div className="intro-section">
|
|
12
|
+
<img
|
|
13
|
+
src={AccessibilityIcon}
|
|
14
|
+
alt="Icône d'accessibilité"
|
|
15
|
+
className="accessibility-icon"
|
|
16
|
+
/>
|
|
17
|
+
<p className="intro-text">
|
|
18
|
+
Le composant HeaderLoading affiche un squelette de chargement destiné à indiquer qu'un contenu est en cours de chargement.
|
|
19
|
+
Ce composant a été conçu en tenant compte des normes d'accessibilité RGAA et des recommandations pour les loaders visuels.
|
|
20
|
+
Ce guide détaille comment notre implémentation respecte ces standards et garantit une expérience utilisateur inclusive.
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
10
23
|
|
|
11
|
-
|
|
24
|
+
<div className="criteria-section">
|
|
25
|
+
<h2>Critères d'accessibilité respectés</h2>
|
|
26
|
+
|
|
27
|
+
<div className="criteria-card">
|
|
28
|
+
<div className="criteria-header">
|
|
29
|
+
<span className="criteria-icon">🎨</span>
|
|
30
|
+
<h3>Contraste minimal</h3>
|
|
31
|
+
</div>
|
|
32
|
+
<ul>
|
|
33
|
+
<li><strong>Ratio de contraste</strong>: Utilise un niveau de contraste de 1.5:1 sur fond blanc pour les squelettes</li>
|
|
34
|
+
<li><strong>Visibilité garantie</strong>: Visible dans différentes conditions d'éclairage</li>
|
|
35
|
+
<li><strong>Couleur configurable</strong>: S'adapte aux thèmes pour maintenir le contraste</li>
|
|
36
|
+
</ul>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div className="criteria-card">
|
|
40
|
+
<div className="criteria-header">
|
|
41
|
+
<span className="criteria-icon">⚡</span>
|
|
42
|
+
<h3>Support des préférences de mouvement réduit</h3>
|
|
43
|
+
</div>
|
|
44
|
+
<ul>
|
|
45
|
+
<li><strong>Media query</strong>: Utilise <code>prefers-reduced-motion</code> pour détecter les préférences</li>
|
|
46
|
+
<li><strong>Désactivation automatique</strong>: Arrête les animations si l'utilisateur le préfère</li>
|
|
47
|
+
<li><strong>Respect du système</strong>: Aligne le comportement sur les paramètres du système d'exploitation</li>
|
|
48
|
+
</ul>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div className="criteria-card">
|
|
52
|
+
<div className="criteria-header">
|
|
53
|
+
<span className="criteria-icon">📱</span>
|
|
54
|
+
<h3>Modes d'implémentation flexibles</h3>
|
|
55
|
+
</div>
|
|
56
|
+
<ul>
|
|
57
|
+
<li><strong>Mode autonome</strong>: Pour un seul squelette, avec <code>role="alert"</code> et <code>aria-live="polite"</code></li>
|
|
58
|
+
<li><strong>Mode multiple</strong>: Pour plusieurs squelettes, avec <code>aria-hidden="true"</code> et un message unique</li>
|
|
59
|
+
<li><strong>Surcharge évitée</strong>: Évite la multiplication des annonces pour les lecteurs d'écran</li>
|
|
60
|
+
</ul>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
12
63
|
|
|
13
|
-
<
|
|
14
|
-
<
|
|
64
|
+
<div className="demo-section">
|
|
65
|
+
<h2>API du composant</h2>
|
|
66
|
+
<p>
|
|
67
|
+
Le composant HeaderLoading prend en charge les propriétés suivantes pour personnaliser son apparence et son comportement d'accessibilité.
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<div className="api-group">
|
|
71
|
+
<h3>Propriétés de dimensions</h3>
|
|
72
|
+
<table className="api-table">
|
|
73
|
+
<thead>
|
|
74
|
+
<tr>
|
|
75
|
+
<th>Propriété</th>
|
|
76
|
+
<th>Type</th>
|
|
77
|
+
<th>Par défaut</th>
|
|
78
|
+
<th>Description</th>
|
|
79
|
+
</tr>
|
|
80
|
+
</thead>
|
|
81
|
+
<tbody>
|
|
82
|
+
<tr>
|
|
83
|
+
<td><code>width</code></td>
|
|
84
|
+
<td>String</td>
|
|
85
|
+
<td>'100px'</td>
|
|
86
|
+
<td>Largeur du squelette de chargement. Accepte toutes les unités CSS valides (px, %, em, rem, vw).</td>
|
|
87
|
+
</tr>
|
|
88
|
+
<tr>
|
|
89
|
+
<td><code>height</code></td>
|
|
90
|
+
<td>String</td>
|
|
91
|
+
<td>'1rem'</td>
|
|
92
|
+
<td>Hauteur du squelette de chargement. Accepte toutes les unités CSS valides (px, %, em, rem, vh).</td>
|
|
93
|
+
</tr>
|
|
94
|
+
</tbody>
|
|
95
|
+
</table>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div className="api-group">
|
|
99
|
+
<h3>Propriétés d'accessibilité</h3>
|
|
100
|
+
<table className="api-table">
|
|
101
|
+
<thead>
|
|
102
|
+
<tr>
|
|
103
|
+
<th>Propriété</th>
|
|
104
|
+
<th>Type</th>
|
|
105
|
+
<th>Par défaut</th>
|
|
106
|
+
<th>Description</th>
|
|
107
|
+
</tr>
|
|
108
|
+
</thead>
|
|
109
|
+
<tbody>
|
|
110
|
+
<tr>
|
|
111
|
+
<td><code>standalone</code></td>
|
|
112
|
+
<td>Boolean</td>
|
|
113
|
+
<td>false</td>
|
|
114
|
+
<td>
|
|
115
|
+
<strong>Mode d'utilisation du composant</strong>:<br/>
|
|
116
|
+
- <code>true</code>: Le composant gère sa propre annonce d'accessibilité (pour un squelette unique)<br/>
|
|
117
|
+
- <code>false</code>: Le composant est silencieux et doit être utilisé avec un conteneur parent qui a <code>aria-busy="true"</code>
|
|
118
|
+
</td>
|
|
119
|
+
</tr>
|
|
120
|
+
<tr>
|
|
121
|
+
<td><code>ariaLabel</code></td>
|
|
122
|
+
<td>String</td>
|
|
123
|
+
<td>'Chargement en cours...'</td>
|
|
124
|
+
<td>
|
|
125
|
+
Message vocalisé par les lecteurs d'écran pour indiquer l'état de chargement.<br/>
|
|
126
|
+
<strong>Note</strong>: Ne fonctionne que si <code>standalone</code> est <code>true</code>.
|
|
127
|
+
</td>
|
|
128
|
+
</tr>
|
|
129
|
+
<tr>
|
|
130
|
+
<td><code>statusMessageId</code></td>
|
|
131
|
+
<td>String</td>
|
|
132
|
+
<td>undefined</td>
|
|
133
|
+
<td>
|
|
134
|
+
ID d'un élément externe qui contient le message de statut de chargement (référence ARIA).<br/>
|
|
135
|
+
<strong>Exemple</strong>: Si vous avez <code><div id="status-msg">Chargement...</div></code>, utilisez <code>statusMessageId="status-msg"</code>
|
|
136
|
+
</td>
|
|
137
|
+
</tr>
|
|
138
|
+
</tbody>
|
|
139
|
+
</table>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div className="implementation-section">
|
|
144
|
+
<h2>Modes d'implémentation</h2>
|
|
145
|
+
|
|
146
|
+
<div className="implementation-card">
|
|
147
|
+
<h3>1. Mode Autonome (Standalone)</h3>
|
|
148
|
+
<p>
|
|
149
|
+
À utiliser lorsque vous avez besoin d'<strong>un seul</strong> squelette de chargement dans une section.
|
|
150
|
+
Ce mode annonce l'état de chargement via les attributs <code>role="alert"</code> et <code>aria-live="polite"</code>.
|
|
151
|
+
</p>
|
|
152
|
+
|
|
153
|
+
<div className="code-example">
|
|
154
|
+
<div className="preview-container">
|
|
155
|
+
<div style={{ padding: '16px', background: 'white', border: '1px solid #eaecef', borderRadius: '4px' }}>
|
|
156
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '16px' }}>
|
|
157
|
+
<div style={{ width: '200px', height: '1rem', background: '#E6E6E6', borderRadius: '35px' }}></div>
|
|
158
|
+
<span style={{ fontSize: '12px', color: '#666' }}>← Squelette avec <code>standalone</code></span>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
<div className="code-block">
|
|
164
|
+
<Source
|
|
165
|
+
language="vue"
|
|
166
|
+
dark
|
|
167
|
+
format
|
|
168
|
+
code={`<template>
|
|
169
|
+
<SyHeaderLoading
|
|
170
|
+
standalone
|
|
171
|
+
ariaLabel="Chargement en cours des informations utilisateur..."
|
|
172
|
+
width="200px"
|
|
173
|
+
/>
|
|
174
|
+
</template>`}
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<div className="implementation-card">
|
|
181
|
+
<h3>2. Mode Multiples Squelettes</h3>
|
|
182
|
+
<p>
|
|
183
|
+
À utiliser lorsque vous avez besoin de <strong>plusieurs</strong> squelettes dans la même section.
|
|
184
|
+
Dans ce cas, la responsabilité de l'accessibilité est partagée avec le développeur qui doit :
|
|
185
|
+
</p>
|
|
186
|
+
<ol>
|
|
187
|
+
<li>Ajouter <code>aria-busy="true"</code> sur le conteneur parent</li>
|
|
188
|
+
<li>Fournir un message de statut unique via un élément avec <code>role="alert"</code> et <code>aria-live="polite"</code></li>
|
|
189
|
+
</ol>
|
|
190
|
+
|
|
191
|
+
<div className="code-example">
|
|
192
|
+
<div className="preview-container">
|
|
193
|
+
<div style={{ padding: '16px', background: 'white', border: '1px solid #eaecef', borderRadius: '4px' }}>
|
|
194
|
+
<div style={{ border: '1px dashed #999', padding: '12px', marginBottom: '12px' }}>
|
|
195
|
+
<div style={{ fontSize: '12px', color: '#666', marginBottom: '8px' }}><code>aria-busy="true"</code> sur ce conteneur</div>
|
|
196
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
197
|
+
<div style={{ width: '150px', height: '1rem', background: '#E6E6E6', borderRadius: '35px' }}></div>
|
|
198
|
+
<div style={{ width: '200px', height: '1rem', background: '#E6E6E6', borderRadius: '35px' }}></div>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<div style={{ fontSize: '12px', color: '#666', padding: '4px 8px', background: '#f5f5f5', borderRadius: '4px' }}>
|
|
202
|
+
Message d'état unique pour lecteurs d'écran (invisible visuellement)
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div className="code-block">
|
|
208
|
+
<Source
|
|
209
|
+
language="vue"
|
|
210
|
+
dark
|
|
211
|
+
format
|
|
212
|
+
code={`<template>
|
|
213
|
+
<header role="banner">
|
|
214
|
+
<!-- Conteneur avec aria-busy pour indiquer le chargement -->
|
|
215
|
+
<div id="header-infos" aria-busy="true">
|
|
216
|
+
<!-- Multiples squelettes, tous avec aria-hidden="true" -->
|
|
217
|
+
<SyHeaderLoading width="150px" />
|
|
218
|
+
<SyHeaderLoading width="200px" />
|
|
219
|
+
</div>
|
|
220
|
+
</header>
|
|
221
|
+
|
|
222
|
+
<!-- Message de statut unique pour éviter la surcharge -->
|
|
223
|
+
<div role="alert" aria-live="polite" class="sr-only">
|
|
224
|
+
Chargement en cours des informations pour le header...
|
|
225
|
+
</div>
|
|
226
|
+
</template>`}
|
|
227
|
+
/>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div className="best-practices">
|
|
234
|
+
<h2>Bonnes pratiques d'utilisation</h2>
|
|
235
|
+
<ul>
|
|
236
|
+
<li><strong>Ne pas multiplier les messages de statut</strong>: La multiplication des messages de statuts complexifie la compréhension du site par les utilisateurs de technologies d'assistance.</li>
|
|
237
|
+
<li><strong>Utiliser le mode approprié</strong>: Choisir entre le mode autonome ou multiple selon le contexte d'utilisation.</li>
|
|
238
|
+
<li><strong>Messages clairs</strong>: Fournir des messages de statut informatifs et concis pour les utilisateurs de lecteurs d'écran.</li>
|
|
239
|
+
<li><strong>Contrôler le temps d'affichage</strong>: Ne pas laisser les squelettes affichés indéfiniment, prévoir un timeout raisonnable.</li>
|
|
240
|
+
</ul>
|
|
241
|
+
</div>
|
|
242
|
+
|
|
243
|
+
<div className="resources-section">
|
|
244
|
+
<h2>Ressources et références</h2>
|
|
245
|
+
<ul>
|
|
246
|
+
<li><a href="https://adrianroselli.com/2020/11/more-accessible-skeletons.html#Warning" target="_blank" rel="noopener noreferrer">More Accessible Skeletons</a> - Article critique sur l'approche de Vuetify concernant les skeleton loaders</li>
|
|
247
|
+
<li><a href="https://github.com/vuetifyjs/vuetify/issues/19622" target="_blank" rel="noopener noreferrer">Issue Vuetify #19622</a> - Concernant le support de <code>prefers-reduced-motion</code></li>
|
|
248
|
+
<li><a href="https://github.com/vuetifyjs/vuetify/issues/10999" target="_blank" rel="noopener noreferrer">Issue Vuetify #10999</a> - Concernant l'accessibilité des skeleton loaders</li>
|
|
249
|
+
<li><a href="https://www.w3.org/WAI/ARIA/apg/patterns/live-region-alert/" target="_blank" rel="noopener noreferrer">Guide WAI-ARIA pour les régions live et alertes</a></li>
|
|
250
|
+
</ul>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<div className="demo-section">
|
|
254
|
+
<h2>Démonstration interactive</h2>
|
|
255
|
+
<p>
|
|
256
|
+
Explorez ci-dessous un exemple de HeaderLoading entièrement accessible.
|
|
257
|
+
Essayez de modifier les propriétés pour voir comment le composant s'adapte.
|
|
258
|
+
</p>
|
|
259
|
+
<div className="demo-container">
|
|
260
|
+
<Canvas of={HeaderLoadingStories.Default} />
|
|
261
|
+
<Controls of={HeaderLoadingStories.Default} exclude={['heading', 'itemsNumber', 'row']} />
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
<div className="compliance-section">
|
|
266
|
+
<h2>Conformité RGAA</h2>
|
|
267
|
+
<div className="legend-container">
|
|
268
|
+
<Story of={AccessStories.Legende} />
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<h3>État de la conformité</h3>
|
|
272
|
+
<div className="compliance-status">
|
|
273
|
+
<Story of={AccessStories.AccessibilitePanel} />
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<style>
|
|
279
|
+
{`
|
|
280
|
+
.accessibility-guide {
|
|
281
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
282
|
+
max-width: 1200px;
|
|
283
|
+
margin: 0 auto;
|
|
284
|
+
padding: 20px;
|
|
285
|
+
color: #333;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
.intro-section {
|
|
289
|
+
display: flex;
|
|
290
|
+
align-items: center;
|
|
291
|
+
margin-bottom: 30px;
|
|
292
|
+
background-color: #f8f9fa;
|
|
293
|
+
padding: 20px;
|
|
294
|
+
border-radius: 8px;
|
|
295
|
+
border-left: 5px solid #0077cc;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.accessibility-icon {
|
|
299
|
+
width: 60px;
|
|
300
|
+
height: 60px;
|
|
301
|
+
margin-right: 20px;
|
|
302
|
+
flex-shrink: 0;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.intro-text {
|
|
306
|
+
font-size: 1.1em;
|
|
307
|
+
line-height: 1.6;
|
|
308
|
+
margin: 0;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.criteria-section {
|
|
312
|
+
margin-bottom: 40px;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.criteria-section h2,
|
|
316
|
+
.demo-section h2,
|
|
317
|
+
.implementation-section h2,
|
|
318
|
+
.best-practices h2,
|
|
319
|
+
.resources-section h2,
|
|
320
|
+
.compliance-section h2 {
|
|
321
|
+
border-bottom: 2px solid #eaecef;
|
|
322
|
+
padding-bottom: 10px;
|
|
323
|
+
margin-top: 30px;
|
|
324
|
+
margin-bottom: 20px;
|
|
325
|
+
color: #0077cc;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.criteria-card, .implementation-card {
|
|
329
|
+
background-color: #fff;
|
|
330
|
+
border-radius: 8px;
|
|
331
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
332
|
+
padding: 20px;
|
|
333
|
+
margin-bottom: 20px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.criteria-header {
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
margin-bottom: 15px;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.criteria-icon {
|
|
343
|
+
font-size: 1.8em;
|
|
344
|
+
margin-right: 15px;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.criteria-header h3, .implementation-card h3 {
|
|
348
|
+
margin: 0;
|
|
349
|
+
font-size: 1.3em;
|
|
350
|
+
color: #0077cc;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.criteria-card ul, .implementation-card ul {
|
|
354
|
+
margin: 0;
|
|
355
|
+
padding-left: 20px;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.criteria-card li, .implementation-card li, .best-practices li {
|
|
359
|
+
margin-bottom: 8px;
|
|
360
|
+
line-height: 1.5;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.code-example {
|
|
364
|
+
margin-top: 20px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.preview-container {
|
|
368
|
+
margin-bottom: 15px;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
.api-group {
|
|
372
|
+
margin-bottom: 30px;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.api-table {
|
|
376
|
+
width: 100%;
|
|
377
|
+
border-collapse: collapse;
|
|
378
|
+
margin-bottom: 20px;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.api-table th {
|
|
382
|
+
text-align: left;
|
|
383
|
+
padding: 10px;
|
|
384
|
+
background-color: #f0f7ff;
|
|
385
|
+
border-bottom: 2px solid #d1e5f9;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.api-table td {
|
|
389
|
+
padding: 10px;
|
|
390
|
+
border-bottom: 1px solid #eaecef;
|
|
391
|
+
vertical-align: top;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.best-practices {
|
|
395
|
+
background-color: #f5f5f5;
|
|
396
|
+
padding: 20px;
|
|
397
|
+
border-radius: 8px;
|
|
398
|
+
margin-bottom: 30px;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.resources-section {
|
|
402
|
+
background-color: #f8f9fa;
|
|
403
|
+
padding: 20px;
|
|
404
|
+
border-radius: 8px;
|
|
405
|
+
margin-bottom: 30px;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.resources-section ul, .best-practices ul {
|
|
409
|
+
padding-left: 20px;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.resources-section a {
|
|
413
|
+
color: #0077cc;
|
|
414
|
+
text-decoration: none;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.resources-section a:hover {
|
|
418
|
+
text-decoration: underline;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.demo-container {
|
|
422
|
+
background-color: #f8f9fa;
|
|
423
|
+
border-radius: 8px;
|
|
424
|
+
padding: 15px;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
code {
|
|
428
|
+
background-color: #f0f0f0;
|
|
429
|
+
padding: 2px 5px;
|
|
430
|
+
border-radius: 3px;
|
|
431
|
+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
432
|
+
font-size: 0.9em;
|
|
433
|
+
}
|
|
434
|
+
`}
|
|
435
|
+
</style>
|
|
@@ -160,6 +160,10 @@ export const Legende: StoryObj = {
|
|
|
160
160
|
</div>
|
|
161
161
|
</div>
|
|
162
162
|
</div>
|
|
163
|
+
<div class="mt-4 mb-6">
|
|
164
|
+
<p>Rapport d’audit manuel : <a href="/audits/HeaderLoding.xlsx" style="color:#0C41BD;">Voir le rapport</a></p>
|
|
165
|
+
<p style="color: grey; font-size: 14px">Correctifs associés (<a href="https://github.com/orgs/assurance-maladie-digital/projects/8/views/6?pane=issue&itemId=112098733&issue=assurance-maladie-digital%7Cdesign-system-v3%7C639" target="_blank" style="color:#0C41BD;">issue #639</a>)</p>
|
|
166
|
+
</div>
|
|
163
167
|
`,
|
|
164
168
|
}
|
|
165
169
|
},
|
|
@@ -10,11 +10,44 @@
|
|
|
10
10
|
type: String,
|
|
11
11
|
default: '1rem',
|
|
12
12
|
},
|
|
13
|
+
// Optional ID for the associated status message element
|
|
14
|
+
statusMessageId: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: undefined,
|
|
17
|
+
},
|
|
18
|
+
// Whether this is a standalone loader that should announce itself
|
|
19
|
+
standalone: {
|
|
20
|
+
type: Boolean,
|
|
21
|
+
default: false,
|
|
22
|
+
},
|
|
23
|
+
// Aria label for the standalone loader
|
|
24
|
+
ariaLabel: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: 'Chargement en cours...',
|
|
27
|
+
},
|
|
13
28
|
})
|
|
14
29
|
</script>
|
|
15
30
|
|
|
16
31
|
<template>
|
|
32
|
+
<!-- Standalone skeleton with self-announcing capability -->
|
|
33
|
+
<div
|
|
34
|
+
v-if="props.standalone"
|
|
35
|
+
role="alert"
|
|
36
|
+
aria-live="polite"
|
|
37
|
+
:aria-label="props.ariaLabel"
|
|
38
|
+
class="vd-header-loading-container"
|
|
39
|
+
>
|
|
40
|
+
<VSkeletonLoader
|
|
41
|
+
v-bind="$attrs"
|
|
42
|
+
:width="props.width"
|
|
43
|
+
:height="props.height"
|
|
44
|
+
type="heading"
|
|
45
|
+
class="vd-header-loading"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
<!-- Non-standalone skeleton (to be used with aria-busy parent and separate status message) -->
|
|
17
49
|
<VSkeletonLoader
|
|
50
|
+
v-else
|
|
18
51
|
v-bind="$attrs"
|
|
19
52
|
:width="props.width"
|
|
20
53
|
:height="props.height"
|
|
@@ -25,6 +58,10 @@
|
|
|
25
58
|
</template>
|
|
26
59
|
|
|
27
60
|
<style lang="scss" scoped>
|
|
61
|
+
.vd-header-loading-container {
|
|
62
|
+
display: inline-block;
|
|
63
|
+
}
|
|
64
|
+
|
|
28
65
|
.vd-header-loading :deep() {
|
|
29
66
|
background: transparent;
|
|
30
67
|
|
|
@@ -33,6 +70,15 @@
|
|
|
33
70
|
height: 100%;
|
|
34
71
|
border-radius: 35px;
|
|
35
72
|
margin: 0;
|
|
73
|
+
|
|
74
|
+
/* Use #E6E6E6 for a contrast ratio of ~1.5:1 against white background */
|
|
75
|
+
background-color: #e6e6e6 !important;
|
|
76
|
+
|
|
77
|
+
/* Disable animations for users who prefer reduced motion */
|
|
78
|
+
@media (prefers-reduced-motion: reduce) {
|
|
79
|
+
animation: none !important;
|
|
80
|
+
position: static !important;
|
|
81
|
+
}
|
|
36
82
|
}
|
|
37
83
|
}
|
|
38
84
|
|
|
@@ -42,4 +88,17 @@
|
|
|
42
88
|
border-radius: 0;
|
|
43
89
|
}
|
|
44
90
|
}
|
|
91
|
+
|
|
92
|
+
/* Helper class for screen reader only content */
|
|
93
|
+
.sr-only {
|
|
94
|
+
position: absolute;
|
|
95
|
+
width: 1px;
|
|
96
|
+
height: 1px;
|
|
97
|
+
padding: 0;
|
|
98
|
+
margin: -1px;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
clip: rect(0, 0, 0, 0);
|
|
101
|
+
white-space: nowrap;
|
|
102
|
+
border-width: 0;
|
|
103
|
+
}
|
|
45
104
|
</style>
|
|
@@ -121,8 +121,23 @@ Pour plus d'information sur la manière de construire un menu avec le composant
|
|
|
121
121
|
<Canvas of={HeaderNavigationBarStories.WithNavigationMenuAppendSlot} />
|
|
122
122
|
|
|
123
123
|
|
|
124
|
-
##
|
|
124
|
+
## Confirmation de changement d'onglet
|
|
125
125
|
|
|
126
|
-
Le composant `HeaderNavigationBar`
|
|
126
|
+
Le composant `HeaderNavigationBar` intègre une fonctionnalité de confirmation avant la navigation entre les onglets. Cela peut être utile pour prévenir une perte de données non sauvegardées ou pour s'assurer que l'utilisateur souhaite vraiment quitter la page actuelle.
|
|
127
|
+
|
|
128
|
+
Pour activer cette fonctionnalité, utilisez les propriétés suivantes :
|
|
129
|
+
- `confirmTabChange` : active la confirmation de changement d'onglet (booléen)
|
|
130
|
+
|
|
131
|
+
Vous pouvez intercepter l'événement `confirm-tab-change` pour implémenter votre propre logique de confirmation (par exemple, avec une boîte de dialogue personnalisée).
|
|
132
|
+
|
|
133
|
+
<Canvas of={HeaderNavigationBarStories.WithTabConfirmation} />
|
|
134
|
+
|
|
135
|
+
## Composants internes et personnalisation
|
|
136
|
+
|
|
137
|
+
> **Note importante** : Le composant `HeaderNavigationBar` utilise désormais notre composant `SyTabs` du Design System au lieu des composants `VTabs` et `VTab` de Vuetify. Ce changement permet une meilleure accessibilité et une expérience utilisateur plus cohérente avec les standards RGAA.
|
|
138
|
+
|
|
139
|
+
Vous pouvez consulter la documentation complète du composant [SyTabs](/docs/composants-customs-sytabs--docs) pour plus d'informations sur ses fonctionnalités et son API.
|
|
140
|
+
|
|
141
|
+
Pour la personnalisation des autres composants internes comme `VSheet`, vous pouvez toujours utiliser la props `vuetifyOptions`.
|
|
127
142
|
|
|
128
143
|
<Canvas of={HeaderNavigationBarStories.WithVuetifyOptions} />
|
|
@@ -247,6 +247,16 @@ const meta = {
|
|
|
247
247
|
},
|
|
248
248
|
},
|
|
249
249
|
},
|
|
250
|
+
'confirmTabChange': {
|
|
251
|
+
control: { type: 'boolean' },
|
|
252
|
+
description: 'Si activé, une confirmation sera demandée avant de changer d\'onglet',
|
|
253
|
+
table: {
|
|
254
|
+
category: 'props',
|
|
255
|
+
type: {
|
|
256
|
+
summary: 'boolean',
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
250
260
|
},
|
|
251
261
|
} satisfies Meta<typeof HeaderNavigationBar>
|
|
252
262
|
|
|
@@ -832,8 +842,8 @@ export const WithVuetifyOptions: Story = {
|
|
|
832
842
|
code: `
|
|
833
843
|
<HeaderNavigationBar
|
|
834
844
|
:items="[
|
|
835
|
-
{ label: 'Home', href: '' },
|
|
836
|
-
{ label: 'About', href: '' },
|
|
845
|
+
{ label: 'Home', href: '/home/about' },
|
|
846
|
+
{ label: 'About', href: '/about' },
|
|
837
847
|
]"
|
|
838
848
|
:vuetifyOptions="{
|
|
839
849
|
sheet: {
|
|
@@ -854,3 +864,82 @@ export const WithVuetifyOptions: Story = {
|
|
|
854
864
|
],
|
|
855
865
|
},
|
|
856
866
|
}
|
|
867
|
+
|
|
868
|
+
export const WithTabConfirmation: Story = {
|
|
869
|
+
args: {
|
|
870
|
+
items: [
|
|
871
|
+
{ label: 'Home', href: '/home' },
|
|
872
|
+
{ label: 'Test avec href', href: '/test-avec-href' },
|
|
873
|
+
{ label: 'Test sans href', href: '' },
|
|
874
|
+
],
|
|
875
|
+
confirmTabChange: true,
|
|
876
|
+
},
|
|
877
|
+
render: (args) => {
|
|
878
|
+
return {
|
|
879
|
+
components: { HeaderNavigationBar },
|
|
880
|
+
setup() {
|
|
881
|
+
const showCustomConfirmDialog = (message: string, callback: (confirmed: boolean) => void) => {
|
|
882
|
+
// Simulation d'une boîte de dialogue personnalisée
|
|
883
|
+
// Dans un cas réel, vous afficheriez votre propre composant de dialogue
|
|
884
|
+
// Pour cette démo, on utilise encore window.confirm mais avec un préfixe
|
|
885
|
+
const confirmed = window.confirm('Changer d\'onglet ?')
|
|
886
|
+
console.log('Réponse de l\'utilisateur:', confirmed ? 'Accepté' : 'Refusé')
|
|
887
|
+
callback(confirmed)
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
return { args, showCustomConfirmDialog }
|
|
891
|
+
},
|
|
892
|
+
template: `
|
|
893
|
+
<div>
|
|
894
|
+
<HeaderNavigationBar
|
|
895
|
+
v-bind="args"
|
|
896
|
+
@confirm-tab-change="showCustomConfirmDialog"
|
|
897
|
+
/>
|
|
898
|
+
<div style="padding: 20px; background-color: #f5f5f5;">
|
|
899
|
+
<p>Cette démo montre comment intercepter l'événement <code>confirm-tab-change</code> et gérer la confirmation via votre propre UI.</p>
|
|
900
|
+
<p>Cliquez sur un onglet pour voir la boîte de dialogue de confirmation.</p>
|
|
901
|
+
<p><em>Consultez la console pour voir les logs de confirmation.</em></p>
|
|
902
|
+
</div>
|
|
903
|
+
</div>
|
|
904
|
+
`,
|
|
905
|
+
}
|
|
906
|
+
},
|
|
907
|
+
parameters: {
|
|
908
|
+
sourceCode: [
|
|
909
|
+
{
|
|
910
|
+
name: 'Template',
|
|
911
|
+
code: `
|
|
912
|
+
<template>
|
|
913
|
+
<HeaderNavigationBar
|
|
914
|
+
:items="[
|
|
915
|
+
{ label: 'Home', href: '/home' },
|
|
916
|
+
{ label: 'About', href: '/about' },
|
|
917
|
+
]"
|
|
918
|
+
:confirmTabChange="true"
|
|
919
|
+
@confirm-tab-change="showCustomConfirmDialog"
|
|
920
|
+
/>
|
|
921
|
+
</template>
|
|
922
|
+
`,
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
name: 'Script',
|
|
926
|
+
code: `
|
|
927
|
+
<script setup lang="ts">
|
|
928
|
+
import { HeaderNavigationBar } from '@cnamts/synapse'
|
|
929
|
+
|
|
930
|
+
const showCustomConfirmDialog = (message: string, callback: (confirmed: boolean) => void) => {
|
|
931
|
+
// Dans un cas réel, vous afficheriez votre propre composant de dialogue modal
|
|
932
|
+
// Par exemple avec v-dialog de Vuetify
|
|
933
|
+
// Pour cette démo, on utilise encore window.confirm mais avec un préfixe
|
|
934
|
+
const confirmed = window.confirm('Changer d'onglet ?')
|
|
935
|
+
|
|
936
|
+
|
|
937
|
+
// Appel du callback avec la décision (true/false)
|
|
938
|
+
callback(confirmed)
|
|
939
|
+
}
|
|
940
|
+
</script>
|
|
941
|
+
`,
|
|
942
|
+
},
|
|
943
|
+
],
|
|
944
|
+
},
|
|
945
|
+
}
|