@cnamts/synapse 1.0.26 → 1.0.27
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-BPR-a55G.js → AutocompleteFilter-C9eLKyW8.js} +3 -3
- package/dist/{DateFilter-CknrJWs2.js → DateFilter-y-GLkAkn.js} +8 -8
- package/dist/{NumberFilter-DJ-yNlzv.js → NumberFilter-DN6hIBS7.js} +1 -1
- package/dist/{PeriodFilter-CiB5Oa9Z.js → PeriodFilter-MoUUp9qS.js} +1 -1
- package/dist/{SelectFilter-EiafX97M.js → SelectFilter-bCbrdLmu.js} +1 -1
- package/dist/{TextFilter-BzOmpdxj.js → TextFilter-CvjgEaoM.js} +4 -4
- package/dist/apLightTheme2026-ug4Y23ns.js +611 -0
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +2369 -353
- package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +18 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/ariaManager.d.ts +1 -1
- package/dist/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.d.ts +3 -1
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +9 -10
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +1 -0
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +15 -0
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +3 -3
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +3 -3
- package/dist/components/Customs/SyIconButton/SyIconButton.d.ts +18 -0
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +20 -38
- package/dist/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.d.ts +50 -0
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +6 -6
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +147 -136
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +62 -54
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +27 -24
- package/dist/components/DatePicker/composables/index.d.ts +1 -0
- package/dist/components/DatePicker/composables/useDatePickerValidationBridge.d.ts +51 -0
- package/dist/components/MonthPicker/MonthPicker.d.ts +23 -23
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +23 -23
- package/dist/components/NirField/NirField.d.ts +56 -56
- package/dist/components/PasswordField/PasswordField.d.ts +3 -3
- package/dist/components/PeriodField/PeriodField.d.ts +236 -212
- package/dist/components/PhoneField/PhoneField.d.ts +23 -23
- package/dist/components/SyTextArea/SyTextArea.d.ts +25 -15
- package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +20 -0
- package/dist/components/SyTextArea/locales.d.ts +1 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +1 -0
- package/dist/components/Tables/SyTable/SyTable.d.ts +1 -0
- package/dist/components/Tables/common/SyTablePagination.d.ts +25 -25
- package/dist/components/Tables/common/types.d.ts +2 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/composables/unifyValidation/documentationValidationProps.d.ts +160 -160
- package/dist/composables/unifyValidation/useValidation.d.ts +16 -14
- package/dist/design-system-v3.js +81 -80
- package/dist/designTokens/tokens/amelipro/apContextual.d.ts +6 -6
- package/dist/designTokens/tokens/amelipro/apDarkTheme.d.ts +3 -1
- package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +53 -100
- package/dist/designTokens/tokens/baseContextualTokens.d.ts +0 -6
- package/dist/designTokens/tokens/baseTokens.d.ts +232 -0
- package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +6 -6
- package/dist/designTokens/tokens/cnam/cnamDarkTheme.d.ts +1 -1
- package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +57 -101
- package/dist/designTokens/tokens/pa/paContextual.d.ts +0 -6
- package/dist/designTokens/tokens/pa/paDarkTheme.d.ts +1 -1
- package/dist/designTokens/tokens/pa/paLightTheme.d.ts +53 -97
- package/dist/designTokens/tokens/pa/paSemantic.d.ts +1 -0
- package/dist/designTokens/tokens/semanticTokens.d.ts +112 -0
- package/dist/main-CI6Q9nmO.js +39234 -0
- package/dist/synapse.css +1 -1
- package/dist/vuetifyConfig.js +208 -72
- package/package.json +4 -2
- package/src/assets/overrides/_icons.scss +5 -4
- package/src/assets/overrides/_otp.scss +4 -4
- package/src/assets/overrides/_typography.scss +2 -1
- package/src/assets/overrides/_utilities.scss +1 -42
- package/src/components/ChipList/ChipList.vue +30 -18
- package/src/components/ChipList/tests/chipList.spec.ts +4 -4
- package/src/components/CopyBtn/CopyBtn.vue +2 -2
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +4 -0
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +7 -6
- package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +223 -0
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +283 -351
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +182 -218
- package/src/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.ts +101 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +761 -1
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +3 -1
- package/src/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.ts +79 -5
- package/src/components/Customs/Selects/SyAutocomplete/validation/Validation.stories.ts +1029 -0
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +9 -491
- package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -79
- package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +3 -0
- package/src/components/Customs/Selects/SySelect/composables/useSySelectValidation.ts +64 -0
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +196 -0
- package/src/components/Customs/Selects/SySelect/validation/Validation.stories.ts +1026 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +18 -7
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +2 -2
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +8 -8
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +8 -8
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +1 -1
- package/src/components/Customs/SyIcon/accessibilite/Accessibility.mdx +0 -6
- package/src/components/Customs/SyIcon/utils/tests/iconUtils.spec.ts +107 -0
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.mdx +2 -2
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.stories.ts +395 -200
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +82 -127
- package/src/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.ts +127 -0
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.a11y.spec.ts +93 -1
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.spec.ts +146 -9
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.visual.cy.ts +165 -0
- package/src/components/Customs/SyRadioGroup/validation/Validation.stories.ts +773 -0
- package/src/components/Customs/SyTabs/config.ts +3 -3
- package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +265 -0
- package/src/components/Customs/SyTabs/tests/useTabTransition.spec.ts +188 -0
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +10 -29
- package/src/components/Customs/SyTextField/SyTextField.vue +23 -15
- package/src/components/DataList/DataList.stories.ts +1 -1
- package/src/components/DataListItem/tests/DataListItem.spec.ts +3 -1
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +37 -142
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.coverage.spec.ts +156 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.spec.ts +495 -4
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +47 -66
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +206 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/bridge-integration.regression.spec.ts +210 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/calendar-navigation.regression.spec.ts +214 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/validation-cross.regression.spec.ts +194 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/validation-success-messages.regression.spec.ts +83 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +129 -54
- package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +320 -0
- package/src/components/DatePicker/composables/index.ts +1 -0
- package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +360 -0
- package/src/components/DatePicker/composables/tests/useDatePickerValidationBridge.spec.ts +129 -0
- package/src/components/DatePicker/composables/useDatePickerValidationBridge.ts +205 -0
- package/src/components/DatePicker/docExamples/BidirectionalComplexValidation.vue +1 -1
- package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +1 -1
- package/src/components/DatePicker/tests/exposed-methods.coverage.spec.ts +75 -0
- package/src/components/DialogBox/DialogBox.vue +1 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +4 -4
- package/src/components/FileUpload/FileUpload.vue +2 -2
- package/src/components/FileUpload/FileUploadContent.vue +1 -1
- package/src/components/FilterInline/FilterInline.mdx +2 -2
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +1 -1
- package/src/components/FilterSideBar/FilterSideBar.vue +2 -2
- package/src/components/FooterBar/FooterBar.vue +7 -7
- package/src/components/FranceConnectBtn/FranceConnectBtn.vue +1 -1
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +2 -2
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +7 -7
- package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +2 -2
- package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +87 -8
- package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +3 -3
- package/src/components/HeaderNavigationBar/HorizontalNavbar/tests/HorizontalNavbar.spec.ts +589 -0
- package/src/components/HeaderToolbar/tests/HeaderToolBar.spec.ts +153 -1
- package/src/components/HeaderToolbar/tests/useMobileRightMenu.spec.ts +258 -0
- package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +2 -2
- package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +1 -1
- package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +184 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +3 -3
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +1 -1
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +2 -2
- package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +1 -1
- package/src/components/NirField/NirField.vue +3 -3
- package/src/components/NotificationBar/Notification/Notification.vue +12 -12
- package/src/components/NotificationBar/NotificationBar.stories.ts +8 -8
- package/src/components/PaginatedTable/Pagination.vue +2 -2
- package/src/components/PasswordField/PasswordField.vue +8 -8
- package/src/components/PasswordField/tests/PasswordField.spec.ts +3 -3
- package/src/components/RangeField/RangeSlider/RangeSlider.vue +2 -2
- package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +1 -1
- package/src/components/StatusPage/tests/StatusPage.spec.ts +149 -0
- package/src/components/SubHeader/SubHeader.vue +1 -1
- package/src/components/SyAlert/SyAlert.vue +23 -23
- package/src/components/SyTextArea/SyTextArea.stories.ts +177 -131
- package/src/components/SyTextArea/SyTextArea.vue +235 -83
- package/src/components/SyTextArea/composables/useSyTextAreaValidation.ts +81 -0
- package/src/components/SyTextArea/locales.ts +1 -0
- package/src/components/SyTextArea/tests/SyTextArea.spec.ts +449 -1
- package/src/components/SyTextArea/useDefaultValidationRules.ts +2 -7
- package/src/components/SyTextArea/validation/Validation.stories.ts +856 -0
- package/src/components/TableToolbar/TableToolbar.vue +6 -6
- package/src/components/TableToolbar/accessibilite/Accessibility.mdx +81 -7
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +163 -0
- package/src/components/Tables/SyServerTable/SyServerTable.vue +2 -1
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
- package/src/components/Tables/SyTable/SyTable.stories.ts +94 -0
- package/src/components/Tables/SyTable/SyTable.vue +2 -1
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +64 -0
- package/src/components/Tables/common/TableHeader.vue +2 -2
- package/src/components/Tables/common/filters/logics/tests/NumberFilterLogic.spec.ts +176 -0
- package/src/components/Tables/common/filters/logics/tests/SelectFilterLogic.spec.ts +111 -0
- package/src/components/Tables/common/tableStyles.scss +6 -6
- package/src/components/Tables/common/types.ts +2 -0
- package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +2 -0
- package/src/components/index.ts +1 -0
- package/src/composables/date/tests/useDateFormatDayjs.spec.ts +31 -0
- package/src/composables/date/tests/useHolidayDay.spec.ts +109 -0
- package/src/composables/rules/tests/useFieldValidation.spec.ts +374 -0
- package/src/composables/tests/useError.spec.ts +30 -0
- package/src/composables/tests/useFormFieldErrorHandling.spec.ts +234 -0
- package/src/composables/unifyValidation/documentationValidationProps.ts +5 -5
- package/src/composables/unifyValidation/tests/documentationValidationProps.spec.ts +177 -0
- package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +30 -0
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +6 -2
- package/src/composables/unifyValidation/useCustomValidation.ts +19 -9
- package/src/composables/unifyValidation/useValidation.ts +18 -21
- package/src/composables/useFilterable/useFilterable.spec.ts +42 -0
- package/src/composables/useFilterable/useFilterable.ts +11 -7
- package/src/composables/useFormFieldErrorHandling.ts +2 -2
- package/src/composantsVuetify/VBtn/VBtn.mdx +9 -39
- package/src/composantsVuetify/VBtn/v-btn.stories.ts +26 -86
- package/src/designTokens/tokens/amelipro/apContextual.ts +6 -0
- package/src/designTokens/tokens/amelipro/apDarkTheme.ts +2 -2
- package/src/designTokens/tokens/amelipro/apLightTheme.ts +72 -103
- package/src/designTokens/tokens/amelipro/apSemantic.ts +1 -1
- package/src/designTokens/tokens/baseContextualTokens.ts +1 -6
- package/src/designTokens/tokens/baseTokens.ts +232 -0
- package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -0
- package/src/designTokens/tokens/cnam/cnamDarkTheme.ts +2 -2
- package/src/designTokens/tokens/cnam/cnamLightTheme.ts +76 -104
- package/src/designTokens/tokens/pa/paDarkTheme.ts +2 -2
- package/src/designTokens/tokens/pa/paLightTheme.ts +73 -99
- package/src/designTokens/tokens/pa/paSemantic.ts +2 -0
- package/src/designTokens/tokens/semanticTokens.ts +114 -0
- package/src/stories/Components/Components.stories.ts +7 -3
- package/src/stories/DesignTokens/ColorIntegrationExample.vue +2 -3
- package/src/stories/DesignTokens/Colors.mdx +6 -8
- package/src/stories/DesignTokens/colors.stories.ts +244 -1081
- package/src/utils/amelipro/toKebabCase/tests/toKebabCase.spec.ts +52 -0
- package/src/utils/formatNir/tests/formatNir.spec.ts +34 -0
- package/src/utils/tests/insertAt.spec.ts +44 -0
- package/dist/apLightTheme-DS0Uy44H.js +0 -954
- package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +0 -1
- package/dist/main-BsJ9ec3i.js +0 -38954
- package/src/components/BackBtn/tests/__snapshots__/back-btn-custom-bg.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-dark-mode.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-default.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-no-icon.snap.png +0 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.events.spec.ts +0 -178
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-custom-texts.snap.png +0 -0
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-default.snap.png +0 -0
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-no-actions.snap.png +0 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated-submenu-open.snap.png +0 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-custom-width.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-default.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-no-sticky.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-prepend.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-side.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-subtitle.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-avatar.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-dark.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-default.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-no-organism.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-no-signature.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-risque-pro.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-custom-bg.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-custom-range.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-default.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-step.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-with-label.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-closable.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-error.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-info.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-success.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-outlined.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-tonal.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-warning.snap.png +0 -0
- /package/src/components/RatingPicker/tests/{RatingPicker.a11y.spect.ts → RatingPicker.a11y.spec.ts} +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
inheritAttrs: false,
|
|
5
5
|
})
|
|
6
6
|
import { mdiAlertCircle, mdiAlertOutline, mdiCheck, mdiChevronDown, mdiClose, mdiCloseCircle, mdiInformationOutline } from '@mdi/js'
|
|
7
|
-
import { ref, watch, watchEffect, onMounted, onBeforeUnmount, computed, nextTick, useAttrs
|
|
7
|
+
import { ref, watch, watchEffect, onMounted, onBeforeUnmount, computed, nextTick, useAttrs } from 'vue'
|
|
8
8
|
import { useSySelectKeyboard } from './composables/useSySelectKeyboard'
|
|
9
9
|
import type { ColorType, IconType, VariantStyle } from '@/types/vuetifyTypes'
|
|
10
10
|
import type { VList, VTextField } from 'vuetify/components'
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
import IconSlot from '@/components/Common/IconSlot/IconSlot.vue'
|
|
14
14
|
import SyIcon from '@/components/Customs/SyIcon/SyIcon.vue'
|
|
15
15
|
import { locales } from './locales'
|
|
16
|
-
import type
|
|
17
|
-
import {
|
|
16
|
+
import { validationPropsDefaults, type FieldValidationProps } from '@/composables/unifyValidation/useValidation'
|
|
17
|
+
import { useSySelectValidation } from './composables/useSySelectValidation'
|
|
18
18
|
|
|
19
19
|
export type ItemType = {
|
|
20
20
|
[key: string]: unknown
|
|
@@ -121,9 +121,9 @@
|
|
|
121
121
|
|
|
122
122
|
const iconColor = computed(() => {
|
|
123
123
|
if (hasError.value) return 'error'
|
|
124
|
-
if (hasWarning.value) return '
|
|
125
|
-
if (hasSuccess.value) return '
|
|
126
|
-
return 'rgb(var(--v-theme-
|
|
124
|
+
if (hasWarning.value) return 'onWarningVariant'
|
|
125
|
+
if (hasSuccess.value) return 'onSuccessVariant'
|
|
126
|
+
return 'rgb(var(--v-theme-onSurface))'
|
|
127
127
|
})
|
|
128
128
|
|
|
129
129
|
const variant = computed(() => {
|
|
@@ -134,43 +134,9 @@
|
|
|
134
134
|
const isOpen = ref(false)
|
|
135
135
|
// Initialize selectedItem with props.modelValue or empty array for multiple mode
|
|
136
136
|
const selectedItem = ref<SelectItemValueType | SelectItemArrayType>(props.modelValue)
|
|
137
|
-
const focused = ref(false)
|
|
138
137
|
const menuMinWidth = ref<number | null>(null)
|
|
139
138
|
|
|
140
|
-
const
|
|
141
|
-
? [{
|
|
142
|
-
type: 'required',
|
|
143
|
-
options: {
|
|
144
|
-
message: `Le champ ${props.label || 'ce champ'} est requis.`,
|
|
145
|
-
fieldIdentifier: props.label,
|
|
146
|
-
},
|
|
147
|
-
}]
|
|
148
|
-
: [],
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
const { validate, clearValidation, errors, warnings, successes, hasError, hasWarning, hasSuccess } = useValidation({
|
|
152
|
-
modelValue: toRef(props, 'modelValue') as Ref<unknown>,
|
|
153
|
-
readonly: toRef(props, 'readonly'),
|
|
154
|
-
disabled: toRef(props, 'disabled'),
|
|
155
|
-
required: toRef(props, 'required'),
|
|
156
|
-
isValidateOnBlur: toRef(props, 'isValidateOnBlur'),
|
|
157
|
-
showSuccessMessages: toRef(props, 'showSuccessMessages'),
|
|
158
|
-
disableErrorHandling: toRef(props, 'disableErrorHandling'),
|
|
159
|
-
useVuetifyValidation: toRef(props, 'useVuetifyValidation'),
|
|
160
|
-
label: toRef(props, 'label'),
|
|
161
|
-
rules: toRef(props, 'rules'),
|
|
162
|
-
customRules: computed(() => [...defaultRules.value, ...(props.customRules ?? [])]),
|
|
163
|
-
customWarningRules: toRef(props, 'customWarningRules'),
|
|
164
|
-
customSuccessRules: toRef(props, 'customSuccessRules'),
|
|
165
|
-
errorMessages: toRef(props, 'errorMessages'),
|
|
166
|
-
warningMessages: toRef(props, 'warningMessages'),
|
|
167
|
-
successMessages: toRef(props, 'successMessages'),
|
|
168
|
-
hasErrorProp: toRef(props, 'hasError'),
|
|
169
|
-
hasWarningProp: toRef(props, 'hasWarning'),
|
|
170
|
-
hasSuccessProp: toRef(props, 'hasSuccess'),
|
|
171
|
-
maxErrors: toRef(props, 'maxErrors'),
|
|
172
|
-
focused: focused,
|
|
173
|
-
})
|
|
139
|
+
const { focused, validate, clearValidation, errors, warnings, successes, hasError, hasWarning, hasSuccess, validationIcon } = useSySelectValidation(props)
|
|
174
140
|
|
|
175
141
|
const labelWidth = ref(0)
|
|
176
142
|
const labelRef = ref<HTMLElement | null>(null)
|
|
@@ -567,14 +533,6 @@
|
|
|
567
533
|
return formattedErrorMessages.value || 'Le champ contient une erreur.'
|
|
568
534
|
})
|
|
569
535
|
|
|
570
|
-
const validationIcon = computed(() => {
|
|
571
|
-
if (props.useVuetifyValidation) return null
|
|
572
|
-
if (hasError.value) return mdiAlertCircle
|
|
573
|
-
if (hasWarning.value) return mdiAlertOutline
|
|
574
|
-
if (hasSuccess.value) return mdiCheck
|
|
575
|
-
return null
|
|
576
|
-
})
|
|
577
|
-
|
|
578
536
|
watch(() => props.modelValue, (newValue) => {
|
|
579
537
|
selectedItem.value = newValue
|
|
580
538
|
})
|
|
@@ -944,6 +902,14 @@
|
|
|
944
902
|
}
|
|
945
903
|
}
|
|
946
904
|
|
|
905
|
+
const onBlur = () => {
|
|
906
|
+
// Trigger blur validation only when focus truly leaves the component.
|
|
907
|
+
// Skip if the menu is open — focus is moving to the dropdown list, not exiting.
|
|
908
|
+
if (!isOpen.value) {
|
|
909
|
+
validate()
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
|
|
947
913
|
return {
|
|
948
914
|
...activatorProps,
|
|
949
915
|
onKeydown: undefined,
|
|
@@ -953,7 +919,8 @@
|
|
|
953
919
|
textInput.value = el
|
|
954
920
|
activatorProps.ref?.(el)
|
|
955
921
|
},
|
|
956
|
-
onFocus
|
|
922
|
+
onFocus,
|
|
923
|
+
onBlur,
|
|
957
924
|
}
|
|
958
925
|
}
|
|
959
926
|
</script>
|
|
@@ -1270,12 +1237,12 @@
|
|
|
1270
1237
|
|
|
1271
1238
|
:deep(.v-input__prepend > .v-icon__svg),
|
|
1272
1239
|
:deep(.v-input__append > .v-icon__svg) {
|
|
1273
|
-
fill: rgb(var(--v-theme-
|
|
1240
|
+
fill: rgb(var(--v-theme-onSurface));
|
|
1274
1241
|
}
|
|
1275
1242
|
|
|
1276
1243
|
:deep(.v-input__prepend .v-icon:focus-visible),
|
|
1277
1244
|
:deep(.v-input__append .v-icon:focus-visible) {
|
|
1278
|
-
outline: 2px solid rgb(var(--v-theme-
|
|
1245
|
+
outline: 2px solid rgb(var(--v-theme-primary));
|
|
1279
1246
|
outline-offset: 2px;
|
|
1280
1247
|
opacity: 1;
|
|
1281
1248
|
}
|
|
@@ -1283,30 +1250,30 @@
|
|
|
1283
1250
|
|
|
1284
1251
|
.warning-field {
|
|
1285
1252
|
:deep(.v-icon__svg) {
|
|
1286
|
-
fill: rgb(var(--v-theme-
|
|
1253
|
+
fill: rgb(var(--v-theme-onWarningVariant)) !important;
|
|
1287
1254
|
}
|
|
1288
1255
|
|
|
1289
1256
|
:deep(.v-icon.arrow) {
|
|
1290
|
-
color: rgb(var(--v-theme-
|
|
1257
|
+
color: rgb(var(--v-theme-primary)) !important;
|
|
1291
1258
|
}
|
|
1292
1259
|
|
|
1293
1260
|
:deep(.v-icon.arrow .v-icon__svg) {
|
|
1294
|
-
fill: rgb(var(--v-theme-
|
|
1261
|
+
fill: rgb(var(--v-theme-primary)) !important;
|
|
1295
1262
|
}
|
|
1296
1263
|
|
|
1297
1264
|
:deep(.sy-select__clear-icon .v-icon__svg) {
|
|
1298
|
-
fill: rgb(var(--v-theme-
|
|
1265
|
+
fill: rgb(var(--v-theme-primary)) !important;
|
|
1299
1266
|
}
|
|
1300
1267
|
|
|
1301
1268
|
:deep(.v-field) {
|
|
1302
|
-
color: rgb(var(--v-theme-
|
|
1269
|
+
color: rgb(var(--v-theme-onWarningVariant)) !important;
|
|
1303
1270
|
|
|
1304
1271
|
--v-medium-emphasis-opacity: 1;
|
|
1305
1272
|
|
|
1306
1273
|
.v-field__outline {
|
|
1307
1274
|
--v-field-border-opacity: 1;
|
|
1308
1275
|
|
|
1309
|
-
color: rgb(var(--v-theme-
|
|
1276
|
+
color: rgb(var(--v-theme-onWarningVariant)) !important;
|
|
1310
1277
|
}
|
|
1311
1278
|
}
|
|
1312
1279
|
|
|
@@ -1314,19 +1281,19 @@
|
|
|
1314
1281
|
opacity: 1 !important;
|
|
1315
1282
|
|
|
1316
1283
|
.v-messages__message {
|
|
1317
|
-
color: rgb(var(--v-theme-
|
|
1284
|
+
color: rgb(var(--v-theme-onWarningVariant)) !important;
|
|
1318
1285
|
}
|
|
1319
1286
|
}
|
|
1320
1287
|
}
|
|
1321
1288
|
|
|
1322
1289
|
.error-field {
|
|
1323
1290
|
:deep(.v-field) {
|
|
1324
|
-
color: rgb(var(--v-theme-
|
|
1291
|
+
color: rgb(var(--v-theme-error)) !important;
|
|
1325
1292
|
|
|
1326
1293
|
.v-field__outline {
|
|
1327
1294
|
--v-field-border-opacity: 1;
|
|
1328
1295
|
|
|
1329
|
-
color: rgb(var(--v-theme-
|
|
1296
|
+
color: rgb(var(--v-theme-error)) !important;
|
|
1330
1297
|
}
|
|
1331
1298
|
}
|
|
1332
1299
|
|
|
@@ -1334,45 +1301,45 @@
|
|
|
1334
1301
|
opacity: 1 !important;
|
|
1335
1302
|
|
|
1336
1303
|
.v-messages__message {
|
|
1337
|
-
color: rgb(var(--v-theme-
|
|
1304
|
+
color: rgb(var(--v-theme-error)) !important;
|
|
1338
1305
|
}
|
|
1339
1306
|
}
|
|
1340
1307
|
|
|
1341
1308
|
:deep(.v-icon.arrow) {
|
|
1342
|
-
color: rgb(var(--v-theme-
|
|
1309
|
+
color: rgb(var(--v-theme-onSurfaceVariant)) !important;
|
|
1343
1310
|
}
|
|
1344
1311
|
|
|
1345
1312
|
:deep(.v-icon.arrow .v-icon__svg) {
|
|
1346
|
-
fill: rgb(var(--v-theme-
|
|
1313
|
+
fill: rgb(var(--v-theme-onSurfaceVariant)) !important;
|
|
1347
1314
|
}
|
|
1348
1315
|
}
|
|
1349
1316
|
|
|
1350
1317
|
.success-field {
|
|
1351
1318
|
:deep(.v-icon__svg) {
|
|
1352
|
-
fill: rgb(var(--v-theme-
|
|
1319
|
+
fill: rgb(var(--v-theme-onSuccessVariant)) !important;
|
|
1353
1320
|
}
|
|
1354
1321
|
|
|
1355
1322
|
:deep(.v-icon.arrow) {
|
|
1356
|
-
color: rgb(var(--v-theme-
|
|
1323
|
+
color: rgb(var(--v-theme-onSurface)) !important;
|
|
1357
1324
|
}
|
|
1358
1325
|
|
|
1359
1326
|
:deep(.v-icon.arrow .v-icon__svg) {
|
|
1360
|
-
fill: rgb(var(--v-theme-
|
|
1327
|
+
fill: rgb(var(--v-theme-onSurface)) !important;
|
|
1361
1328
|
}
|
|
1362
1329
|
|
|
1363
1330
|
:deep(.sy-select__clear-icon .v-icon__svg) {
|
|
1364
|
-
fill: rgb(var(--v-theme-
|
|
1331
|
+
fill: rgb(var(--v-theme-onSurface)) !important;
|
|
1365
1332
|
}
|
|
1366
1333
|
|
|
1367
1334
|
:deep(.v-field) {
|
|
1368
|
-
color: rgb(var(--v-theme-
|
|
1335
|
+
color: rgb(var(--v-theme-onSuccessVariant)) !important;
|
|
1369
1336
|
|
|
1370
1337
|
--v-medium-emphasis-opacity: 1;
|
|
1371
1338
|
|
|
1372
1339
|
.v-field__outline {
|
|
1373
1340
|
--v-field-border-opacity: 1;
|
|
1374
1341
|
|
|
1375
|
-
color: rgb(var(--v-theme-
|
|
1342
|
+
color: rgb(var(--v-theme-onSuccessVariant)) !important;
|
|
1376
1343
|
}
|
|
1377
1344
|
}
|
|
1378
1345
|
|
|
@@ -1380,14 +1347,14 @@
|
|
|
1380
1347
|
opacity: 1 !important;
|
|
1381
1348
|
|
|
1382
1349
|
.v-messages__message {
|
|
1383
|
-
color: rgb(var(--v-theme-
|
|
1350
|
+
color: rgb(var(--v-theme-onSuccessVariant)) !important;
|
|
1384
1351
|
}
|
|
1385
1352
|
}
|
|
1386
1353
|
}
|
|
1387
1354
|
|
|
1388
1355
|
.basic-field {
|
|
1389
1356
|
:deep(.v-field--focused .v-field__outline) {
|
|
1390
|
-
color: rgb(var(--v-theme-
|
|
1357
|
+
color: rgb(var(--v-theme-primary)) !important;
|
|
1391
1358
|
opacity: 1 !important;
|
|
1392
1359
|
}
|
|
1393
1360
|
}
|
|
@@ -1415,29 +1382,29 @@
|
|
|
1415
1382
|
}
|
|
1416
1383
|
|
|
1417
1384
|
.help-text {
|
|
1418
|
-
color: rgba(var(--v-theme-
|
|
1385
|
+
color: rgba(var(--v-theme-onSurface), var(--v-medium-emphasis-opacity));
|
|
1419
1386
|
font-size: var(--v-fontSize-liensEtLibelles);
|
|
1420
1387
|
line-height: 1.2;
|
|
1421
1388
|
}
|
|
1422
1389
|
|
|
1423
1390
|
.help-text.text-disabled {
|
|
1424
|
-
color: rgba(var(--v-theme-
|
|
1391
|
+
color: rgba(var(--v-theme-onSurface), var(--v-disabled-opacity));
|
|
1425
1392
|
}
|
|
1426
1393
|
|
|
1427
1394
|
.help-text-below {
|
|
1428
|
-
color: rgba(var(--v-theme-
|
|
1395
|
+
color: rgba(var(--v-theme-onSurface), var(--v-medium-emphasis-opacity));
|
|
1429
1396
|
font-size: var(--v-fontSize-liensEtLibelles);
|
|
1430
1397
|
line-height: 1.2;
|
|
1431
1398
|
}
|
|
1432
1399
|
|
|
1433
1400
|
.help-text-below.text-disabled {
|
|
1434
|
-
color: rgba(var(--v-theme-
|
|
1401
|
+
color: rgba(var(--v-theme-onSurface), var(--v-disabled-opacity));
|
|
1435
1402
|
}
|
|
1436
1403
|
|
|
1437
1404
|
/* Ensure focus styles match selection styles for keyboard navigation */
|
|
1438
1405
|
.v-list-item:focus-visible,
|
|
1439
1406
|
.v-list-item.keyboard-focused {
|
|
1440
|
-
outline: 2px solid rgb(var(--v-theme-
|
|
1407
|
+
outline: 2px solid rgb(var(--v-theme-primary));
|
|
1441
1408
|
outline-offset: -2px;
|
|
1442
1409
|
background-color: rgb(0 0 0 / 8%);
|
|
1443
1410
|
}
|
|
@@ -1467,7 +1434,7 @@
|
|
|
1467
1434
|
}
|
|
1468
1435
|
|
|
1469
1436
|
.sy-select__clear-icon {
|
|
1470
|
-
color: rgb(var(--v-theme-
|
|
1437
|
+
color: rgb(var(--v-theme-onSurface)) !important;
|
|
1471
1438
|
opacity: var(--v-medium-emphasis-opacity) !important;
|
|
1472
1439
|
}
|
|
1473
1440
|
|
|
@@ -1512,7 +1479,7 @@
|
|
|
1512
1479
|
|
|
1513
1480
|
.sy-select :deep(.v-field__input) {
|
|
1514
1481
|
opacity: 1;
|
|
1515
|
-
color: rgb(var(--v-theme-
|
|
1482
|
+
color: rgb(var(--v-theme-onSurface)) !important;
|
|
1516
1483
|
cursor: pointer;
|
|
1517
1484
|
caret-color: transparent;
|
|
1518
1485
|
padding-right: 25px;
|
|
@@ -12,6 +12,7 @@ export interface UseSySelectKeyboardOptions {
|
|
|
12
12
|
getItemText: (item: unknown) => unknown
|
|
13
13
|
optionIdPrefix?: string
|
|
14
14
|
focusListItem?: boolean
|
|
15
|
+
skipInitialFocus?: Ref<boolean>
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export function useSySelectKeyboard(options: UseSySelectKeyboardOptions) {
|
|
@@ -23,6 +24,7 @@ export function useSySelectKeyboard(options: UseSySelectKeyboardOptions) {
|
|
|
23
24
|
getItemText,
|
|
24
25
|
optionIdPrefix = 'option',
|
|
25
26
|
focusListItem = true,
|
|
27
|
+
skipInitialFocus,
|
|
26
28
|
} = options
|
|
27
29
|
|
|
28
30
|
const getOptionId = (index: number) => `${optionIdPrefix}-${index}`
|
|
@@ -339,6 +341,7 @@ export function useSySelectKeyboard(options: UseSySelectKeyboardOptions) {
|
|
|
339
341
|
// Gérer l'ouverture et la fermeture de la liste
|
|
340
342
|
watch(isOpen, (open) => {
|
|
341
343
|
if (open) {
|
|
344
|
+
if (skipInitialFocus?.value) return
|
|
342
345
|
// À l'ouverture, restaurer le dernier focus ou initialiser au premier élément
|
|
343
346
|
nextTick(() => {
|
|
344
347
|
if (lastFocusedIndex.value >= 0 && lastFocusedIndex.value < formattedItems.value.length) {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { computed, ref } from 'vue'
|
|
2
|
+
import { mdiAlertCircle, mdiAlertOutline, mdiCheck } from '@mdi/js'
|
|
3
|
+
import { useValidation, type FieldValidationProps } from '@/composables/unifyValidation/useValidation'
|
|
4
|
+
import type { ValidationRule } from '@/composables/validation/useValidation'
|
|
5
|
+
|
|
6
|
+
export function useSySelectValidation(props: FieldValidationProps & { modelValue?: unknown }) {
|
|
7
|
+
const focused = ref(false)
|
|
8
|
+
|
|
9
|
+
const defaultRules = computed<ValidationRule[]>(() => props.required
|
|
10
|
+
? [{
|
|
11
|
+
type: 'required',
|
|
12
|
+
options: {
|
|
13
|
+
message: `Le champ ${props.label || 'ce champ'} est requis.`,
|
|
14
|
+
fieldIdentifier: props.label,
|
|
15
|
+
},
|
|
16
|
+
}]
|
|
17
|
+
: [],
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const { validate, clearValidation, errors, warnings, successes, hasError, hasWarning, hasSuccess } = useValidation({
|
|
21
|
+
modelValue: computed(() => props.modelValue),
|
|
22
|
+
readonly: computed(() => props.readonly ?? false),
|
|
23
|
+
disabled: computed(() => props.disabled ?? false),
|
|
24
|
+
required: computed(() => props.required ?? false),
|
|
25
|
+
isValidateOnBlur: computed(() => props.isValidateOnBlur ?? false),
|
|
26
|
+
showSuccessMessages: computed(() => props.showSuccessMessages ?? false),
|
|
27
|
+
disableErrorHandling: computed(() => props.disableErrorHandling ?? false),
|
|
28
|
+
useVuetifyValidation: computed(() => props.useVuetifyValidation ?? false),
|
|
29
|
+
label: computed(() => props.label ?? ''),
|
|
30
|
+
rules: computed(() => props.rules ?? []),
|
|
31
|
+
customRules: computed(() => [...defaultRules.value, ...(props.customRules ?? [])]),
|
|
32
|
+
customWarningRules: computed(() => props.customWarningRules ?? []),
|
|
33
|
+
customSuccessRules: computed(() => props.customSuccessRules ?? []),
|
|
34
|
+
errorMessages: computed(() => props.errorMessages ?? []),
|
|
35
|
+
warningMessages: computed(() => props.warningMessages ?? []),
|
|
36
|
+
successMessages: computed(() => props.successMessages ?? []),
|
|
37
|
+
hasErrorProp: computed(() => props.hasError ?? false),
|
|
38
|
+
hasWarningProp: computed(() => props.hasWarning ?? false),
|
|
39
|
+
hasSuccessProp: computed(() => props.hasSuccess ?? false),
|
|
40
|
+
maxErrors: computed(() => props.maxErrors ?? 1),
|
|
41
|
+
focused,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const validationIcon = computed(() => {
|
|
45
|
+
if (props.useVuetifyValidation) return null
|
|
46
|
+
if (hasError.value) return mdiAlertCircle
|
|
47
|
+
if (hasWarning.value) return mdiAlertOutline
|
|
48
|
+
if (hasSuccess.value) return mdiCheck
|
|
49
|
+
return null
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
focused,
|
|
54
|
+
validate,
|
|
55
|
+
clearValidation,
|
|
56
|
+
errors,
|
|
57
|
+
warnings,
|
|
58
|
+
successes,
|
|
59
|
+
hasError,
|
|
60
|
+
hasWarning,
|
|
61
|
+
hasSuccess,
|
|
62
|
+
validationIcon,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -783,6 +783,202 @@ describe('SySelect.vue', () => {
|
|
|
783
783
|
|
|
784
784
|
wrapper.unmount()
|
|
785
785
|
})
|
|
786
|
+
|
|
787
|
+
it('ne valide pas lors d\'un changement de valeur mais seulement à la fermeture du menu quand isValidateOnBlur est true', async () => {
|
|
788
|
+
const wrapper = mount(SySelect, {
|
|
789
|
+
props: {
|
|
790
|
+
items: [
|
|
791
|
+
{ text: 'Option 1', value: '1' },
|
|
792
|
+
{ text: 'Option 2', value: '2' },
|
|
793
|
+
],
|
|
794
|
+
label: 'Test Label',
|
|
795
|
+
modelValue: undefined,
|
|
796
|
+
isValidateOnBlur: true,
|
|
797
|
+
customRules: [{
|
|
798
|
+
type: 'custom',
|
|
799
|
+
options: {
|
|
800
|
+
validate: (value: unknown) => value === '2',
|
|
801
|
+
message: 'Test error message',
|
|
802
|
+
},
|
|
803
|
+
}],
|
|
804
|
+
},
|
|
805
|
+
attachTo: document.body,
|
|
806
|
+
})
|
|
807
|
+
|
|
808
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
809
|
+
const instance = wrapper.vm as any
|
|
810
|
+
expect(instance.hasError).toBe(false)
|
|
811
|
+
|
|
812
|
+
// Changement de valeur programmatique — l'erreur ne doit PAS apparaître
|
|
813
|
+
await wrapper.setProps({ modelValue: '1' })
|
|
814
|
+
await wrapper.vm.$nextTick()
|
|
815
|
+
expect(instance.hasError).toBe(false)
|
|
816
|
+
|
|
817
|
+
// Ouverture puis fermeture du menu (= blur) — l'erreur doit apparaître
|
|
818
|
+
await wrapper.find('.v-field').trigger('click')
|
|
819
|
+
await wrapper.vm.$nextTick()
|
|
820
|
+
await wrapper.find('.v-field').trigger('click')
|
|
821
|
+
await wrapper.vm.$nextTick()
|
|
822
|
+
|
|
823
|
+
await vi.waitUntil(() => instance.hasError === true)
|
|
824
|
+
expect(wrapper.find('.v-messages').text()).toContain('Test error message')
|
|
825
|
+
|
|
826
|
+
wrapper.unmount()
|
|
827
|
+
})
|
|
828
|
+
|
|
829
|
+
it('déclenche la validation au blur natif sans ouvrir le menu', async () => {
|
|
830
|
+
const wrapper = mount(SySelect, {
|
|
831
|
+
props: {
|
|
832
|
+
required: true,
|
|
833
|
+
label: 'Test Label',
|
|
834
|
+
modelValue: undefined,
|
|
835
|
+
items: [
|
|
836
|
+
{ text: 'Option 1', value: '1' },
|
|
837
|
+
{ text: 'Option 2', value: '2' },
|
|
838
|
+
],
|
|
839
|
+
},
|
|
840
|
+
attachTo: document.body,
|
|
841
|
+
})
|
|
842
|
+
|
|
843
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
844
|
+
const instance = wrapper.vm as any
|
|
845
|
+
expect(instance.hasError).toBe(false)
|
|
846
|
+
|
|
847
|
+
// Simuler un blur natif sur l'input sans jamais ouvrir le menu
|
|
848
|
+
const input = wrapper.find('input')
|
|
849
|
+
await input.trigger('blur')
|
|
850
|
+
await wrapper.vm.$nextTick()
|
|
851
|
+
|
|
852
|
+
await vi.waitUntil(() => instance.hasError === true)
|
|
853
|
+
expect(wrapper.find('.v-messages').text()).toContain('requis')
|
|
854
|
+
|
|
855
|
+
wrapper.unmount()
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
it('affiche un avertissement avec customWarningRules', async () => {
|
|
859
|
+
const wrapper = mount(SySelect, {
|
|
860
|
+
props: {
|
|
861
|
+
items: [
|
|
862
|
+
{ text: 'Option 1', value: '1' },
|
|
863
|
+
{ text: 'Option 2', value: '2' },
|
|
864
|
+
],
|
|
865
|
+
label: 'Test Label',
|
|
866
|
+
modelValue: undefined,
|
|
867
|
+
isValidateOnBlur: false,
|
|
868
|
+
customWarningRules: [{
|
|
869
|
+
type: 'custom',
|
|
870
|
+
options: {
|
|
871
|
+
validate: (value: unknown) => value === '2',
|
|
872
|
+
warningMessage: 'Option 1 est dépréciée.',
|
|
873
|
+
},
|
|
874
|
+
}],
|
|
875
|
+
},
|
|
876
|
+
attachTo: document.body,
|
|
877
|
+
})
|
|
878
|
+
|
|
879
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
880
|
+
const instance = wrapper.vm as any
|
|
881
|
+
expect(instance.hasWarning).toBe(false)
|
|
882
|
+
|
|
883
|
+
await wrapper.find('.v-field').trigger('click')
|
|
884
|
+
await wrapper.vm.$nextTick()
|
|
885
|
+
await wrapper.findComponent(VList).findAll('.v-list-item').at(0)!.trigger('click')
|
|
886
|
+
await wrapper.setProps({ modelValue: '1' })
|
|
887
|
+
|
|
888
|
+
await vi.waitUntil(() => instance.hasWarning === true)
|
|
889
|
+
expect(wrapper.find('.v-messages').text()).toContain('Option 1 est dépréciée.')
|
|
890
|
+
|
|
891
|
+
wrapper.unmount()
|
|
892
|
+
})
|
|
893
|
+
|
|
894
|
+
it('validateOnSubmit retourne true quand le champ est valide', async () => {
|
|
895
|
+
const wrapper = mount(SySelect, {
|
|
896
|
+
props: {
|
|
897
|
+
required: true,
|
|
898
|
+
label: 'Test Label',
|
|
899
|
+
modelValue: '1',
|
|
900
|
+
items: [
|
|
901
|
+
{ text: 'Option 1', value: '1' },
|
|
902
|
+
{ text: 'Option 2', value: '2' },
|
|
903
|
+
],
|
|
904
|
+
},
|
|
905
|
+
attachTo: document.body,
|
|
906
|
+
})
|
|
907
|
+
|
|
908
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
909
|
+
const isValid = await (wrapper.vm as any).validateOnSubmit()
|
|
910
|
+
await nextTick()
|
|
911
|
+
|
|
912
|
+
expect(isValid).toBe(true)
|
|
913
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
914
|
+
expect((wrapper.vm as any).hasError).toBe(false)
|
|
915
|
+
|
|
916
|
+
wrapper.unmount()
|
|
917
|
+
})
|
|
918
|
+
|
|
919
|
+
it('affiche le message de succès avec customSuccessRules quand showSuccessMessages est true', async () => {
|
|
920
|
+
const wrapper = mount(SySelect, {
|
|
921
|
+
props: {
|
|
922
|
+
items: [
|
|
923
|
+
{ text: 'Option 1', value: '1' },
|
|
924
|
+
{ text: 'Option 2', value: '2' },
|
|
925
|
+
],
|
|
926
|
+
label: 'Test Label',
|
|
927
|
+
modelValue: undefined,
|
|
928
|
+
isValidateOnBlur: false,
|
|
929
|
+
showSuccessMessages: true,
|
|
930
|
+
customSuccessRules: [{
|
|
931
|
+
type: 'custom',
|
|
932
|
+
options: {
|
|
933
|
+
validate: (value: unknown) => value === '2',
|
|
934
|
+
successMessage: 'Test success message',
|
|
935
|
+
},
|
|
936
|
+
}],
|
|
937
|
+
},
|
|
938
|
+
attachTo: document.body,
|
|
939
|
+
})
|
|
940
|
+
|
|
941
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
942
|
+
const instance = wrapper.vm as any
|
|
943
|
+
expect(instance.hasSuccess).toBe(false)
|
|
944
|
+
|
|
945
|
+
await wrapper.setProps({ modelValue: '2' })
|
|
946
|
+
|
|
947
|
+
await vi.waitUntil(() => instance.hasSuccess === true)
|
|
948
|
+
expect(wrapper.find('.success-field').exists()).toBe(true)
|
|
949
|
+
expect(wrapper.find('.v-messages').text()).toContain('Test success message')
|
|
950
|
+
|
|
951
|
+
wrapper.unmount()
|
|
952
|
+
})
|
|
953
|
+
|
|
954
|
+
it('clearValidation remet l\'état d\'erreur à zéro', async () => {
|
|
955
|
+
const wrapper = mount(SySelect, {
|
|
956
|
+
props: {
|
|
957
|
+
required: true,
|
|
958
|
+
label: 'Test Label',
|
|
959
|
+
modelValue: undefined,
|
|
960
|
+
items: [
|
|
961
|
+
{ text: 'Option 1', value: '1' },
|
|
962
|
+
{ text: 'Option 2', value: '2' },
|
|
963
|
+
],
|
|
964
|
+
},
|
|
965
|
+
attachTo: document.body,
|
|
966
|
+
})
|
|
967
|
+
|
|
968
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
969
|
+
const instance = wrapper.vm as any
|
|
970
|
+
|
|
971
|
+
await instance.validateOnSubmit()
|
|
972
|
+
await nextTick()
|
|
973
|
+
expect(instance.hasError).toBe(true)
|
|
974
|
+
|
|
975
|
+
instance.clearValidation()
|
|
976
|
+
await nextTick()
|
|
977
|
+
expect(instance.hasError).toBe(false)
|
|
978
|
+
expect(wrapper.find('.v-messages__message').exists()).toBe(false)
|
|
979
|
+
|
|
980
|
+
wrapper.unmount()
|
|
981
|
+
})
|
|
786
982
|
})
|
|
787
983
|
|
|
788
984
|
describe('Comportement du menu', () => {
|