@cnamts/synapse 1.0.23 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AutocompleteFilter-BWLR3U7W.js +114 -0
- package/dist/AutocompleteFilter-D9jzRzAL.cjs +1 -0
- package/dist/{DateFilter-Dc-gSGwk.js → DateFilter-BpwFexzi.js} +1 -1
- package/dist/DateFilter-DTUl8hb1.cjs +1 -0
- package/dist/{NumberFilter-vP38Wp6j.js → NumberFilter-Bz_NTdX9.js} +3 -3
- package/dist/NumberFilter-MAEojdk0.cjs +1 -0
- package/dist/PeriodFilter-CC4WgIhl.cjs +1 -0
- package/dist/{PeriodFilter-Ba1uYUnT.js → PeriodFilter-DX_wy9g-.js} +1 -1
- package/dist/SelectFilter-BR3fvl-a.cjs +1 -0
- package/dist/SelectFilter-xqiPtPgX.js +135 -0
- package/dist/{TextFilter-B84dpnoq.js → TextFilter-BBl3JFqK.js} +7 -7
- package/dist/TextFilter-CCfYFl5F.cjs +1 -0
- package/dist/apLightTheme-CFSRrjv2.cjs +1 -0
- package/dist/apLightTheme-D1P4jcD0.js +1231 -0
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +7022 -9616
- package/dist/components/Amelipro/AmeliproCarousel/AmeliproCarousel.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +40 -40
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +60 -60
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +7168 -9762
- package/dist/components/Amelipro/AmeliproStepper/AmeliproStepper.d.ts +2 -2
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +7501 -10095
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +21 -21
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +41 -41
- package/dist/components/Amelipro/StructureMenu/StructureTabs/StructureTabs.d.ts +2 -2
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +20 -498
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +108 -146
- package/dist/components/Customs/Selects/SyInputSelect/SyInputSelect.d.ts +5 -5
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +12 -16
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +8 -8
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +28 -506
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +28 -506
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +65 -85
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +627 -771
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +315 -402
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +112 -155
- package/dist/components/DatePicker/composables/index.d.ts +1 -0
- package/dist/components/DatePicker/composables/useDatePickerFocusTrap.d.ts +11 -0
- package/dist/components/DatePicker/composables/useDateTextField.d.ts +4 -4
- package/dist/components/DatePicker/composables/useDateValidation.d.ts +3 -3
- package/dist/components/DatePicker/composables/useInputBlurHandler.d.ts +2 -2
- package/dist/components/DatePicker/composables/useManualDateValidation.d.ts +2 -2
- package/dist/components/HeaderNavigationBar/HeaderNavigationBar.d.ts +4 -4
- package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +20 -28
- package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +3 -3
- package/dist/components/MonthPicker/MonthPicker.d.ts +86 -122
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +85 -121
- package/dist/components/NirField/NirField.d.ts +206 -270
- package/dist/components/NirField/locales.d.ts +10 -10
- package/dist/components/NirField/useNirValidation.d.ts +64 -0
- package/dist/components/PasswordField/PasswordField.d.ts +8 -9
- package/dist/components/PeriodField/PeriodField.d.ts +1352 -1640
- package/dist/components/PhoneField/PhoneField.d.ts +88 -124
- package/dist/components/RangeField/RangeSlider/RangeSlider.d.ts +12 -12
- package/dist/components/SyTextArea/SyTextArea.d.ts +34 -14
- package/dist/components/SyTextArea/useDefaultValidationRules.d.ts +11 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +9 -6
- package/dist/components/Tables/SyTable/SyTable.d.ts +9 -6
- package/dist/components/Tables/common/SyTableFilter.d.ts +2 -3
- package/dist/components/Tables/common/SyTablePagination.d.ts +17 -19
- package/dist/components/Tables/common/filters/AutocompleteFilter.d.ts +120 -0
- package/dist/components/Tables/common/filters/locales.d.ts +0 -1
- package/dist/components/Tables/common/types.d.ts +19 -3
- package/dist/components/Tables/common/useClickableTableRow.d.ts +17 -0
- package/dist/components/Tables/common/usePagination.d.ts +3 -1
- package/dist/components/Tables/common/usePinnedColumns.d.ts +31 -0
- package/dist/components/Tables/common/useTableHeaders.d.ts +2 -0
- package/dist/components/Tables/common/useTableRowCheckboxAccessibility.d.ts +5 -0
- package/dist/components/UploadWorkflow/UploadWorkflow.d.ts +6 -6
- package/dist/composables/date/useDatePickerAccessibility.d.ts +1 -1
- package/dist/composables/rules/useFieldValidation.d.ts +4 -4
- package/dist/composables/unifyValidation/useCustomValidation.d.ts +8 -0
- package/dist/composables/unifyValidation/useValidation.d.ts +102 -0
- package/dist/composables/unifyValidation/useVuetifyValidation.d.ts +18 -0
- package/dist/composables/useFormFieldErrorHandling.d.ts +2 -2
- package/dist/composables/validation/useFormValidation.d.ts +11 -2
- package/dist/composables/validation/useValidation.d.ts +15 -9
- package/dist/design-system-v3.d.ts +2 -0
- package/dist/design-system-v3.js +186 -187
- package/dist/design-system-v3.umd.cjs +1 -1066
- package/dist/{main-aLKwdMi1.js → main-BtTqyn4z.js} +16434 -15672
- package/dist/main-C1e3eoxd.cjs +1067 -0
- package/dist/main.d.ts +0 -1
- package/dist/synapse.css +1 -0
- package/dist/tooth-11-D3sLWv2n.cjs +1 -0
- package/dist/tooth-12-CXrLuH03.cjs +1 -0
- package/dist/tooth-13-BSfo5fpT.cjs +1 -0
- package/dist/tooth-14-DMzulx0h.cjs +1 -0
- package/dist/tooth-15-BKRFVi-9.cjs +1 -0
- package/dist/tooth-16-CpuxAbuM.cjs +1 -0
- package/dist/tooth-17-BPoahUdg.cjs +1 -0
- package/dist/tooth-18-DhHJz8sy.cjs +1 -0
- package/dist/tooth-21-Dgd5hn_X.cjs +1 -0
- package/dist/tooth-22-C2Tn19sB.cjs +1 -0
- package/dist/tooth-23-C9uaaSGb.cjs +1 -0
- package/dist/tooth-24-BrK9UGpf.cjs +1 -0
- package/dist/tooth-25-CE_EfGNp.cjs +1 -0
- package/dist/tooth-26-Ctv4i9Fy.cjs +1 -0
- package/dist/tooth-27-C5J7JkWM.cjs +1 -0
- package/dist/tooth-28-Z9oWqjo0.cjs +1 -0
- package/dist/tooth-31-BrYqmkTi.cjs +1 -0
- package/dist/tooth-32-BNNR0oCZ.cjs +1 -0
- package/dist/tooth-33-DuxvqO2J.cjs +1 -0
- package/dist/tooth-34-BCSCXMB6.cjs +1 -0
- package/dist/tooth-35-BLUXkX88.cjs +1 -0
- package/dist/tooth-36-IrKHYqlA.cjs +1 -0
- package/dist/tooth-37-BYqpdMwo.cjs +1 -0
- package/dist/tooth-38-B_eNXXdu.cjs +1 -0
- package/dist/tooth-41-Ddva4Ot8.cjs +1 -0
- package/dist/tooth-42-szcDqlM0.cjs +1 -0
- package/dist/tooth-43-B3ka6rQm.cjs +1 -0
- package/dist/tooth-44-CazyQucj.cjs +1 -0
- package/dist/tooth-45-B4HQtc8n.cjs +1 -0
- package/dist/tooth-46-BPM40gbG.cjs +1 -0
- package/dist/tooth-47-Dvr20dlh.cjs +1 -0
- package/dist/tooth-48-Bd8ljGsF.cjs +1 -0
- package/dist/tooth-51-OBpwCOF3.cjs +1 -0
- package/dist/tooth-52-aKxyHcmq.cjs +1 -0
- package/dist/tooth-53-vCwJjTOc.cjs +1 -0
- package/dist/tooth-54-DsWu2iFy.cjs +1 -0
- package/dist/tooth-55-BxC1X2Dn.cjs +1 -0
- package/dist/tooth-61-BbLvxMQi.cjs +1 -0
- package/dist/tooth-62-CmTkWczP.cjs +1 -0
- package/dist/tooth-63-DI7l_2qI.cjs +1 -0
- package/dist/tooth-64-B21sOsJh.cjs +1 -0
- package/dist/tooth-65-D2ZC2VEr.cjs +1 -0
- package/dist/tooth-71-D473PPO5.cjs +1 -0
- package/dist/tooth-72-Drh1wnNu.cjs +1 -0
- package/dist/tooth-73-DzlwYI23.cjs +1 -0
- package/dist/tooth-74-8aGvcZPg.cjs +1 -0
- package/dist/tooth-75-BFK7At_r.cjs +1 -0
- package/dist/tooth-81-BZmR-I0M.cjs +1 -0
- package/dist/tooth-82-euVfUUZV.cjs +1 -0
- package/dist/tooth-83-KV010j64.cjs +1 -0
- package/dist/tooth-84-BBg1RjhZ.cjs +1 -0
- package/dist/tooth-85-Cr-kc1wM.cjs +1 -0
- package/dist/vuetifyConfig.js +561 -0
- package/dist/vuetifyConfig.umd.cjs +1 -0
- package/package.json +10 -4
- package/src/assets/overrides/_btns.scss +0 -6
- package/src/assets/overrides/_icons.scss +9 -1
- package/src/assets/overrides/_typography.scss +0 -10
- package/src/components/Amelipro/AmeliproAutoCompleteField/__tests__/__snapshots__/AmeliproAutoCompleteField.spec.ts.snap +2 -2
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +1 -1
- package/src/components/Amelipro/AmeliproTextArea/__tests__/__snapshots__/AmeliproTextArea.spec.ts.snap +2 -2
- package/src/components/Captcha/accessibilite/Accessibility.mdx +86 -8
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +12 -12
- package/src/components/ChipList/ChipList.stories.ts +0 -15
- package/src/components/ChipList/ChipList.vue +5 -1
- package/src/components/ChipList/accessibilite/Accessibility.mdx +83 -10
- package/src/components/ChipList/tests/ChipList.a11y.spec.ts +41 -0
- package/src/components/Customs/Selects/SelectBtnField/accessibilite/Accessibility.mdx +0 -9
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +22 -5
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +143 -0
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +14 -10
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.stories.ts +4 -4
- package/src/components/Customs/Selects/SyInputSelect/SyInputSelect.vue +8 -9
- package/src/components/Customs/Selects/SyInputSelect/tests/SyInputSelect.spec.ts +10 -10
- package/src/components/Customs/Selects/SySelect/SySelect.vue +14 -11
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +54 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +6 -9
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +10 -16
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +16 -11
- package/src/components/Customs/SyCheckbox/accessibilite/Accessibility.mdx +35 -0
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.a11y.spec.ts +134 -2
- package/src/components/Customs/SyForm/SyForm.stories.ts +31 -5
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +4 -7
- package/src/components/Customs/SyTextField/SyTextField.mdx +1 -1
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +29 -27
- package/src/components/Customs/SyTextField/SyTextField.vue +154 -157
- package/src/components/Customs/SyTextField/tests/SyTextField.a11y.spec.ts +32 -0
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +120 -11
- package/src/components/DatePicker/CalendarMode/DatePicker.stories.ts +62 -58
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +330 -223
- package/src/components/DatePicker/CalendarMode/accessibilite/Accessibility.mdx +82 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.a11y.spec.ts +141 -0
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.stories.ts +2 -56
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +195 -159
- package/src/components/DatePicker/ComplexDatePicker/accessibilite/Accessibility.mdx +76 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +10 -10
- package/src/components/DatePicker/DatePickerValidationExample/CalendarMode.stories.ts +8 -8
- package/src/components/DatePicker/DatePickerValidationExample/ComplexDatePicker.stories.ts +106 -8
- package/src/components/DatePicker/DatePickerValidationExample/DateTextInput.stories.ts +12 -11
- package/src/components/DatePicker/DatePickerValidationExample/MultiMode.stories.ts +12 -12
- package/src/components/DatePicker/DateTextInput/DateRange.stories.ts +0 -12
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +63 -57
- package/src/components/DatePicker/DateTextInput/NoCalendar.stories.ts +3 -0
- package/src/components/DatePicker/DateTextInput/accessibilite/Accessibility.mdx +66 -0
- package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +52 -1
- package/src/components/DatePicker/composables/index.ts +1 -0
- package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +109 -65
- package/src/components/DatePicker/composables/tests/useDatePickerFocusTrap.spec.ts +138 -0
- package/src/components/DatePicker/composables/tests/useDateValidation.spec.ts +74 -18
- package/src/components/DatePicker/composables/tests/useInputBlurHandler.spec.ts +39 -0
- package/src/components/DatePicker/composables/tests/useManualDateValidation.spec.ts +91 -0
- package/src/components/DatePicker/composables/useCalendarKeyboardNavigation.ts +442 -36
- package/src/components/DatePicker/composables/useDatePickerFocusTrap.ts +92 -0
- package/src/components/DatePicker/composables/useDateTextField.ts +7 -6
- package/src/components/DatePicker/composables/useDateValidation.ts +36 -35
- package/src/components/DatePicker/composables/useInputBlurHandler.ts +3 -3
- package/src/components/DatePicker/composables/useManualDateValidation.ts +6 -2
- package/src/components/DiacriticPicker/accessibilite/Accessibility.mdx +76 -8
- package/src/components/HeaderBar/HeaderBar.stories.ts +14 -2
- package/src/components/Logo/accessibilite/Accessibility.mdx +73 -11
- package/src/components/LogoBrandSection/accessibilite/Accessibility.mdx +85 -9
- package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +3 -1
- package/src/components/LunarCalendar/useLunarCalendarValidation.ts +4 -5
- package/src/components/MonthPicker/tests/MonthPicker.spec.ts +2 -1
- package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +7 -7
- package/src/components/NirField/NirField.stories.ts +4 -0
- package/src/components/NirField/NirField.vue +64 -260
- package/src/components/NirField/accessibilite/Accessibility.mdx +2 -2
- package/src/components/NirField/locales.ts +1 -1
- package/src/components/NirField/tests/NirField.spec.ts +6 -0
- package/src/components/NirField/useNirValidation.ts +271 -0
- package/src/components/PasswordField/PasswordField.stories.ts +4 -4
- package/src/components/PasswordField/PasswordField.vue +18 -24
- package/src/components/PasswordField/tests/PasswordField.spec.ts +6 -3
- package/src/components/PeriodField/PeriodField.stories.ts +4 -4
- package/src/components/PeriodField/PeriodField.vue +57 -57
- package/src/components/PeriodField/__tests__/PeriodField.async.spec.ts +32 -0
- package/src/components/PeriodField/accessibilite/Accessibility.mdx +68 -8
- package/src/components/PeriodField/tests/PeriodField.spec.ts +28 -2
- package/src/components/PhoneField/PhoneField.vue +5 -6
- package/src/components/PhoneField/tests/PhoneField.spec.ts +1 -0
- package/src/components/RangeField/RangeField.vue +6 -0
- package/src/components/SyTextArea/SyTextArea.stories.ts +138 -2
- package/src/components/SyTextArea/SyTextArea.vue +53 -23
- package/src/components/SyTextArea/tests/SyTextArea.spec.ts +126 -3
- package/src/components/SyTextArea/useDefaultValidationRules.ts +74 -0
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +25 -0
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +673 -1
- package/src/components/Tables/SyServerTable/SyServerTable.vue +148 -91
- package/src/components/Tables/SyServerTable/tests/SyServerTable.a11y.spec.ts +58 -0
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +122 -0
- package/src/components/Tables/SyTable/SyTable.mdx +25 -0
- package/src/components/Tables/SyTable/SyTable.stories.ts +452 -1
- package/src/components/Tables/SyTable/SyTable.vue +130 -56
- package/src/components/Tables/SyTable/tests/SyTable.a11y.spec.ts +57 -0
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +108 -0
- package/src/components/Tables/common/SyTableFilter.vue +22 -2
- package/src/components/Tables/common/TableHeader.vue +5 -1
- package/src/components/Tables/common/filters/AutocompleteFilter.vue +160 -0
- package/src/components/Tables/common/filters/NumberFilter.vue +1 -1
- package/src/components/Tables/common/filters/SelectFilter.vue +10 -11
- package/src/components/Tables/common/filters/TextFilter.vue +1 -1
- package/src/components/Tables/common/filters/getFilterComponent.ts +8 -1
- package/src/components/Tables/common/filters/locales.ts +0 -1
- package/src/components/Tables/common/filters/tests/AutocompleteFilter.a11y.spec.ts +110 -0
- package/src/components/Tables/common/filters/tests/AutocompleteFilter.spec.ts +203 -0
- package/src/components/Tables/common/filters/tests/SelectFilter.a11y.spec.ts +104 -0
- package/src/components/Tables/common/filters/tests/SelectFilter.spec.ts +152 -16
- package/src/components/Tables/common/tableFilterUtils.ts +3 -0
- package/src/components/Tables/common/tableStyles.scss +48 -4
- package/src/components/Tables/common/tests/filterByRange.spec.ts +2 -1
- package/src/components/Tables/common/types.ts +13 -4
- package/src/components/Tables/common/useClickableTableRow.ts +103 -0
- package/src/components/Tables/common/usePagination.ts +13 -0
- package/src/components/Tables/common/usePinnedColumns.ts +237 -0
- package/src/components/Tables/common/useTableHeaders.ts +3 -3
- package/src/components/Tables/common/useTableRowCheckboxAccessibility.ts +41 -0
- package/src/composables/date/tests/useDatePickerAccessibility.spec.ts +2 -6
- package/src/composables/date/useDatePickerAccessibility.ts +42 -207
- package/src/composables/rules/tests/useFieldValidation.spec.ts +120 -120
- package/src/composables/rules/useFieldValidation.ts +34 -17
- package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +601 -0
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +2048 -0
- package/src/composables/unifyValidation/tests/useVuetifyValidation.spec.ts +184 -0
- package/src/composables/unifyValidation/useCustomValidation.ts +95 -0
- package/src/composables/unifyValidation/useValidation.ts +190 -0
- package/src/composables/unifyValidation/useVuetifyValidation.ts +54 -0
- package/src/composables/useFormFieldErrorHandling.ts +4 -7
- package/src/composables/validation/tests/useFormValidation.spec.ts +14 -0
- package/src/composables/validation/tests/useValidation.spec.ts +116 -21
- package/src/composables/validation/useFormValidation.ts +20 -13
- package/src/composables/validation/useValidatable.ts +8 -1
- package/src/composables/validation/useValidation.ts +135 -99
- package/src/composantsVuetify/Introduction.mdx +48 -0
- package/src/composantsVuetify/VBtn/VBtn.mdx +72 -0
- package/src/composantsVuetify/VBtn/v-btn.stories.ts +121 -0
- package/src/composantsVuetify/VTooltip/VTooltip.mdx +32 -0
- package/src/composantsVuetify/VTooltip/v-tooltip.stories.ts +95 -0
- package/src/designTokens/tokens/cnam/cnamSemantic.ts +2 -2
- package/src/main.ts +0 -2
- package/src/stories/Components/Components.stories.ts +74 -9
- package/src/stories/Demarrer/Accueil.stories.ts +3 -3
- package/src/stories/GuideDuDev/Amelipro.mdx +15 -0
- package/src/stories/GuideDuDev/Amelipro.stories.ts +209 -0
- package/src/stories/GuideDuDev/vuetifyOptions.mdx +3 -3
- package/dist/SelectFilter-BioGT6Nn.js +0 -136
- package/dist/style.css +0 -1
- package/src/components/DatePicker/Accessibilite.mdx +0 -14
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed,
|
|
2
|
+
import { computed, onMounted, provide, ref, toRef, useAttrs, watch } from 'vue'
|
|
3
3
|
import type { VDataTableServer } from 'vuetify/components'
|
|
4
4
|
import SyCheckbox from '@/components/Customs/SyCheckbox/SyCheckbox.vue'
|
|
5
5
|
import SyTableFilter from '../common/SyTableFilter.vue'
|
|
6
6
|
import TableHeader from '../common/TableHeader.vue'
|
|
7
7
|
import SyTablePagination from '../common/SyTablePagination.vue'
|
|
8
8
|
import { locales } from '../common/locales'
|
|
9
|
+
import OrganizeColumns from '../common/organizeColumns/OrganizeColumns.vue'
|
|
9
10
|
import { useTableProps } from '../common/tableProps'
|
|
10
11
|
import type { DataOptions, Items, SyServerTableProps } from '../common/types'
|
|
11
12
|
import { useTableFilter } from '../common/useTableFilter'
|
|
12
13
|
import { usePagination } from '../common/usePagination'
|
|
13
14
|
import { useTableOptions } from '../common/useTableOptions'
|
|
14
15
|
import { useTableHeaders } from '../common/useTableHeaders'
|
|
15
|
-
import OrganizeColumns from '../common/organizeColumns/OrganizeColumns.vue'
|
|
16
16
|
import { useTableCheckbox } from '../common/useTableCheckbox'
|
|
17
17
|
import { useTableAria } from '../common/useTableAria'
|
|
18
18
|
import { useTableAccessibility } from '../common/tableAccessibilityUtils'
|
|
19
19
|
import useStoredOptions from '../common/useStoredOptions'
|
|
20
|
+
import { usePinnedColumns } from '../common/usePinnedColumns'
|
|
21
|
+
import { useClickableTableRow } from '../common/useClickableTableRow'
|
|
22
|
+
import { useTableRowCheckboxAccessibility } from '../common/useTableRowCheckboxAccessibility'
|
|
23
|
+
import type { ClickableTableRowPropsInput } from '../common/useClickableTableRow'
|
|
20
24
|
|
|
21
25
|
const props = withDefaults(defineProps<SyServerTableProps>(), {
|
|
22
26
|
caption: '',
|
|
@@ -31,12 +35,18 @@
|
|
|
31
35
|
striped: false,
|
|
32
36
|
showSelect: false,
|
|
33
37
|
showSelectSingle: false,
|
|
38
|
+
stickySelect: false,
|
|
34
39
|
multiSort: false,
|
|
35
40
|
mustSort: false,
|
|
36
41
|
itemsPerPageOptions: undefined,
|
|
37
42
|
headingLevel: 2,
|
|
43
|
+
clickableRow: false,
|
|
38
44
|
})
|
|
39
45
|
|
|
46
|
+
const emit = defineEmits<{
|
|
47
|
+
'row-click': [item: Record<string, unknown>]
|
|
48
|
+
}>()
|
|
49
|
+
|
|
40
50
|
const options = defineModel<Partial<DataOptions>>('options', {
|
|
41
51
|
required: false,
|
|
42
52
|
default: () => ({}),
|
|
@@ -60,7 +70,7 @@
|
|
|
60
70
|
const componentAttributes = useAttrs()
|
|
61
71
|
|
|
62
72
|
// Generate a unique ID for this table instance
|
|
63
|
-
const uniqueTableId = ref(`sy-server-table-${Math.random().toString(36).
|
|
73
|
+
const uniqueTableId = ref(`sy-server-table-${Math.random().toString(36).substring(2, 11)}`)
|
|
64
74
|
|
|
65
75
|
const { storedOptions, storeOptions } = useStoredOptions({
|
|
66
76
|
key: computed(() => props.suffix ? `server-table-${props.suffix}` : 'server-table'),
|
|
@@ -76,6 +86,16 @@
|
|
|
76
86
|
storedOptions: storedOptions.options,
|
|
77
87
|
})
|
|
78
88
|
|
|
89
|
+
const forwardedRowProps = computed<ClickableTableRowPropsInput>(() => {
|
|
90
|
+
return (propsFacade.value.rowProps ?? propsFacade.value['row-props']) as ClickableTableRowPropsInput
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const { clickableRowProps } = useClickableTableRow({
|
|
94
|
+
clickableRow: toRef(props, 'clickableRow'),
|
|
95
|
+
rowProps: forwardedRowProps,
|
|
96
|
+
onRowClick: item => emit('row-click', item),
|
|
97
|
+
})
|
|
98
|
+
|
|
79
99
|
const { setupAccessibility } = useTableAccessibility({
|
|
80
100
|
tableId: uniqueTableId.value,
|
|
81
101
|
})
|
|
@@ -87,42 +107,11 @@
|
|
|
87
107
|
filterInputConfig: props.filterInputConfig,
|
|
88
108
|
})
|
|
89
109
|
|
|
90
|
-
// Use the pagination composable with displayedItemsLength (stable during refetch)
|
|
91
|
-
const itemsLength = computed(() => displayedItemsLength.value)
|
|
92
|
-
const { page, pageCount, itemsPerPageValue, updateItemsPerPage, isUpdatingItemsPerPage } = usePagination({
|
|
93
|
-
options,
|
|
94
|
-
itemsLength,
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
// Defines a function to handle updating the data table options
|
|
98
|
-
function onUpdateOptions(newOptions: Partial<DataOptions>) {
|
|
99
|
-
if (isUpdatingItemsPerPage.value && typeof newOptions.itemsPerPage !== 'undefined') {
|
|
100
|
-
// Creates a copy of the received options
|
|
101
|
-
const rest = { ...newOptions }
|
|
102
|
-
delete (rest as Record<string, unknown>).itemsPerPage
|
|
103
|
-
// Updates the other options without modifying itemsPerPage
|
|
104
|
-
updateOptions(rest)
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
// In all other cases, simply updates the options with the new values
|
|
108
|
-
updateOptions(newOptions)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Create a computed property for items to ensure reactivity
|
|
112
|
-
// Bind to displayedItems so it is always an array
|
|
113
|
-
const tableItems = computed<Items>(() => displayedItems.value)
|
|
114
|
-
|
|
115
110
|
// Keep last non-undefined items to avoid clearing the table during refetches
|
|
116
111
|
const lastNonUndefinedItems = ref<Items>([])
|
|
117
|
-
const isRefetching = ref(false)
|
|
118
112
|
watch(() => props.items, (newVal) => {
|
|
119
113
|
if (Array.isArray(newVal)) {
|
|
120
114
|
lastNonUndefinedItems.value = newVal
|
|
121
|
-
isRefetching.value = false
|
|
122
|
-
}
|
|
123
|
-
else if (newVal === undefined) {
|
|
124
|
-
// Parent temporarily cleared items
|
|
125
|
-
isRefetching.value = true
|
|
126
115
|
}
|
|
127
116
|
}, { immediate: true })
|
|
128
117
|
|
|
@@ -130,74 +119,28 @@
|
|
|
130
119
|
return Array.isArray(props.items) ? props.items : lastNonUndefinedItems.value
|
|
131
120
|
})
|
|
132
121
|
|
|
133
|
-
// Keep last non-undefined server items length as well
|
|
122
|
+
// Keep last non-undefined server items length as well (stable during refetch)
|
|
134
123
|
const lastNonUndefinedLength = ref<number>(0)
|
|
135
124
|
watch([() => props.items, () => props.serverItemsLength], ([itemsVal, lenVal]) => {
|
|
136
|
-
// Update cached length only when we have a valid items array
|
|
137
125
|
if (Array.isArray(itemsVal) && typeof lenVal === 'number') {
|
|
138
126
|
lastNonUndefinedLength.value = lenVal
|
|
139
|
-
isRefetching.value = false
|
|
140
|
-
}
|
|
141
|
-
else if (!Array.isArray(itemsVal)) {
|
|
142
|
-
isRefetching.value = true
|
|
143
127
|
}
|
|
144
128
|
}, { immediate: true })
|
|
145
129
|
|
|
146
130
|
const displayedItemsLength = computed<number>(() => {
|
|
147
|
-
// If current items are an array, use current prop length; otherwise, keep last known length
|
|
148
131
|
return Array.isArray(props.items)
|
|
149
132
|
? (typeof props.serverItemsLength === 'number' ? props.serverItemsLength : lastNonUndefinedLength.value)
|
|
150
133
|
: lastNonUndefinedLength.value
|
|
151
134
|
})
|
|
152
135
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const accessibilityRowCheckboxes = () => {
|
|
158
|
-
nextTick(() => {
|
|
159
|
-
const timeoutId = setTimeout(() => {
|
|
160
|
-
// Check if document is available (for test environment)
|
|
161
|
-
if (typeof document === 'undefined') return
|
|
162
|
-
|
|
163
|
-
const tableElement = document.getElementById(uniqueTableId.value)
|
|
164
|
-
if (!tableElement) return
|
|
165
|
-
|
|
166
|
-
// Find all row checkboxes
|
|
167
|
-
const rowCheckboxes = tableElement.querySelectorAll('td .v-selection-control input[type="checkbox"]')
|
|
168
|
-
rowCheckboxes.forEach((checkbox, index) => {
|
|
169
|
-
const rowLabel = `${locales.selectRow} ${index + 1}`
|
|
170
|
-
checkbox.setAttribute('aria-label', rowLabel)
|
|
171
|
-
checkbox.setAttribute('title', rowLabel)
|
|
172
|
-
})
|
|
173
|
-
}, 100) // Small delay to ensure DOM is updated
|
|
174
|
-
|
|
175
|
-
// Track timeout for cleanup
|
|
176
|
-
timeouts.value.push(timeoutId)
|
|
177
|
-
})
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Watch for changes that might affect the table and update accessibility
|
|
181
|
-
watch(() => props.items, accessibilityRowCheckboxes, { deep: true })
|
|
182
|
-
watch(() => displayedItemsLength.value, accessibilityRowCheckboxes)
|
|
183
|
-
watch(() => page.value, accessibilityRowCheckboxes)
|
|
184
|
-
|
|
185
|
-
// Apply accessibility attributes when component is mounted
|
|
186
|
-
onMounted(() => {
|
|
187
|
-
accessibilityRowCheckboxes()
|
|
188
|
-
setupAria()
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
// Clean up timeouts on unmount to prevent unhandled errors
|
|
192
|
-
onUnmounted(() => {
|
|
193
|
-
timeouts.value.forEach((timeoutId) => {
|
|
194
|
-
clearTimeout(timeoutId)
|
|
195
|
-
})
|
|
196
|
-
timeouts.value = []
|
|
136
|
+
const { page, pageCount, itemsPerPageValue, updateItemsPerPage, onUpdateOptions } = usePagination({
|
|
137
|
+
options,
|
|
138
|
+
itemsLength: displayedItemsLength,
|
|
139
|
+
updateOptions,
|
|
197
140
|
})
|
|
198
141
|
|
|
199
142
|
const { getItemValue, toggleAllRows } = useTableCheckbox({
|
|
200
|
-
items:
|
|
143
|
+
items: displayedItems,
|
|
201
144
|
modelValue: model,
|
|
202
145
|
updateModelValue: (value) => {
|
|
203
146
|
if (props.showSelectSingle && Array.isArray(value)) {
|
|
@@ -218,8 +161,8 @@
|
|
|
218
161
|
setupAria,
|
|
219
162
|
} = useTableAria({
|
|
220
163
|
table,
|
|
221
|
-
items:
|
|
222
|
-
totalItemsCount:
|
|
164
|
+
items: displayedItems,
|
|
165
|
+
totalItemsCount: displayedItemsLength,
|
|
223
166
|
options,
|
|
224
167
|
uniqueTableId: uniqueTableId.value,
|
|
225
168
|
})
|
|
@@ -228,9 +171,41 @@
|
|
|
228
171
|
|
|
229
172
|
setupAccessibility()
|
|
230
173
|
|
|
174
|
+
const { accessibilityRowCheckboxes } = useTableRowCheckboxAccessibility({
|
|
175
|
+
uniqueTableId: uniqueTableId.value,
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
// Watch for changes that might affect the table and update accessibility
|
|
179
|
+
watch(() => props.items, accessibilityRowCheckboxes, { deep: true })
|
|
180
|
+
watch(() => displayedItemsLength.value, accessibilityRowCheckboxes)
|
|
181
|
+
watch(() => page.value, accessibilityRowCheckboxes)
|
|
182
|
+
watch(() => itemsPerPageValue.value, accessibilityRowCheckboxes)
|
|
183
|
+
|
|
184
|
+
onMounted(() => {
|
|
185
|
+
setupAria()
|
|
186
|
+
})
|
|
187
|
+
|
|
231
188
|
// Create a reactive reference to column widths that will be provided to children
|
|
232
189
|
const reactiveColumnWidths = ref(storedOptions.columnWidths || {})
|
|
233
190
|
|
|
191
|
+
const {
|
|
192
|
+
showPinnedLeftShadow,
|
|
193
|
+
showPinnedRightShadow,
|
|
194
|
+
hasPinnedSelectLeft,
|
|
195
|
+
pinnedMeta,
|
|
196
|
+
pinnedEdgeVars,
|
|
197
|
+
displayHeadersWithPinned,
|
|
198
|
+
} = usePinnedColumns({
|
|
199
|
+
displayHeaders,
|
|
200
|
+
reactiveColumnWidths,
|
|
201
|
+
pinnedColumns: toRef(props, 'pinnedColumns'),
|
|
202
|
+
pinnedColumnKey: toRef(props, 'pinnedColumnKey'),
|
|
203
|
+
stickySelect: toRef(props, 'stickySelect'),
|
|
204
|
+
showSelect: toRef(props, 'showSelect'),
|
|
205
|
+
showSelectSingle: toRef(props, 'showSelectSingle'),
|
|
206
|
+
tableRef: table,
|
|
207
|
+
})
|
|
208
|
+
|
|
234
209
|
// Provide column widths and update function to child components
|
|
235
210
|
provide('columnWidths', reactiveColumnWidths)
|
|
236
211
|
provide('updateColumnWidth', (key: string, width: number | string) => {
|
|
@@ -260,7 +235,17 @@
|
|
|
260
235
|
<template>
|
|
261
236
|
<div
|
|
262
237
|
:id="uniqueTableId"
|
|
263
|
-
:class="[
|
|
238
|
+
:class="[
|
|
239
|
+
'sy-server-table',
|
|
240
|
+
{
|
|
241
|
+
'sy-server-table--striped': props.striped,
|
|
242
|
+
'sy-server-table--pinned-left-shadow': showPinnedLeftShadow,
|
|
243
|
+
'sy-server-table--pinned-right-shadow': showPinnedRightShadow,
|
|
244
|
+
'sy-server-table--pinned-select-left': hasPinnedSelectLeft,
|
|
245
|
+
'sy-server-table--select-single': props.showSelectSingle,
|
|
246
|
+
},
|
|
247
|
+
]"
|
|
248
|
+
:style="pinnedEdgeVars"
|
|
264
249
|
>
|
|
265
250
|
<!-- ARIA status region for row count announcements -->
|
|
266
251
|
<div
|
|
@@ -275,7 +260,8 @@
|
|
|
275
260
|
ref="table"
|
|
276
261
|
v-bind="propsFacade"
|
|
277
262
|
v-model="model"
|
|
278
|
-
:headers="
|
|
263
|
+
:headers="displayHeadersWithPinned"
|
|
264
|
+
:row-props="clickableRowProps"
|
|
279
265
|
color="primary"
|
|
280
266
|
:items="displayedItems"
|
|
281
267
|
:items-length="displayedItemsLength || 0"
|
|
@@ -306,11 +292,25 @@
|
|
|
306
292
|
:key="column.key!"
|
|
307
293
|
>
|
|
308
294
|
<th
|
|
309
|
-
:class="
|
|
295
|
+
:class="[
|
|
296
|
+
{ 'checkbox-column': column.key === 'data-table-select' },
|
|
297
|
+
{
|
|
298
|
+
'sy-table__pinned': pinnedMeta.left[column.key!] !== undefined || pinnedMeta.right[column.key!] !== undefined,
|
|
299
|
+
'sy-table__pinned--left': pinnedMeta.left[column.key!] !== undefined,
|
|
300
|
+
'sy-table__pinned--right': pinnedMeta.right[column.key!] !== undefined,
|
|
301
|
+
'v-data-table-column--fixed': pinnedMeta.left[column.key!] !== undefined || pinnedMeta.right[column.key!] !== undefined,
|
|
302
|
+
},
|
|
303
|
+
]"
|
|
310
304
|
:style="{
|
|
311
305
|
...(getHeaderForColumn(column)?.maxWidth ? { maxWidth: getHeaderForColumn(column)?.maxWidth as any } : {}),
|
|
312
306
|
...(getHeaderForColumn(column)?.minWidth ? { minWidth: getHeaderForColumn(column)?.minWidth as any } : {}),
|
|
313
307
|
...(getHeaderForColumn(column)?.width ? { width: getHeaderForColumn(column)?.width as any } : {}),
|
|
308
|
+
...(pinnedMeta.left[column.key!] !== undefined
|
|
309
|
+
? { position: 'sticky', left: `${pinnedMeta.left[column.key!] }px`, zIndex: 'var(--sy-table-z-pinned-header)', background: 'var(--sy-table-header-bg-pinned)' }
|
|
310
|
+
: {}),
|
|
311
|
+
...(pinnedMeta.right[column.key!] !== undefined
|
|
312
|
+
? { position: 'sticky', right: `${pinnedMeta.right[column.key!] }px`, zIndex: 'var(--sy-table-z-pinned-header)', background: 'var(--sy-table-header-bg-pinned)' }
|
|
313
|
+
: {}),
|
|
314
314
|
}"
|
|
315
315
|
>
|
|
316
316
|
<template v-if="column.key === 'data-table-select' && props.showSelect && !props.showSelectSingle">
|
|
@@ -487,6 +487,7 @@
|
|
|
487
487
|
|
|
488
488
|
.sy-server-table :deep() {
|
|
489
489
|
@include tablestyles;
|
|
490
|
+
@include clickable-row-styles;
|
|
490
491
|
}
|
|
491
492
|
|
|
492
493
|
@mixin striped-rows {
|
|
@@ -502,4 +503,60 @@
|
|
|
502
503
|
.checkbox-column {
|
|
503
504
|
max-width: fit-content;
|
|
504
505
|
}
|
|
506
|
+
|
|
507
|
+
.sy-server-table :deep(.sy-table__pinned) {
|
|
508
|
+
box-shadow: none;
|
|
509
|
+
opacity: 1 !important;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.sy-server-table--pinned-left-shadow :deep(.sy-table__pinned--left) {
|
|
513
|
+
box-shadow: 2px 0 6px -4px rgba(tokens.$grey-base, 0.6);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
.sy-server-table--pinned-right-shadow :deep(.sy-table__pinned--right) {
|
|
517
|
+
box-shadow: -2px 0 6px -4px rgba(tokens.$grey-base, 0.6);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.sy-server-table--pinned-select-left :deep(.v-data-table__th--select),
|
|
521
|
+
.sy-server-table--pinned-select-left :deep(.v-data-table__td--select-row) {
|
|
522
|
+
opacity: 1 !important;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.sy-server-table--pinned-select-left :deep(.v-data-table__th--select) {
|
|
526
|
+
position: sticky;
|
|
527
|
+
left: 0;
|
|
528
|
+
z-index: 5;
|
|
529
|
+
background: var(--sy-table-header-bg-pinned);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
.sy-server-table--select-single.sy-server-table--pinned-select-left :deep(.v-data-table__th--select) {
|
|
533
|
+
box-shadow: none !important;
|
|
534
|
+
background: transparent !important;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
/* stylelint-disable @stylistic/max-line-length */
|
|
538
|
+
.sy-server-table--select-single.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left :deep(.v-table__wrapper > table > thead > tr > th:first-child) {
|
|
539
|
+
box-shadow: none !important;
|
|
540
|
+
background: transparent !important;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.sy-server-table--pinned-select-left :deep(.v-table__wrapper > table > tbody > tr:not(.v-data-table-rows-loading) > td:first-child),
|
|
544
|
+
.sy-server-table--pinned-select-left :deep(.v-table__wrapper > table > tbody > tr:not(.v-data-table-rows-loading) > .v-data-table__td:first-child),
|
|
545
|
+
.sy-server-table--pinned-select-left :deep(.v-data-table__tbody .v-data-table__tr:not(.v-data-table-rows-loading) > .v-data-table__td:first-child),
|
|
546
|
+
.sy-server-table--pinned-select-left :deep(.v-data-table__tbody tr:not(.v-data-table-rows-loading) > td:first-child) {
|
|
547
|
+
position: sticky !important;
|
|
548
|
+
left: 0 !important;
|
|
549
|
+
z-index: 3;
|
|
550
|
+
background: rgb(var(--v-theme-surface)) !important;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left:not(.sy-server-table--select-single) :deep(.v-data-table__th--select),
|
|
554
|
+
.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left :deep(.v-table__wrapper > table > tbody > tr:not(.v-data-table-rows-loading) > td:first-child),
|
|
555
|
+
.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left :deep(.v-table__wrapper > table > tbody > tr:not(.v-data-table-rows-loading) > .v-data-table__td:first-child),
|
|
556
|
+
.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left :deep(.v-data-table__tbody .v-data-table__tr:not(.v-data-table-rows-loading) > .v-data-table__td:first-child),
|
|
557
|
+
.sy-server-table--pinned-left-shadow.sy-server-table--pinned-select-left :deep(.v-data-table__tbody tr:not(.v-data-table-rows-loading) > td:first-child) {
|
|
558
|
+
box-shadow: 2px 0 6px -4px rgba(tokens.$grey-base, 0.6);
|
|
559
|
+
}
|
|
560
|
+
/* stylelint-enable @stylistic/max-line-length */
|
|
561
|
+
|
|
505
562
|
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
|
|
3
|
+
import { beforeAll, describe, it } from 'vitest'
|
|
4
|
+
import { mount } from '@vue/test-utils'
|
|
5
|
+
import { axe } from 'vitest-axe'
|
|
6
|
+
import { assertNoA11yViolations } from '@tests/unit/accessibility/axeUtils'
|
|
7
|
+
import type { DataOptions } from '@/components/Tables/common/types'
|
|
8
|
+
import SyServerTable from '../SyServerTable.vue'
|
|
9
|
+
|
|
10
|
+
const items = [
|
|
11
|
+
{ id: 1, name: 'John Doe', age: 25 },
|
|
12
|
+
{ id: 2, name: 'Jane Doe', age: 30 },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const headers = [
|
|
16
|
+
{ title: 'ID', key: 'id' },
|
|
17
|
+
{ title: 'Name', key: 'name' },
|
|
18
|
+
{ title: 'Age', key: 'age' },
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
describe('SyServerTable - accessibility (axe)', () => {
|
|
22
|
+
beforeAll(() => {
|
|
23
|
+
global.visualViewport = {
|
|
24
|
+
width: 1024,
|
|
25
|
+
height: 768,
|
|
26
|
+
scale: 1,
|
|
27
|
+
offsetLeft: 0,
|
|
28
|
+
offsetTop: 0,
|
|
29
|
+
pageLeft: 0,
|
|
30
|
+
pageTop: 0,
|
|
31
|
+
onresize: null,
|
|
32
|
+
onscroll: null,
|
|
33
|
+
addEventListener: () => {},
|
|
34
|
+
removeEventListener: () => {},
|
|
35
|
+
dispatchEvent: () => true,
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('has no obvious axe violations when rows are clickable and contain nested actions', async () => {
|
|
40
|
+
const wrapper = mount(SyServerTable, {
|
|
41
|
+
props: {
|
|
42
|
+
options: {} as DataOptions,
|
|
43
|
+
serverItemsLength: items.length,
|
|
44
|
+
suffix: 'a11y-clickable-row-test',
|
|
45
|
+
clickableRow: true,
|
|
46
|
+
showSelect: true,
|
|
47
|
+
headers,
|
|
48
|
+
items,
|
|
49
|
+
},
|
|
50
|
+
attachTo: document.body,
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const results = await axe(wrapper.element as HTMLElement)
|
|
54
|
+
assertNoA11yViolations(results, 'SyServerTable - clickableRow', {
|
|
55
|
+
ignoreRules: ['region', 'aria-allowed-attr', 'aria-prohibited-attr', 'label'],
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
})
|
|
@@ -156,6 +156,128 @@ describe('SyServerTable', () => {
|
|
|
156
156
|
expect(wrapper.text()).toContain('John Doe')
|
|
157
157
|
})
|
|
158
158
|
|
|
159
|
+
it('applies sticky styles for pinnedColumns (left/right) including data-table-select', async () => {
|
|
160
|
+
const wrapper = mount(SyServerTable, {
|
|
161
|
+
props: {
|
|
162
|
+
options: { itemsPerPage: 5, page: 1 } as DataOptions,
|
|
163
|
+
serverItemsLength: 10,
|
|
164
|
+
suffix: 'pinned-columns-test',
|
|
165
|
+
showSelect: true,
|
|
166
|
+
pinnedColumns: [
|
|
167
|
+
'data-table-select',
|
|
168
|
+
{ key: 'name', side: 'left' },
|
|
169
|
+
{ key: 'age', side: 'right' },
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
attrs: {
|
|
173
|
+
items: fakeItems,
|
|
174
|
+
headers: headers,
|
|
175
|
+
},
|
|
176
|
+
attachTo: document.body,
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
await wrapper.vm.$nextTick()
|
|
180
|
+
await flushPromises()
|
|
181
|
+
|
|
182
|
+
const pinnedTh = wrapper.findAll('th[style*="position: sticky"]')
|
|
183
|
+
expect(pinnedTh.length).toBeGreaterThan(0)
|
|
184
|
+
expect(pinnedTh.some(th => (th.attributes('style') || '').includes('left:'))).toBe(true)
|
|
185
|
+
expect(pinnedTh.some(th => (th.attributes('style') || '').includes('right:'))).toBe(true)
|
|
186
|
+
expect(pinnedTh.every(th => (th.attributes('style') || '').includes('background: var(--sy-table-header-bg-pinned)'))).toBe(true)
|
|
187
|
+
|
|
188
|
+
const pinnedTd = wrapper.findAll('tbody td[style*="position: sticky"]')
|
|
189
|
+
expect(pinnedTd.length).toBeGreaterThan(0)
|
|
190
|
+
expect(pinnedTd.some(td => (td.attributes('style') || '').includes('left:'))).toBe(true)
|
|
191
|
+
expect(pinnedTd.some(td => (td.attributes('style') || '').includes('right:'))).toBe(true)
|
|
192
|
+
expect(pinnedTd.every(td => (td.attributes('style') || '').includes('background: rgb(var(--v-theme-surface))'))).toBe(true)
|
|
193
|
+
|
|
194
|
+
activeWrappers.push(wrapper)
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('makes selection column sticky when stickySelect is true', async () => {
|
|
198
|
+
const wrapper = mount(SyServerTable, {
|
|
199
|
+
props: {
|
|
200
|
+
options: { itemsPerPage: 5, page: 1 } as DataOptions,
|
|
201
|
+
serverItemsLength: 10,
|
|
202
|
+
suffix: 'sticky-select-test',
|
|
203
|
+
showSelect: true,
|
|
204
|
+
stickySelect: true,
|
|
205
|
+
pinnedColumns: [{ key: 'age', side: 'right' }],
|
|
206
|
+
},
|
|
207
|
+
attrs: {
|
|
208
|
+
items: fakeItems,
|
|
209
|
+
headers: headers,
|
|
210
|
+
},
|
|
211
|
+
attachTo: document.body,
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
await wrapper.vm.$nextTick()
|
|
215
|
+
await flushPromises()
|
|
216
|
+
|
|
217
|
+
expect(wrapper.classes()).toContain('sy-server-table--pinned-select-left')
|
|
218
|
+
|
|
219
|
+
activeWrappers.push(wrapper)
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('makes rows clickable and emits row-click events', async () => {
|
|
223
|
+
const wrapper = mount(SyServerTable, {
|
|
224
|
+
props: {
|
|
225
|
+
options: {} as DataOptions,
|
|
226
|
+
serverItemsLength: fakeItems.length,
|
|
227
|
+
suffix: 'clickable-row-test',
|
|
228
|
+
clickableRow: true,
|
|
229
|
+
headers,
|
|
230
|
+
items: fakeItems,
|
|
231
|
+
},
|
|
232
|
+
attachTo: document.body,
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
await wrapper.vm.$nextTick()
|
|
236
|
+
await flushPromises()
|
|
237
|
+
|
|
238
|
+
const firstRow = wrapper.find('tbody tr')
|
|
239
|
+
|
|
240
|
+
expect(firstRow.classes()).toContain('v-data-table__tr--clickable')
|
|
241
|
+
expect(firstRow.classes()).toContain('sy-table__clickable-row')
|
|
242
|
+
expect(firstRow.attributes('data-clickable-row')).toBe('true')
|
|
243
|
+
expect(firstRow.attributes('tabindex')).toBe('0')
|
|
244
|
+
expect(firstRow.attributes('role')).toBeUndefined()
|
|
245
|
+
|
|
246
|
+
await firstRow.trigger('click')
|
|
247
|
+
|
|
248
|
+
expect(wrapper.emitted('row-click')).toEqual([[fakeItems[0]]])
|
|
249
|
+
|
|
250
|
+
activeWrappers.push(wrapper)
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
it('does not emit row-click when an interactive element inside the row is clicked', async () => {
|
|
254
|
+
const wrapper = mount(SyServerTable, {
|
|
255
|
+
props: {
|
|
256
|
+
options: {} as DataOptions,
|
|
257
|
+
serverItemsLength: fakeItems.length,
|
|
258
|
+
suffix: 'clickable-row-nested-interactive-test',
|
|
259
|
+
clickableRow: true,
|
|
260
|
+
showSelect: true,
|
|
261
|
+
headers,
|
|
262
|
+
items: fakeItems,
|
|
263
|
+
},
|
|
264
|
+
attachTo: document.body,
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
await wrapper.vm.$nextTick()
|
|
268
|
+
await flushPromises()
|
|
269
|
+
|
|
270
|
+
const nestedCheckbox = wrapper.find('tbody .v-selection-control input')
|
|
271
|
+
|
|
272
|
+
expect(nestedCheckbox.exists()).toBe(true)
|
|
273
|
+
|
|
274
|
+
await nestedCheckbox.trigger('click')
|
|
275
|
+
|
|
276
|
+
expect(wrapper.emitted('row-click')).toBeUndefined()
|
|
277
|
+
|
|
278
|
+
activeWrappers.push(wrapper)
|
|
279
|
+
})
|
|
280
|
+
|
|
159
281
|
it('stores the options in local storage', async () => {
|
|
160
282
|
const setItemMock = vi.spyOn(LocalStorageUtility.prototype, 'setItem')
|
|
161
283
|
|
|
@@ -60,6 +60,31 @@ Exemple d'utilisation :
|
|
|
60
60
|
/>
|
|
61
61
|
`}/>
|
|
62
62
|
|
|
63
|
+
### Click des lignes
|
|
64
|
+
|
|
65
|
+
La prop `clickableRow` active le clic sur toute la ligne du tableau. Quand cette prop vaut `true`, un clic sur une ligne émet l'événement `row-click` avec l'item correspondant.
|
|
66
|
+
|
|
67
|
+
Les lignes deviennent également focusables au clavier afin de pouvoir être activées avec <kbd>Entrée</kbd> ou <kbd>Espace</kbd>.
|
|
68
|
+
|
|
69
|
+
Les éléments interactifs déjà présents dans la ligne, comme les cases à cocher, liens ou boutons, conservent leur comportement propre et ne déclenchent pas `row-click`.
|
|
70
|
+
|
|
71
|
+
L'événement `row-click` est émis lorsqu'une ligne est activée alors que `clickableRow` est à `true`.
|
|
72
|
+
|
|
73
|
+
- Payload : l'objet de la ligne cliquée
|
|
74
|
+
- Cas pris en charge : clic souris sur la ligne, activation clavier via <kbd>Entrée</kbd> ou <kbd>Espace</kbd>
|
|
75
|
+
- Cas exclus : interaction avec un élément interactif imbriqué dans la ligne
|
|
76
|
+
|
|
77
|
+
Exemple :
|
|
78
|
+
<Source dark code={`
|
|
79
|
+
<SyTable
|
|
80
|
+
:items="items"
|
|
81
|
+
:headers="headers"
|
|
82
|
+
clickable-row
|
|
83
|
+
@row-click="handleRowClick"
|
|
84
|
+
/>
|
|
85
|
+
`}/>
|
|
86
|
+
|
|
87
|
+
|
|
63
88
|
### Slot item
|
|
64
89
|
Le composant permet de personnaliser l'affichage des contenus en utilisant le slot `item`. Vous pouvez définir la structure de chaque contenu en fonction de vos besoins.
|
|
65
90
|
|