@cnamts/synapse 1.0.3 → 1.0.4
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-yrwJv_2R.js +95 -0
- package/dist/NumberFilter-BQXtywZI.js +117 -0
- package/dist/PeriodFilter-BYXVSzr5.js +108 -0
- package/dist/SelectFilter-CJV_mlN3.js +133 -0
- package/dist/TextFilter-DN0ejYIs.js +110 -0
- package/dist/components/Accordion/Accordion.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +5 -5
- package/dist/components/Amelipro/AmeliproIcon/AmeliproIcon.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +7 -7
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +5 -5
- package/dist/components/Amelipro/AmeliproStateTile/AmeliproStateTile.d.ts +9 -0
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +10 -10
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +1 -1
- package/dist/components/CookieBanner/CookieBanner.d.ts +302 -1
- package/dist/components/CookieBanner/config.d.ts +1 -0
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +1188 -1
- package/dist/components/CookiesSelection/CookiesSelection.d.ts +217 -0
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +1 -1
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +1 -1
- package/dist/components/DataList/DataList.d.ts +1 -1
- package/dist/components/DataListItem/DataListItem.d.ts +1 -1
- package/dist/components/DatePicker/{DatePicker → CalendarMode}/DatePicker.d.ts +15 -15
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +13 -13
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +4 -4
- package/dist/components/DatePicker/composables/useDatePickerViewMode.d.ts +2 -2
- package/dist/components/DatePicker/composables/useDatePickerVisibility.d.ts +2 -2
- package/dist/components/DatePicker/composables/useDateSelection.d.ts +1 -1
- package/dist/components/DatePicker/composables/useMonthButtonCustomization.d.ts +2 -2
- package/dist/components/DatePicker/composables/useTodayButton.d.ts +1 -1
- package/dist/components/DatePicker/composables/useWeekendDays.d.ts +1 -1
- package/dist/components/DatePicker/constants/messages.d.ts +1 -1
- package/dist/components/DatePicker/types.d.ts +2 -2
- package/dist/components/ExternalLinks/ExternalLinks.d.ts +3 -3
- package/dist/components/ExternalLinks/config.d.ts +4 -3
- package/dist/components/ExternalLinks/locales.d.ts +1 -0
- package/dist/components/NirField/NirField.d.ts +11 -11
- package/dist/components/PasswordField/PasswordField.d.ts +1 -1
- package/dist/components/PeriodField/PeriodField.d.ts +24 -24
- package/dist/components/Tables/common/locales.d.ts +5 -0
- package/dist/components/Tables/common/useTableAria.d.ts +21 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/composables/date/useDatePickerAccessibility.d.ts +2 -2
- package/dist/{style.css → design-system-v3.css} +1 -1
- package/dist/design-system-v3.js +1 -1
- package/dist/design-system-v3.umd.cjs +273 -252
- package/dist/directives/Toolbar.d.ts +15 -0
- package/dist/directives/letterSpacing.d.ts +27 -0
- package/dist/{main-DoYCrS2Q.js → main-BzyNNvHX.js} +10482 -10252
- package/package.json +12 -12
- package/src/assets/_typography.scss +22 -23
- package/src/components/Accordion/Accordion.vue +2 -2
- package/src/components/Accordion/tests/__snapshots__/accordion.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproAutoCompleteField/__tests__/__snapshots__/AmeliproAutoCompleteField.spec.ts.snap +26 -14
- package/src/components/Amelipro/AmeliproBreadcrumb/__tests__/__snapshots__/AmeliproBreadcrumb.spec.ts.snap +15 -3
- package/src/components/Amelipro/AmeliproBtn/tests/__snapshots__/AmeliproBtn.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproCallback/tests/__snapshots__/AmeliproCallback.spec.ts.snap +14 -3
- package/src/components/Amelipro/AmeliproCard/tests/__snapshots__/AmeliproCard.spec.ts.snap +9 -2
- package/src/components/Amelipro/AmeliproChips/tests/__snapshots__/AmeliproChips.spec.ts.snap +4 -1
- package/src/components/Amelipro/AmeliproDialog/tests/__snapshots__/AmeliproDialog.spec.ts.snap +9 -2
- package/src/components/Amelipro/AmeliproDisclosure/tests/__snapshots__/AmeliproDisclosure.spec.ts.snap +19 -3
- package/src/components/Amelipro/AmeliproFooter/tests/__snapshots__/AmeliproFooter.spec.ts.snap +35 -7
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/__snapshots__/AmeliproHeaderBar.spec.ts.snap +5 -2
- package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +130 -30
- package/src/components/Amelipro/AmeliproIconBtn/tests/__snapshots__/AmeliproIconBtn.spec.ts.snap +4 -1
- package/src/components/Amelipro/AmeliproIllustratedDataTile/tests/__snapshots__/AmeliproIllustratedDataTile.spec.ts.snap +4 -1
- package/src/components/Amelipro/AmeliproIllustratedRadioGroup/tests/__snapshots__/AmeliproIllustratedRadioGroup.spec.ts.snap +25 -5
- package/src/components/Amelipro/AmeliproMailTile/tests/__snapshots__/AmeliproMailTile.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproMenu/tests/__snapshots__/AmeliproMenu.spec.ts.snap +77 -15
- package/src/components/Amelipro/AmeliproMessage/tests/__snapshots__/AmeliproMessage.spec.ts.snap +11 -2
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +25 -5
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +10 -2
- package/src/components/Amelipro/AmeliproMessagingLayout/tests/__snapshots__/AmeliproMessagingLayout.spec.ts.snap +42 -8
- package/src/components/Amelipro/AmeliproMultipleFoldingCard/tests/__snapshots__/AmeliproMultipleFoldingCard.spec.ts.snap +13 -3
- package/src/components/Amelipro/AmeliproNumberedCard/tests/__snapshots__/AmeliproNumberedCard.spec.ts.snap +12 -3
- package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +195 -42
- package/src/components/Amelipro/AmeliproPagination/AmeliproPaginationBtn/tests/__snapshots__/AmeliproPaginationBtn.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproPagination/tests/__snapshots__/AmeliproPagination.spec.ts.snap +10 -2
- package/src/components/Amelipro/AmeliproPatientBanner/tests/__snapshots__/AmeliproPatientBanner.spec.ts.snap +26 -4
- package/src/components/Amelipro/AmeliproSelect/tests/__snapshots__/AmeliproSelect.spec.ts.snap +10 -11
- package/src/components/Amelipro/AmeliproStateTile/AmeliproStateTile.stories.ts +2 -0
- package/src/components/Amelipro/AmeliproStateTile/AmeliproStateTile.vue +11 -4
- package/src/components/Amelipro/AmeliproStateTile/AmeliproStateTileTypes.ts +5 -0
- package/src/components/Amelipro/AmeliproStateTile/tests/__snapshots__/AmeliproStateTile.spec.ts.snap +13 -2
- package/src/components/Amelipro/AmeliproStatus/tests/__snapshots__/AmeliproStatus.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproStepper/AmeliproStepBtn/tests/__snapshots__/AmeliproStepBtn.spec.ts.snap +7 -1
- package/src/components/Amelipro/AmeliproStepper/tests/__snapshots__/AmeliproStepper.spec.ts.snap +49 -7
- package/src/components/Amelipro/AmeliproTabs/AmeliproTabBtn/tests/__snapshots__/AmeliproTabBtn.spec.ts.snap +5 -1
- package/src/components/Amelipro/AmeliproTabs/tests/__snapshots__/AmeliproTabs.spec.ts.snap +21 -4
- package/src/components/Amelipro/AmeliproTextArea/__tests__/__snapshots__/AmeliproTextArea.spec.ts.snap +10 -11
- package/src/components/Amelipro/AmeliproTextField/tests/__snapshots__/AmeliproTextField.spec.ts.snap +10 -11
- package/src/components/Amelipro/AmeliproTileBtn/tests/__snapshots__/AmeliproTileBtn.spec.ts.snap +8 -1
- package/src/components/Amelipro/AmeliproTooltips/tests/__snapshots__/AmeliproTooltips.spec.ts.snap +11 -2
- package/src/components/Amelipro/AmeliproTransmission/tests/__snapshots__/AmeliproTransmission.spec.ts.snap +26 -5
- package/src/components/Amelipro/ServiceMenu/ServiceBtn/tests/__snapshots__/ServiceBtn.spec.ts.snap +9 -2
- package/src/components/Amelipro/ServiceMenu/ServiceList/tests/__snapshots__/ServiceList.spec.ts.snap +18 -4
- package/src/components/Amelipro/ServiceMenu/ServiceMenuContent/tests/__snapshots__/ServiceMenuContent.spec.ts.snap +69 -15
- package/src/components/Amelipro/ServiceMenu/tests/__snapshots__/ServiceMenu.spec.ts.snap +84 -19
- package/src/components/Amelipro/StructureMenu/StructureItem/tests/__snapshots__/StructureItem.spec.ts.snap +5 -1
- package/src/components/Amelipro/StructureMenu/StructureList/tests/__snapshots__/StructureList.spec.ts.snap +15 -4
- package/src/components/Amelipro/StructureMenu/StructureTabs/tests/__snapshots__/StructureTabs.spec.ts.snap +30 -8
- package/src/components/Amelipro/StructureMenu/tests/__snapshots__/StructureMenu.spec.ts.snap +72 -16
- package/src/components/Amelipro/UserMenu/tests/__snapshots__/UserMenu.spec.ts.snap +9 -2
- package/src/components/BackToTopBtn/tests/BackToTopBtn.spec.ts +53 -15
- package/src/components/BackToTopBtn/tests/__snapshots__/BackToTopBtn.spec.ts.snap +10 -2
- package/src/components/CollapsibleList/CollapsibleList.vue +5 -1
- package/src/components/CookieBanner/Accessibilite.stories.ts +4 -0
- package/src/components/CookieBanner/CookieBanner.vue +137 -10
- package/src/components/CookieBanner/config.ts +3 -0
- package/src/components/CookieBanner/tests/__snapshots__/CookieBanner.spec.ts.snap +49 -38
- package/src/components/CookiesSelection/CookiesInformation/CookiesInformation.vue +80 -2
- package/src/components/CookiesSelection/CookiesSelection.vue +15 -2
- package/src/components/CookiesSelection/tests/__snapshots__/CookiesSelection.spec.ts.snap +49 -34
- package/src/components/CopyBtn/tests/__snapshots__/CopyBtn.spec.ts.snap +1 -1
- package/src/components/Customs/Selects/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +58 -13
- package/src/components/Customs/Selects/SySelect/SySelect.vue +144 -147
- package/src/components/DatePicker/{DatePicker → CalendarMode}/DatePicker.stories.ts +3 -3
- package/src/components/DatePicker/{DatePicker → CalendarMode}/DatePicker.vue +4 -4
- package/src/components/DatePicker/{DatePicker → CalendarMode}/tests/DatePicker.events.spec.ts +1 -1
- package/src/components/DatePicker/{DatePicker → CalendarMode}/tests/DatePicker.spec.ts +4 -4
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.mdx +1 -1
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +3 -3
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +6 -6
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +3 -3
- package/src/components/DatePicker/DatePickerOverview.mdx +1 -1
- package/src/components/DatePicker/DatePickerValidationExample/DatePickerValidation.stories.ts +1 -1
- package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +76 -3
- package/src/components/DatePicker/DateTextInput/NoCalendar.mdx +1 -1
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +1 -1
- package/src/components/DatePicker/composables/index.ts +2 -2
- package/src/components/DatePicker/composables/tests/useDatePickerVisibility.spec.ts +14 -14
- package/src/components/DatePicker/composables/useDatePickerViewMode.ts +4 -4
- package/src/components/DatePicker/composables/useDatePickerVisibility.ts +12 -12
- package/src/components/DatePicker/composables/useDateSelection.ts +1 -1
- package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +3 -3
- package/src/components/DatePicker/composables/useTodayButton.ts +1 -1
- package/src/components/DatePicker/composables/useWeekendDays.ts +1 -1
- package/src/components/DatePicker/constants/messages.ts +1 -1
- package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +2 -2
- package/src/components/DatePicker/docExamples/DatePickerValidationExamples.vue +1 -1
- package/src/components/DatePicker/types.ts +2 -2
- package/src/components/DialogBox/tests/DialogBox.spec.ts +26 -4
- package/src/components/DialogBox/tests/__snapshots__/DialogBox.spec.ts.snap +13 -3
- package/src/components/DownloadBtn/tests/__snapshots__/DownloadBtn.spec.ts.snap +8 -2
- package/src/components/ErrorPage/tests/__snapshots__/ErrorPage.spec.ts.snap +18 -4
- package/src/components/ExternalLinks/Accessibilite.mdx +4 -1
- package/src/components/ExternalLinks/Accessibilite.stories.ts +34 -0
- package/src/components/ExternalLinks/ExternalLinks.stories.ts +1 -3
- package/src/components/ExternalLinks/ExternalLinks.vue +96 -41
- package/src/components/ExternalLinks/config.ts +5 -4
- package/src/components/ExternalLinks/locales.ts +1 -0
- package/src/components/ExternalLinks/tests/ExternalLinks.spec.ts +3 -3
- package/src/components/ExternalLinks/tests/__snapshots__/ExternalLinks.spec.ts.snap +510 -400
- package/src/components/FilterInline/tests/__snapshots__/FilterInline.spec.ts.snap +3 -3
- package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +15 -6
- package/src/components/FooterBar/Accessibilite.stories.ts +4 -0
- package/src/components/FooterBar/FooterBar.vue +9 -5
- package/src/components/FooterBar/tests/__snapshots__/FooterBar.spec.ts.snap +0 -5
- package/src/components/FranceConnectBtn/tests/__snapshots__/FranceConnectBtn.spec.ts.snap +15 -3
- package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/HeaderBurgerMenu.spec.ts.snap +5 -1
- package/src/components/HeaderBar/HeaderLogo/tests/HeaderLogo.spec.ts +31 -6
- package/src/components/HeaderBar/tests/__snapshots__/HeaderBar.spec.ts.snap +7 -1
- package/src/components/HeaderBar/tests/useHeaderResponsiveMode.spec.ts +63 -5
- package/src/components/NirField/NirField.vue +41 -1
- package/src/components/NirField/tests/NirField.spec.ts +2 -2
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +18 -4
- package/src/components/PeriodField/PeriodField.vue +3 -3
- package/src/components/RangeField/RangeSlider/tests/__snapshots__/rangeSlider.spec.ts.snap +12 -3
- package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +132 -111
- package/src/components/RatingPicker/EmotionPicker/tests/__snapshots__/EmotionPicker.spec.ts.snap +66 -31
- package/src/components/RatingPicker/NumberPicker/tests/__snapshots__/NumberPicker.spec.ts.snap +33 -33
- package/src/components/RatingPicker/StarsPicker/tests/__snapshots__/StarsPicker.spec.ts.snap +43 -23
- package/src/components/RatingPicker/tests/__snapshots__/RatingPicker.spec.ts.snap +33 -33
- package/src/components/SyAlert/tests/__snapshots__/SyAlert.spec.ts.snap +5 -1
- package/src/components/TableToolbar/tests/__snapshots__/TableToolbar.spec.ts.snap +107 -95
- package/src/components/Tables/SyServerTable/SyServerTable.vue +43 -2
- package/src/components/Tables/SyTable/SyTable.vue +45 -7
- package/src/components/Tables/common/SyTablePagination.vue +10 -6
- package/src/components/Tables/common/filters/DateFilter.vue +1 -1
- package/src/components/Tables/common/filters/SelectFilter.vue +1 -2
- package/src/components/Tables/common/filters/tests/DateFilter.spec.ts +2 -2
- package/src/components/Tables/common/locales.ts +7 -0
- package/src/components/Tables/common/useTableAria.ts +279 -0
- package/src/components/ToolbarContainer/ToolbarContainer.vue +4 -4
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +17 -5
- package/src/components/index.ts +1 -1
- package/src/composables/date/tests/useDatePickerAccessibility.spec.ts +1 -1
- package/src/composables/date/useDateInitialization.ts +1 -1
- package/src/composables/date/useDateInitializationDayjs.ts +1 -1
- package/src/composables/date/useDatePickerAccessibility.ts +5 -5
- package/src/composables/useFilterable/useFilterable.spec.ts +10 -2
- package/src/designTokens/utils/createFontVariables.ts +6 -6
- package/src/directives/Toolbar.ts +172 -0
- package/src/directives/letterSpacing.ts +233 -0
- package/src/stories/Accessibilite/Avancement/Avancement.mdx +6 -6
- package/src/stories/Accessibilite/Avancement/Avancement.stories.ts +10 -9
- package/src/utils/functions/throttleDisplayFn/tests/throttleDisplayFn.spec.ts +27 -2
- package/src/utils/rules/isHolidayDay/IsHolidayDay.stories.ts +2 -2
- package/dist/DateFilter-DFKfon7L.js +0 -98
- package/dist/NumberFilter-DmhIL2Pr.js +0 -121
- package/dist/PeriodFilter-C46V6bYN.js +0 -112
- package/dist/SelectFilter-B8dtHtHo.js +0 -136
- package/dist/TextFilter-COKGday2.js +0 -114
- package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +0 -173
- package/src/components/SocialMediaLinks/tests/__snapshots__/SocialMediaLinks.spec.ts.snap +0 -186
- /package/src/components/DatePicker/{DatePicker → CalendarMode}/DatePicker.mdx +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { Directive } from 'vue'
|
|
2
|
+
|
|
3
|
+
type Instance = {
|
|
4
|
+
tools: HTMLElement[]
|
|
5
|
+
lastElementFocused?: HTMLElement
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const toolbarInstances = new WeakMap<HTMLElement, Instance>()
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This directive implements the "roving tabindex" pattern for accessible toolbars.
|
|
12
|
+
*
|
|
13
|
+
* example usage:
|
|
14
|
+
* <div v-toolbar role="toolbar">
|
|
15
|
+
* <button>Tool 1</button>
|
|
16
|
+
* <button>Tool 2</button>
|
|
17
|
+
* <a href="#">Tool 3</a>
|
|
18
|
+
* </div>
|
|
19
|
+
*
|
|
20
|
+
* The directive allows keyboard navigation through the toolbar's tools using arrow keys,
|
|
21
|
+
* home, and end keys, while managing focus and tabindex attributes for accessibility.
|
|
22
|
+
*/
|
|
23
|
+
export const vToolbar: Directive = {
|
|
24
|
+
mounted(el: HTMLElement) {
|
|
25
|
+
el.setAttribute('role', 'toolbar') // Required on firefox to capture arrow keys!
|
|
26
|
+
el.setAttribute('tabindex', '0')
|
|
27
|
+
|
|
28
|
+
const tools = Array.from(el.querySelectorAll<HTMLElement>('button:not([disabled]), a:not([disabled]), input:not([disabled])') || [])
|
|
29
|
+
|
|
30
|
+
toolbarInstances.set(el, {
|
|
31
|
+
tools: tools,
|
|
32
|
+
lastElementFocused: undefined,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
tools.forEach((el) => {
|
|
36
|
+
el.setAttribute('tabindex', '-1')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
el.addEventListener('keydown', (event: KeyboardEvent) => {
|
|
40
|
+
const instance = toolbarInstances.get(el)
|
|
41
|
+
|
|
42
|
+
if (!instance) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
switch (event.key) {
|
|
47
|
+
case 'ArrowRight':
|
|
48
|
+
case 'ArrowDown':
|
|
49
|
+
selectNextElement(event as KeyboardEvent & { target: HTMLElement }, instance.tools)
|
|
50
|
+
break
|
|
51
|
+
case 'ArrowLeft':
|
|
52
|
+
case 'ArrowUp':
|
|
53
|
+
selectPrevElement(event as KeyboardEvent & { target: HTMLElement }, instance.tools)
|
|
54
|
+
break
|
|
55
|
+
case 'Home':
|
|
56
|
+
selectFirstElement(instance.tools)
|
|
57
|
+
break
|
|
58
|
+
case 'End':
|
|
59
|
+
selectLastElement(instance.tools)
|
|
60
|
+
break
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
el.addEventListener('focus', () => {
|
|
65
|
+
const instance = toolbarInstances.get(el)
|
|
66
|
+
|
|
67
|
+
if (!instance) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setupFocus(el, instance)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
el.addEventListener('focusin', (e: FocusEvent) => {
|
|
75
|
+
const instance = toolbarInstances.get(el)
|
|
76
|
+
if (!instance) {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
saveFocus(e, instance)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
el.addEventListener('focusout', (e: FocusEvent) => {
|
|
84
|
+
const instance = toolbarInstances.get(el)
|
|
85
|
+
if (!instance) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
blurToolbar(e, el)
|
|
90
|
+
})
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
unmounted(el: HTMLElement) {
|
|
94
|
+
toolbarInstances.delete(el)
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function selectNextElement(e: Event & { target: HTMLElement }, tools: HTMLElement[]) {
|
|
99
|
+
const currentIndex = tools.findIndex(tool => tool === e.target)
|
|
100
|
+
|
|
101
|
+
const nextIndex = currentIndex < tools.length - 1 ? currentIndex + 1 : 0
|
|
102
|
+
|
|
103
|
+
const nextElem = tools.at(nextIndex)
|
|
104
|
+
|
|
105
|
+
e.target.setAttribute('tabindex', '-1')
|
|
106
|
+
nextElem?.setAttribute('tabindex', '0')
|
|
107
|
+
nextElem?.focus()
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function selectPrevElement(e: Event & { target: HTMLElement }, tools: HTMLElement[]) {
|
|
111
|
+
const currentIndex = tools.findIndex(tool => tool === e.target)
|
|
112
|
+
|
|
113
|
+
const prevIndex = currentIndex > 0 ? currentIndex - 1 : tools.length - 1
|
|
114
|
+
|
|
115
|
+
const nextElem = tools.at(prevIndex)
|
|
116
|
+
|
|
117
|
+
e.target.setAttribute('tabindex', '-1')
|
|
118
|
+
nextElem?.setAttribute('tabindex', '0')
|
|
119
|
+
nextElem?.focus()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function selectFirstElement(tools: HTMLElement[]) {
|
|
123
|
+
const firstElement = tools.at(0)
|
|
124
|
+
if (!firstElement) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
document.activeElement?.setAttribute('tabindex', '-1')
|
|
128
|
+
firstElement.setAttribute('tabindex', '0')
|
|
129
|
+
firstElement.focus()
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function selectLastElement(tools: HTMLElement[]) {
|
|
133
|
+
const lastElement = tools.at(-1)
|
|
134
|
+
if (!lastElement) {
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
document.activeElement?.setAttribute('tabindex', '-1')
|
|
138
|
+
lastElement.setAttribute('tabindex', '0')
|
|
139
|
+
lastElement.focus()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function setupFocus(toolbar: HTMLElement, instance: Instance) {
|
|
143
|
+
// Remove the ability to tab into the toolbar to be able to shift focus to previous focusable element
|
|
144
|
+
toolbar?.setAttribute('tabindex', '-1')
|
|
145
|
+
|
|
146
|
+
if (instance.lastElementFocused) {
|
|
147
|
+
// If there is a last focused element, restore focus to it
|
|
148
|
+
instance.lastElementFocused.setAttribute('tabindex', '0')
|
|
149
|
+
instance.lastElementFocused.focus()
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
selectFirstElement(instance.tools)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function saveFocus(e: FocusEvent, instance: Instance) {
|
|
157
|
+
// Save the last focused element to restore focus later
|
|
158
|
+
if (e.target !== e.currentTarget) {
|
|
159
|
+
instance.lastElementFocused = e.target as HTMLElement
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function blurToolbar(e: FocusEvent, toolbar: HTMLElement) {
|
|
164
|
+
// When an item of the toolbar is blured it should not be focusable anymore
|
|
165
|
+
(e.target as HTMLElement)?.setAttribute('tabindex', '-1')
|
|
166
|
+
|
|
167
|
+
// When the toolbar loses focus, we need to set its focusable
|
|
168
|
+
if (toolbar?.contains(e.relatedTarget as HTMLElement)) {
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
toolbar?.setAttribute('tabindex', '0')
|
|
172
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type { Directive, DirectiveBinding } from 'vue'
|
|
2
|
+
|
|
3
|
+
interface LetterSpacingOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Whether to apply to all typography elements or only specific selectors
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
applyToAll?: boolean
|
|
9
|
+
/**
|
|
10
|
+
* Specific selectors to target (if applyToAll is false)
|
|
11
|
+
*/
|
|
12
|
+
selectors?: string[]
|
|
13
|
+
/**
|
|
14
|
+
* Whether to observe DOM changes for dynamic content
|
|
15
|
+
* @default true
|
|
16
|
+
*/
|
|
17
|
+
observeChanges?: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Find and modify Vuetify's CSS rules to remove !important from letter-spacing
|
|
22
|
+
*/
|
|
23
|
+
function modifyVuetifyStylesheets(): void {
|
|
24
|
+
try {
|
|
25
|
+
// Get all stylesheets
|
|
26
|
+
const stylesheets = Array.from(document.styleSheets)
|
|
27
|
+
|
|
28
|
+
stylesheets.forEach((stylesheet, index) => {
|
|
29
|
+
try {
|
|
30
|
+
// Try to access rules (may fail for cross-origin stylesheets)
|
|
31
|
+
const rules = Array.from(stylesheet.cssRules || stylesheet.rules || [])
|
|
32
|
+
|
|
33
|
+
rules.forEach((rule) => {
|
|
34
|
+
if (rule instanceof CSSStyleRule) {
|
|
35
|
+
// Check if this rule affects typography classes
|
|
36
|
+
const typographyClasses = ['.text-h1', '.text-h2', '.text-h3', '.text-h4', '.text-h5', '.text-h6', '.text-body-1', '.text-body-2', '.text-subtitle-1', '.text-subtitle-2', '.text-caption', '.text-overline', '.text-button']
|
|
37
|
+
|
|
38
|
+
const matchesTypography = typographyClasses.some(cls => rule.selectorText?.includes(cls))
|
|
39
|
+
|
|
40
|
+
if (matchesTypography && rule.style.letterSpacing) {
|
|
41
|
+
// Try to modify the rule
|
|
42
|
+
try {
|
|
43
|
+
rule.style.setProperty('letter-spacing', '0px', '')
|
|
44
|
+
}
|
|
45
|
+
catch (modifyError) {
|
|
46
|
+
console.log(`Could not modify rule: ${rule.selectorText}`, modifyError)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
catch (accessError: unknown) {
|
|
53
|
+
// Stylesheet is cross-origin or inaccessible
|
|
54
|
+
const errorMessage = accessError instanceof Error ? accessError.message : String(accessError)
|
|
55
|
+
console.log(`Cannot access stylesheet ${index}:`, errorMessage)
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Error modifying Vuetify stylesheets:', error)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Inject CSS with !important to override Vuetify, but using CSS custom properties
|
|
66
|
+
*/
|
|
67
|
+
function injectOverrideCSS(): void {
|
|
68
|
+
const styleId = 'letter-spacing-override-styles'
|
|
69
|
+
|
|
70
|
+
// Remove existing style element if it exists
|
|
71
|
+
const existingStyle = document.getElementById(styleId)
|
|
72
|
+
if (existingStyle) {
|
|
73
|
+
existingStyle.remove()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Create new style element
|
|
77
|
+
const styleElement = document.createElement('style')
|
|
78
|
+
styleElement.id = styleId
|
|
79
|
+
styleElement.type = 'text/css'
|
|
80
|
+
|
|
81
|
+
// Use high specificity selectors without !important
|
|
82
|
+
const cssRules = `
|
|
83
|
+
/* Override Vuetify letter-spacing with high specificity and CSS custom properties */
|
|
84
|
+
.v-application .v-application .text-h1 { letter-spacing: var(--v-typography-h1-letter-spacing, 0px); }
|
|
85
|
+
.v-application .v-application .text-h2 { letter-spacing: var(--v-typography-h2-letter-spacing, 0px); }
|
|
86
|
+
.v-application .v-application .text-h3 { letter-spacing: var(--v-typography-h3-letter-spacing, 0px); }
|
|
87
|
+
.v-application .v-application .text-h4 { letter-spacing: var(--v-typography-h4-letter-spacing, 0px); }
|
|
88
|
+
.v-application .v-application .text-h5 { letter-spacing: var(--v-typography-h5-letter-spacing, 0px); }
|
|
89
|
+
.v-application .v-application .text-h6 { letter-spacing: var(--v-typography-h6-letter-spacing, 0px); }
|
|
90
|
+
.v-application .v-application .text-body-1 { letter-spacing: var(--v-typography-body1-letter-spacing, 0px); }
|
|
91
|
+
.v-application .v-application .text-body-2 { letter-spacing: var(--v-typography-body2-letter-spacing, 0px); }
|
|
92
|
+
.v-application .v-application .text-subtitle-1 { letter-spacing: var(--v-typography-subtitle1-letter-spacing, 0px); }
|
|
93
|
+
.v-application .v-application .text-subtitle-2 { letter-spacing: var(--v-typography-subtitle2-letter-spacing, 0px); }
|
|
94
|
+
.v-application .v-application .text-caption { letter-spacing: var(--v-typography-caption-letter-spacing, 0px); }
|
|
95
|
+
.v-application .v-application .text-overline { letter-spacing: var(--v-typography-overline-letter-spacing, 0px); }
|
|
96
|
+
.v-application .v-application .text-button { letter-spacing: var(--v-typography-button-letter-spacing, 0px); }
|
|
97
|
+
.v-application .v-application h1 { letter-spacing: var(--v-typography-h1-letter-spacing, 0px); }
|
|
98
|
+
.v-application .v-application h2 { letter-spacing: var(--v-typography-h2-letter-spacing, 0px); }
|
|
99
|
+
.v-application .v-application h3 { letter-spacing: var(--v-typography-h3-letter-spacing, 0px); }
|
|
100
|
+
.v-application .v-application h4 { letter-spacing: var(--v-typography-h4-letter-spacing, 0px); }
|
|
101
|
+
.v-application .v-application h5 { letter-spacing: var(--v-typography-h5-letter-spacing, 0px); }
|
|
102
|
+
.v-application .v-application h6 { letter-spacing: var(--v-typography-h6-letter-spacing, 0px); }
|
|
103
|
+
`
|
|
104
|
+
|
|
105
|
+
styleElement.textContent = cssRules
|
|
106
|
+
|
|
107
|
+
// Append to head
|
|
108
|
+
document.head.appendChild(styleElement)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Apply design token letter-spacing values using multiple approaches
|
|
113
|
+
*/
|
|
114
|
+
function applyTokenLetterSpacing(element: HTMLElement): void {
|
|
115
|
+
// Try to modify existing Vuetify stylesheets first
|
|
116
|
+
modifyVuetifyStylesheets()
|
|
117
|
+
|
|
118
|
+
// Inject override CSS with !important but using CSS custom properties
|
|
119
|
+
injectOverrideCSS()
|
|
120
|
+
|
|
121
|
+
// Set CSS variables with design token values
|
|
122
|
+
const rootElement = document.documentElement
|
|
123
|
+
const rootStyle = getComputedStyle(rootElement)
|
|
124
|
+
|
|
125
|
+
// List of all typography CSS variables to set
|
|
126
|
+
const typographyVars = [
|
|
127
|
+
'--v-typography-h1-letter-spacing',
|
|
128
|
+
'--v-typography-h2-letter-spacing',
|
|
129
|
+
'--v-typography-h3-letter-spacing',
|
|
130
|
+
'--v-typography-h4-letter-spacing',
|
|
131
|
+
'--v-typography-h5-letter-spacing',
|
|
132
|
+
'--v-typography-h6-letter-spacing',
|
|
133
|
+
'--v-typography-body1-letter-spacing',
|
|
134
|
+
'--v-typography-body2-letter-spacing',
|
|
135
|
+
'--v-typography-subtitle1-letter-spacing',
|
|
136
|
+
'--v-typography-subtitle2-letter-spacing',
|
|
137
|
+
'--v-typography-caption-letter-spacing',
|
|
138
|
+
'--v-typography-overline-letter-spacing',
|
|
139
|
+
'--v-typography-button-letter-spacing',
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
// Set each CSS variable with design token values
|
|
143
|
+
typographyVars.forEach((cssVar) => {
|
|
144
|
+
const tokenValue = rootStyle.getPropertyValue(cssVar).trim()
|
|
145
|
+
const finalValue = tokenValue || '0px'
|
|
146
|
+
|
|
147
|
+
rootElement.style.setProperty(cssVar, finalValue)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Add debugging attributes
|
|
151
|
+
element.setAttribute('data-letter-spacing-override', 'multi-approach')
|
|
152
|
+
element.setAttribute('data-letter-spacing-timestamp', Date.now().toString())
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Vue directive to override Vuetify's !important letter-spacing with design token values
|
|
157
|
+
*
|
|
158
|
+
* Usage:
|
|
159
|
+
* - v-letter-spacing (applies to all typography elements)
|
|
160
|
+
* - v-letter-spacing="{ applyToAll: false, selectors: ['.text-h1', '.text-h2'] }"
|
|
161
|
+
* - v-letter-spacing="{ observeChanges: false }" (disable mutation observer)
|
|
162
|
+
*/
|
|
163
|
+
export const vLetterSpacing: Directive<HTMLElement, LetterSpacingOptions | boolean> = {
|
|
164
|
+
mounted(el: HTMLElement, binding: DirectiveBinding<LetterSpacingOptions | boolean>) {
|
|
165
|
+
const options: LetterSpacingOptions = typeof binding.value === 'boolean'
|
|
166
|
+
? { applyToAll: binding.value }
|
|
167
|
+
: { applyToAll: true, observeChanges: true, ...binding.value }
|
|
168
|
+
|
|
169
|
+
// Apply letter-spacing override immediately
|
|
170
|
+
applyTokenLetterSpacing(el)
|
|
171
|
+
|
|
172
|
+
// Set up mutation observer if enabled
|
|
173
|
+
if (options.observeChanges !== false) {
|
|
174
|
+
const observer = new MutationObserver((mutations) => {
|
|
175
|
+
let shouldReapply = false
|
|
176
|
+
|
|
177
|
+
mutations.forEach((mutation) => {
|
|
178
|
+
// Check if new nodes were added
|
|
179
|
+
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
|
180
|
+
shouldReapply = true
|
|
181
|
+
}
|
|
182
|
+
// Check if class attributes changed
|
|
183
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
|
184
|
+
shouldReapply = true
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
if (shouldReapply) {
|
|
189
|
+
applyTokenLetterSpacing(el)
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
observer.observe(el, {
|
|
194
|
+
childList: true,
|
|
195
|
+
subtree: true,
|
|
196
|
+
attributes: true,
|
|
197
|
+
attributeFilter: ['class'],
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
// Store observer reference for cleanup
|
|
201
|
+
;(el as HTMLElement & { _letterSpacingObserver?: MutationObserver })._letterSpacingObserver = observer
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
updated(el: HTMLElement) {
|
|
206
|
+
// Reapply letter-spacing override when component updates
|
|
207
|
+
applyTokenLetterSpacing(el)
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
beforeUnmount(el: HTMLElement) {
|
|
211
|
+
// Clean up mutation observer
|
|
212
|
+
const observer = (el as HTMLElement & { _letterSpacingObserver?: MutationObserver })._letterSpacingObserver
|
|
213
|
+
if (observer) {
|
|
214
|
+
observer.disconnect()
|
|
215
|
+
delete (el as HTMLElement & { _letterSpacingObserver?: MutationObserver })._letterSpacingObserver
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Remove override attributes
|
|
219
|
+
const elements = el.querySelectorAll('[data-letter-spacing-override]')
|
|
220
|
+
elements.forEach((element) => {
|
|
221
|
+
element.removeAttribute('data-letter-spacing-override')
|
|
222
|
+
element.removeAttribute('data-letter-spacing-timestamp')
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// Clean up the main element if it has the override
|
|
226
|
+
if (el.hasAttribute('data-letter-spacing-override')) {
|
|
227
|
+
el.removeAttribute('data-letter-spacing-override')
|
|
228
|
+
el.removeAttribute('data-letter-spacing-timestamp')
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export default vLetterSpacing
|
|
@@ -187,11 +187,11 @@ import * as AvancementStories from './Avancement.stories';
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
.stat-success {
|
|
190
|
-
color: #
|
|
190
|
+
color: #56C271;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
.stat-
|
|
194
|
-
color: #
|
|
193
|
+
.stat-wip {
|
|
194
|
+
color: #A05BB6;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
.stat-info {
|
|
@@ -513,12 +513,12 @@ import * as AvancementStories from './Avancement.stories';
|
|
|
513
513
|
<p className="stat-label">Progression dans l'audit des composants du Design System</p>
|
|
514
514
|
<div className="progress-stats">
|
|
515
515
|
<div className="stat-item">
|
|
516
|
-
<span className="stat-value stat-success">
|
|
516
|
+
<span className="stat-value stat-success">21</span>
|
|
517
517
|
<span className="stat-label">Composants audités</span>
|
|
518
518
|
</div>
|
|
519
519
|
<div className="stat-item">
|
|
520
|
-
<span className="stat-value stat-
|
|
521
|
-
<span className="stat-label">
|
|
520
|
+
<span className="stat-value stat-wip">3</span>
|
|
521
|
+
<span className="stat-label">En cours</span>
|
|
522
522
|
</div>
|
|
523
523
|
<div className="stat-item">
|
|
524
524
|
<span className="stat-value stat-info">60</span>
|
|
@@ -42,9 +42,9 @@ export const Manuel: StoryObj = {
|
|
|
42
42
|
{ composant: 'PageContainer', status: 'Audité' },
|
|
43
43
|
{ composant: 'SkipLink', status: 'Audité' },
|
|
44
44
|
{ composant: 'Alerts', status: 'Audité' },
|
|
45
|
-
{ composant: 'NotificationBar', status: '
|
|
45
|
+
{ composant: 'NotificationBar', status: 'Non audité' },
|
|
46
46
|
{ composant: 'BackBtn', status: 'Audité' },
|
|
47
|
-
{ composant: 'BackToTopBtn', status: '
|
|
47
|
+
{ composant: 'BackToTopBtn', status: 'Audité' },
|
|
48
48
|
{ composant: 'CopyBtn', status: 'Audité' },
|
|
49
49
|
{ composant: 'LangBtn', status: 'Audité' },
|
|
50
50
|
{ composant: 'DownloadBtn', status: 'Audité' },
|
|
@@ -52,7 +52,7 @@ export const Manuel: StoryObj = {
|
|
|
52
52
|
{ composant: 'SyTextField', status: 'Audité' },
|
|
53
53
|
{ composant: 'HeaderBar', status: 'Non audité' },
|
|
54
54
|
{ composant: 'HeaderNavigationBar', status: 'Non audité' },
|
|
55
|
-
{ composant: 'LogoBrandSection', status: '
|
|
55
|
+
{ composant: 'LogoBrandSection', status: 'En cours' },
|
|
56
56
|
{ composant: 'SubHeader', status: 'Non audité' },
|
|
57
57
|
{ composant: 'HeaderLoading', status: 'Non audité' },
|
|
58
58
|
{ composant: 'HeaderToolbar', status: 'Non audité' },
|
|
@@ -65,9 +65,8 @@ export const Manuel: StoryObj = {
|
|
|
65
65
|
{ composant: 'DataListItem', status: 'Non audité' },
|
|
66
66
|
{ composant: 'DataListLoading', status: 'Non audité' },
|
|
67
67
|
{ composant: 'ErrorPage', status: 'Audité' },
|
|
68
|
-
{ composant: 'CookieBanner', status: '
|
|
69
|
-
{ composant: '
|
|
70
|
-
{ composant: 'ContextualMenu', status: 'En cours' },
|
|
68
|
+
{ composant: 'CookieBanner', status: 'Audité' },
|
|
69
|
+
{ composant: 'ContextualMenu', status: 'Audité' },
|
|
71
70
|
{ composant: 'DialogBox', status: 'Non audité' },
|
|
72
71
|
{ composant: 'PasswordField', status: 'Non audité' },
|
|
73
72
|
{ composant: 'PhoneField', status: 'Non audité' },
|
|
@@ -92,9 +91,11 @@ export const Manuel: StoryObj = {
|
|
|
92
91
|
{ composant: 'ErrorPage', status: 'Audité' },
|
|
93
92
|
{ composant: 'NotFoundPage', status: 'Audité' },
|
|
94
93
|
{ composant: 'MaintenancePage', status: 'Audité' },
|
|
95
|
-
{ composant: 'ContextualMenu', status: '
|
|
96
|
-
{ composant: 'ExternalLinks', status: '
|
|
94
|
+
{ composant: 'ContextualMenu', status: 'Audité' },
|
|
95
|
+
{ composant: 'ExternalLinks', status: 'Audité' },
|
|
97
96
|
{ composant: 'SyIcon', status: 'Non audité' },
|
|
97
|
+
{ composant: 'SocialMediaLinks', status: 'Audité' },
|
|
98
|
+
{ composant: 'CollapsibleList', status: 'Audité' },
|
|
98
99
|
]
|
|
99
100
|
|
|
100
101
|
// Options de filtrage par statut
|
|
@@ -225,7 +226,7 @@ export const Manuel: StoryObj = {
|
|
|
225
226
|
</div>
|
|
226
227
|
|
|
227
228
|
<div class="pa-2 text-caption text-right">
|
|
228
|
-
Dernière mise à jour:
|
|
229
|
+
Dernière mise à jour: 18/07/2025
|
|
229
230
|
</div>
|
|
230
231
|
</div>
|
|
231
232
|
</div>
|
|
@@ -2,15 +2,31 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
2
2
|
import throttleDisplayFn from '../throttleDisplayFn'
|
|
3
3
|
|
|
4
4
|
describe('throttleDisplayFn', () => {
|
|
5
|
-
|
|
5
|
+
let mockPerformanceNow: ReturnType<typeof vi.fn>
|
|
6
|
+
let mockRequestAnimationFrame: ReturnType<typeof vi.fn>
|
|
6
7
|
|
|
7
8
|
beforeEach(() => {
|
|
8
9
|
vi.useFakeTimers()
|
|
10
|
+
|
|
11
|
+
// Mock performance.now to return a controllable time
|
|
12
|
+
mockPerformanceNow = vi.fn(() => 0)
|
|
13
|
+
vi.stubGlobal('performance', { now: mockPerformanceNow })
|
|
14
|
+
|
|
15
|
+
// Mock window.requestAnimationFrame to execute immediately
|
|
16
|
+
mockRequestAnimationFrame = vi.fn((fn: () => void) => {
|
|
17
|
+
fn()
|
|
18
|
+
return 1
|
|
19
|
+
})
|
|
20
|
+
Object.defineProperty(window, 'requestAnimationFrame', {
|
|
21
|
+
value: mockRequestAnimationFrame,
|
|
22
|
+
writable: true,
|
|
23
|
+
})
|
|
9
24
|
})
|
|
10
25
|
|
|
11
26
|
afterEach(() => {
|
|
12
27
|
vi.restoreAllMocks()
|
|
13
28
|
vi.clearAllTimers()
|
|
29
|
+
vi.useRealTimers()
|
|
14
30
|
})
|
|
15
31
|
|
|
16
32
|
it('should call the function immediately if delay has passed', () => {
|
|
@@ -18,10 +34,13 @@ describe('throttleDisplayFn', () => {
|
|
|
18
34
|
const delay = 100
|
|
19
35
|
const throttledFn = throttleDisplayFn(mockFn, delay)
|
|
20
36
|
|
|
37
|
+
// First call should execute immediately (lastCalled starts at 0)
|
|
38
|
+
mockPerformanceNow.mockReturnValue(delay + 1) // Ensure delay condition is met
|
|
21
39
|
throttledFn()
|
|
22
40
|
expect(mockFn).toHaveBeenCalledTimes(1)
|
|
23
41
|
|
|
24
|
-
|
|
42
|
+
// Simulate more time passing beyond the delay
|
|
43
|
+
mockPerformanceNow.mockReturnValue(delay * 2 + 1)
|
|
25
44
|
throttledFn()
|
|
26
45
|
expect(mockFn).toHaveBeenCalledTimes(2)
|
|
27
46
|
})
|
|
@@ -31,17 +50,23 @@ describe('throttleDisplayFn', () => {
|
|
|
31
50
|
const delay = 100
|
|
32
51
|
const throttledFn = throttleDisplayFn(mockFn, delay)
|
|
33
52
|
|
|
53
|
+
// First call should execute immediately (lastCalled starts at 0)
|
|
54
|
+
mockPerformanceNow.mockReturnValue(delay + 1) // Ensure delay condition is met
|
|
34
55
|
throttledFn()
|
|
35
56
|
expect(mockFn).toHaveBeenCalledTimes(1)
|
|
36
57
|
|
|
58
|
+
// Subsequent calls within delay should be throttled
|
|
59
|
+
mockPerformanceNow.mockReturnValue(delay + 50) // Still within delay from last call
|
|
37
60
|
throttledFn()
|
|
38
61
|
throttledFn()
|
|
39
62
|
|
|
63
|
+
// Should still only have been called once
|
|
40
64
|
expect(mockFn).toHaveBeenCalledTimes(1)
|
|
41
65
|
|
|
42
66
|
// Advance timers to trigger the setTimeout
|
|
43
67
|
vi.advanceTimersByTime(delay)
|
|
44
68
|
|
|
69
|
+
// Now the setTimeout should have executed the function
|
|
45
70
|
expect(mockFn).toHaveBeenCalledTimes(2)
|
|
46
71
|
})
|
|
47
72
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
2
|
import { ref } from 'vue'
|
|
3
|
-
import DatePicker from '@/components/DatePicker/
|
|
3
|
+
import DatePicker from '@/components/DatePicker/CalendarMode/DatePicker.vue'
|
|
4
4
|
import { useHolidayDay } from '@/composables/date/useHolidayDay'
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof DatePicker> = {
|
|
@@ -17,7 +17,7 @@ export default meta
|
|
|
17
17
|
type Story = StoryObj<typeof DatePicker>
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Exemple d'utilisation de la règle isHolidayDay avec un
|
|
20
|
+
* Exemple d'utilisation de la règle isHolidayDay avec un CalendarMode
|
|
21
21
|
*/
|
|
22
22
|
export const Default: Story = {
|
|
23
23
|
render: () => ({
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { defineComponent as h, computed as D, createBlock as k, openBlock as p } from "vue";
|
|
2
|
-
import { u as C, D as F, _ as V } from "./main-DoYCrS2Q.js";
|
|
3
|
-
const v = /* @__PURE__ */ h({
|
|
4
|
-
__name: "DateFilter",
|
|
5
|
-
props: {
|
|
6
|
-
header: {
|
|
7
|
-
type: Object,
|
|
8
|
-
required: !0
|
|
9
|
-
},
|
|
10
|
-
filters: {
|
|
11
|
-
type: Array,
|
|
12
|
-
default: () => []
|
|
13
|
-
},
|
|
14
|
-
filterValue: {
|
|
15
|
-
type: [String, Date, Object, null],
|
|
16
|
-
default: null
|
|
17
|
-
},
|
|
18
|
-
inputConfig: {
|
|
19
|
-
type: Object,
|
|
20
|
-
default: () => ({})
|
|
21
|
-
},
|
|
22
|
-
disableErrorHandling: {
|
|
23
|
-
type: Boolean,
|
|
24
|
-
default: !1
|
|
25
|
-
},
|
|
26
|
-
variant: {
|
|
27
|
-
type: String,
|
|
28
|
-
default: "outlined"
|
|
29
|
-
},
|
|
30
|
-
hideDetails: {
|
|
31
|
-
type: Boolean,
|
|
32
|
-
default: !0
|
|
33
|
-
},
|
|
34
|
-
density: {
|
|
35
|
-
type: String,
|
|
36
|
-
default: "compact"
|
|
37
|
-
},
|
|
38
|
-
backgroundColor: {
|
|
39
|
-
type: String,
|
|
40
|
-
default: "white"
|
|
41
|
-
},
|
|
42
|
-
clearable: {
|
|
43
|
-
type: Boolean,
|
|
44
|
-
default: !0
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
emits: ["update:filters"],
|
|
48
|
-
setup(e, { emit: g }) {
|
|
49
|
-
const { parseDate: y } = C(), t = e, u = g;
|
|
50
|
-
function s() {
|
|
51
|
-
return String(t.header.key || t.header.value || (t.header.title ? `filter_${t.header.title}` : `filter_${Date.now()}`));
|
|
52
|
-
}
|
|
53
|
-
const f = D({
|
|
54
|
-
get: () => t.filterValue,
|
|
55
|
-
set: (a) => {
|
|
56
|
-
const i = s();
|
|
57
|
-
if (!i) return;
|
|
58
|
-
if (a === null) {
|
|
59
|
-
const r = t.filters.filter((o) => o.key !== i);
|
|
60
|
-
u("update:filters", r);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const l = t.filters.findIndex((r) => r.key === i), n = [...t.filters];
|
|
64
|
-
let d = a;
|
|
65
|
-
typeof a == "string" && a.trim() !== "" && y(a, t.header.dateFormat || "DD/MM/YYYY") && (d = a), l >= 0 ? n[l].value = d : n.push({
|
|
66
|
-
key: i,
|
|
67
|
-
value: d,
|
|
68
|
-
type: "date"
|
|
69
|
-
}), u("update:filters", n);
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
function m() {
|
|
73
|
-
const a = s(), i = t.filters.filter((l) => l.key !== a);
|
|
74
|
-
u("update:filters", i);
|
|
75
|
-
}
|
|
76
|
-
return (a, i) => {
|
|
77
|
-
var l, n, d, r, o, c;
|
|
78
|
-
return p(), k(F, {
|
|
79
|
-
modelValue: f.value,
|
|
80
|
-
"onUpdate:modelValue": i[0] || (i[0] = (b) => f.value = b),
|
|
81
|
-
label: e.header.title,
|
|
82
|
-
clearable: ((l = e.inputConfig) == null ? void 0 : l.clearable) ?? e.clearable,
|
|
83
|
-
density: ((n = e.inputConfig) == null ? void 0 : n.density) ?? e.density,
|
|
84
|
-
"hide-details": ((d = e.inputConfig) == null ? void 0 : d.hideDetails) ?? e.hideDetails,
|
|
85
|
-
"hide-messages": e.header.hideMessages,
|
|
86
|
-
variant: ((r = e.inputConfig) == null ? void 0 : r.variant) ?? e.variant,
|
|
87
|
-
"disable-error-handling": ((o = e.inputConfig) == null ? void 0 : o.disableErrorHandling) ?? e.disableErrorHandling,
|
|
88
|
-
"bg-color": ((c = e.inputConfig) == null ? void 0 : c.backgroundColor) ?? e.backgroundColor,
|
|
89
|
-
format: e.header.dateFormat,
|
|
90
|
-
class: "filter-input",
|
|
91
|
-
"onClick:clear": m
|
|
92
|
-
}, null, 8, ["modelValue", "label", "clearable", "density", "hide-details", "hide-messages", "variant", "disable-error-handling", "bg-color", "format"]);
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
}), B = /* @__PURE__ */ V(v, [["__scopeId", "data-v-1676b500"]]);
|
|
96
|
-
export {
|
|
97
|
-
B as default
|
|
98
|
-
};
|