@cnamts/synapse 0.0.11-alpha → 0.0.12-alpha

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 (108) hide show
  1. package/dist/design-system-v3.js +3878 -3189
  2. package/dist/design-system-v3.umd.cjs +1 -1
  3. package/dist/src/components/Amelipro/types/languages.d.ts +6 -0
  4. package/dist/src/components/Amelipro/types/types.d.ts +65 -0
  5. package/dist/src/components/CookieBanner/CookieBanner.d.ts +1 -1
  6. package/dist/src/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
  7. package/dist/src/components/Customs/SyTextField/SyTextField.d.ts +29 -23
  8. package/dist/src/components/Customs/SyTextField/types.d.ts +1 -0
  9. package/dist/src/components/DatePicker/DatePicker.d.ts +70 -59
  10. package/dist/src/components/DatePicker/DateTextInput.d.ts +67 -56
  11. package/dist/src/components/ErrorPage/ErrorPage.d.ts +1 -1
  12. package/dist/src/components/FileList/FileList.d.ts +1 -0
  13. package/dist/src/components/FileList/UploadItem/UploadItem.d.ts +1 -1
  14. package/dist/src/components/FilterSideBar/FilterSideBar.d.ts +31 -0
  15. package/dist/src/components/FilterSideBar/locales.d.ts +7 -0
  16. package/dist/src/components/FilterSideBar/tests/FilterSideBar.spec.d.ts +1 -0
  17. package/dist/src/components/LangBtn/LangBtn.d.ts +2 -2
  18. package/dist/src/components/NirField/NirField.d.ts +940 -0
  19. package/dist/src/components/NotificationBar/NotificationBar.d.ts +1 -1
  20. package/dist/src/components/PasswordField/PasswordField.d.ts +40 -8
  21. package/dist/src/components/PeriodField/PeriodField.d.ts +142 -120
  22. package/dist/src/components/PhoneField/PhoneField.d.ts +11 -2
  23. package/dist/src/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +1 -1
  24. package/dist/src/components/RatingPicker/NumberPicker/NumberPicker.d.ts +1 -1
  25. package/dist/src/components/RatingPicker/StarsPicker/StarsPicker.d.ts +1 -1
  26. package/dist/src/components/UploadWorkflow/config.d.ts +29 -0
  27. package/dist/src/components/UploadWorkflow/locales.d.ts +7 -0
  28. package/dist/src/components/UploadWorkflow/tests/UploadWorkflow.spec.d.ts +1 -0
  29. package/dist/src/components/UploadWorkflow/types.d.ts +19 -0
  30. package/dist/src/components/UploadWorkflow/useFileList.d.ts +10 -0
  31. package/dist/src/components/UploadWorkflow/useFileUploadJourney.d.ts +9 -0
  32. package/dist/src/components/index.d.ts +2 -0
  33. package/dist/src/composables/rules/useFieldValidation.d.ts +1 -0
  34. package/dist/src/composables/validation/tests/useValidation.spec.d.ts +1 -0
  35. package/dist/src/composables/validation/useValidation.d.ts +39 -0
  36. package/dist/src/designTokens/index.d.ts +3 -1
  37. package/dist/src/vuetifyConfig.d.ts +81 -0
  38. package/dist/style.css +1 -1
  39. package/package.json +1 -1
  40. package/src/assets/_elevations.scss +89 -0
  41. package/src/assets/_fonts.scss +6 -0
  42. package/src/assets/_radius.scss +86 -0
  43. package/src/assets/_spacers.scss +149 -0
  44. package/src/assets/settings.scss +7 -3
  45. package/src/assets/tokens.scss +32 -29
  46. package/src/components/Amelipro/types/languages.d.ts +6 -0
  47. package/src/components/Amelipro/types/types.d.ts +65 -0
  48. package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +65 -0
  49. package/src/components/Customs/SyInputSelect/SyInputSelect.vue +13 -3
  50. package/src/components/Customs/SySelect/SySelect.stories.ts +88 -5
  51. package/src/components/Customs/SySelect/SySelect.vue +36 -10
  52. package/src/components/Customs/SySelect/tests/SySelect.spec.ts +135 -2
  53. package/src/components/Customs/SyTextField/SyTextField.stories.ts +576 -85
  54. package/src/components/Customs/SyTextField/SyTextField.vue +132 -104
  55. package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +190 -38
  56. package/src/components/Customs/SyTextField/types.d.ts +1 -0
  57. package/src/components/DatePicker/DatePicker.vue +405 -137
  58. package/src/components/DatePicker/DateTextInput.vue +15 -0
  59. package/src/components/DatePicker/tests/DatePicker.spec.ts +8 -15
  60. package/src/components/FileList/FileList.vue +2 -1
  61. package/src/components/FileList/UploadItem/UploadItem.vue +10 -0
  62. package/src/components/FileUpload/FileUpload.stories.ts +84 -0
  63. package/src/components/FileUpload/FileUpload.vue +1 -0
  64. package/src/components/FileUpload/tests/FileUpload.spec.ts +4 -4
  65. package/src/components/FilterInline/FilterInline.mdx +180 -34
  66. package/src/components/FilterInline/FilterInline.stories.ts +363 -6
  67. package/src/components/FilterSideBar/FilterSideBar.mdx +237 -0
  68. package/src/components/FilterSideBar/FilterSideBar.stories.ts +798 -0
  69. package/src/components/FilterSideBar/FilterSideBar.vue +193 -0
  70. package/src/components/FilterSideBar/locales.ts +8 -0
  71. package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +305 -0
  72. package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +39 -0
  73. package/src/components/HeaderBar/Usages.mdx +1 -1
  74. package/src/components/NirField/NirField.stories.ts +573 -29
  75. package/src/components/NirField/NirField.vue +397 -359
  76. package/src/components/NirField/tests/NirField.spec.ts +88 -52
  77. package/src/components/NirField/tests//342/200/257dataset/342/200/257.md +12 -0
  78. package/src/components/NotificationBar/Accessibilite.stories.ts +4 -0
  79. package/src/components/NotificationBar/NotificationBar.stories.ts +18 -13
  80. package/src/components/PasswordField/PasswordField.mdx +129 -47
  81. package/src/components/PasswordField/PasswordField.stories.ts +924 -120
  82. package/src/components/PasswordField/PasswordField.vue +209 -99
  83. package/src/components/PasswordField/tests/PasswordField.spec.ts +138 -9
  84. package/src/components/PeriodField/PeriodField.vue +55 -54
  85. package/src/components/PhoneField/PhoneField.stories.ts +69 -0
  86. package/src/components/PhoneField/PhoneField.vue +3 -0
  87. package/src/components/PhoneField/indicatifs.ts +1 -1
  88. package/src/components/UploadWorkflow/UploadWorkflow.mdx +75 -0
  89. package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +943 -0
  90. package/src/components/UploadWorkflow/UploadWorkflow.vue +230 -0
  91. package/src/components/UploadWorkflow/config.ts +29 -0
  92. package/src/components/UploadWorkflow/locales.ts +8 -0
  93. package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +257 -0
  94. package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +54 -0
  95. package/src/components/UploadWorkflow/types.ts +21 -0
  96. package/src/components/UploadWorkflow/useFileList.ts +84 -0
  97. package/src/components/UploadWorkflow/useFileUploadJourney.ts +18 -0
  98. package/src/components/index.ts +2 -0
  99. package/src/composables/rules/useFieldValidation.ts +5 -2
  100. package/src/composables/validation/tests/useValidation.spec.ts +154 -0
  101. package/src/composables/validation/useValidation.ts +165 -0
  102. package/src/designTokens/index.ts +4 -0
  103. package/src/stories/Demarrer/Accueil.mdx +1 -1
  104. package/src/stories/DesignTokens/ThemePA.mdx +4 -30
  105. package/src/stories/GuideDuDev/UtiliserLesRules.mdx +319 -76
  106. package/src/stories/GuideDuDev/moduleDeNotification.mdx +1 -1
  107. package/src/vuetifyConfig.ts +61 -0
  108. package/src/composables/useFilterable/__snapshots__/useFilterable.spec.ts.snap +0 -3
@@ -1,4 +1,6 @@
1
1
  import type { StoryObj, Meta } from '@storybook/vue3'
2
+ import { ref } from 'vue'
3
+ import { VBtn } from 'vuetify/components'
2
4
  import NirField from './NirField.vue'
3
5
 
4
6
  const meta: Meta<typeof NirField> = {
@@ -51,6 +53,20 @@ const meta: Meta<typeof NirField> = {
51
53
  },
52
54
  },
53
55
  },
56
+ nirTooltipPosition: {
57
+ description: 'Position de l\'infobulle pour le champ NIR, si le `nirTooltip` est renseigné',
58
+ control: 'select',
59
+ options: ['prepend', 'append'],
60
+ default: 'append',
61
+ table: {
62
+ type: {
63
+ summary: 'string',
64
+ },
65
+ defaultValue: {
66
+ summary: 'append',
67
+ },
68
+ },
69
+ },
54
70
  keyTooltip: {
55
71
  description: 'Infobulle pour le champ clé.',
56
72
  control: 'text',
@@ -60,24 +76,44 @@ const meta: Meta<typeof NirField> = {
60
76
  },
61
77
  },
62
78
  },
79
+ keyTooltipPosition: {
80
+ description: 'Position de l\'infobulle pour le champ clé, si le `keyTooltip` est renseigné',
81
+ control: 'select',
82
+ options: ['prepend', 'append'],
83
+ default: 'append',
84
+ table: {
85
+ type: {
86
+ summary: 'string',
87
+ },
88
+ defaultValue: {
89
+ summary: 'append',
90
+ },
91
+ },
92
+ },
63
93
  numberLabel: {
64
- description: 'Étiquette pour le champ numéro.',
94
+ description: 'Label pour le champ numéro.',
65
95
  control: 'text',
66
96
  default: 'Numéro de sécurité sociale',
67
97
  table: {
68
98
  type: {
69
99
  summary: 'string',
70
100
  },
101
+ defaultValue: {
102
+ summary: 'Numéro de sécurité sociale',
103
+ },
71
104
  },
72
105
  },
73
106
  keyLabel: {
74
- description: 'Étiquette pour le champ clé.',
107
+ description: 'Label pour le champ clé.',
75
108
  control: 'text',
76
109
  default: 'Clé',
77
110
  table: {
78
111
  type: {
79
112
  summary: 'string',
80
113
  },
114
+ defaultValue: {
115
+ summary: 'Clé',
116
+ },
81
117
  },
82
118
  },
83
119
  displayKey: {
@@ -118,6 +154,177 @@ const meta: Meta<typeof NirField> = {
118
154
  },
119
155
  },
120
156
  },
157
+ bgColor: {
158
+ description: 'Définit la couleur de fond du champ.',
159
+ control: 'color',
160
+ default: undefined,
161
+ table: {
162
+ type: {
163
+ summary: 'string',
164
+ },
165
+ },
166
+ },
167
+ isDisabled: {
168
+ description: 'Indique si le champ est désactivé.',
169
+ control: 'boolean',
170
+ default: false,
171
+ table: {
172
+ type: {
173
+ summary: 'boolean',
174
+ },
175
+ },
176
+ },
177
+ width: {
178
+ description: 'Définit la largeur du champ NIR. Accepte toute valeur CSS valide (%, px, rem, etc.). Le champ numéro occupera 80% de cette largeur et le champ clé 20%.',
179
+ control: 'text',
180
+ default: '100%',
181
+ table: {
182
+ type: {
183
+ summary: 'string',
184
+ },
185
+ defaultValue: {
186
+ summary: '100%',
187
+ },
188
+ },
189
+ },
190
+ // Propriétés natives de Vuetify
191
+ density: {
192
+ description: 'Contrôle la densité du champ.',
193
+ control: 'select',
194
+ options: ['default', 'comfortable', 'compact'],
195
+ default: 'default',
196
+ table: {
197
+ type: {
198
+ summary: 'string',
199
+ },
200
+ defaultValue: {
201
+ summary: 'default',
202
+ },
203
+ },
204
+ },
205
+ hideDetails: {
206
+ description: 'Masque les détails du champ (messages d\'erreur, compteur, etc.).',
207
+ control: 'boolean',
208
+ default: false,
209
+ table: {
210
+ type: {
211
+ summary: 'boolean | "auto"',
212
+ },
213
+ defaultValue: {
214
+ summary: 'false',
215
+ },
216
+ },
217
+ },
218
+ hideSpinButtons: {
219
+ description: 'Masque les boutons de spin pour les champs numériques.',
220
+ control: 'boolean',
221
+ default: false,
222
+ table: {
223
+ type: {
224
+ summary: 'boolean',
225
+ },
226
+ defaultValue: {
227
+ summary: 'false',
228
+ },
229
+ },
230
+ },
231
+ placeholder: {
232
+ description: 'Texte à afficher lorsque le champ est vide.',
233
+ control: 'text',
234
+ table: {
235
+ type: {
236
+ summary: 'string',
237
+ },
238
+ },
239
+ },
240
+ readonly: {
241
+ description: 'Rend le champ en lecture seule.',
242
+ control: 'boolean',
243
+ default: false,
244
+ table: {
245
+ type: {
246
+ summary: 'boolean',
247
+ },
248
+ defaultValue: {
249
+ summary: 'false',
250
+ },
251
+ },
252
+ },
253
+ variant: {
254
+ description: 'Style du champ.',
255
+ control: 'select',
256
+ options: ['filled', 'outlined', 'plain', 'underlined', 'solo'],
257
+ default: 'outlined',
258
+ table: {
259
+ type: {
260
+ summary: 'string',
261
+ },
262
+ defaultValue: {
263
+ summary: 'outlined',
264
+ },
265
+ },
266
+ },
267
+ clearable: {
268
+ description: 'Permet d\'afficher un bouton pour effacer le contenu.',
269
+ control: 'boolean',
270
+ default: false,
271
+ table: {
272
+ type: {
273
+ summary: 'boolean',
274
+ },
275
+ defaultValue: {
276
+ summary: 'false',
277
+ },
278
+ },
279
+ },
280
+ counter: {
281
+ description: 'Affiche un compteur de caractères.',
282
+ control: 'boolean',
283
+ default: false,
284
+ table: {
285
+ type: {
286
+ summary: 'boolean | number | string',
287
+ },
288
+ defaultValue: {
289
+ summary: 'false',
290
+ },
291
+ },
292
+ },
293
+ hint: {
294
+ description: 'Texte d\'aide affiché sous le champ.',
295
+ control: 'text',
296
+ table: {
297
+ type: {
298
+ summary: 'string',
299
+ },
300
+ },
301
+ },
302
+ persistentHint: {
303
+ description: 'Affiche toujours l\'indice, même lorsque le champ n\'est pas en focus.',
304
+ control: 'boolean',
305
+ default: false,
306
+ table: {
307
+ type: {
308
+ summary: 'boolean',
309
+ },
310
+ defaultValue: {
311
+ summary: 'false',
312
+ },
313
+ },
314
+ },
315
+ persistentPlaceholder: {
316
+ description: 'Affiche toujours le placeholder, même lorsque le champ est en focus.',
317
+ control: 'boolean',
318
+ default: false,
319
+ table: {
320
+ type: {
321
+ summary: 'boolean',
322
+ },
323
+ defaultValue: {
324
+ summary: 'false',
325
+ },
326
+ },
327
+ },
121
328
  },
122
329
  } satisfies Meta<typeof NirField>
123
330
 
@@ -171,32 +378,73 @@ export const Required: Story = {
171
378
  required: true,
172
379
  },
173
380
  parameters: {
174
- ...Default.parameters,
381
+ docs: {
382
+ description: {
383
+ story: `
384
+ ### Champs requis sans astérisque
385
+
386
+ Cette story montre des champs requis sans astérisque.
387
+ Pour afficher l'astérisque sur des champs requis, il faut activer la prop \`displayAsterisk\`.`,
388
+ },
389
+ },
175
390
  sourceCode: [
176
391
  {
177
392
  name: 'Template',
178
- code: `
179
- <template>
180
- <NirField
181
- v-model="value"
182
- :required="true"
183
- numberLabel="Numéro de sécurité sociale"
184
- keyLabel="Clé"
185
- :displayKey="true"
186
- />
187
- </template>
188
- `,
393
+ code: `<template>
394
+ <NirField
395
+ v-model="value"
396
+ required
397
+ />
398
+ </template>`,
189
399
  },
190
400
  {
191
401
  name: 'Script',
192
- code: `
193
- <script setup lang="ts">
194
- import NirField from '@cnamts/synapse'
195
- import { ref } from 'vue'
196
-
197
- const value = ref('')
198
- </script>
199
- `,
402
+ code: `<script setup lang="ts">
403
+ import { NirField } from '@cnamts/synapse'
404
+ import { ref } from 'vue'
405
+
406
+ const value = ref('')
407
+ </script>`,
408
+ },
409
+ ],
410
+ },
411
+ }
412
+
413
+ export const RequiredWithAsterisk: Story = {
414
+ args: {
415
+ ...Default.args,
416
+ displayAsterisk: true,
417
+ required: true,
418
+ },
419
+ parameters: {
420
+ docs: {
421
+ description: {
422
+ story: `
423
+ ### Champs non requis avec astérisque
424
+
425
+ Cette story montre que des champs non requis ne peuvent pas avoir d'astérisque.
426
+ Même si \`displayAsterisk\` est à \`true\`, l'astérisque ne s'affichera pas car les champs ne sont pas requis.`,
427
+ },
428
+ },
429
+ sourceCode: [
430
+ {
431
+ name: 'Template',
432
+ code: `<template>
433
+ <NirField
434
+ v-model="value"
435
+ display-asterisk
436
+ required
437
+ />
438
+ </template>`,
439
+ },
440
+ {
441
+ name: 'Script',
442
+ code: `<script setup lang="ts">
443
+ import { NirField } from '@cnamts/synapse'
444
+ import { ref } from 'vue'
445
+
446
+ const value = ref('')
447
+ </script>`,
200
448
  },
201
449
  ],
202
450
  },
@@ -335,13 +583,22 @@ export const CustomRules: Story = {
335
583
  },
336
584
  }
337
585
 
338
- export const WithNumberTooltip: Story = {
586
+ export const WithNirTooltip: Story = {
339
587
  args: {
340
588
  ...Default.args,
341
- nirTooltip: 'Ceci est un tooltip pour le champs numéro de sécurité sociale',
589
+ nirTooltip: 'Ceci est un tooltip pour le champs numéro de sécurité sociale si le champs `nirTooltip` est saisi',
590
+ nirTooltipPosition: 'prepend',
342
591
  },
343
592
  parameters: {
344
- ...Default.parameters,
593
+ docs: {
594
+ description: {
595
+ story: `
596
+ ### Tooltip sur le champ NIR
597
+
598
+ Cette story montre l'affichage d'une infobulle sur le champ du numéro de sécurité sociale.
599
+ L'infobulle est positionnée avant le champ et s'affiche au survol de l'icône d'information.`,
600
+ },
601
+ },
345
602
  sourceCode: [
346
603
  {
347
604
  name: 'Template',
@@ -353,7 +610,8 @@ export const WithNumberTooltip: Story = {
353
610
  numberLabel="Numéro de sécurité sociale"
354
611
  keyLabel="Clé"
355
612
  :displayKey="true"
356
- nirTooltip="Ceci est un tooltip pour le champs numéro de sécurité sociale"
613
+ :nirTooltip="'Ceci est un tooltip pour le champs numéro de sécurité sociale'"
614
+ nirTooltipPosition="prepend"
357
615
  />
358
616
  </template>
359
617
  `,
@@ -377,9 +635,18 @@ export const WithKeyTooltip: Story = {
377
635
  args: {
378
636
  ...Default.args,
379
637
  keyTooltip: 'Ceci est un tooltip pour la clef du numéro de sécurité sociale',
638
+ keyTooltipPosition: 'append',
380
639
  },
381
640
  parameters: {
382
- ...Default.parameters,
641
+ docs: {
642
+ description: {
643
+ story: `
644
+ ### Tooltip sur le champ clé
645
+
646
+ Cette story montre l'affichage d'une infobulle sur le champ de la clé.
647
+ L'infobulle est positionnée après le champ et s'affiche au survol de l'icône d'information.`,
648
+ },
649
+ },
383
650
  sourceCode: [
384
651
  {
385
652
  name: 'Template',
@@ -391,7 +658,185 @@ export const WithKeyTooltip: Story = {
391
658
  numberLabel="Numéro de sécurité sociale"
392
659
  keyLabel="Clé"
393
660
  :displayKey="true"
394
- keyTooltip="Ceci est un tooltip pour la clef du numéro de sécurité sociale"
661
+ :keyTooltip="'Ceci est un tooltip pour la clef du numéro de sécurité sociale'"
662
+ keyTooltipPosition="append"
663
+ />
664
+ </template>
665
+ `,
666
+ },
667
+ {
668
+ name: 'Script',
669
+ code: `
670
+ <script setup lang="ts">
671
+ import NirField from '@cnamts/synapse'
672
+ import { ref } from 'vue'
673
+
674
+ const value = ref('')
675
+ </script>
676
+ `,
677
+ },
678
+ ],
679
+ },
680
+ }
681
+
682
+ export const WithWarnings: Story = {
683
+ args: {
684
+ ...Default.args,
685
+ showSuccessMessages: false,
686
+ customNumberWarningRules: [
687
+ {
688
+ type: 'custom',
689
+ options: {
690
+ message: 'Attention : ce NIR commence par 1 (homme)',
691
+ warningMessage: 'Attention : ce NIR commence par 1 (homme)',
692
+ validate: (value: string) => {
693
+ if (!value) return false
694
+ // On retourne true si la règle n'est PAS respectée (= warning)
695
+ return !value.startsWith('1')
696
+ },
697
+ isWarning: true,
698
+ },
699
+ },
700
+ {
701
+ type: 'custom',
702
+ options: {
703
+ message: 'Attention : ce NIR commence par 2 (femme)',
704
+ warningMessage: 'Attention : ce NIR commence par 2 (femme)',
705
+ validate: (value: string) => {
706
+ if (!value) return false
707
+ // On retourne true si la règle n'est PAS respectée (= warning)
708
+ return !value.startsWith('2')
709
+ },
710
+ isWarning: true,
711
+ },
712
+ },
713
+ ],
714
+ customKeyRules: [
715
+ {
716
+ type: 'custom',
717
+ options: {
718
+ message: 'La clé doit être comprise entre 01 et 97',
719
+ validate: (value: string) => {
720
+ if (!value) return true
721
+ const numValue = parseInt(value)
722
+ return numValue >= 1 && numValue <= 97
723
+ },
724
+ },
725
+ },
726
+ ],
727
+ customKeyWarningRules: [
728
+ {
729
+ type: 'custom',
730
+ options: {
731
+ message: 'Attention : la clé est supérieure à 50',
732
+ warningMessage: 'Attention : la clé est supérieure à 50',
733
+ validate: (value: string) => {
734
+ if (!value) return false
735
+ const numValue = parseInt(value)
736
+ // On retourne true si la règle n'est PAS respectée (= warning)
737
+ return !(numValue > 50)
738
+ },
739
+ isWarning: true,
740
+ },
741
+ },
742
+ ],
743
+ },
744
+ parameters: {
745
+ ...Default.parameters,
746
+ docs: {
747
+ description: {
748
+ story: `
749
+ ## Exemple d'utilisation des warnings
750
+
751
+ Le NirField peut afficher des warnings pour guider l'utilisateur sans bloquer la validation.
752
+
753
+ ### Warnings sur le NIR
754
+ - Un warning s'affiche si le NIR commence par 1 (homme)
755
+ - Un warning s'affiche si le NIR commence par 2 (femme)
756
+
757
+ ### Warnings sur la clé
758
+ - Un warning s'affiche si la clé est supérieure à 50
759
+ - Une erreur s'affiche si la clé n'est pas entre 01 et 97
760
+
761
+ ### Exemples de NIR valides avec warnings :
762
+ - \`1234567891011\` (warning : homme)
763
+ - \`2234567891011\` (warning : femme)
764
+ - Clé \`51\` (warning : clé > 50)
765
+
766
+ Les warnings sont affichés en jaune avec une icône d'avertissement mais ne bloquent pas la validation.
767
+ Les erreurs sont affichées en rouge et bloquent la validation.
768
+ `,
769
+ },
770
+ },
771
+ sourceCode: [
772
+ {
773
+ name: 'Template',
774
+ code: `
775
+ <template>
776
+ <NirField
777
+ v-model="value"
778
+ :required="false"
779
+ :show-success-messages="true"
780
+ numberLabel="Numéro de sécurité sociale"
781
+ keyLabel="Clé"
782
+ :display-key="true"
783
+ :customNumberWarningRules="[
784
+ {
785
+ type: 'custom',
786
+ options: {
787
+ message: 'Attention : ce NIR commence par 1 (homme)',
788
+ warningMessage: 'Attention : ce NIR commence par 1 (homme)',
789
+ validate: (value) => {
790
+ if (!value) return false
791
+ // On retourne true si la règle n'est PAS respectée (= warning)
792
+ return !value.startsWith('1')
793
+ },
794
+ isWarning: true,
795
+ },
796
+ },
797
+ {
798
+ type: 'custom',
799
+ options: {
800
+ message: 'Attention : ce NIR commence par 2 (femme)',
801
+ warningMessage: 'Attention : ce NIR commence par 2 (femme)',
802
+ validate: (value) => {
803
+ if (!value) return false
804
+ // On retourne true si la règle n'est PAS respectée (= warning)
805
+ return !value.startsWith('2')
806
+ },
807
+ isWarning: true,
808
+ },
809
+ },
810
+ ]"
811
+ :customKeyRules="[
812
+ {
813
+ type: 'custom',
814
+ options: {
815
+ message: 'La clé doit être comprise entre 01 et 97',
816
+ validate: (value) => {
817
+ if (!value) return true
818
+ const numValue = parseInt(value)
819
+ return numValue >= 1 && numValue <= 97
820
+ },
821
+ },
822
+ },
823
+ ]"
824
+ :customKeyWarningRules="[
825
+ {
826
+ type: 'custom',
827
+ options: {
828
+ message: 'Attention : la clé est supérieure à 50',
829
+ warningMessage: 'Attention : la clé est supérieure à 50',
830
+ validate: (value) => {
831
+ if (!value) return false
832
+ const numValue = parseInt(value)
833
+ // On retourne true si la règle n'est PAS respectée (= warning)
834
+ return !(numValue > 50)
835
+ },
836
+ isWarning: true,
837
+ },
838
+ },
839
+ ]"
395
840
  />
396
841
  </template>
397
842
  `,
@@ -400,7 +845,7 @@ export const WithKeyTooltip: Story = {
400
845
  name: 'Script',
401
846
  code: `
402
847
  <script setup lang="ts">
403
- import NirField from '@cnamts/synapse'
848
+ import { NirField } from '@cnamts/synapse'
404
849
  import { ref } from 'vue'
405
850
 
406
851
  const value = ref('')
@@ -410,3 +855,102 @@ export const WithKeyTooltip: Story = {
410
855
  ],
411
856
  },
412
857
  }
858
+
859
+ export const FormValidation: Story = {
860
+ parameters: {
861
+ docs: {
862
+ description: {
863
+ story: `
864
+ ### Validation de formulaire
865
+
866
+ Cette story montre l'utilisation du NirField dans un formulaire avec validation. Le formulaire :
867
+ - Requiert un NIR valide (13 chiffres)
868
+ - Requiert une clé valide (2 chiffres)
869
+ - Affiche des messages de succès quand les champs sont valides
870
+ - Affiche des messages d'erreur quand les champs sont invalides
871
+ `,
872
+ },
873
+ },
874
+ sourceCode: [
875
+ {
876
+ name: 'Template',
877
+ code: `<form @submit.prevent="onSubmit">
878
+ <NirField
879
+ v-model="value"
880
+ label="Numéro de sécurité sociale"
881
+ required
882
+ showSuccessMessages
883
+ ref="nirField"
884
+ />
885
+ <v-btn
886
+ type="submit"
887
+ color="primary"
888
+ class="mt-4"
889
+ >
890
+ Valider
891
+ </v-btn>
892
+ </form>`,
893
+ },
894
+ {
895
+ name: 'Script',
896
+ code: `<script setup lang="ts">
897
+ import { ref } from 'vue'
898
+ import { NirField } from '@cnamts/synapse'
899
+
900
+ const value = ref('')
901
+ const nirField = ref()
902
+
903
+ const onSubmit = async () => {
904
+ const isValid = await nirField.value?.validateOnSubmit()
905
+
906
+ if (isValid) {
907
+ alert('Formulaire soumis avec succès !')
908
+ }
909
+ else {
910
+ alert('Formulaire non soumis !')
911
+ }
912
+ }
913
+ </script>`,
914
+ },
915
+ ],
916
+ },
917
+ render: args => ({
918
+ components: { NirField, VBtn },
919
+ setup() {
920
+ const value = ref('')
921
+ const nirField = ref()
922
+
923
+ const onSubmit = async () => {
924
+ const isValid = await nirField.value?.validateOnSubmit()
925
+
926
+ if (isValid) {
927
+ alert('Formulaire soumis avec succès !')
928
+ }
929
+ else {
930
+ alert('Formulaire non soumis !')
931
+ }
932
+ }
933
+
934
+ return { args, value, nirField, onSubmit }
935
+ },
936
+ template: `
937
+ <form @submit.prevent="onSubmit">
938
+ <NirField
939
+ v-model="value"
940
+ v-bind="args"
941
+ label="Numéro de sécurité sociale"
942
+ required
943
+ showSuccessMessages
944
+ ref="nirField"
945
+ />
946
+ <v-btn
947
+ type="submit"
948
+ color="primary"
949
+ class="mt-4"
950
+ >
951
+ Valider
952
+ </v-btn>
953
+ </form>
954
+ `,
955
+ }),
956
+ }