@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,717 @@
1
+ import SyForm from '@/components/Customs/SyForm/SyForm.vue'
2
+ import PhoneField from '../PhoneField.vue'
3
+ import type { StoryObj, Meta } from '@storybook/vue3'
4
+ import { ref, onMounted } from 'vue'
5
+ import { VBtn } from 'vuetify/components'
6
+ import { VForm } from 'vuetify/components/VForm'
7
+ import { default as phoneFieldMeta } from '../PhoneField.stories'
8
+
9
+ const meta: Meta<typeof PhoneField> = {
10
+ ...phoneFieldMeta,
11
+ title: 'Composants/Formulaires/PhoneField/Validation',
12
+ } as Meta<typeof PhoneField>
13
+
14
+ export default meta
15
+
16
+ type Story = StoryObj<typeof meta>
17
+
18
+ export const WithError: Story = {
19
+ parameters: {
20
+ docs: {
21
+ description: {
22
+ story: 'Un numéro invalide est pré-rempli et déclenche une erreur bloquante au chargement.',
23
+ },
24
+ },
25
+ sourceCode: [
26
+ {
27
+ name: 'Template',
28
+ code: `
29
+ <template>
30
+ <PhoneField
31
+ ref="phoneRef"
32
+ v-model="phone"
33
+ :customRules="[
34
+ {
35
+ type: 'custom',
36
+ options: {
37
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
38
+ message: 'Le numéro de téléphone n\\'est pas valide.'
39
+ }
40
+ }
41
+ ]"
42
+ />
43
+ </template>`,
44
+ },
45
+ {
46
+ name: 'Script',
47
+ code: `
48
+ <script setup lang="ts">
49
+ import { onMounted, ref } from 'vue'
50
+ import { PhoneField } from '@cnamts/synapse'
51
+
52
+ const phone = ref('123')
53
+ const phoneRef = ref(null)
54
+
55
+ onMounted(() => {
56
+ phoneRef.value?.validateOnSubmit()
57
+ })
58
+ </script>`,
59
+ },
60
+ ],
61
+ },
62
+ render: args => ({
63
+ components: { PhoneField },
64
+ setup() {
65
+ const phone = ref('123')
66
+ const phoneRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
67
+
68
+ onMounted(() => {
69
+ phoneRef.value?.validateOnSubmit()
70
+ })
71
+
72
+ return { args, phone, phoneRef }
73
+ },
74
+ template: `
75
+ <div class="pa-4">
76
+ <PhoneField
77
+ ref="phoneRef"
78
+ v-model="phone"
79
+ v-bind="args"
80
+ :customRules="[
81
+ {
82
+ type: 'custom',
83
+ options: {
84
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
85
+ message: 'Le numéro de téléphone n\\'est pas valide.'
86
+ }
87
+ }
88
+ ]"
89
+ />
90
+ </div>
91
+ `,
92
+ }),
93
+ }
94
+
95
+ export const WithWarning: Story = {
96
+ parameters: {
97
+ docs: {
98
+ description: {
99
+ story: 'Un numéro est pré-rempli et déclenche un avertissement (non bloquant) au chargement.',
100
+ },
101
+ },
102
+ sourceCode: [
103
+ {
104
+ name: 'Template',
105
+ code: `
106
+ <template>
107
+ <PhoneField
108
+ ref="phoneRef"
109
+ v-model="phone"
110
+ :customWarningRules="[
111
+ {
112
+ type: 'custom',
113
+ options: {
114
+ validate: (value) => !value.replace(/\\s/g, '').startsWith('08'),
115
+ warningMessage: 'Les numéros commençant par 08 peuvent être surtaxés.'
116
+ }
117
+ }
118
+ ]"
119
+ />
120
+ </template>`,
121
+ },
122
+ {
123
+ name: 'Script',
124
+ code: `
125
+ <script setup lang="ts">
126
+ import { onMounted, ref } from 'vue'
127
+ import { PhoneField } from '@cnamts/synapse'
128
+
129
+ const phone = ref('0812345678')
130
+ const phoneRef = ref(null)
131
+
132
+ onMounted(() => {
133
+ phoneRef.value?.validateOnSubmit()
134
+ })
135
+ </script>`,
136
+ },
137
+ ],
138
+ },
139
+ render: args => ({
140
+ components: { PhoneField },
141
+ setup() {
142
+ const phone = ref('0812345678')
143
+ const phoneRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
144
+
145
+ onMounted(() => {
146
+ phoneRef.value?.validateOnSubmit()
147
+ })
148
+
149
+ return { args, phone, phoneRef }
150
+ },
151
+ template: `
152
+ <div class="pa-4">
153
+ <PhoneField
154
+ ref="phoneRef"
155
+ v-model="phone"
156
+ v-bind="args"
157
+ :customWarningRules="[
158
+ {
159
+ type: 'custom',
160
+ options: {
161
+ validate: (value) => !value.replace(/\\s/g, '').startsWith('08'),
162
+ warningMessage: 'Les numéros commençant par 08 peuvent être surtaxés.'
163
+ }
164
+ }
165
+ ]"
166
+ />
167
+ </div>
168
+ `,
169
+ }),
170
+ }
171
+
172
+ export const WithSuccess: Story = {
173
+ parameters: {
174
+ docs: {
175
+ description: {
176
+ story: 'Un numéro valide est pré-rempli et déclenche la confirmation de succès au chargement.',
177
+ },
178
+ },
179
+ sourceCode: [
180
+ {
181
+ name: 'Template',
182
+ code: `
183
+ <template>
184
+ <PhoneField
185
+ ref="phoneRef"
186
+ v-model="phone"
187
+ show-success-messages
188
+ :customSuccessRules="[
189
+ {
190
+ type: 'custom',
191
+ options: {
192
+ validate: (value) => value.replace(/\\s/g, '').length === 10,
193
+ successMessage: 'Numéro de téléphone valide.'
194
+ }
195
+ }
196
+ ]"
197
+ />
198
+ </template>`,
199
+ },
200
+ {
201
+ name: 'Script',
202
+ code: `
203
+ <script setup lang="ts">
204
+ import { onMounted, ref } from 'vue'
205
+ import { PhoneField } from '@cnamts/synapse'
206
+
207
+ const phone = ref('0612345678')
208
+ const phoneRef = ref(null)
209
+
210
+ onMounted(() => {
211
+ phoneRef.value?.validateOnSubmit()
212
+ })
213
+ </script>`,
214
+ },
215
+ ],
216
+ },
217
+ args: {
218
+ showSuccessMessages: true,
219
+ } as Record<string, unknown>,
220
+ render: args => ({
221
+ components: { PhoneField },
222
+ setup() {
223
+ const phone = ref('0612345678')
224
+ const phoneRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
225
+
226
+ onMounted(() => {
227
+ phoneRef.value?.validateOnSubmit()
228
+ })
229
+
230
+ return { args, phone, phoneRef }
231
+ },
232
+ template: `
233
+ <div class="pa-4">
234
+ <PhoneField
235
+ ref="phoneRef"
236
+ v-model="phone"
237
+ v-bind="args"
238
+ :customSuccessRules="[
239
+ {
240
+ type: 'custom',
241
+ options: {
242
+ validate: (value) => value.replace(/ /g, '').length === 10,
243
+ successMessage: 'Numéro de téléphone valide.'
244
+ }
245
+ }
246
+ ]"
247
+ />
248
+ </div>
249
+ `,
250
+ }),
251
+ }
252
+
253
+ export const NoValidateOnBlur: Story = {
254
+ parameters: {
255
+ docs: {
256
+ description: {
257
+ story: 'Avec `isValidateOnBlur: false`, la validation se déclenche **immédiatement** dès que la valeur change, sans attendre que le champ perde le focus.\n\nCliquez sur « Définir une valeur invalide » : l\'erreur apparaît aussitôt, sans qu\'il soit nécessaire de quitter le champ. Avec le comportement par défaut (`isValidateOnBlur: true`), la même action ne déclencherait aucune erreur tant que l\'utilisateur n\'a pas quitté le champ.',
258
+ },
259
+ },
260
+ sourceCode: [
261
+ {
262
+ name: 'Template',
263
+ code: `
264
+ <template>
265
+ <div class="d-flex flex-column ga-4 pa-4">
266
+ <PhoneField
267
+ v-model="phone"
268
+ :is-validate-on-blur="false"
269
+ :show-success-messages="true"
270
+ :custom-rules="[{
271
+ type: 'custom',
272
+ options: {
273
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
274
+ message: 'Le numéro de téléphone n\\'est pas valide.'
275
+ }
276
+ }]"
277
+ :custom-success-rules="[{
278
+ type: 'custom',
279
+ options: {
280
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
281
+ successMessage: 'Numéro de téléphone valide.'
282
+ }
283
+ }]"
284
+ />
285
+ <div class="d-flex ga-4 mt-2">
286
+ <VBtn color="primary" @click="phone = '123'">Définir une valeur invalide</VBtn>
287
+ <VBtn color="primary" @click="phone = '0612345678'">Définir une valeur valide</VBtn>
288
+ <VBtn @click="phone = ''">Réinitialiser</VBtn>
289
+ </div>
290
+ </div>
291
+ </template>`,
292
+ },
293
+ {
294
+ name: 'Script',
295
+ code: `
296
+ <script setup lang="ts">
297
+ import { ref } from 'vue'
298
+ import { PhoneField } from '@cnamts/synapse'
299
+ import { VBtn } from 'vuetify/components'
300
+
301
+ const phone = ref('')
302
+ </script>`,
303
+ },
304
+ ],
305
+ },
306
+ args: {
307
+ isValidateOnBlur: false,
308
+ showSuccessMessages: true,
309
+ } as Record<string, unknown>,
310
+ render: args => ({
311
+ components: { PhoneField, VBtn },
312
+ setup() {
313
+ const phone = ref('')
314
+ return { args, phone }
315
+ },
316
+ template: `
317
+ <div class="d-flex flex-column ga-4 pa-4">
318
+ <PhoneField
319
+ v-model="phone"
320
+ v-bind="args"
321
+ :custom-rules="[{
322
+ type: 'custom',
323
+ options: {
324
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
325
+ message: 'Le numéro de téléphone n\\'est pas valide.'
326
+ }
327
+ }]"
328
+ :custom-success-rules="[{
329
+ type: 'custom',
330
+ options: {
331
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
332
+ successMessage: 'Numéro de téléphone valide.'
333
+ }
334
+ }]"
335
+ />
336
+ <div class="d-flex ga-4 mt-2">
337
+ <VBtn color="primary" @click="phone = '123'">Définir une valeur invalide</VBtn>
338
+ <VBtn color="primary" @click="phone = '0612345678'">Définir une valeur valide</VBtn>
339
+ <VBtn @click="phone = ''">Réinitialiser</VBtn>
340
+ </div>
341
+ </div>
342
+ `,
343
+ }),
344
+ }
345
+
346
+ export const DisableErrorHandling: Story = {
347
+ parameters: {
348
+ docs: {
349
+ description: {
350
+ story: 'Avec `disableErrorHandling: true`, les règles d\'erreur sont évaluées mais n\'affectent pas l\'état visuel du champ (pas de bordure rouge ni d\'icône d\'erreur). Utile dans les cas où la validation doit être effectuée en arrière-plan sans perturber l\'expérience utilisateur.',
351
+ },
352
+ },
353
+ sourceCode: [
354
+ {
355
+ name: 'Template',
356
+ code: `
357
+ <template>
358
+ <PhoneField
359
+ v-model="phone"
360
+ :disable-error-handling="true"
361
+ :custom-rules="[{
362
+ type: 'custom',
363
+ options: {
364
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
365
+ message: 'Le numéro de téléphone n\\'est pas valide.'
366
+ }
367
+ }]"
368
+ />
369
+ </template>`,
370
+ },
371
+ {
372
+ name: 'Script',
373
+ code: `
374
+ <script setup lang="ts">
375
+ import { ref } from 'vue'
376
+ import { PhoneField } from '@cnamts/synapse'
377
+
378
+ const phone = ref('123')
379
+ </script>`,
380
+ },
381
+ ],
382
+ },
383
+ args: {
384
+ disableErrorHandling: true,
385
+ } as Record<string, unknown>,
386
+ render: args => ({
387
+ components: { PhoneField },
388
+ setup() {
389
+ const phone = ref('123')
390
+ return { args, phone }
391
+ },
392
+ template: `
393
+ <div class="pa-4">
394
+ <PhoneField
395
+ v-model="phone"
396
+ v-bind="args"
397
+ :custom-rules="[{
398
+ type: 'custom',
399
+ options: {
400
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
401
+ message: 'Le numéro de téléphone n\\'est pas valide.'
402
+ }
403
+ }]"
404
+ />
405
+ </div>
406
+ `,
407
+ }),
408
+ }
409
+
410
+ export const SyFormValidation: Story = {
411
+ parameters: {
412
+ docs: {
413
+ description: {
414
+ story: 'Le champ peut être intégré dans un formulaire utilisant `SyForm` pour bénéficier de la validation globale du formulaire. Dans cet exemple, le bouton de soumission est désactivé tant que le numéro de téléphone n\'est pas valide.',
415
+ },
416
+ },
417
+ sourceCode: [
418
+ {
419
+ name: 'Template',
420
+ code: `
421
+ <template>
422
+ <SyForm @submit="onSubmit">
423
+ <PhoneField
424
+ v-model="phone"
425
+ required
426
+ :custom-rules="[{
427
+ type: 'custom',
428
+ options: {
429
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
430
+ message: 'Le numéro de téléphone n\\'est pas valide.'
431
+ }
432
+ }]"
433
+ />
434
+ <VBtn type="submit" color="primary">Soumettre</VBtn>
435
+ </SyForm>
436
+ </template>`,
437
+ },
438
+ {
439
+ name: 'Script',
440
+ code: `
441
+ <script setup lang="ts">
442
+ import { ref } from 'vue'
443
+ import { SyForm, PhoneField } from '@cnamts/synapse'
444
+ import { VBtn } from 'vuetify/components'
445
+
446
+ const phone = ref('')
447
+
448
+ const onSubmit = (e) => {
449
+ alert('Le formulaire est : ' + (e.isValid ? 'valide' : 'invalide'))
450
+ }
451
+ </script>`,
452
+ },
453
+ ],
454
+ },
455
+ render: args => ({
456
+ components: { SyForm, PhoneField, VBtn },
457
+ setup() {
458
+ const phone = ref('')
459
+ const onSubmit = (e) => {
460
+ alert('Le formulaire est : ' + (e.isValid ? 'valide' : 'invalide'))
461
+ }
462
+ return { args, phone, onSubmit }
463
+ },
464
+ template: `
465
+ <div class="pa-4">
466
+ <SyForm @submit="onSubmit">
467
+ <PhoneField
468
+ v-model="phone"
469
+ v-bind="args"
470
+ required
471
+ :custom-rules="[{
472
+ type: 'custom',
473
+ options: {
474
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
475
+ message: 'Le numéro de téléphone n\\'est pas valide.'
476
+ }
477
+ }]"
478
+ />
479
+ <VBtn type="submit" class="mt-4" color="primary">Soumettre</VBtn>
480
+ </SyForm>
481
+ </div>
482
+ `,
483
+ }),
484
+ }
485
+
486
+ export const VFormValidation: Story = {
487
+ parameters: {
488
+ docs: {
489
+ description: {
490
+ story: 'Le champ peut également être utilisé dans un formulaire classique de Vuetify (`VForm`). Dans cet exemple, le bouton de soumission est désactivé tant que le numéro de téléphone n\'est pas valide.',
491
+ },
492
+ },
493
+ sourceCode: [
494
+ {
495
+ name: 'Template',
496
+ code: `
497
+ <template>
498
+ <VForm @submit.prevent="onSubmit">
499
+ <PhoneField
500
+ v-model="phone"
501
+ ref="phoneFieldRef"
502
+ required
503
+ :custom-rules="[{
504
+ type: 'custom',
505
+ options: {
506
+ validate: (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')),
507
+ message: 'Le numéro de téléphone n\\'est pas valide.'
508
+ }
509
+ }]"
510
+ />
511
+ <VBtn color="primary" type="submit">Soumettre</VBtn>
512
+ </VForm>
513
+ </template>`,
514
+ },
515
+ {
516
+ name: 'Script',
517
+ code: `
518
+ <script setup lang="ts">
519
+ import { ref } from 'vue'
520
+ import { PhoneField } from '@cnamts/synapse'
521
+ import { VForm, VBtn } from 'vuetify/components'
522
+
523
+ const phoneFieldRef = ref(null)
524
+ const phone = ref('')
525
+ async function onSubmit() {
526
+ const result = await phoneFieldRef.value.validateOnSubmit()
527
+ alert('Le formulaire est : ' + (result ? 'valide' : 'invalide'))
528
+ }
529
+ </script>`,
530
+ },
531
+ ],
532
+ },
533
+ render: args => ({
534
+ components: { PhoneField, VForm, VBtn },
535
+ setup() {
536
+ const phone = ref('')
537
+ const phoneFieldRef = ref<{ validateOnSubmit: () => Promise<boolean> } | null>(null)
538
+ async function onSubmit() {
539
+ const result = await phoneFieldRef.value!.validateOnSubmit()
540
+ alert('Le formulaire est : ' + (result ? 'valide' : 'invalide'))
541
+ }
542
+ return { args, phone, phoneFieldRef, onSubmit }
543
+ },
544
+ template: `
545
+ <div class="pa-4">
546
+ <VForm @submit.prevent="onSubmit">
547
+ <p>Preferable d'utiliser SyForm pour bénéficier de la validation globale du formulaire.</p>
548
+ <PhoneField
549
+ v-model="phone"
550
+ v-bind="args"
551
+ ref="phoneFieldRef"
552
+ required
553
+ :custom-rules="[{
554
+ type: 'custom',
555
+ options: {
556
+ validate: (value) => {
557
+ return /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, ''))
558
+ },
559
+ message: 'Le numéro de téléphone n\\'est pas valide.'
560
+ }
561
+ }]"
562
+ />
563
+ <VBtn type="submit" color="primary" class="mt-4">Soumettre</VBtn>
564
+ </VForm>
565
+ </div>
566
+ `,
567
+ }),
568
+ }
569
+
570
+ export const SyFormVuetifyValidation: Story = {
571
+ parameters: {
572
+ docs: {
573
+ description: {
574
+ story: 'Le champ est compatible avec les deux types de formulaires (`SyForm` et `VForm`) dans le même projet, permettant une intégration flexible selon les besoins spécifiques de chaque formulaire.\n\n- **SyForm** : la soumission déclenche automatiquement la validation de tous les champs enregistrés.\n- **VForm** : le bouton de soumission appelle manuellement `validateOnSubmit()` sur le champ.',
575
+ },
576
+ },
577
+ sourceCode: [
578
+ {
579
+ name: 'Template',
580
+ code: `
581
+ <template>
582
+ <SyForm @submit="onSyFormSubmit">
583
+ <PhoneField
584
+ v-model="phone"
585
+ required
586
+ display-asterisk
587
+ class="mb-4"
588
+ use-vuetify-validation
589
+ :rules="rules"
590
+ />
591
+ <VBtn type="submit" color="primary">Soumettre (SyForm)</VBtn>
592
+ </SyForm>
593
+ </template>`,
594
+ },
595
+ {
596
+ name: 'Script',
597
+ code: `
598
+ <script setup lang="ts">
599
+ import { ref } from 'vue'
600
+ import { SyForm, PhoneField } from '@cnamts/synapse'
601
+ import { VBtn, VForm } from 'vuetify/components'
602
+
603
+ const phone = ref('')
604
+
605
+ const rules = [
606
+ (value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')) || 'Le numéro de téléphone n\\'est pas valide.'
607
+ ]
608
+
609
+ function onSyFormSubmit(event: { isValid: boolean }) {
610
+ if (event.isValid) {
611
+ alert('SyForm valide : ' + phone.value)
612
+ } else {
613
+ alert('SyForm invalide : veuillez corriger les erreurs.')
614
+ }
615
+ }
616
+
617
+ </script>`,
618
+ },
619
+ ],
620
+ },
621
+ render: args => ({
622
+ components: { SyForm, PhoneField, VForm, VBtn },
623
+ setup() {
624
+ const phone = ref('')
625
+
626
+ function onSyFormSubmit(event: { isValid: boolean }) {
627
+ if (event.isValid) {
628
+ alert(`SyForm valide : ${phone.value}`)
629
+ }
630
+ else {
631
+ alert('SyForm invalide : veuillez corriger les erreurs.')
632
+ }
633
+ }
634
+
635
+ const rules = [
636
+ value => /^0[1-9][0-9]{8}$/.test(value.replace(/\s/g, '')) || 'Le numéro de téléphone n\'est pas valide.',
637
+ ]
638
+
639
+ return { args, phone, rules, onSyFormSubmit }
640
+ },
641
+ template: `
642
+ <SyForm @submit="onSyFormSubmit" class="pa-4">
643
+ <PhoneField
644
+ v-model="phone"
645
+ v-bind="args"
646
+ required
647
+ display-asterisk
648
+ class="mb-4"
649
+ use-vuetify-validation
650
+ :rules="rules"
651
+ />
652
+ <VBtn type="submit" color="primary">Soumettre (SyForm)</VBtn>
653
+ </SyForm>
654
+ `,
655
+ }),
656
+ }
657
+
658
+ export const VFormAndVuetifyValidation: Story = {
659
+ parameters: {
660
+ docs: {
661
+ description: {
662
+ story: 'En utilisant vuetifyValidation, le champ peut être validé à la fois par `SyForm` et `VForm` selon le contexte d\'utilisation.',
663
+ },
664
+ },
665
+ sourceCode: [
666
+ {
667
+ name: 'Template',
668
+ code: `
669
+ <template>
670
+ <VForm v-slot="{ isValid }">
671
+ <PhoneField
672
+ v-model="phone"
673
+ :use-vuetify-validation="true"
674
+ :rules="[(value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')) || 'Le numéro de téléphone n\\'est pas valide.']"
675
+ />
676
+ <VBtn type="submit" :disabled="isValid === false" color="primary">Soumettre</VBtn>
677
+ </VForm>
678
+ </template>`,
679
+ },
680
+ {
681
+ name: 'Script',
682
+ code: `
683
+ <script setup lang="ts">
684
+ import { ref } from 'vue'
685
+ import { PhoneField } from '@cnamts/synapse'
686
+ import { VForm, VBtn } from 'vuetify/components'
687
+
688
+ const phone = ref('')
689
+ </script>`,
690
+ },
691
+ ],
692
+ },
693
+ render: args => ({
694
+ components: { PhoneField, VForm, VBtn },
695
+ setup() {
696
+ const phone = ref('')
697
+ async function onSubmit(e: Promise<{ valid: boolean }>) {
698
+ const result = await e
699
+ alert('Le formulaire est : ' + (result.valid ? 'valide' : 'invalide'))
700
+ }
701
+ return { args, phone, onSubmit }
702
+ },
703
+ template: `
704
+ <div class="pa-4">
705
+ <VForm @submit.prevent="onSubmit">
706
+ <PhoneField
707
+ v-model="phone"
708
+ v-bind="args"
709
+ :use-vuetify-validation="true"
710
+ :rules="[(value) => /^0[1-9][0-9]{8}$/.test(value.replace(/\\s/g, '')) || 'Le numéro de téléphone n\\'est pas valide.']"
711
+ />
712
+ <VBtn type="submit" class="mt-4" color="primary">Soumettre</VBtn>
713
+ </VForm>
714
+ </div>
715
+ `,
716
+ }),
717
+ }
@@ -29,7 +29,6 @@ Vous pouvez personnaliser les limites de l'intervalle en utilisant les props `mi
29
29
  import { RangeField } from '@cnamts/synapse'
30
30
 
31
31
  const range = ref([0, 100])
32
- import '../../stories/styles/shared.css';
33
32
  </script>
34
33
 
35
34
  <template>