@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.
- package/dist/design-system-v3.js +3878 -3189
- package/dist/design-system-v3.umd.cjs +1 -1
- package/dist/src/components/Amelipro/types/languages.d.ts +6 -0
- package/dist/src/components/Amelipro/types/types.d.ts +65 -0
- package/dist/src/components/CookieBanner/CookieBanner.d.ts +1 -1
- package/dist/src/components/Customs/SyInputSelect/SyInputSelect.d.ts +2 -0
- package/dist/src/components/Customs/SyTextField/SyTextField.d.ts +29 -23
- package/dist/src/components/Customs/SyTextField/types.d.ts +1 -0
- package/dist/src/components/DatePicker/DatePicker.d.ts +70 -59
- package/dist/src/components/DatePicker/DateTextInput.d.ts +67 -56
- package/dist/src/components/ErrorPage/ErrorPage.d.ts +1 -1
- package/dist/src/components/FileList/FileList.d.ts +1 -0
- package/dist/src/components/FileList/UploadItem/UploadItem.d.ts +1 -1
- package/dist/src/components/FilterSideBar/FilterSideBar.d.ts +31 -0
- package/dist/src/components/FilterSideBar/locales.d.ts +7 -0
- package/dist/src/components/FilterSideBar/tests/FilterSideBar.spec.d.ts +1 -0
- package/dist/src/components/LangBtn/LangBtn.d.ts +2 -2
- package/dist/src/components/NirField/NirField.d.ts +940 -0
- package/dist/src/components/NotificationBar/NotificationBar.d.ts +1 -1
- package/dist/src/components/PasswordField/PasswordField.d.ts +40 -8
- package/dist/src/components/PeriodField/PeriodField.d.ts +142 -120
- package/dist/src/components/PhoneField/PhoneField.d.ts +11 -2
- package/dist/src/components/RatingPicker/EmotionPicker/EmotionPicker.d.ts +1 -1
- package/dist/src/components/RatingPicker/NumberPicker/NumberPicker.d.ts +1 -1
- package/dist/src/components/RatingPicker/StarsPicker/StarsPicker.d.ts +1 -1
- package/dist/src/components/UploadWorkflow/config.d.ts +29 -0
- package/dist/src/components/UploadWorkflow/locales.d.ts +7 -0
- package/dist/src/components/UploadWorkflow/tests/UploadWorkflow.spec.d.ts +1 -0
- package/dist/src/components/UploadWorkflow/types.d.ts +19 -0
- package/dist/src/components/UploadWorkflow/useFileList.d.ts +10 -0
- package/dist/src/components/UploadWorkflow/useFileUploadJourney.d.ts +9 -0
- package/dist/src/components/index.d.ts +2 -0
- package/dist/src/composables/rules/useFieldValidation.d.ts +1 -0
- package/dist/src/composables/validation/tests/useValidation.spec.d.ts +1 -0
- package/dist/src/composables/validation/useValidation.d.ts +39 -0
- package/dist/src/designTokens/index.d.ts +3 -1
- package/dist/src/vuetifyConfig.d.ts +81 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/_elevations.scss +89 -0
- package/src/assets/_fonts.scss +6 -0
- package/src/assets/_radius.scss +86 -0
- package/src/assets/_spacers.scss +149 -0
- package/src/assets/settings.scss +7 -3
- package/src/assets/tokens.scss +32 -29
- package/src/components/Amelipro/types/languages.d.ts +6 -0
- package/src/components/Amelipro/types/types.d.ts +65 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.stories.ts +65 -0
- package/src/components/Customs/SyInputSelect/SyInputSelect.vue +13 -3
- package/src/components/Customs/SySelect/SySelect.stories.ts +88 -5
- package/src/components/Customs/SySelect/SySelect.vue +36 -10
- package/src/components/Customs/SySelect/tests/SySelect.spec.ts +135 -2
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +576 -85
- package/src/components/Customs/SyTextField/SyTextField.vue +132 -104
- package/src/components/Customs/SyTextField/tests/SyTextField.spec.ts +190 -38
- package/src/components/Customs/SyTextField/types.d.ts +1 -0
- package/src/components/DatePicker/DatePicker.vue +405 -137
- package/src/components/DatePicker/DateTextInput.vue +15 -0
- package/src/components/DatePicker/tests/DatePicker.spec.ts +8 -15
- package/src/components/FileList/FileList.vue +2 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +10 -0
- package/src/components/FileUpload/FileUpload.stories.ts +84 -0
- package/src/components/FileUpload/FileUpload.vue +1 -0
- package/src/components/FileUpload/tests/FileUpload.spec.ts +4 -4
- package/src/components/FilterInline/FilterInline.mdx +180 -34
- package/src/components/FilterInline/FilterInline.stories.ts +363 -6
- package/src/components/FilterSideBar/FilterSideBar.mdx +237 -0
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +798 -0
- package/src/components/FilterSideBar/FilterSideBar.vue +193 -0
- package/src/components/FilterSideBar/locales.ts +8 -0
- package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +305 -0
- package/src/components/FilterSideBar/tests/__snapshots__/FilterSideBar.spec.ts.snap +39 -0
- package/src/components/HeaderBar/Usages.mdx +1 -1
- package/src/components/NirField/NirField.stories.ts +573 -29
- package/src/components/NirField/NirField.vue +397 -359
- package/src/components/NirField/tests/NirField.spec.ts +88 -52
- package/src/components/NirField/tests//342/200/257dataset/342/200/257.md +12 -0
- package/src/components/NotificationBar/Accessibilite.stories.ts +4 -0
- package/src/components/NotificationBar/NotificationBar.stories.ts +18 -13
- package/src/components/PasswordField/PasswordField.mdx +129 -47
- package/src/components/PasswordField/PasswordField.stories.ts +924 -120
- package/src/components/PasswordField/PasswordField.vue +209 -99
- package/src/components/PasswordField/tests/PasswordField.spec.ts +138 -9
- package/src/components/PeriodField/PeriodField.vue +55 -54
- package/src/components/PhoneField/PhoneField.stories.ts +69 -0
- package/src/components/PhoneField/PhoneField.vue +3 -0
- package/src/components/PhoneField/indicatifs.ts +1 -1
- package/src/components/UploadWorkflow/UploadWorkflow.mdx +75 -0
- package/src/components/UploadWorkflow/UploadWorkflow.stories.ts +943 -0
- package/src/components/UploadWorkflow/UploadWorkflow.vue +230 -0
- package/src/components/UploadWorkflow/config.ts +29 -0
- package/src/components/UploadWorkflow/locales.ts +8 -0
- package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +257 -0
- package/src/components/UploadWorkflow/tests/__snapshots__/UploadWorkflow.spec.ts.snap +54 -0
- package/src/components/UploadWorkflow/types.ts +21 -0
- package/src/components/UploadWorkflow/useFileList.ts +84 -0
- package/src/components/UploadWorkflow/useFileUploadJourney.ts +18 -0
- package/src/components/index.ts +2 -0
- package/src/composables/rules/useFieldValidation.ts +5 -2
- package/src/composables/validation/tests/useValidation.spec.ts +154 -0
- package/src/composables/validation/useValidation.ts +165 -0
- package/src/designTokens/index.ts +4 -0
- package/src/stories/Demarrer/Accueil.mdx +1 -1
- package/src/stories/DesignTokens/ThemePA.mdx +4 -30
- package/src/stories/GuideDuDev/UtiliserLesRules.mdx +319 -76
- package/src/stories/GuideDuDev/moduleDeNotification.mdx +1 -1
- package/src/vuetifyConfig.ts +61 -0
- package/src/composables/useFilterable/__snapshots__/useFilterable.spec.ts.snap +0 -3
|
@@ -1,108 +1,351 @@
|
|
|
1
|
-
import {Meta, Source} from '@storybook/addon-docs/blocks';
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
2
2
|
|
|
3
3
|
<Meta title="Guide Du Dev/Utiliser les rules"/>
|
|
4
4
|
|
|
5
5
|
# Utiliser les règles de validation
|
|
6
6
|
|
|
7
|
-
Ce guide décrit comment utiliser le
|
|
7
|
+
Ce guide décrit comment utiliser le système de validation de formulaires du Design System pour créer des validations flexibles et intuitives.
|
|
8
8
|
|
|
9
9
|
## Introduction
|
|
10
10
|
|
|
11
|
-
Le
|
|
11
|
+
Le système de validation repose sur deux composables principaux :
|
|
12
|
+
- `useFieldValidation` : Gère la création des règles de validation
|
|
13
|
+
- `useValidation` : Gère l'état de validation et l'affichage des messages
|
|
14
|
+
|
|
15
|
+
## Les 3 types de validation
|
|
16
|
+
|
|
17
|
+
Notre système supporte trois types de retours de validation :
|
|
18
|
+
|
|
19
|
+
1. **Erreurs** (rouge 🔴) : Bloquent la soumission du formulaire
|
|
20
|
+
2. **Avertissements** (orange 🟠) : Informent l'utilisateur sans bloquer
|
|
21
|
+
3. **Succès** (vert 🟢) : Confirment la validité du champ
|
|
22
|
+
|
|
23
|
+
### Priorité des validations
|
|
24
|
+
|
|
25
|
+
Les validations suivent un ordre de priorité :
|
|
26
|
+
1. Si une erreur est présente, elle est affichée en priorité
|
|
27
|
+
2. S'il n'y a pas d'erreur mais des avertissements, ils sont affichés
|
|
28
|
+
3. S'il n'y a ni erreur ni avertissement, les messages de succès sont affichés
|
|
29
|
+
|
|
30
|
+
## Structure des types
|
|
31
|
+
|
|
32
|
+
### Type `ValidationOptions`
|
|
33
|
+
|
|
34
|
+
Options de configuration pour la validation :
|
|
35
|
+
|
|
36
|
+
<Source dark code={`
|
|
37
|
+
interface ValidationOptions {
|
|
38
|
+
showSuccessMessages?: boolean; // Activer/désactiver les messages de succès
|
|
39
|
+
fieldIdentifier?: string; // Nom du champ pour les messages
|
|
40
|
+
customRules?: ValidationRule[]; // Règles personnalisées
|
|
41
|
+
warningRules?: ValidationRule[]; // Règles d'avertissement
|
|
42
|
+
successRules?: ValidationRule[]; // Règles de succès
|
|
43
|
+
}
|
|
44
|
+
`}/>
|
|
45
|
+
|
|
46
|
+
### Type `ValidationRule`
|
|
47
|
+
|
|
48
|
+
Structure d'une règle de validation :
|
|
49
|
+
|
|
50
|
+
<Source dark code={`
|
|
51
|
+
type ValidationRule = {
|
|
52
|
+
type: string; // Type de règle (ex: 'required', 'email')
|
|
53
|
+
options: RuleOptions;
|
|
54
|
+
}
|
|
55
|
+
`}/>
|
|
12
56
|
|
|
13
|
-
## Structure du composable
|
|
14
|
-
#
|
|
15
57
|
### Type `RuleOptions`
|
|
16
58
|
|
|
59
|
+
Options disponibles pour configurer une règle :
|
|
60
|
+
|
|
17
61
|
<Source dark code={`
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
62
|
+
interface RuleOptions {
|
|
63
|
+
message?: string; // Message d'erreur personnalisé
|
|
64
|
+
successMessage?: string; // Message de succès personnalisé
|
|
65
|
+
warningMessage?: string; // Message d'avertissement personnalisé
|
|
66
|
+
fieldName?: string; // Nom du champ pour les messages
|
|
67
|
+
fieldIdentifier?: string; // Identifiant du champ
|
|
68
|
+
value?: any; // Valeur pour les règles min/max
|
|
69
|
+
length?: number; // Longueur pour minLength/maxLength
|
|
70
|
+
pattern?: RegExp; // Expression régulière
|
|
71
|
+
ignoreSpace?: boolean; // Ignorer les espaces
|
|
72
|
+
isWarning?: boolean; // Traiter comme un avertissement
|
|
26
73
|
validate?: (value: any) => boolean | string; // Validation personnalisée
|
|
27
|
-
}
|
|
28
|
-
`}
|
|
29
|
-
|
|
74
|
+
}
|
|
75
|
+
`}/>
|
|
76
|
+
|
|
77
|
+
## Exemple complet d'utilisation
|
|
78
|
+
|
|
79
|
+
### Avec un input simple
|
|
80
|
+
|
|
81
|
+
Voici un exemple complet montrant les différentes possibilités de validation :
|
|
82
|
+
|
|
83
|
+
<Source dark code={`
|
|
84
|
+
<script lang="ts" setup>
|
|
85
|
+
import { ref } from 'vue'
|
|
86
|
+
import { useValidation } from '@cnamts/synapse'
|
|
87
|
+
|
|
88
|
+
const password = ref('')
|
|
89
|
+
|
|
90
|
+
const { validateField, hasError, hasWarning, hasSuccess, errors, warnings, successes } = useValidation({
|
|
91
|
+
fieldIdentifier: 'Mot de passe',
|
|
92
|
+
showSuccessMessages: true
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// Règles d'erreur (bloquantes)
|
|
96
|
+
const errorRules = [
|
|
97
|
+
{
|
|
98
|
+
type: 'required',
|
|
99
|
+
options: { message: 'Le mot de passe est requis' }
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
type: 'minLength',
|
|
103
|
+
options: { length: 6, message: 'Le mot de passe doit contenir au moins 6 caractères' }
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
// Règles d'avertissement (non-bloquantes)
|
|
108
|
+
const warningRules = [
|
|
109
|
+
{
|
|
110
|
+
type: 'minLength',
|
|
111
|
+
options: {
|
|
112
|
+
length: 8,
|
|
113
|
+
warningMessage: 'Un mot de passe de 8 caractères minimum est recommandé'
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
]
|
|
30
117
|
|
|
31
|
-
|
|
118
|
+
// Règles de succès (messages positifs)
|
|
119
|
+
const successRules = [
|
|
120
|
+
{
|
|
121
|
+
type: 'minLength',
|
|
122
|
+
options: {
|
|
123
|
+
length: 12,
|
|
124
|
+
successMessage: 'Excellent ! Votre mot de passe est très sécurisé'
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
const validate = () => {
|
|
130
|
+
const result = validateField(
|
|
131
|
+
password.value,
|
|
132
|
+
errorRules,
|
|
133
|
+
warningRules,
|
|
134
|
+
successRules
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
// result contient :
|
|
138
|
+
// - hasError: boolean
|
|
139
|
+
// - hasWarning: boolean
|
|
140
|
+
// - hasSuccess: boolean
|
|
141
|
+
// - state: { errors, warnings, successes }
|
|
142
|
+
}
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<template>
|
|
146
|
+
<div>
|
|
147
|
+
<input
|
|
148
|
+
v-model="password"
|
|
149
|
+
@input="validate"
|
|
150
|
+
:class="{
|
|
151
|
+
'error': hasError,
|
|
152
|
+
'warning': hasWarning && !hasError,
|
|
153
|
+
'success': hasSuccess
|
|
154
|
+
}"
|
|
155
|
+
/>
|
|
156
|
+
|
|
157
|
+
<!-- Affichage des messages -->
|
|
158
|
+
<div v-if="hasError" class="error-messages">
|
|
159
|
+
<p v-for="error in errors" :key="error">{{ error }}</p>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<div v-else-if="hasWarning" class="warning-messages">
|
|
163
|
+
<p v-for="warning in warnings" :key="warning">{{ warning }}</p>
|
|
164
|
+
</div>
|
|
165
|
+
|
|
166
|
+
<div v-else-if="hasSuccess" class="success-messages">
|
|
167
|
+
<p v-for="success in successes" :key="success">{{ success }}</p>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</template>
|
|
171
|
+
`}/>
|
|
172
|
+
|
|
173
|
+
### Avec SyTextField
|
|
174
|
+
|
|
175
|
+
Le `SyTextField` intègre nativement notre système de validation. Voici un exemple complet :
|
|
32
176
|
|
|
33
177
|
<Source dark code={`
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
`}
|
|
39
|
-
/>
|
|
178
|
+
<script lang="ts" setup>
|
|
179
|
+
import { ref } from 'vue'
|
|
180
|
+
import { SyTextField } from '@cnamts/synapse'
|
|
40
181
|
|
|
41
|
-
|
|
182
|
+
const password = ref('')
|
|
183
|
+
|
|
184
|
+
// Règles d'erreur (bloquantes)
|
|
185
|
+
const rules = [
|
|
186
|
+
{
|
|
187
|
+
type: 'required',
|
|
188
|
+
options: { message: 'Le mot de passe est requis' }
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
type: 'minLength',
|
|
192
|
+
options: { length: 6, message: 'Le mot de passe doit contenir au moins 6 caractères' }
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
// Règles d'avertissement (non-bloquantes)
|
|
197
|
+
const warningRules = [
|
|
198
|
+
{
|
|
199
|
+
type: 'minLength',
|
|
200
|
+
options: {
|
|
201
|
+
length: 8,
|
|
202
|
+
warningMessage: 'Un mot de passe de 8 caractères minimum est recommandé'
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
// Règles de succès (messages positifs)
|
|
208
|
+
const successRules = [
|
|
209
|
+
{
|
|
210
|
+
type: 'minLength',
|
|
211
|
+
options: {
|
|
212
|
+
length: 12,
|
|
213
|
+
successMessage: 'Excellent ! Votre mot de passe est très sécurisé'
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
</script>
|
|
42
218
|
|
|
43
|
-
|
|
219
|
+
<template>
|
|
220
|
+
<SyTextField
|
|
221
|
+
v-model="password"
|
|
222
|
+
label="Mot de passe"
|
|
223
|
+
type="password"
|
|
224
|
+
:customRules="rules"
|
|
225
|
+
:customWarningRules="warningRules"
|
|
226
|
+
:customSuccessRules="successRules"
|
|
227
|
+
placeholder="Entrez votre mot de passe"
|
|
228
|
+
/>
|
|
229
|
+
</template>
|
|
230
|
+
`}/>
|
|
231
|
+
|
|
232
|
+
Le composant affichera automatiquement :
|
|
233
|
+
- Une icône et un message d'erreur en rouge si le champ est vide ou contient moins de 6 caractères
|
|
234
|
+
- Une icône et un message d'avertissement en orange si le mot de passe fait entre 6 et 8 caractères
|
|
235
|
+
- Une icône et un message de succès en vert si le mot de passe fait 12 caractères ou plus
|
|
236
|
+
|
|
237
|
+
### Validation personnalisée avec SyTextField
|
|
238
|
+
|
|
239
|
+
Voici un exemple plus avancé avec une validation personnalisée :
|
|
44
240
|
|
|
45
241
|
<Source dark code={`
|
|
46
242
|
<script lang="ts" setup>
|
|
47
|
-
import { ref } from 'vue'
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
243
|
+
import { ref } from 'vue'
|
|
244
|
+
import { SyTextField } from '@cnamts/synapse'
|
|
245
|
+
|
|
246
|
+
const email = ref('')
|
|
247
|
+
|
|
248
|
+
// Règle personnalisée pour vérifier le domaine ameli.fr
|
|
249
|
+
const rules = [
|
|
250
|
+
{
|
|
251
|
+
type: 'required',
|
|
252
|
+
options: { message: 'L\'email est requis' }
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
type: 'email',
|
|
256
|
+
options: { message: 'Format d\'email invalide' }
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
type: 'custom',
|
|
260
|
+
options: {
|
|
261
|
+
validate: (value: string) => {
|
|
262
|
+
if (!value.endsWith('@ameli.fr')) {
|
|
263
|
+
return 'L\'email doit être un email ameli.fr'
|
|
264
|
+
}
|
|
265
|
+
return true
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
// Règle d'avertissement pour le format prénom.nom
|
|
272
|
+
const warningRules = [
|
|
273
|
+
{
|
|
274
|
+
type: 'custom',
|
|
275
|
+
options: {
|
|
276
|
+
validate: (value: string) => {
|
|
277
|
+
const [localPart] = value.split('@')
|
|
278
|
+
if (!/^[a-z]+\.[a-z]+$/.test(localPart)) {
|
|
279
|
+
return 'Format recommandé : prenom.nom@ameli.fr'
|
|
280
|
+
}
|
|
281
|
+
return true
|
|
282
|
+
},
|
|
283
|
+
isWarning: true
|
|
284
|
+
}
|
|
81
285
|
}
|
|
82
|
-
|
|
286
|
+
]
|
|
83
287
|
</script>
|
|
84
|
-
`}
|
|
85
|
-
/>
|
|
86
288
|
|
|
87
|
-
|
|
289
|
+
<template>
|
|
290
|
+
<SyTextField
|
|
291
|
+
v-model="email"
|
|
292
|
+
label="Email professionnel"
|
|
293
|
+
:customRules="rules"
|
|
294
|
+
:customWarningRules="warningRules"
|
|
295
|
+
placeholder="prenom.nom@ameli.fr"
|
|
296
|
+
/>
|
|
297
|
+
</template>
|
|
298
|
+
`}/>
|
|
88
299
|
|
|
89
|
-
|
|
300
|
+
Dans cet exemple :
|
|
301
|
+
- Le champ est invalide si l'email n'est pas au format @ameli.fr
|
|
302
|
+
- Un avertissement s'affiche si l'email ne suit pas le format prenom.nom
|
|
303
|
+
- La validation se fait automatiquement à la perte du focus
|
|
304
|
+
- Les icônes et couleurs sont gérées automatiquement par le composant
|
|
90
305
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
- **
|
|
94
|
-
- **
|
|
95
|
-
- **
|
|
96
|
-
- **
|
|
97
|
-
- **
|
|
98
|
-
- **
|
|
306
|
+
## Règles de validation disponibles
|
|
307
|
+
|
|
308
|
+
- **required** : Vérifie qu'un champ est rempli
|
|
309
|
+
- **email** : Valide le format d'une adresse email
|
|
310
|
+
- **minLength** : Vérifie une longueur minimale
|
|
311
|
+
- **maxLength** : Vérifie une longueur maximale
|
|
312
|
+
- **min** : Vérifie une valeur minimale (nombre)
|
|
313
|
+
- **max** : Vérifie une valeur maximale (nombre)
|
|
314
|
+
- **pattern** : Valide avec une expression régulière
|
|
315
|
+
- **custom** : Validation personnalisée via une fonction
|
|
99
316
|
|
|
100
317
|
## Bonnes pratiques
|
|
101
318
|
|
|
102
|
-
|
|
103
|
-
|
|
319
|
+
1. **Messages clairs** : Utilisez des messages explicites qui guident l'utilisateur
|
|
320
|
+
2. **Validation progressive** : Validez au fur et à mesure de la saisie
|
|
321
|
+
3. **Avertissements utiles** : Utilisez les warnings pour des recommandations non-bloquantes
|
|
322
|
+
4. **Messages de succès** : Encouragez les bonnes pratiques avec des messages positifs
|
|
323
|
+
5. **Identifiants de champs** : Utilisez `fieldIdentifier` pour des messages contextuels
|
|
104
324
|
|
|
105
|
-
##
|
|
325
|
+
## Exemple de validation personnalisée
|
|
326
|
+
|
|
327
|
+
<Source dark code={`
|
|
328
|
+
const customRules = [
|
|
329
|
+
{
|
|
330
|
+
type: 'custom',
|
|
331
|
+
options: {
|
|
332
|
+
validate: (value: string) => {
|
|
333
|
+
const hasNumber = /\d/.test(value)
|
|
334
|
+
const hasUpper = /[A-Z]/.test(value)
|
|
335
|
+
const hasLower = /[a-z]/.test(value)
|
|
336
|
+
|
|
337
|
+
if (!hasNumber || !hasUpper || !hasLower) {
|
|
338
|
+
return 'Le mot de passe doit contenir au moins un chiffre, une majuscule et une minuscule'
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return true
|
|
342
|
+
},
|
|
343
|
+
successMessage: 'Votre mot de passe respecte les critères de sécurité'
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
`}/>
|
|
106
348
|
|
|
107
|
-
|
|
349
|
+
## Conclusion
|
|
108
350
|
|
|
351
|
+
Le système de validation du Design System offre une grande flexibilité tout en restant simple à utiliser. La combinaison des erreurs, avertissements et succès permet de créer une expérience utilisateur riche et intuitive.
|
|
@@ -8,7 +8,7 @@ import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
|
8
8
|
## Importation et utilisation
|
|
9
9
|
|
|
10
10
|
<Source dark code={`
|
|
11
|
-
import { useNotificationService } from '@cnamts/
|
|
11
|
+
import { useNotificationService } from '@cnamts/synpase'
|
|
12
12
|
|
|
13
13
|
const { notificationQueue, addNotification, removeNotification, clearQueue } = useNotificationService()
|
|
14
14
|
`} />
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createVuetify } from 'vuetify'
|
|
2
|
+
import * as components from 'vuetify/components'
|
|
3
|
+
import * as directives from 'vuetify/directives'
|
|
4
|
+
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
|
|
5
|
+
import {
|
|
6
|
+
cnamColorsTokens,
|
|
7
|
+
cnamContextualTokens,
|
|
8
|
+
cnamLightTheme,
|
|
9
|
+
cnamDarkTheme,
|
|
10
|
+
paColorsTokens,
|
|
11
|
+
paContextualTokens,
|
|
12
|
+
paLightTheme,
|
|
13
|
+
paDarkTheme,
|
|
14
|
+
} from './designTokens'
|
|
15
|
+
import { createFlattenTheme } from './designTokens/utils'
|
|
16
|
+
import { fr } from 'vuetify/locale'
|
|
17
|
+
|
|
18
|
+
export const createVuetifyInstance = () => createVuetify({
|
|
19
|
+
components,
|
|
20
|
+
directives,
|
|
21
|
+
locale: {
|
|
22
|
+
locale: 'fr',
|
|
23
|
+
messages: { fr },
|
|
24
|
+
},
|
|
25
|
+
theme: {
|
|
26
|
+
defaultTheme: 'cnam',
|
|
27
|
+
themes: {
|
|
28
|
+
cnam: {
|
|
29
|
+
dark: false,
|
|
30
|
+
colors: {
|
|
31
|
+
...cnamLightTheme,
|
|
32
|
+
...cnamDarkTheme,
|
|
33
|
+
},
|
|
34
|
+
variables: {
|
|
35
|
+
'border-color': cnamColorsTokens.grey.base,
|
|
36
|
+
'font-family': '"Arial", sans-serif',
|
|
37
|
+
...createFlattenTheme(cnamContextualTokens),
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
pa: {
|
|
41
|
+
dark: false,
|
|
42
|
+
colors: {
|
|
43
|
+
...paLightTheme,
|
|
44
|
+
...paDarkTheme,
|
|
45
|
+
},
|
|
46
|
+
variables: {
|
|
47
|
+
'border-color': paColorsTokens.grey.base,
|
|
48
|
+
'font-family': '"Roboto", sans-serif',
|
|
49
|
+
...createFlattenTheme(paContextualTokens),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
icons: {
|
|
55
|
+
defaultSet: 'mdi',
|
|
56
|
+
aliases,
|
|
57
|
+
sets: {
|
|
58
|
+
mdi,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
})
|