@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.
Files changed (200) hide show
  1. package/dist/{DateFilter-QEfKOz0P.js → DateFilter-_EFzsvvM.js} +1 -1
  2. package/dist/{NumberFilter-C0h7gVzp.js → NumberFilter-CUxEbKJh.js} +1 -1
  3. package/dist/{PeriodFilter-8dVrKjju.js → PeriodFilter-D5ueqtKy.js} +1 -1
  4. package/dist/{SelectFilter-BI3QGbqb.js → SelectFilter-BciBNydy.js} +1 -1
  5. package/dist/{TextFilter-UOp1hcPp.js → TextFilter-DMN_WAQB.js} +1 -1
  6. package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordion.d.ts +7 -3
  7. package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordionTemplate/AmeliproAccordionTemplate.d.ts +1 -1
  8. package/dist/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.d.ts +2 -0
  9. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +7 -3
  10. package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +1 -1
  11. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +50 -68
  12. package/dist/components/Amelipro/AmeliproCard/AmeliproCard.d.ts +1 -1
  13. package/dist/components/Amelipro/AmeliproIcon/AmeliproIcon.d.ts +1 -1
  14. package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +5 -5
  15. package/dist/components/Amelipro/AmeliproMultipleFoldingCard/AmeliproMultipleFoldingCard.d.ts +1 -1
  16. package/dist/components/Amelipro/AmeliproNumberedCard/AmeliproNumberedCard.d.ts +1 -1
  17. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +24 -32
  18. package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +36 -48
  19. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +50 -68
  20. package/dist/components/Amelipro/AmeliproTable/AmeliproTable.d.ts +4 -0
  21. package/dist/components/Amelipro/AmeliproTable/types.d.ts +11 -0
  22. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +50 -68
  23. package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +0 -4
  24. package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +12 -16
  25. package/dist/components/Captcha/Captcha.d.ts +68 -0
  26. package/dist/components/Captcha/CaptchaAlert.d.ts +13 -0
  27. package/dist/components/Captcha/CaptchaBase.d.ts +55 -0
  28. package/dist/components/Captcha/CaptchaBtn.d.ts +12 -0
  29. package/dist/components/Captcha/CaptchaForm.d.ts +16 -0
  30. package/dist/components/Captcha/CaptchaImg.d.ts +12 -0
  31. package/dist/components/Captcha/CaptchaInformation.d.ts +20 -0
  32. package/dist/components/Captcha/captchaApi.d.ts +41 -0
  33. package/dist/components/Captcha/icons/volumeUp.d.ts +2 -0
  34. package/dist/components/Captcha/locales.d.ts +35 -0
  35. package/dist/components/Captcha/types.d.ts +2 -0
  36. package/dist/components/ChipList/ChipList.d.ts +2 -2
  37. package/dist/components/CookiesSelection/CookiesInformation/CookiesInformation.d.ts +14 -14
  38. package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +5 -5
  39. package/dist/components/Customs/SyForm/SyForm.d.ts +6 -3
  40. package/dist/components/Customs/SyTextField/SyTextField.d.ts +12 -16
  41. package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +96 -68
  42. package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +63 -38
  43. package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +23 -27
  44. package/dist/components/DatePicker/composables/useDatePickerViewMode.d.ts +2 -1
  45. package/dist/components/DatePicker/tests/setup.d.ts +816 -520
  46. package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +10 -10
  47. package/dist/components/NirField/NirField.d.ts +31 -34
  48. package/dist/components/NirField/locales.d.ts +1 -3
  49. package/dist/components/PasswordField/PasswordField.d.ts +2 -0
  50. package/dist/components/PeriodField/PeriodField.d.ts +192 -128
  51. package/dist/components/PhoneField/PhoneField.d.ts +13 -17
  52. package/dist/components/SearchListField/SearchListField.d.ts +5 -5
  53. package/dist/components/SyTextArea/SyTextArea.d.ts +0 -4
  54. package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +5 -8
  55. package/dist/components/Tables/SyTable/SyTable.d.ts +5 -8
  56. package/dist/components/Tables/common/SyTablePagination.d.ts +5 -5
  57. package/dist/components/Tables/common/types.d.ts +4 -0
  58. package/dist/components/Tables/common/usePagination.d.ts +3 -4
  59. package/dist/components/Tables/common/useTableCheckbox.d.ts +10 -6
  60. package/dist/components/index.d.ts +1 -0
  61. package/dist/composables/validation/useFormValidation.d.ts +10 -0
  62. package/dist/composables/validation/useValidatable.d.ts +10 -2
  63. package/dist/design-system-v3.js +126 -125
  64. package/dist/design-system-v3.umd.cjs +265 -265
  65. package/dist/main-DISHlqcd.js +34217 -0
  66. package/dist/style.css +1 -1
  67. package/package.json +1 -1
  68. package/src/assets/overrides/_forms.scss +2 -0
  69. package/src/components/Amelipro/AmeliproAccordion/AmeliproAccordion.stories.ts +7 -4
  70. package/src/components/Amelipro/AmeliproAccordion/AmeliproAccordion.vue +2 -0
  71. package/src/components/Amelipro/AmeliproAccordionFrieze/AmeliproAccordionFrieze.vue +1 -0
  72. package/src/components/Amelipro/AmeliproAccordionFrieze/__tests__/__snapshots__/AmeliproAccordionFrieze.spec.ts.snap +574 -112
  73. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.stories.ts +5 -2
  74. package/src/components/Amelipro/AmeliproAccordionList/AmeliproAccordionList.vue +2 -1
  75. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.stories.ts +6 -3
  76. package/src/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.vue +2 -0
  77. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.stories.ts +5 -2
  78. package/src/components/Amelipro/AmeliproAccordionResultList/AmeliproAccordionResultList.vue +2 -1
  79. package/src/components/Amelipro/AmeliproCheckbox/__tests__/AmeliproCheckbox.spec.ts +175 -0
  80. package/src/components/Amelipro/AmeliproCheckbox/__tests__/__snapshots__/AmeliproCheckbox.spec.ts.snap +88 -0
  81. package/src/components/Amelipro/AmeliproCheckboxGroup/__tests__/AmeliproCheckboxGroup.spec.ts +423 -0
  82. package/src/components/Amelipro/AmeliproCheckboxGroup/{tests → __tests__}/__snapshots__/AmeliproCheckboxGroup.spec.ts.snap +112 -78
  83. package/src/components/Amelipro/AmeliproChips/__tests__/AmeliproChips.spec.ts +92 -0
  84. package/src/components/Amelipro/AmeliproChips/__tests__/__snapshots__/AmeliproChips.spec.ts.snap +81 -0
  85. package/src/components/Amelipro/AmeliproDialog/__tests__/AmeliproDialog.spec.ts +257 -0
  86. package/src/components/Amelipro/AmeliproDialog/__tests__/__snapshots__/AmeliproDialog.spec.ts.snap +61 -0
  87. package/src/components/Amelipro/AmeliproDisclosure/__tests__/AmeliproDisclosure.spec.ts +79 -0
  88. package/src/components/Amelipro/AmeliproDisclosure/__tests__/__snapshots__/AmeliproDisclosure.spec.ts.snap +89 -0
  89. package/src/components/Amelipro/AmeliproFooter/AmeliproFooter.vue +6 -7
  90. package/src/components/Amelipro/AmeliproFooter/__tests__/AmeliproFooter.spec.ts +787 -0
  91. package/src/components/Amelipro/AmeliproFooter/__tests__/__snapshots__/AmeliproFooter.spec.ts.snap +318 -0
  92. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/AmeliproHeaderBrandSection.spec.ts +167 -0
  93. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +100 -0
  94. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/AmeliproHeaderBar.spec.ts +312 -0
  95. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/__snapshots__/AmeliproHeaderBar.spec.ts.snap +98 -0
  96. package/src/components/Amelipro/AmeliproHeader/__tests__/AmeliproHeader.spec.ts +361 -0
  97. package/src/components/Amelipro/AmeliproHeader/__tests__/__snapshots__/AmeliproHeader.spec.ts.snap +22 -0
  98. package/src/components/Amelipro/AmeliproMenu/__tests__/AmeliproMenu.spec.ts +168 -0
  99. package/src/components/Amelipro/AmeliproMenu/__tests__/__snapshots__/AmeliproMenu.spec.ts.snap +295 -0
  100. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/AmeliproDropdownMenuBtn.spec.ts +128 -0
  101. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +67 -0
  102. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/AmeliproDropdownMenu.spec.ts +266 -0
  103. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +134 -0
  104. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/AmeliproMessagingMenuBtn.spec.ts +72 -0
  105. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +71 -0
  106. package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +12 -0
  107. package/src/components/Amelipro/AmeliproTable/AmeliproTable.stories.ts +81 -9
  108. package/src/components/Amelipro/AmeliproTable/AmeliproTable.vue +139 -61
  109. package/src/components/Amelipro/AmeliproTable/__tests__/AmeliproTable.spec.ts +10 -0
  110. package/src/components/Amelipro/AmeliproTable/__tests__/__snapshots__/AmeliproTable.spec.ts.snap +361 -187
  111. package/src/components/Amelipro/AmeliproTable/types.d.ts +11 -0
  112. package/src/components/Captcha/Captcha.mdx +72 -0
  113. package/src/components/Captcha/Captcha.stories.ts +276 -0
  114. package/src/components/Captcha/Captcha.vue +325 -0
  115. package/src/components/Captcha/CaptchaAlert.vue +60 -0
  116. package/src/components/Captcha/CaptchaBase.vue +219 -0
  117. package/src/components/Captcha/CaptchaBtn.vue +35 -0
  118. package/src/components/Captcha/CaptchaForm.vue +58 -0
  119. package/src/components/Captcha/CaptchaImg.vue +41 -0
  120. package/src/components/Captcha/CaptchaInformation.vue +64 -0
  121. package/src/components/Captcha/captchaApi.ts +111 -0
  122. package/src/components/Captcha/icons/volumeUp.vue +11 -0
  123. package/src/components/Captcha/locales.ts +35 -0
  124. package/src/components/Captcha/readme.md +5 -0
  125. package/src/components/Captcha/tests/Captcha.spec.ts +298 -0
  126. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +716 -0
  127. package/src/components/Captcha/types.ts +2 -0
  128. package/src/components/Customs/Selects/SySelect/SySelect.vue +2 -2
  129. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +4 -0
  130. package/src/components/Customs/SyForm/SyForm.stories.ts +133 -23
  131. package/src/components/Customs/SyForm/SyForm.vue +17 -1
  132. package/src/components/Customs/SyTextField/SyTextField.vue +29 -7
  133. package/src/components/DatePicker/CalendarMode/DatePicker.vue +32 -9
  134. package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +154 -18
  135. package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +2 -2
  136. package/src/components/DatePicker/DateTextInput/DateTextInput.vue +35 -4
  137. package/src/components/DatePicker/composables/tests/useDatePickerViewMode.spec.ts +107 -72
  138. package/src/components/DatePicker/composables/tests/useMonthButtonCustomization.spec.ts +6 -6
  139. package/src/components/DatePicker/composables/useDatePickerViewMode.ts +57 -7
  140. package/src/components/DatePicker/composables/useMonthButtonCustomization.ts +14 -14
  141. package/src/components/DatePicker/tests/navigation.regression.spec.ts +74 -0
  142. package/src/components/DatePicker/tests/navigation.simple.spec.ts +137 -0
  143. package/src/components/NirField/NirField.stories.ts +85 -2
  144. package/src/components/NirField/NirField.vue +55 -18
  145. package/src/components/NirField/locales.ts +1 -3
  146. package/src/components/PasswordField/PasswordField.vue +39 -7
  147. package/src/components/PhoneField/PhoneField.vue +43 -10
  148. package/src/components/RangeField/tests/RangeField.spec.ts +0 -3
  149. package/src/components/Tables/SyServerTable/SyServerTable.mdx +15 -0
  150. package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +309 -0
  151. package/src/components/Tables/SyServerTable/SyServerTable.vue +18 -3
  152. package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
  153. package/src/components/Tables/SyTable/SyTable.mdx +15 -0
  154. package/src/components/Tables/SyTable/SyTable.stories.ts +228 -0
  155. package/src/components/Tables/SyTable/SyTable.vue +18 -3
  156. package/src/components/Tables/SyTable/tests/SyTable.spec.ts +63 -0
  157. package/src/components/Tables/common/SyTablePagination.vue +10 -8
  158. package/src/components/Tables/common/types.ts +4 -0
  159. package/src/components/Tables/common/usePagination.ts +11 -20
  160. package/src/components/Tables/common/useTableCheckbox.ts +23 -11
  161. package/src/components/index.ts +1 -0
  162. package/src/composables/validation/AvecVosComposants.mdx.old +1 -1
  163. package/src/composables/validation/FormValidation.stories.ts.old +5 -5
  164. package/src/composables/validation/useFormValidation.ts +46 -8
  165. package/src/composables/validation/useValidatable.ts +19 -8
  166. package/src/stories/Accessibilite/Introduction.mdx +1 -1
  167. package/src/stories/Demarrer/EnrichirLeDesignSystem.mdx +43 -0
  168. package/src/stories/Demarrer/EnrichirLeDesignSystem.stories.ts +239 -0
  169. package/src/stories/Demarrer/SignalerUneAnomalie.mdx +39 -0
  170. package/src/stories/Demarrer/SignalerUneAnomalie.stories.ts +261 -0
  171. package/dist/main-DyEOPqqn.js +0 -33329
  172. package/src/components/Amelipro/AmeliproCheckbox/tests/AmeliproCheckbox.spec.ts +0 -19
  173. package/src/components/Amelipro/AmeliproCheckbox/tests/__snapshots__/AmeliproCheckbox.spec.ts.snap +0 -40
  174. package/src/components/Amelipro/AmeliproCheckboxGroup/tests/AmeliproCheckboxGroup.spec.ts +0 -46
  175. package/src/components/Amelipro/AmeliproChips/tests/AmeliproChips.spec.ts +0 -16
  176. package/src/components/Amelipro/AmeliproChips/tests/__snapshots__/AmeliproChips.spec.ts.snap +0 -97
  177. package/src/components/Amelipro/AmeliproDialog/tests/AmeliproDialog.spec.ts +0 -24
  178. package/src/components/Amelipro/AmeliproDialog/tests/__snapshots__/AmeliproDialog.spec.ts.snap +0 -134
  179. package/src/components/Amelipro/AmeliproDisclosure/tests/AmeliproDisclosure.spec.ts +0 -19
  180. package/src/components/Amelipro/AmeliproDisclosure/tests/__snapshots__/AmeliproDisclosure.spec.ts.snap +0 -104
  181. package/src/components/Amelipro/AmeliproFooter/tests/AmeliproFooter.spec.ts +0 -15
  182. package/src/components/Amelipro/AmeliproFooter/tests/__snapshots__/AmeliproFooter.spec.ts.snap +0 -432
  183. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/AmeliproHeaderBrandSection.spec.ts +0 -15
  184. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +0 -131
  185. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/AmeliproHeaderBar.spec.ts +0 -15
  186. package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/__snapshots__/AmeliproHeaderBar.spec.ts.snap +0 -172
  187. package/src/components/Amelipro/AmeliproHeader/tests/AmeliproHeader.spec.ts +0 -159
  188. package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +0 -841
  189. package/src/components/Amelipro/AmeliproMenu/tests/AmeliproMenu.spec.ts +0 -85
  190. package/src/components/Amelipro/AmeliproMenu/tests/__snapshots__/AmeliproMenu.spec.ts.snap +0 -537
  191. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/AmeliproDropdownMenuBtn.spec.ts +0 -16
  192. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +0 -56
  193. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/AmeliproDropdownMenu.spec.ts +0 -28
  194. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +0 -300
  195. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/AmeliproMessagingMenuBtn.spec.ts +0 -16
  196. package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +0 -89
  197. package/src/components/BackBtn/tests/__snapshots__/BackBtn.spec.ts.snap +0 -45
  198. package/src/components/RangeField/tests/__snapshots__/RangeField.spec.ts.snap +0 -1270
  199. package/src/stories/Demarrer/CreerUneIssue.mdx +0 -67
  200. 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
- hint: {
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
- hint?: string
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
- hint: undefined,
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(70% - 8px)' : '0 0 calc(72% - 8px)')
125
- const keyFieldWidth = computed(() => props.clearable ? '0 0 calc(29% - 8px)' : '0 0 calc(25% - 8px)')
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: locales.errorRequiredNumber,
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.erreurInvalidNumber
233
+ return props.customLocale.errorInvalidNumber || locales.errorInvalidNumber
223
234
  }
224
235
  const result = checkNIR(value, props.nirType)
225
- return result === true ? true : locales.erreurInvalidNumber
236
+ return result ? true : props.customLocale.errorInvalidNumber || locales.errorInvalidNumber
226
237
  },
227
- message: locales.erreurInvalidNumber,
228
- successMessage: locales.successNumberValid,
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: locales.errorRequiredKey,
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: locales.errorInvalidKey,
276
- successMessage: locales.successKeyValid,
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(validateOnSubmit)
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(75% - 8px);
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(25% - 8px);
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
- errorLengthNumber: (length: number) => `Le numéro de sécurité sociale doit contenir ${length} caractères.`,
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
- watch(() => password.value, () => {
164
- if (props.readonly) return
165
- validateField(password.value, [...defaultRules.value, ...(props.customRules || [])], props.customWarningRules || [], props.customSuccessRules || [])
166
- emit('update:modelValue', password.value)
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="hasError"
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 mt-1"
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