@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
@@ -49,7 +49,14 @@ import NirField from './NirField.vue';
49
49
  <NirField
50
50
  ref="nirFieldRef"
51
51
  v-model="model"
52
+ number-label="Numéro de sécurité sociale"
53
+ key-label="Clé"
52
54
  :display-key="true"
55
+ number-hint="Exemple : 1 84 01 234 567 890"
56
+ key-hint="Exemple : 74"
57
+ number-tooltip="message d'aide pour le NIR"
58
+ key-tooltip="message d'aide pour la clef"
59
+ outlined
53
60
  required
54
61
  />
55
62
  <button type="submit">
@@ -70,17 +77,14 @@ Le composant `NirField` utilise des règles de validation par défaut pour le nu
70
77
 
71
78
  - Le 1er chiffre (1er composant) permet d'identifier le sexe de l'assuré (1 pour un homme et 2 pour une femme) ;
72
79
  - Le second composant est un groupe de deux chiffres permettant de distinguer l'année de naissance (exemple 77 pour 1977) ;
73
- - Le 3ème composant est un groupe de deux chiffres correspondant au mois de naissance (de 01 à 12) mais peut aussi prendre dautres valeurs (de 20 à 99) qui indiquent que le mois de naissance de lindividu nest pas connu (cela peut arriver pour des personnes nées à l’étranger) (https://www.insee.fr/fr/information/6665190?sommaire=6665196#titre-bloc-encadre4) ;
80
+ - Le 3ème composant est un groupe de deux chiffres correspondant au mois de naissance (de 01 à 12) mais peut aussi prendre d'autres valeurs (de 20 à 99) qui indiquent que le mois de naissance de l'individu n'est pas connu (cela peut arriver pour des personnes nées à l'étranger) (https://www.insee.fr/fr/information/6665190?sommaire=6665196#titre-bloc-encadre4) ;
74
81
  - Le 4ème correspond au département de naissance selon le code géographique officiel (de 01 à 95 et 97 pour les DOM et COM 976, 98 pour les TOM et COM et enfin 99 pour les nés hors de France) ;
75
82
  - Le 5ème est un groupe de 3 chiffres permettant d'identifier la commune de naissance, selon le code géographique officiel édité par l'INSEE (https://www.insee.fr/fr/information/5057840) ;
76
83
  - Le 6ème est un groupe de 3 chiffres, correspondant au rang d'inscription sur la liste du répertoire régional de l'INSEE ;
77
84
  - Le 7ème composant optionnel est un groupe de 2 chiffres appelé la clé de contrôle du NIR.
78
85
 
79
86
  - Props: `nirType` à complexe : d'après la page [Wikipedia](https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France)
80
-
81
- - Le numéro NIR doit être composé de 13 chiffres.
82
- - Le numéro NIR doit respecter le format suivant :
83
- - 1 chiffre pour le sexe (1-4, 7, 8)
87
+ - 1 chiffre pour le sexe (1=homme, 2=femme, 3=homme étranger, 4=femme étrangère, 7=homme inconnu, 8=femme inconnue)
84
88
  - 2 chiffres pour l'année de naissance
85
89
  - 2 chiffres pour le mois de naissance (01-12, 20-42)
86
90
  - 2 chiffres pour le département de naissance (01-99, 2A, 2B, 96, 97X, 98X)
@@ -104,7 +108,7 @@ Chaque règle est un objet avec la structure suivante :
104
108
 
105
109
  - `type` (string) : Le type de validation (par exemple, `minLength`).
106
110
  - `options` (object) : Options pour la règle de validation, incluant :
107
- - `length` (number) : La longueur requise pour les règles `minLength`, `maxLength`, `min` et `max`.
111
+ - `length` (number) : La longueur requise pour les règles `minLength`, `maxLength`, `min` et `max`.
108
112
  - `message` (string | optionnel) : Le message d'erreur à afficher si la validation échoue (sinon le message par default s'affiche).
109
113
  - `successMessage` (string | optionnel) : Le message à afficher si la validation réussit (sinon le message par default s'affiche).
110
114
 
@@ -112,19 +116,108 @@ Vous trouverez la liste des rules mises à disposition dans la section [Comment
112
116
 
113
117
  #### 2. Regles personnalisées :
114
118
 
115
- Pour les regles de gestion personnalisées, vous pouvez utiliser les règles de type `custom` et définir une fonction de validation personnalisée. Cette fonction doit retourner un objet avec les propriétés `valid` (booléen) et `message` (string) :
119
+ Pour les regles de gestion personnalisées, vous pouvez utiliser les règles de type `custom` et définir une fonction de validation personnalisée. Cette fonction doit retourner un booléen (`true` si la valeur est valide, `false` si elle est invalide) :
116
120
 
117
121
  <Source dark code={`
118
122
  {
119
123
  type: 'custom',
120
124
  options: {
121
- validate: (value: string) => value.startsWith('123') || 'Le NIR doit commencer par 123.',
125
+ validate: (value: string) => value.startsWith('123'),
122
126
  message: 'Le NIR est invalide.',
123
127
  successMessage: 'Le NIR est valide.',
124
128
  },
125
129
 
126
- `}
127
- />
130
+ `}/>
131
+ `}/>
132
+
133
+ ### Custom Rules Precedence
134
+
135
+ <h4 id="ancre-customrulesprecedent">Priorité des règles personnalisées</h4>
136
+
137
+ La prop `custom-rules-precedence` permet de donner la priorité absolue aux règles de validation personnalisées sur la validation standard du composant.
138
+
139
+ #### Quand l'utiliser ?
140
+
141
+ - **NIR migrants** : Pour accepter les codes sexe 5 (masculin) et 6 (féminin) non supportés par la validation standard
142
+ - **Formats spécifiques** : Besoin de valider des formats particuliers non couverts par la regex standard
143
+ - **Migration progressive** : Accepter temporairement des formats legacy en attendant une correction native
144
+
145
+ #### Comment ça fonctionne ?
146
+
147
+ 1. **Activation** : `custom-rules-precedence="true"`
148
+ 2. **Priorité** : Les règles personnalisées s'exécutent en premier
149
+ 3. **Ignorer la standard** : La règle de validation NIR native n'est pas exécutée du tout
150
+ 4. **Contrôle total** : Vous définissez complètement la logique de validation
151
+
152
+ #### Exemple d'usage pour les NIR migrants :
153
+
154
+ <Source dark code={`
155
+ <template>
156
+ <NirField
157
+ v-model="nirValue"
158
+ :custom-number-rules="migrantNumberRules"
159
+ :custom-key-rules="migrantKeyRules"
160
+ custom-rules-precedence
161
+ nir-type="complexe"
162
+ />
163
+ </template>
164
+
165
+ <script setup>
166
+ import { ref } from 'vue'
167
+
168
+ const nirValue = ref('')
169
+
170
+ const migrantNumberRules = [
171
+ {
172
+ type: 'custom',
173
+ options: {
174
+ validate: (value) => {
175
+ if (!value || value.length < 13) return true
176
+ // Accepte tous les codes sexe 1-8 (y compris 5 et 6 pour migrants)
177
+ const migrantRegex = /^[1-8]\\d{12}$/
178
+ return migrantRegex.test(value.replace(/\\s/g, ''))
179
+ },
180
+ message: 'Format du NIR invalide',
181
+ successMessage: 'Le numéro de sécurité sociale est valide',
182
+ },
183
+ },
184
+ ]
185
+
186
+ const migrantKeyRules = [
187
+ {
188
+ type: 'custom',
189
+ options: {
190
+ validate: (value) => {
191
+ if (!value || value.length !== 2) return true
192
+ return /^\\d{2}$/.test(value)
193
+ },
194
+ message: 'Format de clé invalide',
195
+ successMessage: 'La clé de contrôle est valide',
196
+ },
197
+ },
198
+ ]
199
+ </script>
200
+ `}/>
201
+
202
+ #### Limitations importantes
203
+
204
+ - **Clé de contrôle** : L'algorithme standard de calcul de clé ne fonctionne pas pour les NIR migrants
205
+ - **Contournement** : C'est une solution temporaire, pas une correction native du composant
206
+ - **Maintenance** : Nécessite de maintenir les règles personnalisées en parallèle
207
+
208
+ #### Exemples de NIR acceptés
209
+
210
+ - `5900175120005` (masculin migrant)
211
+ - `6900175120005` (féminin migrante)
212
+ - `1900175120005` (masculin standard)
213
+ - `188052A004123` (masculin — Corse-du-Sud)
214
+ - `288052A004456` (féminin — Corse-du-Sud)
215
+ - `190112B033789` (masculin — Haute-Corse)
216
+ - `290112B033321` (féminin — Haute-Corse)
217
+
218
+
219
+
220
+ Pour voir un exemple fonctionnel, consultez la [story CustomRulesPrecedence](/?path=/story/composants-formulaires-nirfield--custom-rules-precedence).
128
221
 
129
222
  ### Exemple d'utilisation
130
223
 
@@ -140,74 +233,36 @@ const customNumberRules = [
140
233
  {
141
234
  type: 'custom',
142
235
  options: {
143
- validate: (value: string) => value.startsWith('123') || 'Le NIR doit commencer par 123.',
236
+ validate: (value: string) => value.startsWith('123'),
144
237
  message: 'Le NIR est invalide.',
145
238
  successMessage: 'Le NIR est valide.',
146
239
  },
147
240
  },
148
241
  ]
149
242
  const customKeyRules = [
150
- {
151
- type: 'minLength',
243
+ {
244
+ type: 'custom',
152
245
  options: {
153
- length: 2,
154
- message: 'La clé doit avoir au moins 2 caractères.',
155
- successMessage: 'La clé a une longueur valide.',
246
+ validate: (value: string) => value.length === 2,
247
+ message: 'La clé doit faire 2 caractères.',
248
+ successMessage: 'La clé est valide.',
156
249
  },
157
250
  },
158
251
  ]
159
252
  </script>
160
253
 
161
254
  <template>
162
- <NirField
163
- v-model="nir"
164
- :outlined="true"
165
- :required="true"
166
- numberLabel="NIR"
167
- keyLabel="Clé"
168
- :displayKey="true"
169
- :customNumberRules="customNumberRules"
170
- :customKeyRules="customKeyRules"
171
- />
172
- </template>
173
- `}
174
- />
175
-
176
- ### Méthode validateOnSubmit
177
-
178
- La méthode `validateOnSubmit` permet de valider les champs du composant `NirField` lors de la soumission du formulaire. Elle retourne `true` si tous les champs sont valides, sinon `false`.
179
-
180
- Pour utiliser cette méthode, vous devez ajouter une référence Vue au composant `NirField` et appeler la méthode `validateOnSubmit` via cette référence.
181
-
182
- <Source dark code={`
183
- <script setup lang="ts">
184
- import {ref} from 'vue'
185
- import { NirField } from '@cnamts/synapse'
186
-
187
- const model = ref('')
188
- import '../../stories/styles/shared.css';
189
- const nirFieldRef = ref() // Référence Vue pour accéder au composant enfant
190
- const handleSubmit = () => {
191
- // Appeler la méthode exposée validateOnSubmit via la référence
192
- const isValid = nirFieldRef.value?.validateOnSubmit()
193
- if (!isValid) {
194
- alert('Corrigez les erreurs avant de soumettre !')
195
- } else {
196
- alert('Formulaire soumis avec succès !')
197
- }
198
- }
199
- </script>
200
-
201
- <template>
202
- <main>
203
- <form
204
- class="mx-16 my-6"
205
- @submit.prevent="handleSubmit"
206
- >
207
- <NirField
208
- ref="nirFieldRef"
209
- v-model="model"
210
- :display-key="true"
255
+ <main>
256
+ <form class="mx-16 my-6">
257
+ <NirField
258
+ v-model="nir"
259
+ :custom-number-rules="customNumberRules"
260
+ :custom-key-rules="customKeyRules"
261
+ number-label="Numéro de sécurité sociale"
262
+ key-label="Clé"
263
+ :display-key="true"
264
+ number-hint="Exemple : 1 84 01 234 567 890"
265
+ key-hint="Exemple : 74"
211
266
  key-tooltip="message d'aide pour la clef"
212
267
  nir-tooltip="message d'aide pour le NIR"
213
268
  outlined
@@ -223,4 +278,3 @@ import '../../stories/styles/shared.css';
223
278
  />
224
279
 
225
280
  <a href="/?path=/docs/guide-du-dev-guide-de-validation-des-formulaires--docs" className="action-link">Pour plus d'informations sur la validation, consultez le guide de validation des formulaires.</a>
226
-
@@ -16,6 +16,20 @@ const meta: Meta<typeof NirField> = {
16
16
  },
17
17
  argTypes: {
18
18
  ...getValidationDocumentation('string'),
19
+ customRulesPrecedence: {
20
+ description: 'Définit si les règles personnalisées ont priorité sur la validation standard du NIR. `custom` = les règles personnalisées remplacent la validation standard (utile pour les NIR migrants), `default` = la validation standard est appliquée puis les règles personnalisées.',
21
+ control: 'select',
22
+ options: ['custom', 'default'],
23
+ default: 'custom',
24
+ table: {
25
+ type: {
26
+ summary: 'string',
27
+ },
28
+ defaultValue: {
29
+ summary: 'custom',
30
+ },
31
+ },
32
+ },
19
33
  modelValue: {
20
34
  description: 'La valeur du modèle pour le champ.',
21
35
  control: 'text',
@@ -817,3 +831,205 @@ export const ComplexNirType: Story = {
817
831
  `,
818
832
  }),
819
833
  }
834
+
835
+ export const CustomRulesPrecedence: Story = {
836
+ args: {
837
+ modelValue: '',
838
+ required: false,
839
+ numberLabel: 'Numéro de sécurité sociale',
840
+ keyLabel: 'Clé',
841
+ displayKey: true,
842
+ nirType: 'complexe',
843
+ customNumberRules: [
844
+ {
845
+ type: 'custom',
846
+ options: {
847
+ validate: (value: string) => {
848
+ if (!value) return true
849
+ if (value.length < 13) return true
850
+
851
+ // Accepte tous les codes sexe 1-8 (y compris 5 et 6 pour migrants)
852
+ const migrantRegex = /^[1-8]\d{12}$/
853
+ return migrantRegex.test(value.replace(/\s/g, ''))
854
+ },
855
+ message: 'Format du NIR invalide',
856
+ successMessage: 'Le numéro de sécurité sociale est valide',
857
+ },
858
+ },
859
+ ],
860
+ customKeyRules: [
861
+ {
862
+ type: 'custom',
863
+ options: {
864
+ validate: (value: string) => {
865
+ if (!value) return true
866
+ if (value.length !== 2) return true
867
+ return /^\d{2}$/.test(value)
868
+ },
869
+ message: 'Format de clé invalide',
870
+ successMessage: 'La clé de contrôle est valide',
871
+ },
872
+ },
873
+ ],
874
+ customRulesPrecedence: true,
875
+ showSuccessMessages: true,
876
+ },
877
+ parameters: {
878
+ docs: {
879
+ description: {
880
+ story: `
881
+ ### Custom Rules Precedence - Support des NIR migrants
882
+
883
+ Cette story démontre l'utilisation de la prop \`customRulesPrecedence\` pour contourner la validation standard
884
+ et accepter des formats de NIR non prévus initialement, comme les NIR de migrants (codes sexe 5 et 6).
885
+
886
+ #### Cas d'usage
887
+ - **NIR migrants** : Codes sexe 5 (masculin) et 6 (féminin) non supportés par la validation standard
888
+ - **Formats spécifiques** : Besoin de valider des formats particuliers non couverts par la regex standard
889
+ - **Migration progressive** : Accepter temporairement des formats legacy en attendant une correction native
890
+
891
+ #### Fonctionnement
892
+ 1. **customRulesPrecedence="true"** : Donne priorité absolue aux règles personnalisées
893
+ 2. **Ignorer la validation standard** : La règle de validation NIR native n'est pas exécutée
894
+ 3. **Contrôle total** : Vous définissez complètement la logique de validation
895
+
896
+ #### Exemples de NIR acceptés avec cette configuration :
897
+ - \`5900175120005\` (masculin migrant)
898
+ - \`6900175120005\` (féminin migrante)
899
+ - \`1900175120005\` (masculin standard)
900
+ - \`2900175120005\` (féminin standard)
901
+
902
+ #### Limitations
903
+ - La clé de contrôle n'est pas calculée avec l'algorithme standard pour les NIR migrants
904
+ - C'est un contournement, pas une correction native du composant
905
+ - Nécessite de maintenir les règles personnalisées en parallèle
906
+
907
+ Pour plus d'informations, voir la [documentation technique](/?path=/docs/composants-formulaires-nirfield--docs#ancre-customrulesprecedent).`,
908
+ },
909
+ },
910
+ sourceCode: [
911
+ {
912
+ name: 'Template',
913
+ code: `
914
+ <template>
915
+ <NirField
916
+ v-model="value"
917
+ :required="false"
918
+ numberLabel="Numéro de sécurité sociale"
919
+ keyLabel="Clé"
920
+ :displayKey="true"
921
+ nirType="complexe"
922
+ :custom-number-rules="customNumberRules"
923
+ :custom-key-rules="customKeyRules"
924
+ custom-rules-precedence
925
+ :show-success-messages="true"
926
+ />
927
+ </template>
928
+ `,
929
+ },
930
+ {
931
+ name: 'Script',
932
+ code: `
933
+ <script setup lang="ts">
934
+ import { NirField } from '@cnamts/synapse'
935
+ import { ref } from 'vue'
936
+
937
+ const value = ref('')
938
+
939
+ const customNumberRules = [
940
+ {
941
+ type: 'custom',
942
+ options: {
943
+ validate: (value: string) => {
944
+ if (!value) return true
945
+ if (value.length < 13) return true
946
+
947
+ // Accepte tous les codes sexe 1-8 (y compris 5 et 6 pour migrants)
948
+ const migrantRegex = /^[1-8]\\d{12}$/
949
+ return migrantRegex.test(value.replace(/\\s/g, ''))
950
+ },
951
+ message: 'Format du NIR invalide',
952
+ successMessage: 'Le numéro de sécurité sociale est valide',
953
+ },
954
+ },
955
+ ]
956
+
957
+ const customKeyRules = [
958
+ {
959
+ type: 'custom',
960
+ options: {
961
+ validate: (value: string) => {
962
+ if (!value) return true
963
+ if (value.length !== 2) return true
964
+ return /^\\d{2}$/.test(value)
965
+ },
966
+ message: 'Format de clé invalide',
967
+ successMessage: 'La clé de contrôle est valide',
968
+ },
969
+ },
970
+ ]
971
+ </script>
972
+ `,
973
+ },
974
+ ],
975
+ },
976
+ render: () => ({
977
+ components: { NirField },
978
+ setup() {
979
+ const value = ref('')
980
+
981
+ const customNumberRules = [
982
+ {
983
+ type: 'custom',
984
+ options: {
985
+ validate: (value: string) => {
986
+ if (!value) return true
987
+ if (value.length < 13) return true
988
+
989
+ // Accepte tous les codes sexe 1-8 (y compris 5 et 6 pour migrants)
990
+ const migrantRegex = /^[1-8]\d{12}$/
991
+ return migrantRegex.test(value.replace(/\s/g, ''))
992
+ },
993
+ message: 'Format du NIR invalide',
994
+ successMessage: 'Le numéro de sécurité sociale est valide',
995
+ },
996
+ },
997
+ ]
998
+
999
+ const customKeyRules = [
1000
+ {
1001
+ type: 'custom',
1002
+ options: {
1003
+ validate: (value: string) => {
1004
+ if (!value) return true
1005
+ if (value.length !== 2) return true
1006
+ return /^\d{2}$/.test(value)
1007
+ },
1008
+ message: 'Format de clé invalide',
1009
+ successMessage: 'La clé de contrôle est valide',
1010
+ },
1011
+ },
1012
+ ]
1013
+
1014
+ return { value, customNumberRules, customKeyRules }
1015
+ },
1016
+ template: `
1017
+ <div>
1018
+ <p class="mt-2">Cette configuration utilise <code>customRulesPrecedence</code> pour accepter les NIR migrants (codes 5 et 6).</p>
1019
+ <p class="mb-4">Essayez de saisir : <strong>5900175120005</strong> ou <strong>6900175120005</strong></p>
1020
+ </div>
1021
+ <NirField
1022
+ v-model="value"
1023
+ :required="false"
1024
+ :numberLabel="'Numéro de sécurité sociale'"
1025
+ :keyLabel="'Clé'"
1026
+ :displayKey="true"
1027
+ nirType="complexe"
1028
+ :custom-number-rules="customNumberRules"
1029
+ :custom-key-rules="customKeyRules"
1030
+ custom-rules-precedence
1031
+ :show-success-messages="true"
1032
+ />
1033
+ `,
1034
+ }),
1035
+ }
@@ -93,24 +93,23 @@ export function useNirValidation(
93
93
  })))
94
94
  }
95
95
 
96
- // Règle de validation standard du NIR
97
- rules.push({
98
- type: 'custom',
99
- options: {
100
- validate: (value: string) => {
101
- if (!value) return true
102
- // Ne valider que si tous les caractères sont saisis
103
- if (value.length < 13) {
104
- return customLocale.value.errorInvalidNumber || locales.errorInvalidNumber
105
- }
106
- const result = checkNIR(value, nirType.value)
107
- return result ? true : customLocale.value.errorInvalidNumber || locales.errorInvalidNumber
96
+ // Règle de validation standard du NIR (ignorée si customRulesPrecedence est activé)
97
+ if (!customRulesPrecedence.value) {
98
+ rules.push({
99
+ type: 'custom',
100
+ options: {
101
+ validate: (value: string) => {
102
+ if (!value) return true
103
+ // Ne valider que si tous les caractères sont saisis
104
+ if (value.length < 13) return false
105
+ return checkNIR(value, nirType.value)
106
+ },
107
+ message: customLocale.value.errorInvalidNumber || locales.errorInvalidNumber,
108
+ successMessage: customLocale.value.successNumberValid || locales.successNumberValid,
109
+ fieldIdentifier: numberLabel.value,
108
110
  },
109
- message: customLocale.value.errorInvalidNumber || locales.errorInvalidNumber,
110
- successMessage: customLocale.value.successNumberValid || locales.successNumberValid,
111
- fieldIdentifier: numberLabel.value,
112
- },
113
- })
111
+ })
112
+ }
114
113
 
115
114
  // Ajout des règles personnalisées sans prévalence (comportement par défaut)
116
115
  if (!customRulesPrecedence.value && customNumberRules.value && customNumberRules.value.length > 0) {