@cnamts/synapse 1.1.0 → 1.1.1

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 (202) hide show
  1. package/dist/{AutocompleteFilter-DXd4szWO.js → AutocompleteFilter-CGF33skz.js} +1 -1
  2. package/dist/{DateFilter-BD59Kgwf.js → DateFilter-D7-MsKtx.js} +1 -1
  3. package/dist/{NumberFilter-BSMZE7uw.js → NumberFilter-bjQPPfsj.js} +1 -1
  4. package/dist/{PeriodFilter-keUdSSk0.js → PeriodFilter-B3wJpK8-.js} +1 -1
  5. package/dist/{SelectFilter-Dhvvwazl.js → SelectFilter-BN6DbKAV.js} +1 -1
  6. package/dist/{TextFilter-CU8FpXz0.js → TextFilter-BffP0J2f.js} +1 -1
  7. package/dist/{apLightTheme2026-DbS7BPUf.js → apLightTheme2026-C4ygwMHC.js} +11 -11
  8. package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +6 -6
  9. package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +6 -6
  10. package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +6 -6
  11. package/dist/components/Captcha/Captcha.d.ts +27 -16
  12. package/dist/components/Captcha/CaptchaForm.d.ts +29 -3
  13. package/dist/components/Captcha/types.d.ts +14 -0
  14. package/dist/components/Captcha/useCaptchaValidation.d.ts +37 -0
  15. package/dist/components/Customs/Selects/SelectBtnField/SelectBtnField.d.ts +33 -13
  16. package/dist/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.d.ts +23 -0
  17. package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +2 -2
  18. package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +2 -2
  19. package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +17 -48
  20. package/dist/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.d.ts +29 -0
  21. package/dist/components/Customs/SyCheckBoxGroup/types.d.ts +46 -0
  22. package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +16 -51
  23. package/dist/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.d.ts +27 -0
  24. package/dist/components/Customs/SyCheckbox/types.d.ts +49 -0
  25. package/dist/components/Customs/SyTextField/FieldState.d.ts +5 -0
  26. package/dist/components/Customs/SyTextField/useSyTextFieldValidation.d.ts +3 -3
  27. package/dist/components/DialogBox/DialogBox.d.ts +2 -0
  28. package/dist/components/DialogBox/locales.d.ts +1 -0
  29. package/dist/components/FilterSideBar/FilterSideBar.d.ts +4 -0
  30. package/dist/components/LunarCalendar/LunarCalendar.d.ts +43 -14
  31. package/dist/components/LunarCalendar/types.d.ts +35 -0
  32. package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +11 -12
  33. package/dist/components/MonthPicker/MonthPicker.d.ts +72 -1747
  34. package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +21 -1733
  35. package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +5 -0
  36. package/dist/components/MonthPicker/locales.d.ts +1 -0
  37. package/dist/components/MonthPicker/types.d.ts +11 -0
  38. package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +37 -24
  39. package/dist/components/NirField/NirField.d.ts +6 -4
  40. package/dist/components/NirField/useNirValidation.d.ts +7 -5
  41. package/dist/components/PageContainer/PageContainer.d.ts +8 -0
  42. package/dist/components/PasswordField/PasswordField.d.ts +2 -2
  43. package/dist/components/PasswordField/usePasswordFieldValidation.d.ts +2 -2
  44. package/dist/components/PhoneField/PhoneField.d.ts +960 -1938
  45. package/dist/components/PhoneField/indicatifs.d.ts +715 -8
  46. package/dist/components/PhoneField/locales.d.ts +7 -0
  47. package/dist/components/PhoneField/types.d.ts +29 -0
  48. package/dist/components/PhoneField/usePhoneFieldValidation.d.ts +45 -0
  49. package/dist/components/PhoneField/usePhoneIndicatifs.d.ts +947 -0
  50. package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +2 -2
  51. package/dist/composables/unifyValidation/documentationValidationProps.d.ts +1 -1
  52. package/dist/composables/unifyValidation/useValidation.d.ts +4 -5
  53. package/dist/design-system-v3.js +2 -2
  54. package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +10 -10
  55. package/dist/designTokens/tokens/baseTokens.d.ts +18 -18
  56. package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +10 -10
  57. package/dist/designTokens/tokens/pa/paLightTheme.d.ts +10 -10
  58. package/dist/designTokens/tokens/semanticTokens.d.ts +14 -14
  59. package/dist/{main-D8ryUoS5.js → main-C4wAktOs.js} +13718 -12991
  60. package/dist/synapse.css +1 -1
  61. package/dist/vuetifyConfig.js +1 -1
  62. package/package.json +7 -7
  63. package/src/assets/compat/_legacy-tokens.scss +91 -0
  64. package/src/assets/overrides/_utilities.scss +23 -0
  65. package/src/components/Accordion/Accordion.stories.ts +121 -1
  66. package/src/components/BackBtn/BackBtn.mdx +1 -1
  67. package/src/components/BackToTopBtn/BackToTopBtn.mdx +0 -1
  68. package/src/components/Captcha/Captcha.stories.ts +134 -31
  69. package/src/components/Captcha/Captcha.vue +95 -28
  70. package/src/components/Captcha/CaptchaForm.vue +51 -22
  71. package/src/components/Captcha/tests/Captcha.focus.spec.ts +214 -0
  72. package/src/components/Captcha/tests/Captcha.spec.ts +233 -24
  73. package/src/components/Captcha/tests/CaptchaForm.spec.ts +82 -0
  74. package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +16 -42
  75. package/src/components/Captcha/types.ts +15 -0
  76. package/src/components/Captcha/useCaptchaValidation.ts +87 -0
  77. package/src/components/Captcha/validation/validation.stories.ts +1194 -0
  78. package/src/components/ChipList/ChipList.mdx +0 -1
  79. package/src/components/CollapsibleList/CollapsibleList.mdx +0 -1
  80. package/src/components/CookieBanner/CookieBanner.mdx +0 -1
  81. package/src/components/CopyBtn/CopyBtn.mdx +0 -1
  82. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +123 -439
  83. package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +147 -41
  84. package/src/components/Customs/Selects/SelectBtnField/Validation/Validation.stories.ts +600 -0
  85. package/src/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.ts +87 -0
  86. package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +402 -33
  87. package/src/components/Customs/Selects/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +52 -38
  88. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +342 -162
  89. package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +77 -129
  90. package/src/components/Customs/SyCheckBoxGroup/Validation/Validation.stories.ts +1008 -0
  91. package/src/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.ts +107 -0
  92. package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.spec.ts +180 -7
  93. package/src/components/Customs/SyCheckBoxGroup/types.ts +49 -0
  94. package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +41 -161
  95. package/src/components/Customs/SyCheckbox/SyCheckbox.vue +71 -148
  96. package/src/components/Customs/SyCheckbox/Validation/Validation.stories.ts +654 -0
  97. package/src/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.ts +105 -0
  98. package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +106 -0
  99. package/src/components/Customs/SyCheckbox/tests/useSyCheckboxValidation.spec.ts +98 -0
  100. package/src/components/Customs/SyCheckbox/types.ts +51 -0
  101. package/src/components/Customs/SyTextField/FieldState.vue +50 -0
  102. package/src/components/Customs/SyTextField/SyTextField.vue +12 -9
  103. package/src/components/Customs/SyTextField/useSyTextFieldValidation.ts +2 -11
  104. package/src/components/DataList/DataList.mdx +0 -1
  105. package/src/components/DataListGroup/DataListGroup.mdx +0 -1
  106. package/src/components/DiacriticPicker/DiacriticPicker.mdx +0 -1
  107. package/src/components/DialogBox/DialogBox.mdx +0 -1
  108. package/src/components/DialogBox/DialogBox.stories.ts +399 -4
  109. package/src/components/DialogBox/DialogBox.vue +20 -0
  110. package/src/components/DialogBox/locales.ts +1 -0
  111. package/src/components/DialogBox/tests/DialogBox.spec.ts +73 -0
  112. package/src/components/DialogBox/tests/DialogBox.visual.cy.ts +24 -0
  113. package/src/components/ErrorPage/ErrorPage.mdx +1 -1
  114. package/src/components/ExternalLinks/ExternalLinks.mdx +0 -1
  115. package/src/components/FileList/FileList.mdx +0 -1
  116. package/src/components/FilterInline/FilterInline.mdx +0 -1
  117. package/src/components/FilterSideBar/FilterSideBar.mdx +8 -1
  118. package/src/components/FilterSideBar/FilterSideBar.stories.ts +133 -1
  119. package/src/components/FilterSideBar/FilterSideBar.vue +19 -2
  120. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +55 -0
  121. package/src/components/FooterBar/FooterBar.mdx +0 -1
  122. package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +0 -1
  123. package/src/components/HeaderBar/HeaderBar.mdx +0 -1
  124. package/src/components/HeaderLoading/HeaderLoading.mdx +0 -1
  125. package/src/components/LangBtn/LangBtn.mdx +0 -1
  126. package/src/components/Logo/Logo.mdx +1 -1
  127. package/src/components/LunarCalendar/LunarCalendar.mdx +6 -9
  128. package/src/components/LunarCalendar/LunarCalendar.stories.ts +243 -46
  129. package/src/components/LunarCalendar/LunarCalendar.vue +61 -26
  130. package/src/components/LunarCalendar/Validation/Validation.stories.ts +717 -0
  131. package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +1 -1
  132. package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +197 -6
  133. package/src/components/LunarCalendar/tests/useLunarCalendarValidation.spec.ts +287 -0
  134. package/src/components/LunarCalendar/types.ts +39 -0
  135. package/src/components/LunarCalendar/useLunarCalendarValidation.ts +115 -39
  136. package/src/components/MonthPicker/MonthPicker.stories.ts +38 -281
  137. package/src/components/MonthPicker/MonthPicker.vue +66 -17
  138. package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +44 -20
  139. package/src/components/MonthPicker/MonthPickerText/useTextField.ts +5 -0
  140. package/src/components/MonthPicker/Validation/Validation.stories.ts +1117 -0
  141. package/src/components/MonthPicker/locales.ts +1 -0
  142. package/src/components/MonthPicker/tests/MonthPicker.spec.ts +353 -2
  143. package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +12 -8
  144. package/src/components/MonthPicker/types.ts +16 -0
  145. package/src/components/MonthPicker/useMonthPickerValidation.ts +64 -27
  146. package/src/components/NirField/NirField.mdx +120 -66
  147. package/src/components/NirField/NirField.stories.ts +216 -0
  148. package/src/components/NirField/useNirValidation.ts +16 -17
  149. package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +263 -245
  150. package/src/components/NotificationBar/NotificationBar.mdx +0 -1
  151. package/src/components/PageContainer/PageContainer.mdx +0 -1
  152. package/src/components/PageContainer/PageContainer.stories.ts +170 -2
  153. package/src/components/PageContainer/PageContainer.vue +63 -8
  154. package/src/components/PageContainer/tests/__snapshots__/PageContainer.spec.ts.snap +19 -11
  155. package/src/components/PaginatedTable/PaginatedTable.mdx +0 -1
  156. package/src/components/PeriodField/PeriodField.mdx +0 -1
  157. package/src/components/PhoneField/PhoneField.mdx +2 -3
  158. package/src/components/PhoneField/PhoneField.stories.ts +227 -410
  159. package/src/components/PhoneField/PhoneField.vue +204 -438
  160. package/src/components/PhoneField/indicatifs.ts +1 -1
  161. package/src/components/PhoneField/locales.ts +7 -0
  162. package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -1
  163. package/src/components/PhoneField/tests/PhoneField.spec.ts +517 -220
  164. package/src/components/PhoneField/types.ts +30 -0
  165. package/src/components/PhoneField/usePhoneFieldValidation.ts +119 -0
  166. package/src/components/PhoneField/usePhoneIndicatifs.ts +89 -0
  167. package/src/components/PhoneField/validation/validation.stories.ts +717 -0
  168. package/src/components/RangeField/RangeField.mdx +0 -1
  169. package/src/components/RatingPicker/RatingPicker.mdx +0 -1
  170. package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +0 -1
  171. package/src/components/StatusPage/StatusPage.vue +1 -0
  172. package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +248 -230
  173. package/src/components/SubHeader/SubHeader.mdx +5 -6
  174. package/src/components/Tables/common/tests/SyTableFilter.spec.ts +11 -12
  175. package/src/components/UploadWorkflow/UploadWorkflow.mdx +0 -1
  176. package/src/components/UserMenuBtn/UserMenuBtn.mdx +0 -1
  177. package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +177 -0
  178. package/src/composables/unifyValidation/documentationValidationProps.ts +1 -1
  179. package/src/composables/unifyValidation/tests/useValidation.spec.ts +13 -1
  180. package/src/composables/unifyValidation/useValidation.ts +37 -33
  181. package/src/composantsVuetify/VCard/VCard.mdx +4 -0
  182. package/src/composantsVuetify/VCard/v-card.stories.ts +93 -1
  183. package/src/composantsVuetify/VCarousel/VCarousel.mdx +74 -0
  184. package/src/composantsVuetify/VCarousel/v-carousel.stories.ts +531 -0
  185. package/src/composantsVuetify/VNavigationDrawer/VNavgationDrawer.mdx +53 -0
  186. package/src/composantsVuetify/VNavigationDrawer/v-navigation-drawer.stories.ts +310 -0
  187. package/src/composantsVuetify/VSlideGroup/VSlideGroup.mdx +105 -0
  188. package/src/composantsVuetify/VSlideGroup/v-slide-group.stories.ts +463 -0
  189. package/src/designTokens/tokens/baseColors.ts +1 -1
  190. package/src/designTokens/tokens/baseTokens.ts +18 -18
  191. package/src/stories/Components/Components.stories.ts +34 -1
  192. package/src/stories/Demarrer/Releases.stories.ts +16 -2
  193. package/src/stories/DesignTokens/Arrondis.mdx +1 -1
  194. package/src/stories/DesignTokens/Correspondances.mdx +219 -0
  195. package/src/stories/DesignTokens/UtiliserLesTokens.mdx +235 -0
  196. package/src/stories/DesignTokens/colors.stories.ts +569 -569
  197. package/src/stories/GuideDuDev/Amelipro.stories.ts +335 -267
  198. package/dist/components/LunarCalendar/useLunarCalendarRules.d.ts +0 -5
  199. package/dist/components/PhoneField/tests/types.d.ts +0 -18
  200. package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +0 -184
  201. package/src/components/LunarCalendar/useLunarCalendarRules.ts +0 -96
  202. package/src/components/PhoneField/tests/types.d.ts +0 -19
@@ -0,0 +1,654 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import { computed, onMounted, ref } from 'vue'
3
+ import SyCheckbox from '../SyCheckbox.vue'
4
+ import SyForm from '../../SyForm/SyForm.vue'
5
+ import { VBtn, VForm } from 'vuetify/components'
6
+ import { getValidationDocumentation } from '@/composables/unifyValidation/documentationValidationProps'
7
+
8
+ const meta: Meta<typeof SyCheckbox> = {
9
+ title: 'Composants/Formulaires/SyCheckbox/Validation',
10
+ component: SyCheckbox,
11
+ decorators: [
12
+ () => ({ template: '<div style="padding: 20px;"><story/></div>' }),
13
+ ],
14
+ parameters: {
15
+ layout: 'fullscreen',
16
+ docs: {
17
+ description: {
18
+ component: 'Stories démontrant les différents cas de validation de SyCheckbox (système unifié). Pour une case unique, « required » signifie que la case doit être cochée.',
19
+ },
20
+ },
21
+ },
22
+ argTypes: {
23
+ ...getValidationDocumentation(),
24
+ label: { control: 'text', description: 'Label de la case' },
25
+ },
26
+ args: {
27
+ label: 'J\'accepte les conditions générales',
28
+ required: true,
29
+ },
30
+ }
31
+
32
+ export default meta
33
+ type Story = StoryObj<typeof SyCheckbox>
34
+
35
+ /**
36
+ * Champ requis : la case doit être cochée, sinon une erreur s'affiche à la validation.
37
+ */
38
+ export const WithError: Story = {
39
+ parameters: {
40
+ sourceCode: [
41
+ {
42
+ name: 'Template',
43
+ code: `
44
+ <template>
45
+ <SyCheckbox
46
+ ref="checkboxRef"
47
+ v-model="accepted"
48
+ label="J'accepte les conditions générales"
49
+ required
50
+ />
51
+ </template>`,
52
+ },
53
+ {
54
+ name: 'Script',
55
+ code: `<script setup lang="ts">
56
+ import { onMounted, ref } from 'vue'
57
+ import { SyCheckbox } from '@cnamts/synapse'
58
+
59
+ const accepted = ref(false)
60
+ const checkboxRef = ref()
61
+
62
+ // Affiche l'état dès le chargement
63
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
64
+ </script>`,
65
+ },
66
+ ],
67
+ },
68
+ render: args => ({
69
+ components: { SyCheckbox },
70
+ setup() {
71
+ const accepted = ref(false)
72
+ const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
73
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
74
+ return { args, accepted, checkboxRef }
75
+ },
76
+ template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
77
+ }),
78
+ }
79
+
80
+ /**
81
+ * Avertissement (customWarningRules) : non bloquant.
82
+ */
83
+ export const WithWarning: Story = {
84
+ args: {
85
+ required: false,
86
+ customWarningRules: [{
87
+ type: 'custom',
88
+ options: {
89
+ validate: (value: unknown) => value === true,
90
+ warningMessage: 'Il est recommandé de cocher cette case.',
91
+ },
92
+ }],
93
+ },
94
+ parameters: {
95
+ sourceCode: [
96
+ {
97
+ name: 'Template',
98
+ code: `
99
+ <template>
100
+ <SyCheckbox
101
+ ref="checkboxRef"
102
+ v-model="accepted"
103
+ label="J'accepte les conditions générales"
104
+ :custom-warning-rules="warningRules"
105
+ />
106
+ </template>`,
107
+ },
108
+ {
109
+ name: 'Script',
110
+ code: `<script setup lang="ts">
111
+ import { onMounted, ref } from 'vue'
112
+ import { SyCheckbox } from '@cnamts/synapse'
113
+
114
+ const accepted = ref(false)
115
+ const checkboxRef = ref()
116
+
117
+ const warningRules = [{
118
+ type: 'custom',
119
+ options: {
120
+ validate: (value: unknown) => value === true,
121
+ warningMessage: 'Il est recommandé de cocher cette case.',
122
+ },
123
+ }]
124
+
125
+ // Affiche l'état dès le chargement
126
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
127
+ </script>`,
128
+ },
129
+ ],
130
+ },
131
+ render: args => ({
132
+ components: { SyCheckbox },
133
+ setup() {
134
+ const accepted = ref(false)
135
+ const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
136
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
137
+ return { args, accepted, checkboxRef }
138
+ },
139
+ template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
140
+ }),
141
+ }
142
+
143
+ /**
144
+ * Message de succès (customSuccessRules + showSuccessMessages).
145
+ */
146
+ export const WithSuccess: Story = {
147
+ args: {
148
+ required: false,
149
+ showSuccessMessages: true,
150
+ customSuccessRules: [{
151
+ type: 'custom',
152
+ options: {
153
+ validate: (value: unknown) => value === true,
154
+ successMessage: 'Merci d\'avoir accepté.',
155
+ },
156
+ }],
157
+ },
158
+ parameters: {
159
+ sourceCode: [
160
+ {
161
+ name: 'Template',
162
+ code: `
163
+ <template>
164
+ <SyCheckbox
165
+ ref="checkboxRef"
166
+ v-model="accepted"
167
+ label="J'accepte les conditions générales"
168
+ :custom-success-rules="successRules"
169
+ show-success-messages
170
+ />
171
+ </template>`,
172
+ },
173
+ {
174
+ name: 'Script',
175
+ code: `<script setup lang="ts">
176
+ import { onMounted, ref } from 'vue'
177
+ import { SyCheckbox } from '@cnamts/synapse'
178
+
179
+ const accepted = ref(true)
180
+ const checkboxRef = ref()
181
+
182
+ const successRules = [{
183
+ type: 'custom',
184
+ options: {
185
+ validate: (value: unknown) => value === true,
186
+ successMessage: 'Merci d\\'avoir accepté.',
187
+ },
188
+ }]
189
+
190
+ // Affiche l'état dès le chargement
191
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
192
+ </script>`,
193
+ },
194
+ ],
195
+ },
196
+ render: args => ({
197
+ components: { SyCheckbox },
198
+ setup() {
199
+ const accepted = ref(true)
200
+ const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
201
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
202
+ return { args, accepted, checkboxRef }
203
+ },
204
+ template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
205
+ }),
206
+ }
207
+
208
+ /**
209
+ * Règle personnalisée (customRules) avec validation **contextuelle** : ici la case ne peut être
210
+ * cochée que si un prérequis est validé. C'est un vrai cas d'usage de `customRules`, distinct de
211
+ * `required` (qui se contente d'exiger que la case soit cochée).
212
+ */
213
+ export const WithCustomRules: Story = {
214
+ parameters: {
215
+ docs: {
216
+ description: {
217
+ story: 'La règle dépend d\'un état externe (le prérequis). Cocher la case sans valider le prérequis déclenche une erreur.',
218
+ },
219
+ },
220
+ sourceCode: [
221
+ {
222
+ name: 'Template',
223
+ code: `
224
+ <template>
225
+ <SyCheckbox v-model="prerequisite" label="Prérequis : j'ai lu le document" hide-details />
226
+ <SyCheckbox
227
+ v-model="accepted"
228
+ label="J'accepte (uniquement si le prérequis est validé)"
229
+ :custom-rules="customRules"
230
+ :is-validate-on-blur="false"
231
+ />
232
+ </template>`,
233
+ },
234
+ {
235
+ name: 'Script',
236
+ code: `<script setup lang="ts">
237
+ import { computed, ref } from 'vue'
238
+ import { SyCheckbox } from '@cnamts/synapse'
239
+
240
+ const prerequisite = ref(false)
241
+ const accepted = ref(false)
242
+
243
+ const customRules = computed(() => [{
244
+ type: 'custom',
245
+ options: {
246
+ // Valide tant que la case n'est pas cochée, ou que le prérequis est rempli
247
+ validate: (value: unknown) => value !== true || prerequisite.value,
248
+ message: 'Vous devez d\\'abord valider le prérequis avant de cocher cette case.',
249
+ },
250
+ }])
251
+ </script>`,
252
+ },
253
+ ],
254
+ },
255
+ render: () => ({
256
+ components: { SyCheckbox },
257
+ setup() {
258
+ const prerequisite = ref(false)
259
+ const accepted = ref(false)
260
+
261
+ const customRules = computed(() => [{
262
+ type: 'custom',
263
+ options: {
264
+ validate: (value: unknown) => value !== true || prerequisite.value,
265
+ message: 'Vous devez d\'abord valider le prérequis avant de cocher cette case.',
266
+ },
267
+ }])
268
+
269
+ return { prerequisite, accepted, customRules }
270
+ },
271
+ template: `
272
+ <div class="d-flex flex-column ga-2">
273
+ <SyCheckbox v-model="prerequisite" label="Prérequis : j'ai lu le document" hide-details />
274
+ <SyCheckbox
275
+ v-model="accepted"
276
+ label="J'accepte (uniquement si le prérequis est validé)"
277
+ :custom-rules="customRules"
278
+ :is-validate-on-blur="false"
279
+ />
280
+ </div>
281
+ `,
282
+ }),
283
+ }
284
+
285
+ /**
286
+ * Messages externes : l'état d'erreur est piloté par la prop errorMessages.
287
+ */
288
+ export const ExternalMessages: Story = {
289
+ args: {
290
+ required: false,
291
+ hasError: true,
292
+ errorMessages: ['Cette case est invalide (message externe).'],
293
+ },
294
+ parameters: {
295
+ sourceCode: [
296
+ {
297
+ name: 'Template',
298
+ code: `
299
+ <template>
300
+ <SyCheckbox
301
+ v-model="accepted"
302
+ label="J'accepte les conditions générales"
303
+ :has-error="true"
304
+ :error-messages="errorMessages"
305
+ />
306
+ </template>`,
307
+ },
308
+ {
309
+ name: 'Script',
310
+ code: `<script setup lang="ts">
311
+ import { ref } from 'vue'
312
+ import { SyCheckbox } from '@cnamts/synapse'
313
+
314
+ const accepted = ref(false)
315
+ const errorMessages = ['Cette case est invalide (message externe).']
316
+ </script>`,
317
+ },
318
+ ],
319
+ },
320
+ render: args => ({
321
+ components: { SyCheckbox },
322
+ setup() {
323
+ const accepted = ref(false)
324
+ return { args, accepted }
325
+ },
326
+ template: `<SyCheckbox v-model="accepted" v-bind="args" />`,
327
+ }),
328
+ }
329
+
330
+ /**
331
+ * Avec `disableErrorHandling: true`, les règles sont ignorées visuellement : aucune erreur ne
332
+ * s'affiche même si la case requise reste décochée (utile quand la validation est pilotée ailleurs).
333
+ */
334
+ export const DisableErrorHandling: Story = {
335
+ args: {
336
+ required: true,
337
+ disableErrorHandling: true,
338
+ },
339
+ parameters: {
340
+ sourceCode: [
341
+ {
342
+ name: 'Template',
343
+ code: `
344
+ <template>
345
+ <SyCheckbox
346
+ ref="checkboxRef"
347
+ v-model="accepted"
348
+ label="J'accepte les conditions générales"
349
+ required
350
+ disable-error-handling
351
+ />
352
+ </template>`,
353
+ },
354
+ {
355
+ name: 'Script',
356
+ code: `<script setup lang="ts">
357
+ import { onMounted, ref } from 'vue'
358
+ import { SyCheckbox } from '@cnamts/synapse'
359
+
360
+ const accepted = ref(false)
361
+ const checkboxRef = ref()
362
+
363
+ // Même en déclenchant la validation, aucune erreur ne s'affiche
364
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
365
+ </script>`,
366
+ },
367
+ ],
368
+ },
369
+ render: args => ({
370
+ components: { SyCheckbox },
371
+ setup() {
372
+ const accepted = ref(false)
373
+ const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
374
+ onMounted(() => checkboxRef.value?.validateOnSubmit())
375
+ return { args, accepted, checkboxRef }
376
+ },
377
+ template: `<SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />`,
378
+ }),
379
+ }
380
+
381
+ /**
382
+ * Intégration avec SyForm : la case s'enregistre automatiquement (useValidatable)
383
+ * et est validée à la soumission du formulaire.
384
+ */
385
+ export const SyFormValidation: Story = {
386
+ parameters: {
387
+ docs: {
388
+ description: {
389
+ story: 'Il faut privilégier l\'utilisation de `SyForm`, qui valide automatiquement les composants enregistrés via `useValidatable`.',
390
+ },
391
+ },
392
+ sourceCode: [
393
+ {
394
+ name: 'Template',
395
+ code: `
396
+ <template>
397
+ <SyForm @submit="onSubmit">
398
+ <SyCheckbox v-model="accepted" label="J'accepte les conditions générales" required />
399
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
400
+ </SyForm>
401
+ </template>`,
402
+ },
403
+ {
404
+ name: 'Script',
405
+ code: `<script setup lang="ts">
406
+ import { ref } from 'vue'
407
+ import { SyCheckbox, SyForm } from '@cnamts/synapse'
408
+ import { VBtn } from 'vuetify/components'
409
+
410
+ const accepted = ref(false)
411
+
412
+ function onSubmit(e: { isValid: boolean }) {
413
+ alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
414
+ }
415
+ </script>`,
416
+ },
417
+ ],
418
+ },
419
+ render: args => ({
420
+ components: { SyCheckbox, SyForm, VBtn },
421
+ setup() {
422
+ const accepted = ref(false)
423
+ function onSubmit(e: { isValid: boolean }) {
424
+ alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
425
+ }
426
+ return { args, accepted, onSubmit }
427
+ },
428
+ template: `
429
+ <SyForm @submit="onSubmit">
430
+ <SyCheckbox v-model="accepted" v-bind="args" />
431
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
432
+ </SyForm>
433
+ `,
434
+ }),
435
+ }
436
+
437
+ /**
438
+ * Intégration avec un VForm Vuetify natif : la validation est déclenchée manuellement via la ref
439
+ * du composant (`validateOnSubmit`). Il est toutefois recommandé d'utiliser `SyForm` pour
440
+ * l'intégration automatique.
441
+ */
442
+ export const VFormValidation: Story = {
443
+ parameters: {
444
+ docs: {
445
+ description: {
446
+ story: 'Avec un `VForm` natif, la case n\'est pas auto-enregistrée : on appelle `validateOnSubmit()` via une ref. Préférez `SyForm` (cf. story SyFormValidation).',
447
+ },
448
+ },
449
+ sourceCode: [
450
+ {
451
+ name: 'Template',
452
+ code: `
453
+ <template>
454
+ <VForm @submit.prevent="handleSubmit">
455
+ <SyCheckbox
456
+ ref="checkboxRef"
457
+ v-model="accepted"
458
+ label="J'accepte les conditions générales"
459
+ required
460
+ />
461
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
462
+ </VForm>
463
+ </template>`,
464
+ },
465
+ {
466
+ name: 'Script',
467
+ code: `<script setup lang="ts">
468
+ import { ref } from 'vue'
469
+ import { SyCheckbox } from '@cnamts/synapse'
470
+ import { VBtn, VForm } from 'vuetify/components'
471
+
472
+ const accepted = ref(false)
473
+ const checkboxRef = ref()
474
+
475
+ async function handleSubmit() {
476
+ const isValid = await checkboxRef.value?.validateOnSubmit()
477
+ alert(isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
478
+ }
479
+ </script>`,
480
+ },
481
+ ],
482
+ },
483
+ render: args => ({
484
+ components: { SyCheckbox, VForm, VBtn },
485
+ setup() {
486
+ const accepted = ref(false)
487
+ const checkboxRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
488
+
489
+ async function handleSubmit() {
490
+ const isValid = await checkboxRef.value?.validateOnSubmit()
491
+ alert(isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
492
+ }
493
+
494
+ return { args, accepted, checkboxRef, handleSubmit }
495
+ },
496
+ template: `
497
+ <VForm @submit.prevent="handleSubmit">
498
+ <SyCheckbox ref="checkboxRef" v-model="accepted" v-bind="args" />
499
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
500
+ </VForm>
501
+ `,
502
+ }),
503
+ }
504
+
505
+ /**
506
+ * Mode de validation natif Vuetify (`useVuetifyValidation`) intégré à `SyForm`.
507
+ * Les règles sont de simples fonctions `(value) => true | 'message'`, comme la prop `rules` de Vuetify.
508
+ */
509
+ export const SyFormVuetifyValidation: Story = {
510
+ parameters: {
511
+ docs: {
512
+ description: {
513
+ story: 'Avec `use-vuetify-validation`, la case délègue sa validation à Vuetify via la prop `rules` (fonctions natives), tout en restant intégrée à `SyForm`.',
514
+ },
515
+ },
516
+ sourceCode: [
517
+ {
518
+ name: 'Template',
519
+ code: `<template>
520
+ <SyForm @submit="handleSubmit">
521
+ <SyCheckbox
522
+ v-model="accepted"
523
+ label="J'accepte les conditions générales"
524
+ :use-vuetify-validation="true"
525
+ :rules="vuetifyRules"
526
+ />
527
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
528
+ </SyForm>
529
+ </template>`,
530
+ },
531
+ {
532
+ name: 'Script',
533
+ code: `<script setup lang="ts">
534
+ import { ref } from 'vue'
535
+ import { SyCheckbox, SyForm } from '@cnamts/synapse'
536
+ import { VBtn } from 'vuetify/components'
537
+
538
+ const accepted = ref(false)
539
+
540
+ const vuetifyRules = [
541
+ (value: boolean | null) => value === true || 'Vous devez cocher cette case.',
542
+ ]
543
+
544
+ function handleSubmit(e: { isValid: boolean }) {
545
+ alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
546
+ }
547
+ </script>`,
548
+ },
549
+ ],
550
+ },
551
+ render: args => ({
552
+ components: { SyCheckbox, SyForm, VBtn },
553
+ setup() {
554
+ const accepted = ref(false)
555
+
556
+ const vuetifyRules = [
557
+ (value: boolean | null) => value === true || 'Vous devez cocher cette case.',
558
+ ]
559
+
560
+ function handleSubmit(e: { isValid: boolean }) {
561
+ alert(e.isValid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
562
+ }
563
+
564
+ return { args, accepted, vuetifyRules, handleSubmit }
565
+ },
566
+ template: `
567
+ <SyForm @submit="handleSubmit">
568
+ <SyCheckbox
569
+ v-bind="args"
570
+ v-model="accepted"
571
+ :use-vuetify-validation="true"
572
+ :rules="vuetifyRules"
573
+ />
574
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
575
+ </SyForm>
576
+ `,
577
+ }),
578
+ }
579
+
580
+ /**
581
+ * Mode de validation natif Vuetify (`useVuetifyValidation`) dans un `VForm` Vuetify.
582
+ */
583
+ export const VFormVuetifyValidation: Story = {
584
+ parameters: {
585
+ docs: {
586
+ description: {
587
+ story: 'Validation déléguée à Vuetify (`use-vuetify-validation` + `rules`) dans un `VForm` natif.',
588
+ },
589
+ },
590
+ sourceCode: [
591
+ {
592
+ name: 'Template',
593
+ code: `<template>
594
+ <VForm @submit.prevent="handleSubmit">
595
+ <SyCheckbox
596
+ v-model="accepted"
597
+ label="J'accepte les conditions générales"
598
+ :use-vuetify-validation="true"
599
+ :rules="vuetifyRules"
600
+ />
601
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
602
+ </VForm>
603
+ </template>`,
604
+ },
605
+ {
606
+ name: 'Script',
607
+ code: `<script setup lang="ts">
608
+ import { ref } from 'vue'
609
+ import { SyCheckbox } from '@cnamts/synapse'
610
+ import { VBtn, VForm } from 'vuetify/components'
611
+
612
+ const accepted = ref(false)
613
+
614
+ const vuetifyRules = [
615
+ (value: boolean | null) => value === true || 'Vous devez cocher cette case.',
616
+ ]
617
+
618
+ async function handleSubmit(e: Promise<{ valid: boolean }>) {
619
+ const { valid } = await e
620
+ alert(valid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
621
+ }
622
+ </script>`,
623
+ },
624
+ ],
625
+ },
626
+ render: args => ({
627
+ components: { SyCheckbox, VForm, VBtn },
628
+ setup() {
629
+ const accepted = ref(false)
630
+
631
+ const vuetifyRules = [
632
+ (value: boolean | null) => value === true || 'Vous devez cocher cette case.',
633
+ ]
634
+
635
+ async function handleSubmit(e: Promise<{ valid: boolean }>) {
636
+ const { valid } = await e
637
+ alert(valid ? 'Formulaire valide !' : 'Veuillez cocher la case.')
638
+ }
639
+
640
+ return { args, accepted, vuetifyRules, handleSubmit }
641
+ },
642
+ template: `
643
+ <VForm @submit.prevent="handleSubmit">
644
+ <SyCheckbox
645
+ v-bind="args"
646
+ v-model="accepted"
647
+ :use-vuetify-validation="true"
648
+ :rules="vuetifyRules"
649
+ />
650
+ <VBtn type="submit" color="primary" class="mt-4">Valider</VBtn>
651
+ </VForm>
652
+ `,
653
+ }),
654
+ }