@cnamts/synapse 1.0.11 → 1.0.13
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-QEfKOz0P.js → DateFilter-_EFzsvvM.js} +1 -1
- package/dist/{NumberFilter-C0h7gVzp.js → NumberFilter-CUxEbKJh.js} +1 -1
- package/dist/{PeriodFilter-8dVrKjju.js → PeriodFilter-D5ueqtKy.js} +1 -1
- package/dist/{SelectFilter-BI3QGbqb.js → SelectFilter-BciBNydy.js} +1 -1
- package/dist/{TextFilter-UOp1hcPp.js → TextFilter-DMN_WAQB.js} +1 -1
- package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordion.d.ts +7 -3
- package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordionTemplate/AmeliproAccordionTemplate.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +2 -0
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +7 -3
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +50 -68
- package/dist/components/Amelipro/AmeliproCard/AmeliproCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIcon/AmeliproIcon.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +5 -5
- package/dist/components/Amelipro/AmeliproMultipleFoldingCard/AmeliproMultipleFoldingCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproNumberedCard/AmeliproNumberedCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +24 -32
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +36 -48
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +50 -68
- package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +4 -0
- package/dist/components/Amelipro/AmeliproTable/types.d.ts +11 -0
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +50 -68
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +0 -4
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +12 -16
- package/dist/components/Captcha/Captcha.d.ts +68 -0
- package/dist/components/Captcha/CaptchaAlert.d.ts +13 -0
- package/dist/components/Captcha/CaptchaBase.d.ts +55 -0
- package/dist/components/Captcha/CaptchaBtn.d.ts +12 -0
- package/dist/components/Captcha/CaptchaForm.d.ts +16 -0
- package/dist/components/Captcha/CaptchaImg.d.ts +12 -0
- package/dist/components/Captcha/CaptchaInformation.d.ts +20 -0
- package/dist/components/Captcha/captchaApi.d.ts +41 -0
- package/dist/components/Captcha/icons/volumeUp.d.ts +2 -0
- package/dist/components/Captcha/locales.d.ts +35 -0
- package/dist/components/Captcha/types.d.ts +2 -0
- package/dist/components/ChipList/ChipList.d.ts +2 -2
- package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +14 -14
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +5 -5
- package/dist/components/Customs/SyForm/SyForm.d.ts +6 -3
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +12 -16
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +96 -68
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +63 -38
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -27
- package/dist/components/DatePicker/composables/useDatePickerViewMode.d.ts +2 -1
- package/dist/components/DatePicker/tests/setup.d.ts +816 -520
- package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +10 -10
- package/dist/components/NirField/NirField.d.ts +31 -34
- package/dist/components/NirField/locales.d.ts +1 -3
- package/dist/components/PasswordField/PasswordField.d.ts +2 -0
- package/dist/components/PeriodField/PeriodField.d.ts +192 -128
- package/dist/components/PhoneField/PhoneField.d.ts +13 -17
- package/dist/components/SearchListField/SearchListField.d.ts +5 -5
- package/dist/components/SyTextArea/SyTextArea.d.ts +0 -4
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -8
- package/dist/components/Tables/SyTable/SyTable.d.ts +5 -8
- package/dist/components/Tables/common/SyTablePagination.d.ts +5 -5
- package/dist/components/Tables/common/types.d.ts +4 -0
- package/dist/components/Tables/common/usePagination.d.ts +3 -4
- package/dist/components/Tables/common/useTableCheckbox.d.ts +10 -6
- package/dist/components/index.d.ts +1 -0
- package/dist/composables/validation/useFormValidation.d.ts +10 -0
- package/dist/composables/validation/useValidatable.d.ts +10 -2
- package/dist/design-system-v3.js +126 -125
- package/dist/design-system-v3.umd.cjs +265 -265
- package/dist/main-DISHlqcd.js +34217 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/overrides/_forms.scss +2 -0
- package/src/components/Amelipro/AmeliproAccordion/AmeliproAccordion.stories.ts +7 -4
- package/src/components/Amelipro/AmeliproAccordion/AmeliproAccordion.vue +2 -0
- package/src/components/Amelipro/AmeliproAccordionFrieze/AmeliproAccordionFrieze.vue +1 -0
- package/src/components/Amelipro/AmeliproAccordionFrieze/__tests__/__snapshots__/AmeliproAccordionFrieze.spec.ts.snap +574 -112
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +5 -2
- package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +2 -1
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +6 -3
- package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +2 -0
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +5 -2
- package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +2 -1
- package/src/components/Amelipro/AmeliproCheckbox/__tests__/AmeliproCheckbox.spec.ts +175 -0
- package/src/components/Amelipro/AmeliproCheckbox/__tests__/__snapshots__/AmeliproCheckbox.spec.ts.snap +88 -0
- package/src/components/Amelipro/AmeliproCheckboxGroup/__tests__/AmeliproCheckboxGroup.spec.ts +423 -0
- package/src/components/Amelipro/AmeliproCheckboxGroup/{tests → __tests__}/__snapshots__/AmeliproCheckboxGroup.spec.ts.snap +112 -78
- package/src/components/Amelipro/AmeliproChips/__tests__/AmeliproChips.spec.ts +92 -0
- package/src/components/Amelipro/AmeliproChips/__tests__/__snapshots__/AmeliproChips.spec.ts.snap +81 -0
- package/src/components/Amelipro/AmeliproDialog/__tests__/AmeliproDialog.spec.ts +257 -0
- package/src/components/Amelipro/AmeliproDialog/__tests__/__snapshots__/AmeliproDialog.spec.ts.snap +61 -0
- package/src/components/Amelipro/AmeliproDisclosure/__tests__/AmeliproDisclosure.spec.ts +79 -0
- package/src/components/Amelipro/AmeliproDisclosure/__tests__/__snapshots__/AmeliproDisclosure.spec.ts.snap +89 -0
- package/src/components/Amelipro/AmeliproFooter/AmeliproFooter.vue +6 -7
- package/src/components/Amelipro/AmeliproFooter/__tests__/AmeliproFooter.spec.ts +787 -0
- package/src/components/Amelipro/AmeliproFooter/__tests__/__snapshots__/AmeliproFooter.spec.ts.snap +318 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/AmeliproHeaderBrandSection.spec.ts +167 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +100 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/AmeliproHeaderBar.spec.ts +312 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/__snapshots__/AmeliproHeaderBar.spec.ts.snap +98 -0
- package/src/components/Amelipro/AmeliproHeader/__tests__/AmeliproHeader.spec.ts +361 -0
- package/src/components/Amelipro/AmeliproHeader/__tests__/__snapshots__/AmeliproHeader.spec.ts.snap +22 -0
- package/src/components/Amelipro/AmeliproMenu/__tests__/AmeliproMenu.spec.ts +168 -0
- package/src/components/Amelipro/AmeliproMenu/__tests__/__snapshots__/AmeliproMenu.spec.ts.snap +295 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/AmeliproDropdownMenuBtn.spec.ts +128 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +67 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/AmeliproDropdownMenu.spec.ts +266 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +134 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/AmeliproMessagingMenuBtn.spec.ts +72 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +71 -0
- package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +12 -0
- package/src/components/Amelipro/AmeliproTable/AmeliproTable.stories.ts +81 -9
- package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +139 -61
- package/src/components/Amelipro/AmeliproTable/__tests__/AmeliproTable.spec.ts +10 -0
- package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +361 -187
- package/src/components/Amelipro/AmeliproTable/types.d.ts +11 -0
- package/src/components/Captcha/Captcha.mdx +72 -0
- package/src/components/Captcha/Captcha.stories.ts +276 -0
- package/src/components/Captcha/Captcha.vue +325 -0
- package/src/components/Captcha/CaptchaAlert.vue +60 -0
- package/src/components/Captcha/CaptchaBase.vue +219 -0
- package/src/components/Captcha/CaptchaBtn.vue +35 -0
- package/src/components/Captcha/CaptchaForm.vue +58 -0
- package/src/components/Captcha/CaptchaImg.vue +41 -0
- package/src/components/Captcha/CaptchaInformation.vue +64 -0
- package/src/components/Captcha/captchaApi.ts +111 -0
- package/src/components/Captcha/icons/volumeUp.vue +11 -0
- package/src/components/Captcha/locales.ts +35 -0
- package/src/components/Captcha/readme.md +5 -0
- package/src/components/Captcha/tests/Captcha.spec.ts +298 -0
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +716 -0
- package/src/components/Captcha/types.ts +2 -0
- package/src/components/Customs/Selects/SySelect/SySelect.vue +2 -2
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +4 -0
- package/src/components/Customs/SyForm/SyForm.stories.ts +133 -23
- package/src/components/Customs/SyForm/SyForm.vue +17 -1
- package/src/components/Customs/SyTextField/SyTextField.vue +29 -7
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +32 -9
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +154 -18
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +2 -2
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +35 -4
- package/src/components/DatePicker/composables/tests/useDatePickerViewMode.spec.ts +107 -72
- package/src/components/DatePicker/composables/tests/useMonthButtonCustomization.spec.ts +6 -6
- package/src/components/DatePicker/composables/useDatePickerViewMode.ts +57 -7
- package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +14 -14
- package/src/components/DatePicker/tests/navigation.regression.spec.ts +74 -0
- package/src/components/DatePicker/tests/navigation.simple.spec.ts +137 -0
- package/src/components/NirField/NirField.stories.ts +85 -2
- package/src/components/NirField/NirField.vue +55 -18
- package/src/components/NirField/locales.ts +1 -3
- package/src/components/PasswordField/PasswordField.vue +39 -7
- package/src/components/PhoneField/PhoneField.vue +43 -10
- package/src/components/RangeField/tests/RangeField.spec.ts +0 -3
- package/src/components/Tables/SyServerTable/SyServerTable.mdx +15 -0
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +309 -0
- package/src/components/Tables/SyServerTable/SyServerTable.vue +18 -3
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
- package/src/components/Tables/SyTable/SyTable.mdx +15 -0
- package/src/components/Tables/SyTable/SyTable.stories.ts +228 -0
- package/src/components/Tables/SyTable/SyTable.vue +18 -3
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +63 -0
- package/src/components/Tables/common/SyTablePagination.vue +10 -8
- package/src/components/Tables/common/types.ts +4 -0
- package/src/components/Tables/common/usePagination.ts +11 -20
- package/src/components/Tables/common/useTableCheckbox.ts +23 -11
- package/src/components/index.ts +1 -0
- package/src/composables/validation/AvecVosComposants.mdx.old +1 -1
- package/src/composables/validation/FormValidation.stories.ts.old +5 -5
- package/src/composables/validation/useFormValidation.ts +46 -8
- package/src/composables/validation/useValidatable.ts +19 -8
- package/src/stories/Accessibilite/Introduction.mdx +1 -1
- package/src/stories/Demarrer/EnrichirLeDesignSystem.mdx +43 -0
- package/src/stories/Demarrer/EnrichirLeDesignSystem.stories.ts +239 -0
- package/src/stories/Demarrer/SignalerUneAnomalie.mdx +39 -0
- package/src/stories/Demarrer/SignalerUneAnomalie.stories.ts +261 -0
- package/dist/main-DyEOPqqn.js +0 -33329
- package/src/components/Amelipro/AmeliproCheckbox/tests/AmeliproCheckbox.spec.ts +0 -19
- package/src/components/Amelipro/AmeliproCheckbox/tests/__snapshots__/AmeliproCheckbox.spec.ts.snap +0 -40
- package/src/components/Amelipro/AmeliproCheckboxGroup/tests/AmeliproCheckboxGroup.spec.ts +0 -46
- package/src/components/Amelipro/AmeliproChips/tests/AmeliproChips.spec.ts +0 -16
- package/src/components/Amelipro/AmeliproChips/tests/__snapshots__/AmeliproChips.spec.ts.snap +0 -97
- package/src/components/Amelipro/AmeliproDialog/tests/AmeliproDialog.spec.ts +0 -24
- package/src/components/Amelipro/AmeliproDialog/tests/__snapshots__/AmeliproDialog.spec.ts.snap +0 -134
- package/src/components/Amelipro/AmeliproDisclosure/tests/AmeliproDisclosure.spec.ts +0 -19
- package/src/components/Amelipro/AmeliproDisclosure/tests/__snapshots__/AmeliproDisclosure.spec.ts.snap +0 -104
- package/src/components/Amelipro/AmeliproFooter/tests/AmeliproFooter.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproFooter/tests/__snapshots__/AmeliproFooter.spec.ts.snap +0 -432
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/AmeliproHeaderBrandSection.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +0 -131
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/AmeliproHeaderBar.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/__snapshots__/AmeliproHeaderBar.spec.ts.snap +0 -172
- package/src/components/Amelipro/AmeliproHeader/tests/AmeliproHeader.spec.ts +0 -159
- package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +0 -841
- package/src/components/Amelipro/AmeliproMenu/tests/AmeliproMenu.spec.ts +0 -85
- package/src/components/Amelipro/AmeliproMenu/tests/__snapshots__/AmeliproMenu.spec.ts.snap +0 -537
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/AmeliproDropdownMenuBtn.spec.ts +0 -16
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +0 -56
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/AmeliproDropdownMenu.spec.ts +0 -28
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +0 -300
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/AmeliproMessagingMenuBtn.spec.ts +0 -16
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +0 -89
- package/src/components/BackBtn/tests/__snapshots__/BackBtn.spec.ts.snap +0 -45
- package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +0 -1270
- package/src/stories/Demarrer/CreerUneIssue.mdx +0 -67
- package/src/stories/Demarrer/components.stories.ts +0 -25
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import { nextTick } from 'vue'
|
|
4
|
+
import { vuetify } from '../../../../tests/unit/setup'
|
|
5
|
+
import CalendarModeDatePicker from '@/components/DatePicker/CalendarMode/DatePicker.vue'
|
|
6
|
+
import ComplexDatePicker from '@/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tests simples pour vérifier que la correction de navigation année/mois fonctionne
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
describe('DatePicker Navigation Fix - Simple Tests', () => {
|
|
13
|
+
const baseConfig = {
|
|
14
|
+
global: {
|
|
15
|
+
plugins: [vuetify],
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('CalendarMode DatePicker', () => {
|
|
20
|
+
it('should have the correct navigation handlers', async () => {
|
|
21
|
+
const wrapper = mount(CalendarModeDatePicker, {
|
|
22
|
+
...baseConfig,
|
|
23
|
+
props: {
|
|
24
|
+
modelValue: null,
|
|
25
|
+
label: 'Date Test',
|
|
26
|
+
isBirthDate: true,
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any
|
|
31
|
+
const component = wrapper.vm as any
|
|
32
|
+
|
|
33
|
+
// Vérifier que les handlers existent
|
|
34
|
+
expect(typeof component.handleYearUpdate).toBe('function')
|
|
35
|
+
expect(typeof component.handleMonthUpdate).toBe('function')
|
|
36
|
+
expect(typeof component.resetViewMode).toBe('function')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('should navigate correctly through year -> months -> month', async () => {
|
|
40
|
+
const wrapper = mount(CalendarModeDatePicker, {
|
|
41
|
+
...baseConfig,
|
|
42
|
+
props: {
|
|
43
|
+
modelValue: null,
|
|
44
|
+
label: 'Date Test',
|
|
45
|
+
isBirthDate: true,
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any
|
|
50
|
+
const component = wrapper.vm as any
|
|
51
|
+
|
|
52
|
+
// État initial : year
|
|
53
|
+
expect(component.currentViewMode).toBe('year')
|
|
54
|
+
|
|
55
|
+
// Navigation : year -> months
|
|
56
|
+
component.handleYearUpdate()
|
|
57
|
+
await nextTick()
|
|
58
|
+
expect(component.currentViewMode).toBe('months')
|
|
59
|
+
|
|
60
|
+
// Navigation : months -> month
|
|
61
|
+
component.handleMonthUpdate()
|
|
62
|
+
await nextTick()
|
|
63
|
+
expect(component.currentViewMode).toBe('month')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('should reset view mode correctly', async () => {
|
|
67
|
+
const wrapper = mount(CalendarModeDatePicker, {
|
|
68
|
+
...baseConfig,
|
|
69
|
+
props: {
|
|
70
|
+
modelValue: null,
|
|
71
|
+
label: 'Date Test',
|
|
72
|
+
isBirthDate: true,
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any
|
|
77
|
+
const component = wrapper.vm as any
|
|
78
|
+
|
|
79
|
+
// Changer le mode
|
|
80
|
+
component.currentViewMode = 'months'
|
|
81
|
+
expect(component.currentViewMode).toBe('months')
|
|
82
|
+
|
|
83
|
+
// Réinitialiser
|
|
84
|
+
component.resetViewMode()
|
|
85
|
+
await nextTick()
|
|
86
|
+
expect(component.currentViewMode).toBe('year') // Retour à year pour birthDate
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('ComplexDatePicker', () => {
|
|
91
|
+
it('should have the correct navigation handlers', async () => {
|
|
92
|
+
const wrapper = mount(ComplexDatePicker, {
|
|
93
|
+
...baseConfig,
|
|
94
|
+
props: {
|
|
95
|
+
modelValue: null,
|
|
96
|
+
label: 'Date Test',
|
|
97
|
+
isBirthDate: true,
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any
|
|
102
|
+
const component = wrapper.vm as any
|
|
103
|
+
|
|
104
|
+
// Vérifier que les handlers existent
|
|
105
|
+
expect(typeof component.handleYearUpdate).toBe('function')
|
|
106
|
+
expect(typeof component.handleMonthUpdate).toBe('function')
|
|
107
|
+
expect(typeof component.resetViewMode).toBe('function')
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should navigate correctly through year -> months -> month', async () => {
|
|
111
|
+
const wrapper = mount(ComplexDatePicker, {
|
|
112
|
+
...baseConfig,
|
|
113
|
+
props: {
|
|
114
|
+
modelValue: null,
|
|
115
|
+
label: 'Date Test',
|
|
116
|
+
isBirthDate: true,
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- any
|
|
121
|
+
const component = wrapper.vm as any
|
|
122
|
+
|
|
123
|
+
// État initial : year
|
|
124
|
+
expect(component.currentViewMode).toBe('year')
|
|
125
|
+
|
|
126
|
+
// Navigation : year -> months
|
|
127
|
+
component.handleYearUpdate()
|
|
128
|
+
await nextTick()
|
|
129
|
+
expect(component.currentViewMode).toBe('months')
|
|
130
|
+
|
|
131
|
+
// Navigation : months -> month
|
|
132
|
+
component.handleMonthUpdate()
|
|
133
|
+
await nextTick()
|
|
134
|
+
expect(component.currentViewMode).toBe('month')
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
})
|
|
@@ -295,8 +295,17 @@ const meta: Meta<typeof NirField> = {
|
|
|
295
295
|
},
|
|
296
296
|
},
|
|
297
297
|
},
|
|
298
|
-
|
|
299
|
-
description: 'Texte d\'aide affiché sous le champ.',
|
|
298
|
+
numberHint: {
|
|
299
|
+
description: 'Texte d\'aide spécifique affiché sous le champ numéro.',
|
|
300
|
+
control: 'text',
|
|
301
|
+
table: {
|
|
302
|
+
type: {
|
|
303
|
+
summary: 'string',
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
keyHint: {
|
|
308
|
+
description: 'Texte d\'aide spécifique affiché sous le champ clé.',
|
|
300
309
|
control: 'text',
|
|
301
310
|
table: {
|
|
302
311
|
type: {
|
|
@@ -340,6 +349,16 @@ const meta: Meta<typeof NirField> = {
|
|
|
340
349
|
},
|
|
341
350
|
},
|
|
342
351
|
},
|
|
352
|
+
customLocale: {
|
|
353
|
+
description: 'Objet permettant de surcharger les messages du composant. Clés supportées : `errorRequiredNumber`, `errorInvalidNumber`, `errorRequiredKey`, `errorInvalidKey`, `successNumberValid`, `successKeyValid`.',
|
|
354
|
+
control: 'object',
|
|
355
|
+
table: {
|
|
356
|
+
type: {
|
|
357
|
+
summary: 'Partial<typeof locales>',
|
|
358
|
+
},
|
|
359
|
+
defaultValue: { summary: '{}' },
|
|
360
|
+
},
|
|
361
|
+
},
|
|
343
362
|
},
|
|
344
363
|
} satisfies Meta<typeof NirField>
|
|
345
364
|
|
|
@@ -1306,3 +1325,67 @@ mais gérer leur affichage différemment, ou utiliser la validation uniquement a
|
|
|
1306
1325
|
`,
|
|
1307
1326
|
}),
|
|
1308
1327
|
}
|
|
1328
|
+
|
|
1329
|
+
export const WithCustomLocale: Story = {
|
|
1330
|
+
args: {
|
|
1331
|
+
...Default.args,
|
|
1332
|
+
required: true,
|
|
1333
|
+
showSuccessMessages: true,
|
|
1334
|
+
customLocale: {
|
|
1335
|
+
errorRequiredNumber: 'Veuillez renseigner votre numéro de sécurité sociale (13 caractères).',
|
|
1336
|
+
errorInvalidNumber: 'Format NIR non reconnu, merci de vérifier.',
|
|
1337
|
+
errorRequiredKey: 'La clé (2 chiffres) est requise.',
|
|
1338
|
+
errorInvalidKey: 'La clé ne correspond pas au NIR saisi.',
|
|
1339
|
+
successNumberValid: 'Numéro reconnu ✅',
|
|
1340
|
+
successKeyValid: 'Clé correspondante ✅',
|
|
1341
|
+
},
|
|
1342
|
+
},
|
|
1343
|
+
parameters: {
|
|
1344
|
+
docs: {
|
|
1345
|
+
description: {
|
|
1346
|
+
story: `
|
|
1347
|
+
### Surcharger les messages avec customLocale
|
|
1348
|
+
|
|
1349
|
+
Utilisez la prop \`customLocale\` pour remplacer les messages par défaut sans toucher au composant.
|
|
1350
|
+
|
|
1351
|
+
Clés supportées :
|
|
1352
|
+
- \`errorRequiredNumber\`
|
|
1353
|
+
- \`erreurInvalidNumber\`
|
|
1354
|
+
- \`errorRequiredKey\`
|
|
1355
|
+
- \`errorInvalidKey\`
|
|
1356
|
+
- \`successNumberValid\`
|
|
1357
|
+
- \`successKeyValid\`
|
|
1358
|
+
`,
|
|
1359
|
+
},
|
|
1360
|
+
},
|
|
1361
|
+
sourceCode: [
|
|
1362
|
+
{
|
|
1363
|
+
name: 'Template',
|
|
1364
|
+
code: `<template>
|
|
1365
|
+
<NirField
|
|
1366
|
+
v-model="value"
|
|
1367
|
+
required
|
|
1368
|
+
show-success-messages
|
|
1369
|
+
:custom-locale="{
|
|
1370
|
+
errorRequiredNumber: 'Veuillez renseigner votre numéro de sécurité sociale (13 caractères).',
|
|
1371
|
+
errorInvalidNumber: 'Format NIR non reconnu, merci de vérifier.',
|
|
1372
|
+
errorRequiredKey: 'La clé (2 chiffres) est requise.',
|
|
1373
|
+
errorInvalidKey: 'La clé ne correspond pas au NIR saisi.',
|
|
1374
|
+
successNumberValid: 'Numéro reconnu ✅',
|
|
1375
|
+
successKeyValid: 'Clé correspondante ✅'
|
|
1376
|
+
}"
|
|
1377
|
+
/>
|
|
1378
|
+
</template>`,
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
name: 'Script',
|
|
1382
|
+
code: `<script setup lang="ts">
|
|
1383
|
+
import { NirField } from '@cnamts/synapse'
|
|
1384
|
+
import { ref } from 'vue'
|
|
1385
|
+
|
|
1386
|
+
const value = ref('')
|
|
1387
|
+
</script>`,
|
|
1388
|
+
},
|
|
1389
|
+
],
|
|
1390
|
+
},
|
|
1391
|
+
}
|
|
@@ -36,12 +36,14 @@
|
|
|
36
36
|
variant?: 'filled' | 'outlined' | 'plain' | 'underlined' | 'solo'
|
|
37
37
|
clearable?: boolean
|
|
38
38
|
counter?: boolean | number | string
|
|
39
|
-
|
|
39
|
+
numberHint?: string
|
|
40
|
+
keyHint?: string
|
|
40
41
|
persistentHint?: boolean
|
|
41
42
|
persistentPlaceholder?: boolean
|
|
42
43
|
disableErrorHandling?: boolean
|
|
43
44
|
nirType?: 'simple' | 'complexe'
|
|
44
45
|
withoutFieldset?: boolean
|
|
46
|
+
customLocale?: Partial<Record<keyof typeof locales, string>>
|
|
45
47
|
}>(), {
|
|
46
48
|
modelValue: undefined,
|
|
47
49
|
label: 'Identifiant d\'assuré',
|
|
@@ -71,12 +73,21 @@
|
|
|
71
73
|
variant: 'outlined',
|
|
72
74
|
clearable: false,
|
|
73
75
|
counter: false,
|
|
74
|
-
|
|
76
|
+
numberHint: undefined,
|
|
77
|
+
keyHint: undefined,
|
|
75
78
|
persistentHint: false,
|
|
76
79
|
persistentPlaceholder: false,
|
|
77
80
|
disableErrorHandling: false,
|
|
78
81
|
nirType: 'simple',
|
|
79
82
|
withoutFieldset: false,
|
|
83
|
+
customLocale: () => ({
|
|
84
|
+
errorRequiredNumber: locales.errorRequiredNumber,
|
|
85
|
+
errorInvalidNumber: locales.errorInvalidNumber,
|
|
86
|
+
errorRequiredKey: locales.errorRequiredKey,
|
|
87
|
+
errorInvalidKey: locales.errorInvalidKey,
|
|
88
|
+
successNumberValid: locales.successNumberValid,
|
|
89
|
+
successKeyValid: locales.successKeyValid,
|
|
90
|
+
} as Partial<Record<keyof typeof locales, string>>),
|
|
80
91
|
})
|
|
81
92
|
|
|
82
93
|
const emit = defineEmits(['update:modelValue'])
|
|
@@ -121,8 +132,8 @@
|
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
const fieldWidth = computed(() => props.width || '100%')
|
|
124
|
-
const nirFieldWidth = computed(() => props.clearable ? '0 0 calc(
|
|
125
|
-
const keyFieldWidth = computed(() => props.clearable ? '0 0 calc(
|
|
135
|
+
const nirFieldWidth = computed(() => props.clearable ? '0 0 calc(68% - 8px)' : '0 0 calc(68% - 8px)')
|
|
136
|
+
const keyFieldWidth = computed(() => props.clearable ? '0 0 calc(32% - 8px)' : '0 0 calc(32% - 8px)')
|
|
126
137
|
|
|
127
138
|
const fieldId = useId()
|
|
128
139
|
const numberFieldErrorId = `nir-number-error-${fieldId}`
|
|
@@ -197,7 +208,7 @@
|
|
|
197
208
|
rules.push({
|
|
198
209
|
type: 'required',
|
|
199
210
|
options: {
|
|
200
|
-
message:
|
|
211
|
+
message: props.customLocale.errorRequiredNumber,
|
|
201
212
|
fieldIdentifier: props.numberLabel,
|
|
202
213
|
},
|
|
203
214
|
})
|
|
@@ -219,13 +230,13 @@
|
|
|
219
230
|
if (!value) return true
|
|
220
231
|
// Ne valider que si tous les caractères sont saisis
|
|
221
232
|
if (value.length < 13) {
|
|
222
|
-
return locales.
|
|
233
|
+
return props.customLocale.errorInvalidNumber || locales.errorInvalidNumber
|
|
223
234
|
}
|
|
224
235
|
const result = checkNIR(value, props.nirType)
|
|
225
|
-
return result
|
|
236
|
+
return result ? true : props.customLocale.errorInvalidNumber || locales.errorInvalidNumber
|
|
226
237
|
},
|
|
227
|
-
message:
|
|
228
|
-
successMessage:
|
|
238
|
+
message: props.customLocale.errorInvalidNumber,
|
|
239
|
+
successMessage: props.customLocale.successNumberValid,
|
|
229
240
|
fieldIdentifier: props.numberLabel,
|
|
230
241
|
},
|
|
231
242
|
})
|
|
@@ -248,7 +259,7 @@
|
|
|
248
259
|
rules.push({
|
|
249
260
|
type: 'required',
|
|
250
261
|
options: {
|
|
251
|
-
message:
|
|
262
|
+
message: props.customLocale.errorRequiredKey,
|
|
252
263
|
fieldIdentifier: props.keyLabel,
|
|
253
264
|
},
|
|
254
265
|
})
|
|
@@ -272,8 +283,8 @@
|
|
|
272
283
|
type: 'custom',
|
|
273
284
|
options: {
|
|
274
285
|
validate: validateKey,
|
|
275
|
-
message:
|
|
276
|
-
successMessage:
|
|
286
|
+
message: props.customLocale.errorInvalidKey,
|
|
287
|
+
successMessage: props.customLocale.successKeyValid,
|
|
277
288
|
fieldIdentifier: props.keyLabel,
|
|
278
289
|
},
|
|
279
290
|
})
|
|
@@ -504,7 +515,23 @@
|
|
|
504
515
|
})
|
|
505
516
|
|
|
506
517
|
// Rendre le composant auto-validable dans un SyForm
|
|
507
|
-
useValidatable(
|
|
518
|
+
useValidatable(
|
|
519
|
+
validateOnSubmit,
|
|
520
|
+
() => {
|
|
521
|
+
try {
|
|
522
|
+
numberValidation.clearValidation()
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
void 0
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
keyValidation.clearValidation()
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
void 0
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
)
|
|
508
535
|
|
|
509
536
|
defineExpose({
|
|
510
537
|
validateOnSubmit,
|
|
@@ -560,9 +587,13 @@
|
|
|
560
587
|
:readonly="props.readonly"
|
|
561
588
|
:clearable="props.clearable"
|
|
562
589
|
:counter="props.counter"
|
|
590
|
+
:hint="props.numberHint || locales.numberHint"
|
|
591
|
+
:persistent-hint="props.persistentHint"
|
|
563
592
|
:persistent-placeholder="props.persistentPlaceholder"
|
|
564
|
-
:hint="props.hint || locales.numberHint"
|
|
565
593
|
class="number-field"
|
|
594
|
+
:class="{
|
|
595
|
+
'sy-hide-detail': props.hideDetails,
|
|
596
|
+
}"
|
|
566
597
|
:display-asterisk="false"
|
|
567
598
|
:aria-describedby="numberFieldErrorId + ' ' + numberFieldWarningId + ' ' + numberFieldSuccessId"
|
|
568
599
|
:show-success-messages="false"
|
|
@@ -585,7 +616,6 @@
|
|
|
585
616
|
:prepend-tooltip="keyTooltip && keyTooltipPosition === 'prepend' ? keyTooltip : undefined"
|
|
586
617
|
:append-tooltip="keyTooltip && keyTooltipPosition === 'append' ? keyTooltip : undefined"
|
|
587
618
|
:error="keyValidation.errors.value.length > 0"
|
|
588
|
-
:hint="props.hint || locales.keyHint"
|
|
589
619
|
:disabled="disabled"
|
|
590
620
|
:bg-color="bgColor"
|
|
591
621
|
:density="props.density"
|
|
@@ -595,6 +625,7 @@
|
|
|
595
625
|
:readonly="props.readonly"
|
|
596
626
|
:clearable="props.clearable"
|
|
597
627
|
:counter="props.counter"
|
|
628
|
+
:hint="props.keyHint || locales.keyHint"
|
|
598
629
|
:persistent-hint="props.persistentHint"
|
|
599
630
|
:persistent-placeholder="props.persistentPlaceholder"
|
|
600
631
|
:aria-required="ariaRequired"
|
|
@@ -603,6 +634,9 @@
|
|
|
603
634
|
:has-success="hasKeySuccess"
|
|
604
635
|
:aria-invalid="ariaInvalidKey"
|
|
605
636
|
class="key-field"
|
|
637
|
+
:class="{
|
|
638
|
+
'sy-hide-detail': props.hideDetails,
|
|
639
|
+
}"
|
|
606
640
|
:display-asterisk="false"
|
|
607
641
|
:aria-describedby="keyFieldErrorId + ' ' + keyFieldWarningId + ' ' + keyFieldSuccessId"
|
|
608
642
|
:show-success-messages="false"
|
|
@@ -709,11 +743,11 @@
|
|
|
709
743
|
|
|
710
744
|
/* Styles pour le mode standard (div) */
|
|
711
745
|
.nir-field:not(.nir-field--fieldset) .number-field-container {
|
|
712
|
-
flex: 0 0 calc(
|
|
746
|
+
flex: 0 0 calc(68% - 8px);
|
|
713
747
|
}
|
|
714
748
|
|
|
715
749
|
.nir-field:not(.nir-field--fieldset) .key-field-container {
|
|
716
|
-
flex: 0 0 calc(
|
|
750
|
+
flex: 0 0 calc(32% - 8px);
|
|
717
751
|
}
|
|
718
752
|
|
|
719
753
|
/* Styles pour le mode fieldset */
|
|
@@ -752,6 +786,10 @@
|
|
|
752
786
|
}
|
|
753
787
|
}
|
|
754
788
|
|
|
789
|
+
.sy-hide-detail {
|
|
790
|
+
padding-bottom: 6px;
|
|
791
|
+
}
|
|
792
|
+
|
|
755
793
|
.sy-number-errors,
|
|
756
794
|
.sy-key-errors {
|
|
757
795
|
color: tokens.$colors-text-error;
|
|
@@ -766,5 +804,4 @@
|
|
|
766
804
|
.sy-key-success {
|
|
767
805
|
color: tokens.$colors-text-success;
|
|
768
806
|
}
|
|
769
|
-
|
|
770
807
|
</style>
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export const locales = {
|
|
2
2
|
errorRequiredNumber: 'Le numéro de sécurité sociale est requis, ce sont les 13 premiers chiffres sur votre carte vitale.',
|
|
3
|
-
|
|
4
|
-
erreurInvalidNumber: 'Le numéro de sécurité sociale est invalide.',
|
|
3
|
+
errorInvalidNumber: 'Le numéro de sécurité sociale est invalide.',
|
|
5
4
|
errorRequiredKey: 'La clé de contrôle est requise, ce sont les 2 derniers chiffres sur votre carte vitale.',
|
|
6
|
-
errorLengthKey: (length: number) => `La clé du numéro de sécurité sociale doit contenir ${length} caractères.`,
|
|
7
5
|
errorInvalidKey: 'La clé de contrôle est invalide.',
|
|
8
6
|
successNumberValid: 'Le numéro de sécurité sociale est valide.',
|
|
9
7
|
successKeyValid: 'La clé de contrôle est valide.',
|
|
@@ -68,10 +68,13 @@
|
|
|
68
68
|
const showEyeIcon = ref(false)
|
|
69
69
|
const passwordFieldId = ref(`password-field-${Math.random().toString(36).substring(2, 10)}`)
|
|
70
70
|
const alertMessage = ref('')
|
|
71
|
+
// Force re-render of SyTextField when needed (e.g., after reset)
|
|
72
|
+
const fieldKey = ref(0)
|
|
71
73
|
|
|
72
74
|
const btnLabel = locales.showPassword
|
|
73
75
|
|
|
74
76
|
const password = ref<string | null>(props.modelValue)
|
|
77
|
+
const isProgrammaticChange = ref(false)
|
|
75
78
|
watch(
|
|
76
79
|
() => props.modelValue,
|
|
77
80
|
(newVal) => {
|
|
@@ -160,11 +163,14 @@
|
|
|
160
163
|
}
|
|
161
164
|
}, { immediate: true })
|
|
162
165
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
// Ne pas revalider automatiquement à chaque changement de valeur.
|
|
167
|
+
// La validation est gérée explicitement au blur et à la soumission.
|
|
168
|
+
watch(
|
|
169
|
+
() => password.value,
|
|
170
|
+
(newVal) => {
|
|
171
|
+
emit('update:modelValue', newVal)
|
|
172
|
+
},
|
|
173
|
+
)
|
|
168
174
|
|
|
169
175
|
function togglePasswordVisibility() {
|
|
170
176
|
showEyeIcon.value = !showEyeIcon.value
|
|
@@ -209,8 +215,32 @@
|
|
|
209
215
|
return isValid
|
|
210
216
|
}
|
|
211
217
|
|
|
218
|
+
// Nettoie uniquement l'état de validation (messages) sans modifier la valeur
|
|
219
|
+
const clearValidation = () => {
|
|
220
|
+
errors.value = []
|
|
221
|
+
warnings.value = []
|
|
222
|
+
successes.value = []
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Reset hook utilisé par SyForm.reset() via useValidatable
|
|
226
|
+
const reset = () => {
|
|
227
|
+
// Réinitialiser d'abord l'état de validation et d'interaction
|
|
228
|
+
clearValidation()
|
|
229
|
+
alertMessage.value = ''
|
|
230
|
+
showEyeIcon.value = false
|
|
231
|
+
|
|
232
|
+
// Réinitialiser le contenu du champ
|
|
233
|
+
isProgrammaticChange.value = true
|
|
234
|
+
password.value = null
|
|
235
|
+
emit('update:modelValue', null)
|
|
236
|
+
isProgrammaticChange.value = false
|
|
237
|
+
|
|
238
|
+
// Forcer la recréation du champ pour réinitialiser l'état interne de Vuetify
|
|
239
|
+
fieldKey.value++
|
|
240
|
+
}
|
|
241
|
+
|
|
212
242
|
// Intégration avec le système de validation du formulaire
|
|
213
|
-
useValidatable(validateOnSubmit)
|
|
243
|
+
useValidatable(validateOnSubmit, clearValidation, reset)
|
|
214
244
|
|
|
215
245
|
defineExpose({
|
|
216
246
|
showEyeIcon,
|
|
@@ -221,6 +251,8 @@
|
|
|
221
251
|
hasWarning,
|
|
222
252
|
hasSuccess,
|
|
223
253
|
validateOnSubmit,
|
|
254
|
+
clearValidation,
|
|
255
|
+
reset,
|
|
224
256
|
})
|
|
225
257
|
</script>
|
|
226
258
|
|
|
@@ -228,6 +260,7 @@
|
|
|
228
260
|
<SyTextField
|
|
229
261
|
v-bind="Object.fromEntries(Object.entries(options).filter(([key]) => key !== 'btn' && key !== 'icon' && key !== 'variant'))"
|
|
230
262
|
:id="passwordFieldId"
|
|
263
|
+
:key="fieldKey"
|
|
231
264
|
v-model="password"
|
|
232
265
|
:variant-style="props.variantStyle"
|
|
233
266
|
:color="props.color"
|
|
@@ -244,7 +277,6 @@
|
|
|
244
277
|
:aria-invalid="hasError"
|
|
245
278
|
:aria-describedby="`${passwordFieldId}-status${props.customRules && props.customRules.length > 0 ? ' ' + passwordFieldId + '-guidelines' : ''}`"
|
|
246
279
|
:display-asterisk="props.displayAsterisk"
|
|
247
|
-
:rules="[...defaultRules, ...props.customRules]"
|
|
248
280
|
:autocomplete="props.autocompleteType"
|
|
249
281
|
class="vd-password"
|
|
250
282
|
:validate-on="props.isValidateOnBlur ? 'blur lazy' : 'lazy'"
|
|
@@ -55,6 +55,8 @@
|
|
|
55
55
|
const phoneNumber = ref(props.modelValue || '')
|
|
56
56
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
57
57
|
const dialCode = ref<string | Record<string, any>>(props.dialCodeModel || '')
|
|
58
|
+
// Force re-render of SySelect when needed (e.g., after reset)
|
|
59
|
+
const dialSelectKey = ref(0)
|
|
58
60
|
const counter = ref(10)
|
|
59
61
|
const phoneMask = ref('## ## ## ## ##')
|
|
60
62
|
const onBlur = ref(false)
|
|
@@ -241,6 +243,13 @@
|
|
|
241
243
|
|
|
242
244
|
const shouldDisableErrorHandling = computed(() => props.disableErrorHandling || props.readonly)
|
|
243
245
|
|
|
246
|
+
// When disabling error handling, immediately clear any existing validation state
|
|
247
|
+
watch(shouldDisableErrorHandling, (disabled) => {
|
|
248
|
+
if (disabled) {
|
|
249
|
+
validation.clearValidation()
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
|
|
244
253
|
const validation = useValidation({
|
|
245
254
|
customRules: validationRules.value,
|
|
246
255
|
showSuccessMessages: true,
|
|
@@ -248,9 +257,9 @@
|
|
|
248
257
|
disableErrorHandling: shouldDisableErrorHandling.value,
|
|
249
258
|
})
|
|
250
259
|
|
|
251
|
-
const hasError = computed(() => validation.hasError.value)
|
|
252
|
-
const hasWarning = computed(() => validation.hasWarning.value)
|
|
253
|
-
const hasSuccess = computed(() => validation.hasSuccess.value)
|
|
260
|
+
const hasError = computed(() => !shouldDisableErrorHandling.value && validation.hasError.value)
|
|
261
|
+
const hasWarning = computed(() => !shouldDisableErrorHandling.value && validation.hasWarning.value)
|
|
262
|
+
const hasSuccess = computed(() => !shouldDisableErrorHandling.value && validation.hasSuccess.value)
|
|
254
263
|
|
|
255
264
|
const iconColor = computed(() => {
|
|
256
265
|
if (shouldDisableErrorHandling.value) return '#222324'
|
|
@@ -260,9 +269,9 @@
|
|
|
260
269
|
return '#222324'
|
|
261
270
|
})
|
|
262
271
|
|
|
263
|
-
const errors = computed(() => validation.errors.value)
|
|
264
|
-
const warnings = computed(() => validation.warnings.value)
|
|
265
|
-
const successes = computed(() => validation.successes.value)
|
|
272
|
+
const errors = computed(() => shouldDisableErrorHandling.value ? [] : validation.errors.value)
|
|
273
|
+
const warnings = computed(() => shouldDisableErrorHandling.value ? [] : validation.warnings.value)
|
|
274
|
+
const successes = computed(() => shouldDisableErrorHandling.value ? [] : validation.successes.value)
|
|
266
275
|
|
|
267
276
|
const showHelpTextBelow = computed(() => {
|
|
268
277
|
// Display help text below by default if it exists
|
|
@@ -312,8 +321,28 @@
|
|
|
312
321
|
return !validation.hasError.value
|
|
313
322
|
}
|
|
314
323
|
|
|
324
|
+
// Reset hook used by SyForm.reset() via useValidatable
|
|
325
|
+
const reset = () => {
|
|
326
|
+
// Reset interaction state and validation FIRST to avoid triggering watchers with errors
|
|
327
|
+
onBlur.value = false
|
|
328
|
+
validation.clearValidation()
|
|
329
|
+
|
|
330
|
+
// Clear content
|
|
331
|
+
phoneNumber.value = ''
|
|
332
|
+
emit('update:modelValue', '')
|
|
333
|
+
|
|
334
|
+
// Clear dial code and restore defaults
|
|
335
|
+
dialCode.value = ''
|
|
336
|
+
emit('update:selectedDialCode', '')
|
|
337
|
+
counter.value = 10
|
|
338
|
+
phoneMask.value = '## ## ## ## ##'
|
|
339
|
+
|
|
340
|
+
// Force SySelect to be recreated to ensure internal classes are reset
|
|
341
|
+
dialSelectKey.value++
|
|
342
|
+
}
|
|
343
|
+
|
|
315
344
|
// Intégration avec le système de validation du formulaire
|
|
316
|
-
useValidatable(validateOnSubmit)
|
|
345
|
+
useValidatable(validateOnSubmit, validation.clearValidation, reset)
|
|
317
346
|
|
|
318
347
|
defineExpose({
|
|
319
348
|
computedValue,
|
|
@@ -342,14 +371,15 @@
|
|
|
342
371
|
<div class="phone-field-container">
|
|
343
372
|
<SySelect
|
|
344
373
|
v-if="withCountryCode"
|
|
374
|
+
:key="dialSelectKey"
|
|
345
375
|
v-model="dialCode"
|
|
346
376
|
:items="dialCodeOptions"
|
|
347
377
|
:label="locales.indicatifLabel"
|
|
348
378
|
:outlined="outlinedIndicatif"
|
|
349
379
|
:required="countryCodeRequired"
|
|
350
380
|
:aria-required="countryCodeRequired"
|
|
351
|
-
:error="
|
|
352
|
-
:error-messages="errors[1]"
|
|
381
|
+
:error="!!errors[1]"
|
|
382
|
+
:error-messages="errors[1] ? [errors[1]] : []"
|
|
353
383
|
:display-asterisk="displayAsterisk"
|
|
354
384
|
:disable-error-handling="shouldDisableErrorHandling"
|
|
355
385
|
:return-object="true"
|
|
@@ -426,7 +456,10 @@
|
|
|
426
456
|
</div>
|
|
427
457
|
<div
|
|
428
458
|
v-if="showHelpTextBelow"
|
|
429
|
-
class="help-text-below px-4
|
|
459
|
+
class="help-text-below px-4"
|
|
460
|
+
:style="{
|
|
461
|
+
marginTop: hasError || hasWarning || hasSuccess ? '0.25rem' : '-1rem',
|
|
462
|
+
}"
|
|
430
463
|
:class="{ 'text-disabled': disabled }"
|
|
431
464
|
>
|
|
432
465
|
{{ helpText }}
|
|
@@ -12,7 +12,6 @@ describe('RangeField', () => {
|
|
|
12
12
|
},
|
|
13
13
|
})
|
|
14
14
|
|
|
15
|
-
expect(wrapper.html()).toMatchSnapshot()
|
|
16
15
|
const inputMin = wrapper.find('input')
|
|
17
16
|
const inputMax = wrapper.findAll('input').at(1) as DOMWrapper<HTMLInputElement>
|
|
18
17
|
|
|
@@ -31,7 +30,6 @@ describe('RangeField', () => {
|
|
|
31
30
|
},
|
|
32
31
|
})
|
|
33
32
|
|
|
34
|
-
expect(wrapper.html()).toMatchSnapshot()
|
|
35
33
|
const inputMin = wrapper.find('input')
|
|
36
34
|
const inputMax = wrapper.findAll('input').at(1) as DOMWrapper<HTMLInputElement>
|
|
37
35
|
|
|
@@ -83,7 +81,6 @@ describe('RangeField', () => {
|
|
|
83
81
|
},
|
|
84
82
|
})
|
|
85
83
|
|
|
86
|
-
expect(wrapper.html()).toMatchSnapshot()
|
|
87
84
|
const inputMin = wrapper.find('input')
|
|
88
85
|
const inputMax = wrapper.findAll('input').at(1) as DOMWrapper<HTMLInputElement>
|
|
89
86
|
|
|
@@ -51,6 +51,21 @@ Le composant permet de cacher ou réorganiser l'ordre des colonnes en utilisant
|
|
|
51
51
|
|
|
52
52
|
Le composant permet de sélectionner des lignes individuellement ou en masse. Vous pouvez activer la sélection en utilisant la prop `show-select`.
|
|
53
53
|
|
|
54
|
+
Par défaut, la clé utilisée pour identifier chaque ligne lors de la sélection est `id`. Si vos éléments ne possèdent pas de propriété `id`, la valeur sélectionnée correspondra à l'objet complet de la ligne.
|
|
55
|
+
|
|
56
|
+
Vous pouvez personnaliser cette clé avec la prop `selection-key` pour indiquer quel champ utiliser (ex: `userId`).
|
|
57
|
+
|
|
58
|
+
Exemple d'utilisation :
|
|
59
|
+
<Source dark code={`
|
|
60
|
+
<SyServerTable
|
|
61
|
+
v-model="selected"
|
|
62
|
+
:items="users"
|
|
63
|
+
:headers="headers"
|
|
64
|
+
show-select
|
|
65
|
+
selection-key="userId"
|
|
66
|
+
/>
|
|
67
|
+
`}/>
|
|
68
|
+
|
|
54
69
|
### Slot item
|
|
55
70
|
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.
|
|
56
71
|
|